Statistics
| Branch: | Revision:

root / disas.c @ 2a29ca73

History | View | Annotate | Download (2.1 kB)

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