< prev index next >

src/solaris/demo/jvmti/hprof/hprof_md.c

Print this page
rev 8219 : 8024900: PPC64: Enable new build on AIX (jdk part)
8024854: PPC64: Basic changes and files to build the class library on AIX
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan, art, erikj
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com


  25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30  */
  31 
  32 /*
  33  * This source code is provided to illustrate the usage of a given feature
  34  * or technique and has been deliberately simplified. Additional steps
  35  * required for a production-quality application, such as security checks,
  36  * input validation and proper error handling, might not be present in
  37  * this sample code.
  38  */
  39 
  40 
  41 #include <sys/types.h>
  42 #include <sys/stat.h>
  43 #include <fcntl.h>
  44 
  45 #if !defined(LINUX) && !defined(_ALLBSD_SOURCE)
  46 #include <procfs.h>
  47 #endif
  48 
  49 #include <stdio.h>
  50 #include <stdlib.h>
  51 #include <string.h>
  52 #include <sys/socket.h>
  53 #include <sys/errno.h>
  54 #include <unistd.h>
  55 #include <errno.h>
  56 #include <dlfcn.h>
  57 #include <sys/time.h>
  58 
  59 #include <netdb.h>
  60 #include <netinet/in.h>
  61 #include <sys/param.h>
  62 #include <time.h>
  63 
  64 #include "jni.h"
  65 #include "jvm_md.h"
  66 #include "hprof.h"
  67 















  68 int
  69 md_getpid(void)
  70 {
  71     static int pid = -1;
  72 
  73     if ( pid >= 0 ) {
  74         return pid;
  75     }
  76     pid = getpid();
  77     return pid;
  78 }
  79 
  80 void
  81 md_sleep(unsigned seconds)
  82 {
  83     sleep(seconds);
  84 }
  85 
  86 void
  87 md_init(void)
  88 {
  89 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
  90     /* No Hi-Res timer option? */
  91 #else
  92     if ( gdata->micro_state_accounting ) {
  93         char proc_ctl_fn[48];
  94         int  procfd;
  95 
  96         /* Turn on micro state accounting, once per process */
  97         (void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn),
  98                 "/proc/%d/ctl", md_getpid());
  99 
 100         procfd = open(proc_ctl_fn, O_WRONLY);
 101         if (procfd >= 0) {
 102             long ctl_op[2];
 103 
 104             ctl_op[0] = PCSET;
 105             ctl_op[1] = PR_MSACCT;
 106             (void)write(procfd, ctl_op, sizeof(ctl_op));
 107             (void)close(procfd);
 108         }
 109     }


 231     return res;
 232 }
 233 
 234 /* Time of day in milli-seconds */
 235 static jlong
 236 md_timeofday(void)
 237 {
 238     struct timeval tv;
 239 
 240     if ( gettimeofday(&tv, (void *)0) != 0 ) {
 241         return (jlong)0; /* EOVERFLOW ? */
 242     }
 243     /*LINTED*/
 244     return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000);
 245 }
 246 
 247 /* Hi-res timer in micro-seconds */
 248 jlong
 249 md_get_microsecs(void)
 250 {
 251 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
 252     return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */
 253 #else
 254     return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */
 255 #endif
 256 }
 257 
 258 /* Time of day in milli-seconds */
 259 jlong
 260 md_get_timemillis(void)
 261 {
 262     return md_timeofday();
 263 }
 264 
 265 /* Current CPU hi-res CPU time used */
 266 jlong
 267 md_get_thread_cpu_timemillis(void)
 268 {
 269 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
 270     return md_timeofday();
 271 #else
 272     return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */
 273 #endif
 274 }
 275 
 276 void
 277 md_get_prelude_path(char *path, int path_len, char *filename)
 278 {
 279     void *addr;
 280     char libdir[FILENAME_MAX+1];
 281     Dl_info dlinfo;
 282 
 283     libdir[0] = 0;
 284 #if defined(LINUX) || defined(_ALLBSD_SOURCE)
 285     addr = (void*)&Agent_OnLoad;
 286 #else
 287     /* Just using &Agent_OnLoad will get the first external symbol with
 288      *   this name in the first .so, which may not be libhprof.so.
 289      *   On Solaris we can actually ask for the address of our Agent_OnLoad.
 290      */
 291     addr = dlsym(RTLD_SELF, "Agent_OnLoad");
 292     /* Just in case the above didn't work (missing linker patch?). */
 293     if ( addr == NULL ) {
 294         addr = (void*)&Agent_OnLoad;
 295     }
 296 #endif
 297 
 298     /* Use dladdr() to get the full path to libhprof.so, which we use to find
 299      *  the prelude file.
 300      */
 301     dlinfo.dli_fname = NULL;
 302     (void)dladdr(addr, &dlinfo);
 303     if ( dlinfo.dli_fname != NULL ) {
 304         char * lastSlash;


 435     }
 436     return result;
 437 }
 438 
 439 /* Unload this library */
 440 void
 441 md_unload_library(void *handle)
 442 {
 443     (void)dlclose(handle);
 444 }
 445 
 446 /* Find an entry point inside this library (return NULL if not found) */
 447 void *
 448 md_find_library_entry(void *handle, const char *name)
 449 {
 450     void * sym;
 451 
 452     sym =  dlsym(handle, name);
 453     return sym;
 454 }






























































  25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30  */
  31 
  32 /*
  33  * This source code is provided to illustrate the usage of a given feature
  34  * or technique and has been deliberately simplified. Additional steps
  35  * required for a production-quality application, such as security checks,
  36  * input validation and proper error handling, might not be present in
  37  * this sample code.
  38  */
  39 
  40 
  41 #include <sys/types.h>
  42 #include <sys/stat.h>
  43 #include <fcntl.h>
  44 
  45 #if !defined(LINUX) && !defined(_ALLBSD_SOURCE) && !defined(AIX)
  46 #include <procfs.h>
  47 #endif
  48 
  49 #include <stdio.h>
  50 #include <stdlib.h>
  51 #include <string.h>
  52 #include <sys/socket.h>
  53 #include <sys/errno.h>
  54 #include <unistd.h>
  55 #include <errno.h>
  56 #include <dlfcn.h>
  57 #include <sys/time.h>
  58 
  59 #include <netdb.h>
  60 #include <netinet/in.h>
  61 #include <sys/param.h>
  62 #include <time.h>
  63 
  64 #include "jni.h"
  65 #include "jvm_md.h"
  66 #include "hprof.h"
  67 
  68 
  69 #ifdef AIX
  70 /* SAPJVM */
  71 #include <sys/ldr.h>
  72 #include <errno.h>
  73 typedef struct {
  74   const char *dli_fname;
  75   void *dli_fbase;
  76   const char *dli_sname;
  77   void *dli_saddr;
  78 } Dl_info;
  79 
  80 static int dladdr(void *addr, Dl_info *info);
  81 #endif /* AIX */
  82 
  83 int
  84 md_getpid(void)
  85 {
  86     static int pid = -1;
  87 
  88     if ( pid >= 0 ) {
  89         return pid;
  90     }
  91     pid = getpid();
  92     return pid;
  93 }
  94 
  95 void
  96 md_sleep(unsigned seconds)
  97 {
  98     sleep(seconds);
  99 }
 100 
 101 void
 102 md_init(void)
 103 {
 104 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
 105     /* No Hi-Res timer option? */
 106 #else
 107     if ( gdata->micro_state_accounting ) {
 108         char proc_ctl_fn[48];
 109         int  procfd;
 110 
 111         /* Turn on micro state accounting, once per process */
 112         (void)md_snprintf(proc_ctl_fn, sizeof(proc_ctl_fn),
 113                 "/proc/%d/ctl", md_getpid());
 114 
 115         procfd = open(proc_ctl_fn, O_WRONLY);
 116         if (procfd >= 0) {
 117             long ctl_op[2];
 118 
 119             ctl_op[0] = PCSET;
 120             ctl_op[1] = PR_MSACCT;
 121             (void)write(procfd, ctl_op, sizeof(ctl_op));
 122             (void)close(procfd);
 123         }
 124     }


 246     return res;
 247 }
 248 
 249 /* Time of day in milli-seconds */
 250 static jlong
 251 md_timeofday(void)
 252 {
 253     struct timeval tv;
 254 
 255     if ( gettimeofday(&tv, (void *)0) != 0 ) {
 256         return (jlong)0; /* EOVERFLOW ? */
 257     }
 258     /*LINTED*/
 259     return ((jlong)tv.tv_sec * (jlong)1000) + (jlong)(tv.tv_usec / 1000);
 260 }
 261 
 262 /* Hi-res timer in micro-seconds */
 263 jlong
 264 md_get_microsecs(void)
 265 {
 266 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
 267     return (jlong)(md_timeofday() * (jlong)1000); /* Milli to micro */
 268 #else
 269     return (jlong)(gethrtime()/(hrtime_t)1000); /* Nano seconds to micro seconds */
 270 #endif
 271 }
 272 
 273 /* Time of day in milli-seconds */
 274 jlong
 275 md_get_timemillis(void)
 276 {
 277     return md_timeofday();
 278 }
 279 
 280 /* Current CPU hi-res CPU time used */
 281 jlong
 282 md_get_thread_cpu_timemillis(void)
 283 {
 284 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
 285     return md_timeofday();
 286 #else
 287     return (jlong)(gethrvtime()/1000); /* Nano seconds to milli seconds */
 288 #endif
 289 }
 290 
 291 void
 292 md_get_prelude_path(char *path, int path_len, char *filename)
 293 {
 294     void *addr;
 295     char libdir[FILENAME_MAX+1];
 296     Dl_info dlinfo;
 297 
 298     libdir[0] = 0;
 299 #if defined(LINUX) || defined(_ALLBSD_SOURCE) || defined(AIX)
 300     addr = (void*)&Agent_OnLoad;
 301 #else
 302     /* Just using &Agent_OnLoad will get the first external symbol with
 303      *   this name in the first .so, which may not be libhprof.so.
 304      *   On Solaris we can actually ask for the address of our Agent_OnLoad.
 305      */
 306     addr = dlsym(RTLD_SELF, "Agent_OnLoad");
 307     /* Just in case the above didn't work (missing linker patch?). */
 308     if ( addr == NULL ) {
 309         addr = (void*)&Agent_OnLoad;
 310     }
 311 #endif
 312 
 313     /* Use dladdr() to get the full path to libhprof.so, which we use to find
 314      *  the prelude file.
 315      */
 316     dlinfo.dli_fname = NULL;
 317     (void)dladdr(addr, &dlinfo);
 318     if ( dlinfo.dli_fname != NULL ) {
 319         char * lastSlash;


 450     }
 451     return result;
 452 }
 453 
 454 /* Unload this library */
 455 void
 456 md_unload_library(void *handle)
 457 {
 458     (void)dlclose(handle);
 459 }
 460 
 461 /* Find an entry point inside this library (return NULL if not found) */
 462 void *
 463 md_find_library_entry(void *handle, const char *name)
 464 {
 465     void * sym;
 466 
 467     sym =  dlsym(handle, name);
 468     return sym;
 469 }
 470 
 471 #ifdef AIX
 472 
 473 /* SAPJVM:
 474  * workaround for the missing dladdr */
 475 static unsigned char dladdr_buffer[0x4000];
 476 
 477 static void fill_dll_info(void) {
 478   int rc = loadquery(L_GETINFO,dladdr_buffer, sizeof(dladdr_buffer));
 479   if (rc == -1) {
 480     fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno));
 481     fflush(stderr);
 482   }
 483 }
 484 
 485 static int dladdr_dont_reload(void* addr, Dl_info* info) {
 486   const struct ld_info* p = (struct ld_info*) dladdr_buffer;
 487   info->dli_fbase = 0; info->dli_fname = 0;
 488   info->dli_sname = 0; info->dli_saddr = 0;
 489   for (;;) {
 490     if (addr >= p->ldinfo_textorg &&
 491             addr < (((char*)p->ldinfo_textorg) + p->ldinfo_textsize)) {
 492       info->dli_fname = p->ldinfo_filename;
 493       info->dli_fbase = p->ldinfo_textorg;
 494       return 1; /* [sic] */
 495     }
 496     if (!p->ldinfo_next) {
 497       break;
 498     }
 499     p = (struct ld_info*)(((char*)p) + p->ldinfo_next);
 500   }
 501   return 0; /* [sic] */
 502 }
 503 
 504 static int dladdr(void *addr, Dl_info *info) {
 505   static int loaded = 0;
 506   if (!loaded) {
 507     fill_dll_info();
 508     loaded = 1;
 509   }
 510   if (!addr) {
 511     return 0;  /* [sic] */
 512   }
 513   /* Address cuold be AIX function descriptor? */
 514   void* const addr0 = *( (void**) addr );
 515   int rc = dladdr_dont_reload(addr, info);
 516   if (rc == 0) {
 517     rc = dladdr_dont_reload(addr0, info);
 518     if (rc == 0) { /* [sic] */
 519       fill_dll_info(); /* refill, maybe loadquery info is outdated */
 520       rc = dladdr_dont_reload(addr, info);
 521       if (rc == 0) {
 522         rc = dladdr_dont_reload(addr0, info);
 523       }
 524     }
 525   }
 526   return rc;
 527 }
 528 
 529 #endif /* AIX */
< prev index next >