/* decomp.h
* This file is part of decomp - a disassembler.
*
* Copyright (C) 2001 Jonathan duSaint <dusaint@earthlink.net>
*/
#ifndef DECOMP_H
#define DECOMP_H
#include <stdio.h>
/* 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 "<dusaint@earthlink.net>"
#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 */