--- old/src/share/tools/hsdis/hsdis.c Thu Sep 17 16:09:20 2009 +++ new/src/share/tools/hsdis/hsdis.c Thu Sep 17 16:09:20 2009 @@ -27,13 +27,13 @@ HotSpot PrintAssembly option. */ -#include "hsdis.h" - -#include #include #include #include #include +#include +#include +#include "hsdis.h" #ifndef bool #define bool int @@ -47,11 +47,15 @@ /* disassemble_info.application_data object */ struct hsdis_app_data { - /* the arguments to decode_instructions */ - uintptr_t start; uintptr_t end; + /* virtual address of data */ + uintptr_t start_va, end_va; + /* the instructions to be decoded */ + unsigned char* buffer; + uintptr_t length; event_callback_t event_callback; void* event_stream; printf_callback_t printf_callback; void* printf_stream; bool losing; + bool do_newline; /* the architecture being disassembled */ const char* arch_name; @@ -65,6 +69,8 @@ char insn_options[256]; }; +static void* decode(struct hsdis_app_data* app_data, const char* options); + #define DECL_APP_DATA(dinfo) \ struct hsdis_app_data* app_data = (struct hsdis_app_data*) (dinfo)->application_data @@ -85,6 +91,7 @@ disassemble_info* dinfo, char* buf, size_t bufsize); +/* This is the compatability interface for older version of hotspot */ void* #ifdef DLL_ENTRY DLL_ENTRY @@ -95,53 +102,88 @@ const char* options) { struct hsdis_app_data app_data; memset(&app_data, 0, sizeof(app_data)); - app_data.start = (uintptr_t) start_pv; - app_data.end = (uintptr_t) end_pv; + app_data.buffer = (unsigned char*) start_pv; + app_data.length = (uintptr_t)end_pv - (uintptr_t)start_pv; + app_data.start_va = (uintptr_t) start_pv; + app_data.end_va = app_data.start_va + app_data.length; app_data.event_callback = event_callback_arg; app_data.event_stream = event_stream_arg; app_data.printf_callback = printf_callback_arg; app_data.printf_stream = printf_stream_arg; + app_data.do_newline = true; - setup_app_data(&app_data, options); + return decode(&app_data, options); +} + +void* +#ifdef DLL_ENTRY + DLL_ENTRY +#endif +decode_instructions_virtual(uintptr_t start_va, uintptr_t end_va, + unsigned char* buffer, uintptr_t length, + event_callback_t event_callback_arg, void* event_stream_arg, + printf_callback_t printf_callback_arg, void* printf_stream_arg, + const char* options) { + struct hsdis_app_data app_data; + memset(&app_data, 0, sizeof(app_data)); + app_data.start_va = start_va; + app_data.end_va = end_va; + app_data.buffer = buffer; + app_data.length = length; + app_data.event_callback = event_callback_arg; + app_data.event_stream = event_stream_arg; + app_data.printf_callback = printf_callback_arg; + app_data.printf_stream = printf_stream_arg; + app_data.do_newline = false; + + return decode(&app_data, options); +} + +static void* decode(struct hsdis_app_data* app_data, const char* options) { + setup_app_data(app_data, options); char buf[128]; { /* now reload everything from app_data: */ - DECL_EVENT_CALLBACK(&app_data); - DECL_PRINTF_CALLBACK(&app_data); - uintptr_t start = app_data.start; - uintptr_t end = app_data.end; + DECL_EVENT_CALLBACK(app_data); + DECL_PRINTF_CALLBACK(app_data); + uintptr_t start = app_data->start_va; + uintptr_t end = app_data->end_va; uintptr_t p = start; (*event_callback)(event_stream, "insns", (void*)start); (*event_callback)(event_stream, "mach name='%s'", - (void*) app_data.arch_info->printable_name); - if (app_data.dinfo.bytes_per_line != 0) { + (void*) app_data->arch_info->printable_name); + if (app_data->dinfo.bytes_per_line != 0) { (*event_callback)(event_stream, "format bytes-per-line='%p'/", - (void*)(intptr_t) app_data.dinfo.bytes_per_line); + (void*)(intptr_t) app_data->dinfo.bytes_per_line); } - while (p < end && !app_data.losing) { + while (p < end && !app_data->losing) { (*event_callback)(event_stream, "insn", (void*) p); /* reset certain state, so we can read it with confidence */ - app_data.dinfo.insn_info_valid = 0; - app_data.dinfo.branch_delay_insns = 0; - app_data.dinfo.data_size = 0; - app_data.dinfo.insn_type = 0; + app_data->dinfo.insn_info_valid = 0; + app_data->dinfo.branch_delay_insns = 0; + app_data->dinfo.data_size = 0; + app_data->dinfo.insn_type = 0; - int size = (*app_data.dfn)((bfd_vma) p, &app_data.dinfo); + int size = (*app_data->dfn)((bfd_vma) p, &app_data->dinfo); if (size > 0) p += size; - else app_data.losing = true; + else app_data->losing = true; - const char* insn_close = format_insn_close("/insn", &app_data.dinfo, - buf, sizeof(buf)); - (*event_callback)(event_stream, insn_close, (void*) p); + if (!app_data->losing) { + const char* insn_close = format_insn_close("/insn", &app_data->dinfo, + buf, sizeof(buf)); + (*event_callback)(event_stream, insn_close, (void*) p) != NULL; - /* follow each complete insn by a nice newline */ - (*printf_callback)(printf_stream, "\n"); + if (app_data->do_newline) { + /* follow each complete insn by a nice newline */ + (*printf_callback)(printf_stream, "\n"); + } + } } (*event_callback)(event_stream, "/insns", (void*) p); @@ -150,7 +192,7 @@ } /* take the address of the function, for luck, and also test the typedef: */ -const decode_instructions_ftype decode_instructions_address = &decode_instructions; +const decode_instructions_ftype decode_instructions_address = &decode_instructions_virtual; static const char* format_insn_close(const char* close, disassemble_info* dinfo, @@ -189,13 +231,14 @@ bfd_byte* myaddr, unsigned int length, struct disassemble_info* dinfo) { - uintptr_t memaddr_p = (uintptr_t) memaddr; DECL_APP_DATA(dinfo); - if (memaddr_p + length > app_data->end) { + /* convert the virtual address memaddr into an address within memory buffer */ + uintptr_t offset = ((uintptr_t) memaddr) - app_data->start_va; + if (offset + length > app_data->length) { /* read is out of bounds */ return EIO; } else { - memcpy(myaddr, (bfd_byte*) memaddr_p, length); + memcpy(myaddr, (bfd_byte*) (app_data->buffer + offset), length); return 0; } } @@ -357,7 +400,7 @@ strncpy(mach_option, p, plen); mach_option[plen] = '\0'; } else if (plen > 6 && strncmp(p, "hsdis-", 6)) { - // do not pass these to the next level + /* do not pass these to the next level */ } else { /* just copy it; {i386,sparc}-dis.c might like to see it */ if (iop > iop_base && iop < iop_limit) (*iop++) = ','; @@ -468,7 +511,7 @@ dinfo->fprintf_func = &print_to_dev_null; (*dfn)(0, dinfo); - // put it back: + /* put it back */ dinfo->read_memory_func = read_memory_func; dinfo->fprintf_func = fprintf_func; }