nkeynes@362: /* Interface between the opcode library and its callers. nkeynes@362: nkeynes@362: Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 nkeynes@362: Free Software Foundation, Inc. nkeynes@362: nkeynes@362: This program is free software; you can redistribute it and/or modify nkeynes@362: it under the terms of the GNU General Public License as published by nkeynes@362: the Free Software Foundation; either version 2, or (at your option) nkeynes@362: any later version. nkeynes@362: nkeynes@362: This program is distributed in the hope that it will be useful, nkeynes@362: but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@362: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@362: GNU General Public License for more details. nkeynes@362: nkeynes@362: You should have received a copy of the GNU General Public License nkeynes@362: along with this program; if not, write to the Free Software nkeynes@362: Foundation, Inc., 59 Temple Place - Suite 330, nkeynes@362: Boston, MA 02111-1307, USA. nkeynes@362: nkeynes@362: Written by Cygnus Support, 1993. nkeynes@362: nkeynes@362: The opcode library (libopcodes.a) provides instruction decoders for nkeynes@362: a large variety of instruction sets, callable with an identical nkeynes@362: interface, for making instruction-processing programs more independent nkeynes@362: of the instruction set being processed. */ nkeynes@362: nkeynes@362: #ifndef DIS_ASM_H nkeynes@362: #define DIS_ASM_H nkeynes@362: nkeynes@362: #ifdef __cplusplus nkeynes@362: extern "C" { nkeynes@362: #endif nkeynes@362: nkeynes@362: #include nkeynes@755: #include "x86dasm/bfd.h" nkeynes@362: nkeynes@362: typedef int (*fprintf_ftype) (void *, const char*, ...); nkeynes@362: nkeynes@362: enum dis_insn_type { nkeynes@362: dis_noninsn, /* Not a valid instruction */ nkeynes@362: dis_nonbranch, /* Not a branch instruction */ nkeynes@362: dis_branch, /* Unconditional branch */ nkeynes@362: dis_condbranch, /* Conditional branch */ nkeynes@362: dis_jsr, /* Jump to subroutine */ nkeynes@362: dis_condjsr, /* Conditional jump to subroutine */ nkeynes@362: dis_dref, /* Data reference instruction */ nkeynes@362: dis_dref2 /* Two data references in instruction */ nkeynes@362: }; nkeynes@362: nkeynes@362: /* This struct is passed into the instruction decoding routine, nkeynes@362: and is passed back out into each callback. The various fields are used nkeynes@362: for conveying information from your main routine into your callbacks, nkeynes@362: for passing information into the instruction decoders (such as the nkeynes@362: addresses of the callback functions), or for passing information nkeynes@362: back from the instruction decoders to their callers. nkeynes@362: nkeynes@362: It must be initialized before it is first passed; this can be done nkeynes@362: by hand, or using one of the initialization macros below. */ nkeynes@362: nkeynes@362: typedef struct disassemble_info { nkeynes@362: fprintf_ftype fprintf_func; nkeynes@362: void *stream; nkeynes@362: void *application_data; nkeynes@362: nkeynes@362: /* Target description. We could replace this with a pointer to the bfd, nkeynes@362: but that would require one. There currently isn't any such requirement nkeynes@362: so to avoid introducing one we record these explicitly. */ nkeynes@362: /* The bfd_flavour. This can be bfd_target_unknown_flavour. */ nkeynes@362: enum bfd_flavour flavour; nkeynes@362: /* The bfd_arch value. */ nkeynes@362: enum bfd_architecture arch; nkeynes@362: /* The bfd_mach value. */ nkeynes@362: unsigned long mach; nkeynes@362: /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */ nkeynes@362: enum bfd_endian endian; nkeynes@362: /* An arch/mach-specific bitmask of selected instruction subsets, mainly nkeynes@362: for processors with run-time-switchable instruction sets. The default, nkeynes@362: zero, means that there is no constraint. CGEN-based opcodes ports nkeynes@362: may use ISA_foo masks. */ nkeynes@362: unsigned long insn_sets; nkeynes@362: nkeynes@362: /* Some targets need information about the current section to accurately nkeynes@362: display insns. If this is NULL, the target disassembler function nkeynes@362: will have to make its best guess. */ nkeynes@362: asection *section; nkeynes@362: nkeynes@362: /* An array of pointers to symbols either at the location being disassembled nkeynes@362: or at the start of the function being disassembled. The array is sorted nkeynes@362: so that the first symbol is intended to be the one used. The others are nkeynes@362: present for any misc. purposes. This is not set reliably, but if it is nkeynes@362: not NULL, it is correct. */ nkeynes@362: asymbol **symbols; nkeynes@362: /* Number of symbols in array. */ nkeynes@362: int num_symbols; nkeynes@362: nkeynes@362: /* For use by the disassembler. nkeynes@362: The top 16 bits are reserved for public use (and are documented here). nkeynes@362: The bottom 16 bits are for the internal use of the disassembler. */ nkeynes@362: unsigned long flags; nkeynes@362: #define INSN_HAS_RELOC 0x80000000 nkeynes@362: void *private_data; nkeynes@362: nkeynes@362: /* Function used to get bytes to disassemble. MEMADDR is the nkeynes@362: address of the stuff to be disassembled, MYADDR is the address to nkeynes@362: put the bytes in, and LENGTH is the number of bytes to read. nkeynes@362: INFO is a pointer to this struct. nkeynes@362: Returns an errno value or 0 for success. */ nkeynes@362: int (*read_memory_func) nkeynes@362: (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, nkeynes@362: struct disassemble_info *info); nkeynes@362: nkeynes@362: /* Function which should be called if we get an error that we can't nkeynes@362: recover from. STATUS is the errno value from read_memory_func and nkeynes@362: MEMADDR is the address that we were trying to read. INFO is a nkeynes@362: pointer to this struct. */ nkeynes@362: void (*memory_error_func) nkeynes@362: (int status, bfd_vma memaddr, struct disassemble_info *info); nkeynes@362: nkeynes@362: /* Function called to print ADDR. */ nkeynes@362: void (*print_address_func) nkeynes@362: (bfd_vma addr, struct disassemble_info *info); nkeynes@362: nkeynes@362: /* Function called to determine if there is a symbol at the given ADDR. nkeynes@362: If there is, the function returns 1, otherwise it returns 0. nkeynes@362: This is used by ports which support an overlay manager where nkeynes@362: the overlay number is held in the top part of an address. In nkeynes@362: some circumstances we want to include the overlay number in the nkeynes@362: address, (normally because there is a symbol associated with nkeynes@362: that address), but sometimes we want to mask out the overlay bits. */ nkeynes@362: int (* symbol_at_address_func) nkeynes@362: (bfd_vma addr, struct disassemble_info * info); nkeynes@362: nkeynes@362: /* Function called to check if a SYMBOL is can be displayed to the user. nkeynes@362: This is used by some ports that want to hide special symbols when nkeynes@362: displaying debugging outout. */ nkeynes@362: bfd_boolean (* symbol_is_valid) nkeynes@362: (asymbol *, struct disassemble_info * info); nkeynes@362: nkeynes@362: /* These are for buffer_read_memory. */ nkeynes@362: bfd_byte *buffer; nkeynes@362: bfd_vma buffer_vma; nkeynes@362: unsigned int buffer_length; nkeynes@362: nkeynes@362: /* This variable may be set by the instruction decoder. It suggests nkeynes@362: the number of bytes objdump should display on a single line. If nkeynes@362: the instruction decoder sets this, it should always set it to nkeynes@362: the same value in order to get reasonable looking output. */ nkeynes@362: int bytes_per_line; nkeynes@362: nkeynes@362: /* The next two variables control the way objdump displays the raw data. */ nkeynes@362: /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */ nkeynes@362: /* output will look like this: nkeynes@362: 00: 00000000 00000000 nkeynes@362: with the chunks displayed according to "display_endian". */ nkeynes@362: int bytes_per_chunk; nkeynes@362: enum bfd_endian display_endian; nkeynes@362: nkeynes@362: /* Number of octets per incremented target address nkeynes@362: Normally one, but some DSPs have byte sizes of 16 or 32 bits. */ nkeynes@362: unsigned int octets_per_byte; nkeynes@362: nkeynes@362: /* The number of zeroes we want to see at the end of a section before we nkeynes@362: start skipping them. */ nkeynes@362: unsigned int skip_zeroes; nkeynes@362: nkeynes@362: /* The number of zeroes to skip at the end of a section. If the number nkeynes@362: of zeroes at the end is between SKIP_ZEROES_AT_END and SKIP_ZEROES, nkeynes@362: they will be disassembled. If there are fewer than nkeynes@362: SKIP_ZEROES_AT_END, they will be skipped. This is a heuristic nkeynes@362: attempt to avoid disassembling zeroes inserted by section nkeynes@362: alignment. */ nkeynes@362: unsigned int skip_zeroes_at_end; nkeynes@362: nkeynes@362: /* Results from instruction decoders. Not all decoders yet support nkeynes@362: this information. This info is set each time an instruction is nkeynes@362: decoded, and is only valid for the last such instruction. nkeynes@362: nkeynes@362: To determine whether this decoder supports this information, set nkeynes@362: insn_info_valid to 0, decode an instruction, then check it. */ nkeynes@362: nkeynes@362: char insn_info_valid; /* Branch info has been set. */ nkeynes@362: char branch_delay_insns; /* How many sequential insn's will run before nkeynes@362: a branch takes effect. (0 = normal) */ nkeynes@362: char data_size; /* Size of data reference in insn, in bytes */ nkeynes@362: enum dis_insn_type insn_type; /* Type of instruction */ nkeynes@362: bfd_vma target; /* Target address of branch or dref, if known; nkeynes@362: zero if unknown. */ nkeynes@362: bfd_vma target2; /* Second target address for dref2 */ nkeynes@362: nkeynes@362: /* Command line options specific to the target disassembler. */ nkeynes@362: char * disassembler_options; nkeynes@362: nkeynes@362: } disassemble_info; nkeynes@362: nkeynes@362: nkeynes@362: /* Standard disassemblers. Disassemble one instruction at the given nkeynes@362: target address. Return number of octets processed. */ nkeynes@362: typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); nkeynes@362: nkeynes@362: extern int print_insn_big_mips (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_little_mips (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_i386 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_i386_att (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_i386_intel (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_ia64 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_i370 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_m68hc11 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_m68hc12 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_m68k (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_z8001 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_z8002 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_h8300 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_h8300h (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_h8300s (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_h8500 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_alpha (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_big_arm (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_little_arm (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_sparc (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_big_a29k (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_little_a29k (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_avr (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_d10v (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_d30v (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_dlx (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_fr30 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_hppa (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_i860 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_i960 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_ip2k (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_m32r (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_m88k (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_maxq_little (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_maxq_big (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_mcore (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_mmix (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_mn10200 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_mn10300 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_msp430 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_ns32k (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_crx (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_openrisc (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_big_or32 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_little_or32 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_pdp11 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_pj (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_big_powerpc (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_little_powerpc (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_rs6000 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_s390 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_sh (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_tic30 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_tic4x (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_tic54x (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_tic80 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_v850 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_vax (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_w65 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_xstormy16 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_xtensa (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_sh64 (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_sh64x_media (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_frv (bfd_vma, disassemble_info *); nkeynes@362: extern int print_insn_iq2000 (bfd_vma, disassemble_info *); nkeynes@362: nkeynes@362: extern disassembler_ftype arc_get_disassembler (void *); nkeynes@362: extern disassembler_ftype cris_get_disassembler (bfd *); nkeynes@362: nkeynes@362: extern void print_mips_disassembler_options (FILE *); nkeynes@362: extern void print_ppc_disassembler_options (FILE *); nkeynes@362: extern void print_arm_disassembler_options (FILE *); nkeynes@362: extern void parse_arm_disassembler_option (char *); nkeynes@362: extern int get_arm_regname_num_options (void); nkeynes@362: extern int set_arm_regname_option (int); nkeynes@362: extern int get_arm_regnames (int, const char **, const char **, const char ***); nkeynes@362: extern bfd_boolean arm_symbol_is_valid (asymbol *, struct disassemble_info *); nkeynes@362: nkeynes@362: /* Fetch the disassembler for a given BFD, if that support is available. */ nkeynes@362: extern disassembler_ftype disassembler (bfd *); nkeynes@362: nkeynes@362: /* Amend the disassemble_info structure as necessary for the target architecture. nkeynes@362: Should only be called after initialising the info->arch field. */ nkeynes@362: extern void disassemble_init_for_target (struct disassemble_info * info); nkeynes@362: nkeynes@362: /* Document any target specific options available from the disassembler. */ nkeynes@362: extern void disassembler_usage (FILE *); nkeynes@362: nkeynes@362: nkeynes@362: /* This block of definitions is for particular callers who read instructions nkeynes@362: into a buffer before calling the instruction decoder. */ nkeynes@362: nkeynes@362: /* Here is a function which callers may wish to use for read_memory_func. nkeynes@362: It gets bytes from a buffer. */ nkeynes@362: extern int buffer_read_memory nkeynes@362: (bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *); nkeynes@362: nkeynes@362: /* This function goes with buffer_read_memory. nkeynes@362: It prints a message using info->fprintf_func and info->stream. */ nkeynes@362: extern void perror_memory (int, bfd_vma, struct disassemble_info *); nkeynes@362: nkeynes@362: nkeynes@362: /* Just print the address in hex. This is included for completeness even nkeynes@362: though both GDB and objdump provide their own (to print symbolic nkeynes@362: addresses). */ nkeynes@362: extern void generic_print_address nkeynes@362: (bfd_vma, struct disassemble_info *); nkeynes@362: nkeynes@362: /* Always true. */ nkeynes@362: extern int generic_symbol_at_address nkeynes@362: (bfd_vma, struct disassemble_info *); nkeynes@362: nkeynes@362: /* Also always true. */ nkeynes@362: extern bfd_boolean generic_symbol_is_valid nkeynes@362: (asymbol *, struct disassemble_info *); nkeynes@362: nkeynes@362: /* Method to initialize a disassemble_info struct. This should be nkeynes@362: called by all applications creating such a struct. */ nkeynes@362: extern void init_disassemble_info (struct disassemble_info *info, void *stream, nkeynes@362: fprintf_ftype fprintf_func); nkeynes@362: nkeynes@362: /* For compatibility with existing code. */ nkeynes@362: #define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \ nkeynes@362: init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC)) nkeynes@362: #define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \ nkeynes@362: init_disassemble_info (&(INFO), (STREAM), (fprintf_ftype) (FPRINTF_FUNC)) nkeynes@362: nkeynes@362: nkeynes@362: #ifdef __cplusplus nkeynes@362: } nkeynes@362: #endif nkeynes@362: nkeynes@362: #endif /* ! defined (DIS_ASM_H) */