aboutsummaryrefslogblamecommitdiff
path: root/decomp/decomp.h
blob: 0057fd3f7f53bfe794d4154f93e2503859c5cc1d (plain) (tree)
































































































































































































































































































                                                                              
/* 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 */