ia64 support
[qemu] / disas.c
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 }