Mercurial > hg > graal-compiler
diff src/share/tools/hsdis/hsdis.c @ 6782:5a98bf7d847b
6879063: SA should use hsdis for disassembly
Summary: We should in SA to use hsdis for it like the JVM does to replace the current java based disassembler.
Reviewed-by: twisti, jrose, sla
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 24 Sep 2012 12:44:00 -0700 |
parents | de34c646c3f7 |
children | 3d701c802d01 |
line wrap: on
line diff
--- a/src/share/tools/hsdis/hsdis.c Thu Sep 20 03:49:15 2012 -0700 +++ b/src/share/tools/hsdis/hsdis.c Mon Sep 24 12:44:00 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,13 +27,13 @@ HotSpot PrintAssembly option. */ -#include "hsdis.h" - -#include <sysdep.h> #include <libiberty.h> #include <bfd.h> #include <dis-asm.h> #include <inttypes.h> +#include <string.h> +#include <errno.h> +#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 @@ -89,59 +95,91 @@ #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); +} + +/* This is the compatability interface for older version of hotspot */ +void* +#ifdef DLL_ENTRY + DLL_ENTRY +#endif decode_instructions(void* start_pv, void* end_pv, 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 = (uintptr_t) start_pv; - app_data.end = (uintptr_t) end_pv; - 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; + decode_instructions_virtual((uintptr_t)start_pv, + (uintptr_t)end_pv, + (unsigned char*)start_pv, + (uintptr_t)end_pv - (uintptr_t)start_pv, + event_callback_arg, + event_stream_arg, + printf_callback_arg, + printf_stream_arg, + options); +} - setup_app_data(&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 +188,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 +227,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; } } @@ -407,16 +446,16 @@ static const char* native_arch_name() { const char* res = NULL; #ifdef LIBARCH_i386 - res = "i386"; + res = "i386"; #endif #ifdef LIBARCH_amd64 - res = "i386:x86-64"; + res = "i386:x86-64"; #endif #ifdef LIBARCH_sparc - res = "sparc:v8plusb"; + res = "sparc:v8plusb"; #endif #ifdef LIBARCH_sparcv9 - res = "sparc:v9b"; + res = "sparc:v9b"; #endif if (res == NULL) res = "architecture not set in Makefile!"; @@ -468,7 +507,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; }