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, |
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 } |