Statistics
| Branch: | Revision:

root / disas.c @ a69d83b6

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 b9adb4a6 bellard
#else
37 b9adb4a6 bellard
        fprintf(out, "Asm output not supported on this arch\n");
38 b9adb4a6 bellard
        return;
39 b9adb4a6 bellard
#endif
40 b9adb4a6 bellard
    } else {
41 b9adb4a6 bellard
        /* Currently only source supported in x86. */
42 b9adb4a6 bellard
        disasm_info.endian = BFD_ENDIAN_LITTLE;
43 b9adb4a6 bellard
        if (type == DISAS_I386_I386)
44 b9adb4a6 bellard
            disasm_info.mach = bfd_mach_i386_i386;
45 b9adb4a6 bellard
        else
46 b9adb4a6 bellard
            disasm_info.mach = bfd_mach_i386_i8086;
47 b9adb4a6 bellard
        print_insn = print_insn_i386;
48 b9adb4a6 bellard
    }
49 b9adb4a6 bellard
50 b9adb4a6 bellard
    for (pc = code; pc < (uint8_t *)code + size; pc += count) {
51 b9adb4a6 bellard
        fprintf(out, "0x%08lx:  ", (long)pc);
52 b9adb4a6 bellard
        count = print_insn((long)pc, &disasm_info);
53 b9adb4a6 bellard
        fprintf(out, "\n");
54 b9adb4a6 bellard
        if (count < 0)
55 b9adb4a6 bellard
            break;
56 b9adb4a6 bellard
    }
57 b9adb4a6 bellard
}
58 b9adb4a6 bellard
59 b9adb4a6 bellard
/* Look up symbol for debugging purpose.  Returns "" if unknown. */
60 b9adb4a6 bellard
const char *lookup_symbol(void *orig_addr)
61 b9adb4a6 bellard
{
62 b9adb4a6 bellard
    unsigned int i;
63 b9adb4a6 bellard
    /* Hack, because we know this is x86. */
64 b9adb4a6 bellard
    Elf32_Sym *sym = disas_symtab;
65 b9adb4a6 bellard
66 b9adb4a6 bellard
    for (i = 0; i < disas_num_syms; i++) {
67 b9adb4a6 bellard
        if (sym[i].st_shndx == SHN_UNDEF
68 b9adb4a6 bellard
            || sym[i].st_shndx >= SHN_LORESERVE)
69 b9adb4a6 bellard
            continue;
70 b9adb4a6 bellard
71 b9adb4a6 bellard
        if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
72 b9adb4a6 bellard
            continue;
73 b9adb4a6 bellard
74 b9adb4a6 bellard
        if ((long)orig_addr >= sym[i].st_value
75 b9adb4a6 bellard
            && (long)orig_addr < sym[i].st_value + sym[i].st_size)
76 b9adb4a6 bellard
            return disas_strtab + sym[i].st_name;
77 b9adb4a6 bellard
    }
78 b9adb4a6 bellard
    return "";
79 b9adb4a6 bellard
}