1 /*
2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
95 va_start(alist, format);
96 fputs("libsaproc DEBUG: ", stderr);
97 vfprintf(stderr, format, alist);
98 va_end(alist);
99 }
100 }
101
102 void print_error(const char* format,...) {
103 va_list alist;
104 va_start(alist, format);
105 fputs("ERROR: ", stderr);
106 vfprintf(stderr, format, alist);
107 va_end(alist);
108 }
109
110 bool is_debug() {
111 return _libsaproc_debug;
112 }
113
114 // initialize libproc
115 bool init_libproc(bool debug) {
116 // init debug mode
117 _libsaproc_debug = debug;
118
119 // initialize the thread_db library
120 if (td_init() != TD_OK) {
121 print_debug("libthread_db's td_init failed\n");
122 return false;
123 }
124
125 return true;
126 }
127
128 static void destroy_lib_info(struct ps_prochandle* ph) {
129 lib_info* lib = ph->libs;
130 while (lib) {
131 lib_info *next = lib->next;
132 if (lib->symtab) {
133 destroy_symtab(lib->symtab);
134 }
135 free(lib);
136 lib = next;
137 }
138 }
139
140 static void destroy_thread_info(struct ps_prochandle* ph) {
141 thread_info* thr = ph->threads;
142 while (thr) {
143 thread_info *next = thr->next;
144 free(thr);
145 thr = next;
146 }
147 }
148
149 // ps_prochandle cleanup
150
151 // ps_prochandle cleanup
152 void Prelease(struct ps_prochandle* ph) {
153 // do the "derived class" clean-up first
154 ph->ops->release(ph);
155 destroy_lib_info(ph);
156 destroy_thread_info(ph);
157 free(ph);
158 }
159
160 lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) {
161 return add_lib_info_fd(ph, libname, -1, base);
162 }
163
164 lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
165 lib_info* newlib;
166
167 if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
168 print_debug("can't allocate memory for lib_info\n");
169 return NULL;
170 }
171
172 if (strlen(libname) >= sizeof(newlib->name)) {
381 lib = lib->next;
382 }
383 return (uintptr_t)NULL;
384 }
385
386 bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
387 lib_info *p = ph->libs;
388 while (p) {
389 if (strcmp(p->name, lib_name) == 0) {
390 return true;
391 }
392 p = p->next;
393 }
394 return false;
395 }
396
397 //--------------------------------------------------------------------------
398 // proc service functions
399
400 // get process id
401 pid_t ps_getpid(struct ps_prochandle *ph) {
402 return ph->pid;
403 }
404
405 // ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
406 // of the load object object_name in the target process identified by ph.
407 // It returns the symbol's value as an address in the target process in
408 // *sym_addr.
409
410 ps_err_e ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
411 const char *sym_name, psaddr_t *sym_addr) {
412 *sym_addr = (psaddr_t) lookup_symbol(ph, object_name, sym_name);
413 return (*sym_addr ? PS_OK : PS_NOSYM);
414 }
415
416 // read "size" bytes info "buf" from address "addr"
417 ps_err_e ps_pdread(struct ps_prochandle *ph, psaddr_t addr,
418 void *buf, size_t size) {
419 return ph->ops->p_pread(ph, (uintptr_t) addr, buf, size)? PS_OK: PS_ERR;
420 }
421
422 // write "size" bytes of data to debuggee at address "addr"
423 ps_err_e ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr,
424 const void *buf, size_t size) {
425 return ph->ops->p_pwrite(ph, (uintptr_t)addr, buf, size)? PS_OK: PS_ERR;
426 }
427
428 // ------------------------------------------------------------------------
429 // Functions below this point are not yet implemented. They are here only
430 // to make the linker happy.
431
432 ps_err_e ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs) {
433 print_debug("ps_lsetfpregs not implemented\n");
434 return PS_OK;
435 }
436
437 ps_err_e ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset) {
438 print_debug("ps_lsetregs not implemented\n");
439 return PS_OK;
440 }
441
442 ps_err_e ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lid, prfpregset_t *fpregs) {
443 print_debug("ps_lgetfpregs not implemented\n");
444 return PS_OK;
445 }
446
447 ps_err_e ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) {
448 print_debug("ps_lgetfpregs not implemented\n");
449 return PS_OK;
450 }
451
452 // new libthread_db of NPTL seem to require this symbol
453 ps_err_e ps_get_thread_area() {
454 print_debug("ps_get_thread_area not implemented\n");
455 return PS_OK;
456 }
|
1 /*
2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
95 va_start(alist, format);
96 fputs("libsaproc DEBUG: ", stderr);
97 vfprintf(stderr, format, alist);
98 va_end(alist);
99 }
100 }
101
102 void print_error(const char* format,...) {
103 va_list alist;
104 va_start(alist, format);
105 fputs("ERROR: ", stderr);
106 vfprintf(stderr, format, alist);
107 va_end(alist);
108 }
109
110 bool is_debug() {
111 return _libsaproc_debug;
112 }
113
114 // initialize libproc
115 JNIEXPORT bool JNICALL
116 init_libproc(bool debug) {
117 // init debug mode
118 _libsaproc_debug = debug;
119
120 // initialize the thread_db library
121 if (td_init() != TD_OK) {
122 print_debug("libthread_db's td_init failed\n");
123 return false;
124 }
125
126 return true;
127 }
128
129 static void destroy_lib_info(struct ps_prochandle* ph) {
130 lib_info* lib = ph->libs;
131 while (lib) {
132 lib_info *next = lib->next;
133 if (lib->symtab) {
134 destroy_symtab(lib->symtab);
135 }
136 free(lib);
137 lib = next;
138 }
139 }
140
141 static void destroy_thread_info(struct ps_prochandle* ph) {
142 thread_info* thr = ph->threads;
143 while (thr) {
144 thread_info *next = thr->next;
145 free(thr);
146 thr = next;
147 }
148 }
149
150 // ps_prochandle cleanup
151
152 // ps_prochandle cleanup
153 JNIEXPORT void JNICALL
154 Prelease(struct ps_prochandle* ph) {
155 // do the "derived class" clean-up first
156 ph->ops->release(ph);
157 destroy_lib_info(ph);
158 destroy_thread_info(ph);
159 free(ph);
160 }
161
162 lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t base) {
163 return add_lib_info_fd(ph, libname, -1, base);
164 }
165
166 lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd, uintptr_t base) {
167 lib_info* newlib;
168
169 if ( (newlib = (lib_info*) calloc(1, sizeof(struct lib_info))) == NULL) {
170 print_debug("can't allocate memory for lib_info\n");
171 return NULL;
172 }
173
174 if (strlen(libname) >= sizeof(newlib->name)) {
383 lib = lib->next;
384 }
385 return (uintptr_t)NULL;
386 }
387
388 bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
389 lib_info *p = ph->libs;
390 while (p) {
391 if (strcmp(p->name, lib_name) == 0) {
392 return true;
393 }
394 p = p->next;
395 }
396 return false;
397 }
398
399 //--------------------------------------------------------------------------
400 // proc service functions
401
402 // get process id
403 JNIEXPORT pid_t JNICALL
404 ps_getpid(struct ps_prochandle *ph) {
405 return ph->pid;
406 }
407
408 // ps_pglobal_lookup() looks up the symbol sym_name in the symbol table
409 // of the load object object_name in the target process identified by ph.
410 // It returns the symbol's value as an address in the target process in
411 // *sym_addr.
412
413 JNIEXPORT ps_err_e JNICALL
414 ps_pglobal_lookup(struct ps_prochandle *ph, const char *object_name,
415 const char *sym_name, psaddr_t *sym_addr) {
416 *sym_addr = (psaddr_t) lookup_symbol(ph, object_name, sym_name);
417 return (*sym_addr ? PS_OK : PS_NOSYM);
418 }
419
420 // read "size" bytes info "buf" from address "addr"
421 JNIEXPORT ps_err_e JNICALL
422 ps_pdread(struct ps_prochandle *ph, psaddr_t addr,
423 void *buf, size_t size) {
424 return ph->ops->p_pread(ph, (uintptr_t) addr, buf, size)? PS_OK: PS_ERR;
425 }
426
427 // write "size" bytes of data to debuggee at address "addr"
428 JNIEXPORT ps_err_e JNICALL
429 ps_pdwrite(struct ps_prochandle *ph, psaddr_t addr,
430 const void *buf, size_t size) {
431 return ph->ops->p_pwrite(ph, (uintptr_t)addr, buf, size)? PS_OK: PS_ERR;
432 }
433
434 // ------------------------------------------------------------------------
435 // Functions below this point are not yet implemented. They are here only
436 // to make the linker happy.
437
438 JNIEXPORT ps_err_e JNICALL
439 ps_lsetfpregs(struct ps_prochandle *ph, lwpid_t lid, const prfpregset_t *fpregs) {
440 print_debug("ps_lsetfpregs not implemented\n");
441 return PS_OK;
442 }
443
444 JNIEXPORT ps_err_e JNICALL
445 ps_lsetregs(struct ps_prochandle *ph, lwpid_t lid, const prgregset_t gregset) {
446 print_debug("ps_lsetregs not implemented\n");
447 return PS_OK;
448 }
449
450 JNIEXPORT ps_err_e JNICALL
451 ps_lgetfpregs(struct ps_prochandle *ph, lwpid_t lid, prfpregset_t *fpregs) {
452 print_debug("ps_lgetfpregs not implemented\n");
453 return PS_OK;
454 }
455
456 JNIEXPORT ps_err_e JNICALL
457 ps_lgetregs(struct ps_prochandle *ph, lwpid_t lid, prgregset_t gregset) {
458 print_debug("ps_lgetfpregs not implemented\n");
459 return PS_OK;
460 }
461
462 // new libthread_db of NPTL seem to require this symbol
463 JNIEXPORT ps_err_e JNICALL
464 ps_get_thread_area() {
465 print_debug("ps_get_thread_area not implemented\n");
466 return PS_OK;
467 }
|