/* * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 * * Subject to the condition set forth below, permission is hereby granted to * any person obtaining a copy of this software, associated documentation * and/or data (collectively the "Software"), free of charge and under any * and all copyright rights in the Software, and any and all patent rights * owned or freely licensable by each licensor hereunder covering either (i) * the unmodified Software as contributed to or provided by such licensor, * or (ii) the Larger Works (as defined below), to deal in both * * (a) the Software, and * * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file * if one is included with the Software (each a "Larger Work" to which the * Software is contributed by such licensors), * * without restriction, including without limitation the rights to copy, * create derivative works of, display, perform, and distribute the Software * and make, use, sell, offer for sale, import, export, have made, and have * sold the Software and the Larger Work(s), and to sublicense the foregoing * rights on either these or other terms. * * This license is subject to the following condition: * * The above copyright notice and either this complete permission notice or * at a minimum a reference to the UPL must be included in all copies or * substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
/* hsdis.c -- dump a range of addresses as native instructions This implements the plugin protocol required by the HotSpot PrintAssembly option.
*/
#ifndef SYSTEM_BINUTILS #include <config.h> /* required by bfd.h */ #endif
/* short names for stuff in hsdis.h */ typedef decode_instructions_event_callback_ftype event_callback_t; typedef decode_instructions_printf_callback_ftype printf_callback_t;
/* disassemble_info.application_data object */ struct hsdis_app_data { /* virtual address of data */
uintptr_t start_va, end_va; /* the instructions to be decoded */ unsignedchar* 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 */ constchar* arch_name; const bfd_arch_info_type* arch_info;
/* the disassembler we are going to use: */
disassembler_ftype dfn; struct disassemble_info dinfo; /* the actual struct! */
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;
int size = (*app_data->dfn)((bfd_vma) p, &app_data->dinfo);
if (size > 0) p += size; else app_data->losing = true;
/* take the address of the function, for luck, and also test the typedef: */ const decode_func_vtype decode_func_virtual_address = &decode_instructions_virtual; const decode_func_stype decode_func_address = &decode_instructions;
constchar* type = "unknown"; switch (itype) { case dis_nonbranch: type = NULL; break; case dis_branch: type = "branch"; break; case dis_condbranch: type = "condbranch"; break; case dis_jsr: type = "jsr"; break; case dis_condjsr: type = "condjsr"; break; case dis_dref: type = "dref"; break; case dis_dref2: type = "dref2"; break; case dis_noninsn: type = "noninsn"; break;
}
strcpy(buf, close); char* p = buf; if (type) sprintf(p += strlen(p), " type='%s'", type); if (dsize) sprintf(p += strlen(p), " dsize='%d'", dsize); if (delays) sprintf(p += strlen(p), " delay='%d'", delays); return buf;
}
/* handler functions */
staticint
hsdis_read_memory_func(bfd_vma memaddr,
bfd_byte* myaddr, unsignedint length, struct disassemble_info* dinfo) {
DECL_APP_DATA(dinfo); /* 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*) (app_data->buffer + offset), length); return 0;
}
}
staticvoid
hsdis_print_address_func(bfd_vma vma, struct disassemble_info* dinfo) { /* the actual value to print: */ void* addr_value = (void*) (uintptr_t) vma;
DECL_APP_DATA(dinfo);
DECL_EVENT_CALLBACK(app_data);
/* issue the event: */ void* result =
(*event_callback)(event_stream, "addr/", addr_value); if (result == NULL) { /* event declined */
generic_print_address(vma, dinfo);
}
}
staticvoid setup_app_data(struct hsdis_app_data* app_data, constchar* caller_options) { /* Make reasonable defaults for null callbacks. A non-null stream for a null callback is assumed to be a FILE* for output. Events are rendered as XML.
*/
set_optional_callbacks(app_data);
/* Look into caller_options for anything interesting. */ if (caller_options != NULL)
parse_caller_options(app_data, caller_options);
/* Discover which architecture we are going to disassemble. */
app_data->arch_name = &app_data->mach_option[0]; if (app_data->arch_name[0] == '\0')
app_data->arch_name = native_arch_name();
app_data->arch_info = find_arch_info(app_data->arch_name);
/* Make a fake bfd to hold the arch. and byteorder info. */ struct {
bfd_target empty_xvec;
bfd empty_bfd;
} buf;
bfd* native_bfd = get_native_bfd(app_data->arch_info, /* to avoid malloc: */
&buf.empty_bfd, &buf.empty_xvec);
init_disassemble_info_from_bfd(&app_data->dinfo,
app_data->printf_stream,
app_data->printf_callback,
native_bfd, /* On PowerPC we get warnings, if we pass empty options */
(caller_options == NULL) ? NULL : app_data->insn_options);
/* Finish linking together the various callback blocks. */
app_data->dinfo.application_data = (void*) app_data;
app_data->dfn = disassembler(bfd_get_arch(native_bfd),
bfd_big_endian(native_bfd),
bfd_get_mach(native_bfd),
native_bfd);
app_data->dinfo.print_address_func = hsdis_print_address_func;
app_data->dinfo.read_memory_func = hsdis_read_memory_func;
if (app_data->dfn == NULL) { constchar* bad = app_data->arch_name; staticbool complained; if (bad == &app_data->mach_option[0])
print_help(app_data, "bad mach=%s", bad); elseif (!complained)
print_help(app_data, "bad native mach=%s; please port hsdis to this platform", bad);
complained = true; /* must bail out */
app_data->losing = true; return;
}
staticconstchar* native_arch_name() { constchar* res = NULL; #ifdef LIBARCH_i386
res = "i386"; #endif #ifdef LIBARCH_amd64
res = "i386:x86-64"; #endif #ifdefined(LIBARCH_ppc64) || defined(LIBARCH_ppc64le)
res = "powerpc:common64"; #endif #ifdef LIBARCH_arm
res = "arm"; #endif #ifdef LIBARCH_aarch64
res = "aarch64"; #endif #ifdef LIBARCH_s390x
res = "s390:64-bit"; #endif #ifdef LIBARCH_riscv64
res = "riscv:rv64"; #endif if (res == NULL)
res = "architecture not set in Makefile!"; return res;
}
/* Prime the pump by running the selected disassembler on a null input. This forces the machine-specific disassembler to divulge invariant information like bytes_per_line.
*/ staticvoid parse_fake_insn(disassembler_ftype dfn, struct disassemble_info* dinfo) { typedefint (*read_memory_ftype)
(bfd_vma memaddr, bfd_byte *myaddr, unsignedint length, struct disassemble_info *info);
read_memory_ftype read_memory_func = dinfo->read_memory_func;
fprintf_ftype fprintf_func = dinfo->fprintf_func;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.