aboutsummaryrefslogtreecommitdiff
path: root/decomp/decomp.h
blob: 0057fd3f7f53bfe794d4154f93e2503859c5cc1d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/* 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 */