/* decomp.h * This file is part of decomp - a disassembler. * * Copyright (C) 2001 Jonathan duSaint */ #ifndef DECOMP_H #define DECOMP_H #include /* something really bad just happened and it's time to bail */ #define PANIC panic (__LINE__, __FILE__) /* some kind of error */ #define error_out(index) error_out_internal ((index), __LINE__, __FILE__) /* used for debugging */ #define PRINT_OK fprintf (stderr, "ok at %d in %s\n", __LINE__, __FILE__) #define PACKAGE_NAME "Decomp" #define PACKAGE_VERSION "0.0" #define AUTHOR "Jonathan duSaint" #define AUTHOR_EMAIL "" #define DEFAULT_OUTPUT_EXTENSION "_decomp.S" /* an invalid hash key */ #define HASH_END (-1UL) /* the maximum output buffer size - this should be sufficiently large so that backwards jump destinations will be properly labeled with temporary labels */ #define MAX_OUTPUT_QUEUE_SIZE 512 /* flags for use with the FLAGS variable passed to the disassembly routines */ #define F_IA32_A (1UL << 0) /* addressing mode 16/32 */ #define F_IA32_D (1UL << 1) /* data mode 16/32 */ #define F_IA32_P (1UL << 2) /* print instruction prefix comments */ /* endian-ness used for the read routines */ #define ELITTLE 0 #define EBIG 1 /* indices into the message table */ enum message_table_index { ERR_INTERNAL_ERROR = 0, ERR_NEED_FILE_NAME, ERR_FILE_INFO, ERR_CLEAN_UP, ERR_FILE_OPEN, ERR_FILE_READ, ERR_INVALID_FILE, ERR_FILE_TYPE, ERR_READ_SECTION }; /* hash table stuff */ struct hash_bucket { struct hash_bucket *next; unsigned long key; void *data; }; struct hash_table { struct hash_bucket **table; unsigned long size; unsigned long items; }; typedef struct hash_table *hash_t; /* type of file */ enum file_type { FT_ELF, /* ELF32/64 */ FT_AOUT, /* a.out - this isn't used for now */ FT_PE, /* Win32 Portable Executable */ FT_NE, /* Win16 New Executable */ FT_MZ, /* Legacy DOS Executable */ FT_COM, /* Legacy DOS COM - this isn't used for now */ FT_UNK /* huh??? - maybe someday I'll add more file types */ }; /* type of machine */ enum mach_type { MT_IA32, /* aka x86/i386/... */ MT_ALPHA, /* DEC Alpha */ MT_UNK /* huh??? - maybe someday I'll add more architectures */ }; /* the data/code wordsize */ enum bs { BS_16, /* 16 bit code/machine */ BS_32, /* 32 bit code/machine */ BS_64, /* 64 bit code/machine */ BS_UNK }; /* the byte order */ enum bo { BO_LITTLE_ENDIAN, BO_BIG_ENDIAN }; /* the type of a section (as concerns decomp) */ enum section_type { CODE_SECTION, DATA_SECTION, HASH_SECTION, STRING_SECTION, OTHER_SECTION }; /* information about a section */ struct section_info { /* the name of the section from .shstrtab */ char *section_name; /* the type of this section */ enum section_type section_type; /* offset in the file of this section */ unsigned long section_offset; /* the section's size */ unsigned long section_size; /* the size of an entry (used for the symtab) */ unsigned long entsize; /* internal section index */ unsigned long section_index; /* virtual load address of this section */ unsigned long load_address; /* the hash table for this section's symbols */ hash_t symtab; /* a string describing any section flags */ char *flags; /* the alignment of the section */ unsigned int align; }; /* all of the relevant information about the file to be disassembled */ struct file_info { /* the name of the file as passed to decomp - prob read-only */ char *file_name; /* the size as returned from fstat */ unsigned long file_size; /* the "bit size" of the object file - 16, 32, or 64 */ enum bs bit_size; /* the machine */ enum mach_type arch; /* object file type */ enum file_type file_type; /* the machine/file byte order */ enum bo endian; /* the file descriptor */ FILE *fp; /* the virtual load address */ unsigned long load_address; /* a NULL terminated array of data sections */ struct section_info **data_sections; /* a NULL terminated array of code sections */ struct section_info **code_sections; /* every other section */ struct section_info **other_sections; /* the .symtab section */ struct section_info *symtab; /* the .strtab section. */ struct section_info *strtab; }; /* do not reorder these */ enum symbol_type { LOCAL_DATA, GLOBAL_DATA, LOCAL_FUNCTION, GLOBAL_FUNCTION, LOCAL_UNKNOWN, GLOBAL_UNKNOWN, UNKNOWN_DATA, UNKNOWN_FUNCTION, UNKNOWN_SYMBOL }; struct symtab { char *name; unsigned long address; unsigned long size; unsigned long idx; enum symbol_type type; }; enum syntax { ATT, INTEL }; /* overall control over AT&T or Intel style disassembly */ extern enum syntax syntax; extern volatile int memory_trace; extern int print_address; extern int print_opcode; extern int print_prefix; extern int debug; extern unsigned long max_queue_size; extern int host_endian, target_endian; extern char pname[]; extern char version[]; /* decomp.c */ void d_read (void *ptr, size_t size, size_t nmemb, FILE *stream, int as_is); /* error.c */ void panic (long line, char *file) __attribute__ ((noreturn)); void error_out_internal (int index, long ling, char *file) __attribute__ ((noreturn)); /* memory.c */ void *xmalloc (size_t amount); void xfree (void *mem); void free_all (void); void mem_trace (void); /* fileinfo.c */ int get_file_info (struct file_info *fi, const char *file); int clean_up_file (struct file_info *fi); struct section_info *alloc_section_info (char *name, enum section_type type, unsigned long offset, unsigned long size, unsigned long entsize, unsigned long index, unsigned long addr, hash_t symtab, char *flags, unsigned int align); /* symtab.c */ char *create_hash_key_from_addr (unsigned long addr); hash_t read_symtab (struct file_info *fi); void clean_symtab (hash_t symtab); void put_data_limits (unsigned long low, unsigned long high); int check_is_data (unsigned long vaddr); struct symtab *create_jump_ref (hash_t symtab, unsigned long vaddr); struct symtab *create_data_ref (hash_t symtab, unsigned long vaddr); /* hash.c */ hash_t hash_new (unsigned long size); double hash_goodness (hash_t table); int hash_add (hash_t table, unsigned long key, void *data); void *hash_get (hash_t table, unsigned long key); void *hash_remove (hash_t table, unsigned long key); void hash_delete (hash_t table); hash_t hash_rehash (hash_t table, unsigned long size); unsigned long hash_walk (hash_t table); void hash_print (hash_t table); /* data.c */ void decode_data_section (struct file_info *fi, struct section_info *s, hash_t symtab, FILE *ofp); /* code.c */ void decode_code_section (struct file_info *fi, struct section_info *s, hash_t symtab, FILE *ofp); /* files dealing with file types */ /* elf.c */ void elf_get_file_info (struct file_info *fi); char *elf_read_strtab (struct file_info *fi); struct symtab *elf_get_next_symbol (struct file_info *fi, char *strtab); /* dos.c */ void mz_get_file_info (struct file_info *fi); char *mz_read_strtab (struct file_info *fi); struct symtab *mz_get_next_symbol (struct file_info *fi, char *strtab); void ne_get_file_info (struct file_info *fi); char *ne_read_strtab (struct file_info *fi); struct symtab *ne_get_next_symbol (struct file_info *fi, char *strtab); void pe_get_file_info (struct file_info *fi); char *pe_read_strtab (struct file_info *fi); struct symtab *pe_get_next_symbol (struct file_info *fi, char *strtab); /* ia32.c */ char *ia32_disassemble_instruction (unsigned char *text, unsigned long *pos, unsigned long flags, unsigned long vaddr, hash_t symtab); /* alpha.c */ char *alpha_disassemble_instruction (unsigned char *text, unsigned long *pos, unsigned long flags, unsigned long vaddr, hash_t symtab); #endif /* DECOMP_H */