Statistics
| Branch: | Revision:

root / disas.c @ b333af06

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
#elif defined(__alpha__)
37
        print_insn = print_insn_alpha;
38
#else
39
        fprintf(out, "Asm output not supported on this arch\n");
40
        return;
41
#endif
42
    } else {
43
        /* Currently only source supported in x86. */
44
        disasm_info.endian = BFD_ENDIAN_LITTLE;
45
        if (type == DISAS_I386_I386)
46
            disasm_info.mach = bfd_mach_i386_i386;
47
        else
48
            disasm_info.mach = bfd_mach_i386_i8086;
49
        print_insn = print_insn_i386;
50
    }
51

    
52
    for (pc = code; pc < (uint8_t *)code + size; pc += count) {
53
        fprintf(out, "0x%08lx:  ", (long)pc);
54
        count = print_insn((long)pc, &disasm_info);
55
        fprintf(out, "\n");
56
        if (count < 0)
57
            break;
58
    }
59
}
60

    
61
/* Look up symbol for debugging purpose.  Returns "" if unknown. */
62
const char *lookup_symbol(void *orig_addr)
63
{
64
    unsigned int i;
65
    /* Hack, because we know this is x86. */
66
    Elf32_Sym *sym = disas_symtab;
67

    
68
    for (i = 0; i < disas_num_syms; i++) {
69
        if (sym[i].st_shndx == SHN_UNDEF
70
            || sym[i].st_shndx >= SHN_LORESERVE)
71
            continue;
72

    
73
        if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC)
74
            continue;
75

    
76
        if ((long)orig_addr >= sym[i].st_value
77
            && (long)orig_addr < sym[i].st_value + sym[i].st_size)
78
            return disas_strtab + sym[i].st_name;
79
    }
80
    return "";
81
}