home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file discribes the 88k disassember functions and structures.
- */
- #import <mach-o/nlist.h>
- #import <mach-o/reloc.h>
- #import "stuff/ofile.h"
- #import <mach-o/m88k/parseinst.h>
-
- /* This is the structure that is filled in by the get_reg() routine */
- union m88k_reg_value {
- struct {
- unsigned long w[4]; /* big endian, most significant word in w[0] */
- } words;
- float f;
- double d;
- };
-
- /*
- * This is the block of parameters for the disassembler. The block itself and
- * all fields are optional (must be 0 if not specified). The disassembler
- * routine never writes any of these fields.
- */
- struct m88k_disassembler_params {
- char *string_before_mnemonic; /* if NULL then "\t" is used */
- char *string_after_mnemonic; /* if NULL then "\t" is used */
-
- /* These are arrays of register names */
- char **general_registers; /* if NULL then "r0"..."r31" is used */
- char **extended_registers; /* if NULL then "x0"..."x31" is used */
- char **control_registers; /* if NULL then "cr0"..."cr63" is used */
- char **fp_control_registers;/* if NULL then "fcr0"..."fcr63" is used */
-
- /*
- * If the current_address parameter of m88k_disassembler() is not NULL and
- * the value it is pointing at is an address of an instruction that is
- * being disassembled then this function is used to get the values of the
- * register operands and they are added to that line as a comment. The
- * parameter num is the register's number, type is one of the four register
- * type m88k_operand_type enumeration constants, format is one of the
- * m88k_operand_format enumeration constants which describes the format and
- * width of the operand to be returned in the value parameter.
- */
- void (*get_reg)(unsigned long num,
- enum m88k_operand_type type,
- enum m88k_operand_format format,
- union m88k_reg_value *value);
-
- /* The default for all of these is flags is FALSE (0) */
- unsigned long
- /*
- * This causes the first thing on the line to be the 8 digit hex
- * address of the instruction (no leading 0x).
- */
- output_instruction_address:1,
- /*
- * This causes the next thing on the line to be the 8 digit hex
- * opcode of the instruction (no leading 0x).
- */
- output_instruction_opcode:1,
- /*
- * These next three are mutually exclusive and are order here is the
- * precedence if more than one is set. They provide different ways to
- * produce labels for instructions and operands of branches. When
- * output_manufactured_instruction_labels is set then targets of
- * branches that don't have symbols have labels of the form "Ln" (when
- * n is a number) are manufactured and only symbols names without an
- * offset are printed. If output_instruction_labels_and_offsets is
- * set then each instruction which has a symbol before it's address is
- * output with the previous symbol plus it's offset. If
- * output_instruction_labels is set then only instructions that have
- * symbols at their addresses are output as labels.
- */
- output_manufactured_instruction_labels:1,
- output_instruction_labels_and_offsets:1,
- output_instruction_labels:1,
- /* this allows for no partial lines to be placed in the buffer */
- output_nopartial_lines:1,
- /*
- * This forces the output to include the next instruction if the last
- * instruction in the range will cause the next instruction to be
- * executed.
- */
- output_execute_next_instructions:1,
- /*
- * This forces the disassembler to not guess a symbolic name for a
- * "symbol+value" operand when all it has is the resulting expression
- * value and not external relocation entries.
- */
- output_noguessed_operands:1,
- output_reserved_flags:24;
-
- /*
- * To get a symbol name for an address the function get_symbol() is used if
- * not NULL, or if NULL the symbol is searched for in the sorted_symbols,
- * nsorted_symbols, string_table and string_table_size if their values are
- * not NULL. The array of sorted_symbols should be sorted by the n_value
- * field and should contain only those symbols that should be considered
- * labels (things like stab entries should not appear). Then the n_strx
- * field of the symbol table entry is used as an index in to the
- * string_table. The function get_symbol() should return the name and
- * value of the symbol that is closest but not greater than addr. It
- * returns -1 if it can't find a symbol before that address and zero
- * otherwise. If get_symbol() is set it can use the field user_data
- * to get at any data it needs.
- */
- long (*get_symbol)(unsigned long addr, /* in */
- const struct m88k_disassembler_params *params, /* in */
- char **name, /* out */
- unsigned long *value); /* out */
- struct nlist *sorted_symbols;
- unsigned long nsorted_symbols;
- char *string_table;
- unsigned long string_table_size;
-
- /*
- * To get a "symbol+value" for an operand of an instruction the function
- * get_reloc() is used if not NULL, or if NULL the symbol is searched for
- * in the original_relocs, noriginal_relocs, original_symbols,
- * noriginal_symbols, as well as sorted_symbols, nsorted_symbols,
- * string_table, and string_table_size (from above) if their values are not
- * NULL. If the tables are used the r_address field of the relocation
- * entries must be changed to a true address and not left as an offset from
- * the start of a section. In the case of disassembling code from the first
- * section of a relocatable object that is linked at zero nothing has to be
- * done to the r_address field for this section's relocation entries. Since
- * the (__TEXT,__text) section is typically first and where disassembly is
- * typically done from and only relocatable objects tend to have relocation
- * entries this works without changing the r_address field. The relocation
- * entries must have their M88K_RELOC_PAIR entries following their
- * M88K_RELOC_{HI16,LO16} entries. The function get_reloc() should return
- * the name, value and type of the "symbol+value" expression for the
- * instruction at addr who opcodeis passed. The name can be returned as
- * NULL if no symbol name can be found and then only the value will be
- * output. The type returned should be one of the M88K_RELOC_* defined in
- * <reloc.h> for an instruction. Only the hi/lo types are used to print
- * the "hi16(symbol+value)" around the operand. Get_reloc() returns -1 if
- * it can't find a symbol/value/type for the address and zero otherwise.
- * If get_reloc() is set it can use the field user_data to get at any data
- * it needs.
- */
- long (*get_reloc)(unsigned long addr, /* in */
- unsigned long opcode, /* in */
- const struct m88k_disassembler_params *params, /* in */
- char **name, /* out */
- long *value, /* out */
- unsigned long *type); /* out */
- struct relocation_info *original_relocs;
- unsigned long noriginal_relocs;
- struct nlist *original_symbols;
- unsigned long noriginal_symbols;
-
- /* This is intended for the user and not used by m88k_disassembler() */
- void *user_data;
- };
-
- /*
- * m88k_disassembler() returns the numbers of bytes of the instructions it
- * disassembles or -1 for errors which prevent it from doing disassembly.
- * Non-fatal errors are just ignored and the best that can be done is done.
- * The range of addresses between start_addr through end_addr (exclusive) is
- * disassembled into the buffer of buffer_size. For one instruction start_addr
- * is equal end_addr. The function get_word() is called to get 32 bit words
- * for the address it is passed and sets word to the value of the 32 bit word.
- * The parameter get_word_data is passed to the function get_word() when called.
- * Get_word returns -1 when it can't get the word at the specified address and
- * zero otherwise. All other parameter are optional and must be NULL if not
- * specified. Params is a pointer to block of options (described above).
- * Current_address is use only for printing register values of the currently
- * executing instruction (see get_reg above). If number_of_instructions is not
- * NULL it is set to the count of instructions disassembled into the buffer.
- * If buffer_size_needed is not NULL it is set the size that is needed to fully
- * disassembled the instructions in the specified range into the buffer.
- */
- extern long m88k_disassembler(
- /* required parameters */
- unsigned long start_addr, /* in */
- unsigned long end_addr, /* in */
- char *buffer, /* in */
- unsigned long buffer_size, /* in */
- long (*get_word)(unsigned long addr /* in */,
- unsigned long *word /* out */,
- void *get_word_data /* in */), /* in */
- void *get_word_data, /* in */
-
- /* optional parameters, must be NULL if not specified */
- const struct m88k_disassembler_params *params, /* in */
- const unsigned long *current_address, /* in */
- unsigned long *number_of_instructions, /* out */
- unsigned long *buffer_size_needed); /* out */
-
- /*
- * m88k_disassemble_routine() returns a a pointer to a buffer that contains the
- * disassembled routine, routine_name, from the object file, object_name, in
- * the archive library, archive_name (or if archive_name is NULL from the named
- * object file). The buffer is created with malloc(3). The argument params is
- * used as the option to the disassembler routine m88k_disassembler() and maybe
- * NULL. This routine causes the symbolic tables in params to be set and then
- * cleared. If m88k_disassemble_routine() can't do it's job NULL is returned.
- */
- extern char * m88k_disassemble_routine(
- const char *archive_name,
- const char *object_name,
- const char *routine_name,
- struct m88k_disassembler_params *params);
-
- /*
- * m88k_disassembler_setup() sets up the symbolic tables that it can from the
- * ofile into the params for the object file (in the archive if archive_name is
- * not NULL). It returns -1 for failure and 0 for success.
- */
- extern long m88k_disassembler_setup(
- const char *archive_name,
- const char *object_name,
- struct m88k_disassembler_params *params,
- struct ofile *ofile);
-
- /*
- * m88k_disassembler_cleanup() cleans up the symbolic tables in param and closes
- * the ofile. It returns -1 for failure and 0 for success.
- */
- extern long m88k_disassembler_cleanup(
- struct m88k_disassembler_params *params,
- struct ofile *ofile);
-
- /*
- * m88k_disassembler_dbgmon_setup() sets up the debug monitor's disassembler.
- * Specifily it set up the sorted symbol table and the string table feilds
- * in to params. It also set the register names to the kernel register names.
- * It is passed the address of the mach_header of the co-loaded program it is
- * going to disassemble. This program must have a mapped LINKEDIT segment and
- * the symbol table must be stripped to only those symbols used for lables and
- * operand values and must be sorted by their n_value field. This routine does
- * no checking of the header or the load commands. It only returns failure if
- * there is no LC_SYMTAB load command or LINKEDIT segment. It returns -1 for
- * failure and 0 for success.
- */
- extern long m88k_disassembler_dbgmon_setup(
- struct mach_header *mh,
- struct m88k_disassembler_params *params);
-
- /*
- * These are arrays of the conventional kernel coding names of the registers.
- */
- extern const char * const kernel_general_register_names[];
- extern const char * const kernel_extended_register_names[];
- extern const char * const kernel_control_register_names[];
- extern const char * const kernel_fp_control_register_names[];
-