Statistics
| Branch: | Revision:

root / disas.c @ a69d83b6

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
}