< prev index next >

src/jdk.hotspot.agent/linux/native/libsaproc/libproc_impl.c

Print this page


   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 }
< prev index next >