Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/tools/hsdis/hsdis-demo.c
32285 views
/*1* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* The Universal Permissive License (UPL), Version 1.05*6* Subject to the condition set forth below, permission is hereby granted to7* any person obtaining a copy of this software, associated documentation8* and/or data (collectively the "Software"), free of charge and under any9* and all copyright rights in the Software, and any and all patent rights10* owned or freely licensable by each licensor hereunder covering either (i)11* the unmodified Software as contributed to or provided by such licensor,12* or (ii) the Larger Works (as defined below), to deal in both13*14* (a) the Software, and15*16* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file17* if one is included with the Software (each a "Larger Work" to which the18* Software is contributed by such licensors),19*20* without restriction, including without limitation the rights to copy,21* create derivative works of, display, perform, and distribute the Software22* and make, use, sell, offer for sale, import, export, have made, and have23* sold the Software and the Larger Work(s), and to sublicense the foregoing24* rights on either these or other terms.25*26* This license is subject to the following condition:27*28* The above copyright notice and either this complete permission notice or29* at a minimum a reference to the UPL must be included in all copies or30* substantial portions of the Software.31*32* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS33* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF34* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN35* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,36* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR37* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE38* USE OR OTHER DEALINGS IN THE SOFTWARE.39*40* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA41* or visit www.oracle.com if you need additional information or have any42* questions.43*44*/4546/* hsdis-demo.c -- dump a range of addresses as native instructions47This demonstrates the protocol required by the HotSpot PrintAssembly option.48*/4950#include <stdio.h>51#include <stdlib.h>52#include <string.h>53#include <inttypes.h>5455#include "hsdis.h"565758void greet(const char*);59void disassemble(uintptr_t, uintptr_t);60void end_of_file();6162const char* options = NULL;63int raw = 0;64int xml = 0;6566int main(int ac, char** av) {67int greeted = 0;68int i;69for (i = 1; i < ac; i++) {70const char* arg = av[i];71if (arg[0] == '-') {72if (!strcmp(arg, "-xml"))73xml ^= 1;74else if (!strcmp(arg, "-raw"))75raw ^= 1;76else if (!strncmp(arg, "-options=", 9))77options = arg+9;78else79{ printf("Usage: %s [-xml] [name...]\n", av[0]); exit(2); }80continue;81}82greet(arg);83greeted = 1;84}85if (!greeted)86greet("world");87printf("...And now for something completely different:\n");88void *start = (void*) &main;89void *end = (void*) &end_of_file;90#if defined(__ia64) || (defined(__powerpc__) && !defined(ABI_ELFv2))91/* On IA64 and PPC function pointers are pointers to function descriptors */92start = *((void**)start);93end = *((void**)end);94#endif95disassemble(start, (end > start) ? end : start + 64);96printf("Cheers!\n");97}9899void greet(const char* whom) {100printf("Hello, %s!\n", whom);101}102103void end_of_file() { }104105/* don't disassemble after this point... */106107#include "dlfcn.h"108109#define DECODE_INSTRUCTIONS_VIRTUAL_NAME "decode_instructions_virtual"110#define DECODE_INSTRUCTIONS_NAME "decode_instructions"111#define HSDIS_NAME "hsdis"112static void* decode_instructions_pv = 0;113static void* decode_instructions_sv = 0;114static const char* hsdis_path[] = {115HSDIS_NAME"-"LIBARCH LIB_EXT,116"./" HSDIS_NAME"-"LIBARCH LIB_EXT,117#ifdef TARGET_DIR118TARGET_DIR"/"HSDIS_NAME"-"LIBARCH LIB_EXT,119#endif120NULL121};122123static const char* load_decode_instructions() {124void* dllib = NULL;125const char* *next_in_path = hsdis_path;126while (1) {127decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_VIRTUAL_NAME);128decode_instructions_sv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);129if (decode_instructions_pv != NULL || decode_instructions_sv != NULL)130return NULL;131if (dllib != NULL)132return "plugin does not defined "DECODE_INSTRUCTIONS_VIRTUAL_NAME" and "DECODE_INSTRUCTIONS_NAME;133for (dllib = NULL; dllib == NULL; ) {134const char* next_lib = (*next_in_path++);135if (next_lib == NULL)136return "cannot find plugin "HSDIS_NAME LIB_EXT;137dllib = dlopen(next_lib, RTLD_LAZY);138}139}140}141142143static const char* lookup(void* addr) {144#if defined(__ia64) || defined(__powerpc__)145/* On IA64 and PPC function pointers are pointers to function descriptors */146#define CHECK_NAME(fn) \147if (addr == *((void**) &fn)) return #fn;148#else149#define CHECK_NAME(fn) \150if (addr == (void*) &fn) return #fn;151#endif152153CHECK_NAME(main);154CHECK_NAME(greet);155return NULL;156}157158/* does the event match the tag, followed by a null, space, or slash? */159#define MATCH(event, tag) \160(!strncmp(event, tag, sizeof(tag)-1) && \161(!event[sizeof(tag)-1] || strchr(" /", event[sizeof(tag)-1])))162163164static const char event_cookie[] = "event_cookie"; /* demo placeholder */165static void* simple_handle_event(void* cookie, const char* event, void* arg) {166if (MATCH(event, "/insn")) {167// follow each complete insn by a nice newline168printf("\n");169}170return NULL;171}172173static void* handle_event(void* cookie, const char* event, void* arg) {174#define NS_DEMO "demo:"175if (cookie != event_cookie)176printf("*** bad event cookie %p != %p\n", cookie, event_cookie);177178if (xml) {179/* We could almost do a printf(event, arg),180but for the sake of a better demo,181we dress the result up as valid XML.182*/183const char* fmt = strchr(event, ' ');184int evlen = (fmt ? fmt - event : strlen(event));185if (!fmt) {186if (event[0] != '/') {187printf("<"NS_DEMO"%.*s>", evlen, event);188} else {189printf("</"NS_DEMO"%.*s>", evlen-1, event+1);190}191} else {192if (event[0] != '/') {193printf("<"NS_DEMO"%.*s", evlen, event);194printf(fmt, arg);195printf(">");196} else {197printf("<"NS_DEMO"%.*s_done", evlen-1, event+1);198printf(fmt, arg);199printf("/></"NS_DEMO"%.*s>", evlen-1, event+1);200}201}202}203204if (MATCH(event, "insn")) {205const char* name = lookup(arg);206if (name) printf("%s:\n", name);207208/* basic action for <insn>: */209printf(" %p\t", arg);210211} else if (MATCH(event, "/insn")) {212// follow each complete insn by a nice newline213printf("\n");214} else if (MATCH(event, "mach")) {215printf("Decoding for CPU '%s'\n", (char*) arg);216217} else if (MATCH(event, "addr")) {218/* basic action for <addr/>: */219const char* name = lookup(arg);220if (name) {221printf("&%s (%p)", name, arg);222/* return non-null to notify hsdis not to print the addr */223return arg;224}225}226227/* null return is always safe; can mean "I ignored it" */228return NULL;229}230231#define fprintf_callback \232(decode_instructions_printf_callback_ftype)&fprintf233234void disassemble(uintptr_t from, uintptr_t to) {235const char* err = load_decode_instructions();236if (err != NULL) {237printf("%s: %s\n", err, dlerror());238exit(1);239}240decode_func_vtype decode_instructions_v241= (decode_func_vtype) decode_instructions_pv;242decode_func_stype decode_instructions_s243= (decode_func_stype) decode_instructions_sv;244void* res;245if (decode_instructions_pv != NULL) {246printf("\nDecoding from %p to %p...with %s\n", from, to, DECODE_INSTRUCTIONS_VIRTUAL_NAME);247if (raw) {248res = (*decode_instructions_v)(from, to,249(unsigned char*)from, to - from,250simple_handle_event, stdout,251NULL, stdout,252options, 0);253} else {254res = (*decode_instructions_v)(from, to,255(unsigned char*)from, to - from,256handle_event, (void*) event_cookie,257fprintf_callback, stdout,258options, 0);259}260if (res != (void*)to)261printf("*** Result was %p!\n", res);262}263void* sres;264if (decode_instructions_sv != NULL) {265printf("\nDecoding from %p to %p...with old decode_instructions\n", from, to, DECODE_INSTRUCTIONS_NAME);266if (raw) {267sres = (*decode_instructions_s)(from, to,268simple_handle_event, stdout,269NULL, stdout,270options);271} else {272sres = (*decode_instructions_s)(from, to,273handle_event, (void*) event_cookie,274fprintf_callback, stdout,275options);276}277if (sres != (void *)to)278printf("*** Result of decode_instructions %p!\n", sres);279}280}281282283