root / disas.c @ fe1e3ce3
History | View | Annotate | Download (2.1 kB)
1 |
/* General "disassemble this chunk" code. Used for debugging. */
|
---|---|
2 |
#include "dis-asm.h" |
3 |
#include "disas.h" |
4 |
#include "elf.h" |
5 |
|
6 |
/* Filled in by elfload.c. Simplistic, but will do for now. */
|
7 |
unsigned int disas_num_syms; |
8 |
void *disas_symtab;
|
9 |
const char *disas_strtab; |
10 |
|
11 |
/* Disassemble this for me please... (debugging). */
|
12 |
void disas(FILE *out, void *code, unsigned long size, enum disas_type type) |
13 |
{ |
14 |
uint8_t *pc; |
15 |
int count;
|
16 |
struct disassemble_info disasm_info;
|
17 |
int (*print_insn)(bfd_vma pc, disassemble_info *info);
|
18 |
|
19 |
INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf); |
20 |
|
21 |
disasm_info.buffer = code; |
22 |
disasm_info.buffer_vma = (unsigned long)code; |
23 |
disasm_info.buffer_length = size; |
24 |
|
25 |
if (type == DISAS_TARGET) {
|
26 |
#ifdef WORDS_BIGENDIAN
|
27 |
disasm_info.endian = BFD_ENDIAN_BIG; |
28 |
#else
|
29 |
disasm_info.endian = BFD_ENDIAN_LITTLE; |
30 |
#endif
|
31 |
#ifdef __i386__
|
32 |
disasm_info.mach = bfd_mach_i386_i386; |
33 |
print_insn = print_insn_i386; |
34 |
#elif defined(__powerpc__)
|
35 |
print_insn = print_insn_ppc; |
36 |
#else
|
37 |
fprintf(out, "Asm output not supported on this arch\n");
|
38 |
return;
|
39 |
#endif
|
40 |
} else {
|
41 |
/* Currently only source supported in x86. */
|
42 |
disasm_info.endian = BFD_ENDIAN_LITTLE; |
43 |
if (type == DISAS_I386_I386)
|
44 |
disasm_info.mach = bfd_mach_i386_i386; |
45 |
else
|
46 |
disasm_info.mach = bfd_mach_i386_i8086; |
47 |
print_insn = print_insn_i386; |
48 |
} |
49 |
|
50 |
for (pc = code; pc < (uint8_t *)code + size; pc += count) {
|
51 |
fprintf(out, "0x%08lx: ", (long)pc); |
52 |
count = print_insn((long)pc, &disasm_info);
|
53 |
fprintf(out, "\n");
|
54 |
if (count < 0) |
55 |
break;
|
56 |
} |
57 |
} |
58 |
|
59 |
/* Look up symbol for debugging purpose. Returns "" if unknown. */
|
60 |
const char *lookup_symbol(void *orig_addr) |
61 |
{ |
62 |
unsigned int i; |
63 |
/* Hack, because we know this is x86. */
|
64 |
Elf32_Sym *sym = disas_symtab; |
65 |
|
66 |
for (i = 0; i < disas_num_syms; i++) { |
67 |
if (sym[i].st_shndx == SHN_UNDEF
|
68 |
|| sym[i].st_shndx >= SHN_LORESERVE) |
69 |
continue;
|
70 |
|
71 |
if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
|
72 |
continue;
|
73 |
|
74 |
if ((long)orig_addr >= sym[i].st_value |
75 |
&& (long)orig_addr < sym[i].st_value + sym[i].st_size)
|
76 |
return disas_strtab + sym[i].st_name;
|
77 |
} |
78 |
return ""; |
79 |
} |