hotspot/src/share/tools/hsdis/hsdis-demo.c
changeset 13873 7b72e3873785
parent 8921 14bfe81f2a9d
child 14384 801df8025142
equal deleted inserted replaced
13871:6f15b84496b0 13873:7b72e3873785
     1 /*
     1 /*
     2  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    24 
    24 
    25 /* hsdis-demo.c -- dump a range of addresses as native instructions
    25 /* hsdis-demo.c -- dump a range of addresses as native instructions
    26    This demonstrates the protocol required by the HotSpot PrintAssembly option.
    26    This demonstrates the protocol required by the HotSpot PrintAssembly option.
    27 */
    27 */
    28 
    28 
       
    29 #include <stdio.h>
       
    30 #include <stdlib.h>
       
    31 #include <string.h>
       
    32 #include <inttypes.h>
       
    33 
    29 #include "hsdis.h"
    34 #include "hsdis.h"
    30 
    35 
    31 #include "stdio.h"
       
    32 #include "stdlib.h"
       
    33 #include "string.h"
       
    34 
    36 
    35 void greet(const char*);
    37 void greet(const char*);
    36 void disassemble(void*, void*);
    38 void disassemble(uintptr_t, uintptr_t);
    37 void end_of_file();
    39 void end_of_file();
    38 
    40 
    39 const char* options = NULL;
    41 const char* options = NULL;
    40 int         raw     = 0;
    42 int         raw     = 0;
    41 int         xml     = 0;
    43 int         xml     = 0;
    60     greeted = 1;
    62     greeted = 1;
    61   }
    63   }
    62   if (!greeted)
    64   if (!greeted)
    63     greet("world");
    65     greet("world");
    64   printf("...And now for something completely different:\n");
    66   printf("...And now for something completely different:\n");
    65   disassemble((void*) &main, (void*) &end_of_file);
    67   void *start = (void*) &main;
       
    68   void *end = (void*) &end_of_file;
       
    69 #if defined(__ia64) || defined(__powerpc__)
       
    70   /* On IA64 and PPC function pointers are pointers to function descriptors */
       
    71   start = *((void**)start);
       
    72   end = *((void**)end);
       
    73 #endif
       
    74   disassemble(start, (end > start) ? end : start + 64);
    66   printf("Cheers!\n");
    75   printf("Cheers!\n");
    67 }
    76 }
    68 
    77 
    69 void greet(const char* whom) {
    78 void greet(const char* whom) {
    70   printf("Hello, %s!\n", whom);
    79   printf("Hello, %s!\n", whom);
    74 
    83 
    75 /* don't disassemble after this point... */
    84 /* don't disassemble after this point... */
    76 
    85 
    77 #include "dlfcn.h"
    86 #include "dlfcn.h"
    78 
    87 
    79 #define DECODE_INSTRUCTIONS_NAME "decode_instructions"
    88 #define DECODE_INSTRUCTIONS_NAME "decode_instructions_virtual"
    80 #define HSDIS_NAME               "hsdis"
    89 #define HSDIS_NAME               "hsdis"
    81 static void* decode_instructions_pv = 0;
    90 static void* decode_instructions_pv = 0;
    82 static const char* hsdis_path[] = {
    91 static const char* hsdis_path[] = {
    83   HSDIS_NAME"-"LIBARCH LIB_EXT,
    92   HSDIS_NAME"-"LIBARCH LIB_EXT,
    84   "./" HSDIS_NAME"-"LIBARCH LIB_EXT,
    93   "./" HSDIS_NAME"-"LIBARCH LIB_EXT,
   106   }
   115   }
   107 }
   116 }
   108 
   117 
   109 
   118 
   110 static const char* lookup(void* addr) {
   119 static const char* lookup(void* addr) {
       
   120 #if defined(__ia64) || defined(__powerpc__)
       
   121   /* On IA64 and PPC function pointers are pointers to function descriptors */
       
   122 #define CHECK_NAME(fn) \
       
   123   if (addr == *((void**) &fn))  return #fn;
       
   124 #else
   111 #define CHECK_NAME(fn) \
   125 #define CHECK_NAME(fn) \
   112   if (addr == (void*) &fn)  return #fn;
   126   if (addr == (void*) &fn)  return #fn;
       
   127 #endif
   113 
   128 
   114   CHECK_NAME(main);
   129   CHECK_NAME(main);
   115   CHECK_NAME(greet);
   130   CHECK_NAME(greet);
   116   return NULL;
   131   return NULL;
   117 }
   132 }
   121   (!strncmp(event, tag, sizeof(tag)-1) && \
   136   (!strncmp(event, tag, sizeof(tag)-1) && \
   122    (!event[sizeof(tag)-1] || strchr(" /", event[sizeof(tag)-1])))
   137    (!event[sizeof(tag)-1] || strchr(" /", event[sizeof(tag)-1])))
   123 
   138 
   124 
   139 
   125 static const char event_cookie[] = "event_cookie"; /* demo placeholder */
   140 static const char event_cookie[] = "event_cookie"; /* demo placeholder */
       
   141 static void* simple_handle_event(void* cookie, const char* event, void* arg) {
       
   142   if (MATCH(event, "/insn")) {
       
   143     // follow each complete insn by a nice newline
       
   144     printf("\n");
       
   145   }
       
   146   return NULL;
       
   147 }
       
   148 
   126 static void* handle_event(void* cookie, const char* event, void* arg) {
   149 static void* handle_event(void* cookie, const char* event, void* arg) {
   127 #define NS_DEMO "demo:"
   150 #define NS_DEMO "demo:"
   128   if (cookie != event_cookie)
   151   if (cookie != event_cookie)
   129     printf("*** bad event cookie %p != %p\n", cookie, event_cookie);
   152     printf("*** bad event cookie %p != %p\n", cookie, event_cookie);
   130 
   153 
   160 
   183 
   161     /* basic action for <insn>: */
   184     /* basic action for <insn>: */
   162     printf(" %p\t", arg);
   185     printf(" %p\t", arg);
   163 
   186 
   164   } else if (MATCH(event, "/insn")) {
   187   } else if (MATCH(event, "/insn")) {
   165     /* basic action for </insn>:
   188     // follow each complete insn by a nice newline
   166        (none, plugin puts the newline for us
   189     printf("\n");
   167     */
       
   168 
       
   169   } else if (MATCH(event, "mach")) {
   190   } else if (MATCH(event, "mach")) {
   170     printf("Decoding for CPU '%s'\n", (char*) arg);
   191     printf("Decoding for CPU '%s'\n", (char*) arg);
   171 
   192 
   172   } else if (MATCH(event, "addr")) {
   193   } else if (MATCH(event, "addr")) {
   173     /* basic action for <addr/>: */
   194     /* basic action for <addr/>: */
   184 }
   205 }
   185 
   206 
   186 #define fprintf_callback \
   207 #define fprintf_callback \
   187   (decode_instructions_printf_callback_ftype)&fprintf
   208   (decode_instructions_printf_callback_ftype)&fprintf
   188 
   209 
   189 void disassemble(void* from, void* to) {
   210 void disassemble(uintptr_t from, uintptr_t to) {
   190   const char* err = load_decode_instructions();
   211   const char* err = load_decode_instructions();
   191   if (err != NULL) {
   212   if (err != NULL) {
   192     printf("%s: %s\n", err, dlerror());
   213     printf("%s: %s\n", err, dlerror());
   193     exit(1);
   214     exit(1);
   194   }
   215   }
   195   printf("Decoding from %p to %p...\n", from, to);
   216   printf("Decoding from %p to %p...\n", from, to);
   196   decode_instructions_ftype decode_instructions
   217   decode_instructions_ftype decode_instructions
   197     = (decode_instructions_ftype) decode_instructions_pv;
   218     = (decode_instructions_ftype) decode_instructions_pv;
   198   void* res;
   219   void* res;
   199   if (raw && xml) {
   220   if (raw && xml) {
   200     res = (*decode_instructions)(from, to, NULL, stdout, NULL, stdout, options);
   221     res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
   201   } else if (raw) {
   222   } else if (raw) {
   202     res = (*decode_instructions)(from, to, NULL, NULL, NULL, stdout, options);
   223     res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
   203   } else {
   224   } else {
   204     res = (*decode_instructions)(from, to,
   225     res = (*decode_instructions)(from, to, (unsigned char*)from, to - from,
   205                                  handle_event, (void*) event_cookie,
   226                                  handle_event, (void*) event_cookie,
   206                                  fprintf_callback, stdout,
   227                                  fprintf_callback, stdout,
   207                                  options);
   228                                  options);
   208   }
   229   }
   209   if (res != to)
   230   if (res != (void*)to)
   210     printf("*** Result was %p!\n", res);
   231     printf("*** Result was %p!\n", res);
   211 }
   232 }