/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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.
*/
#include "hsdis.h"
#include <sysdep.h>
#include <libiberty.h>
#include <bfd.h>
#include <dis-asm.h>
#include <inttypes.h>
#ifndef bool
#define bool int
#define true 1
#define false 0
#endif /*bool*/
/* short names for stuff in hsdis.h */
/* disassemble_info.application_data object */
struct hsdis_app_data {
/* the arguments to decode_instructions */
bool losing;
/* the architecture being disassembled */
const char* arch_name;
/* the disassembler we are going to use: */
};
const char* options);
static const char* format_insn_close(const char* close,
void*
#ifdef DLL_ENTRY
#endif
const char* options) {
{
/* now reload everything from app_data: */
}
/* reset certain state, so we can read it with confidence */
/* follow each complete insn by a nice newline */
}
return (void*) p;
}
}
/* take the address of the function, for luck, and also test the typedef: */
if (!dinfo->insn_info_valid)
return close;
return close;
switch (itype) {
}
char* p = buf;
return buf;
}
/* handler functions */
static int
unsigned int length,
struct disassemble_info* dinfo) {
/* read is out of bounds */
return EIO;
} else {
return 0;
}
}
static void
/* the actual value to print: */
/* issue the event: */
void* result =
/* event declined */
}
}
/* configuration */
const char* caller_options);
static const char* native_arch_name();
static enum bfd_endian native_endian();
/* to avoid malloc: */
void *stream,
char* disassembler_options);
struct disassemble_info* dinfo);
const char* 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.
*/
/* Look into caller_options for anything interesting. */
if (caller_options != NULL)
/* Discover which architecture we are going to disassemble. */
/* Make a fake bfd to hold the arch. and byteorder info. */
struct {
} buf;
/* to avoid malloc: */
/* Finish linking together the various callback blocks. */
static bool complained;
else if (!complained)
complained = true;
/* must bail out */
return;
}
}
/* ignore all events, return a null */
return NULL;
}
/* print all events as XML markup */
if (event[0] != '/') {
/* issue the tag, with or without a formatted argument */
} else {
++event; /* skip slash */
/* no arguments; just issue the closing tag */
} else {
/* split out the closing attributes as <dis:foo_done attr='val'/> */
}
}
return NULL;
}
}
else
}
}
const char* p;
for (p = caller_options; p != NULL; ) {
const char* q = strchr(p, ',');
// do not pass these to the next level
} else {
/* just copy it; {i386,sparc}-dis.c might like to see it */
}
p = q;
}
}
}
else
#if defined(LIBARCH_i386) || defined(LIBARCH_amd64)
#endif
}
/* low-level bfd and arch stuff that binutils doesn't do for us */
extern const bfd_arch_info_type bfd_default_arch_struct;
}
return arch_info;
}
static const char* native_arch_name() {
#ifdef LIBARCH_i386
res = "i386";
#endif
#ifdef LIBARCH_amd64
res = "i386:x86-64";
#endif
#ifdef LIBARCH_sparc
res = "sparc:v8plusb";
#endif
#ifdef LIBARCH_sparcv9
res = "sparc:v9b";
#endif
res = "architecture not set in Makefile!";
return res;
}
if (*(const char*) &endian_test == 'x')
return BFD_ENDIAN_LITTLE;
else
return BFD_ENDIAN_BIG;
}
return empty_bfd;
}
struct disassemble_info *ignore_info) {
return 0;
}
return 0;
}
/* 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.
*/
struct disassemble_info* dinfo) {
typedef int (*read_memory_ftype)
struct disassemble_info *info);
// put it back:
}
void *stream,
char* disassembler_options) {
if (bfd_big_endian(abfd))
else if (bfd_little_endian(abfd))
else
}