]> git.proxmox.com Git - qemu.git/blob - disas.c
fixed popf TF flag bug (should never hapen in user code except in test-i386!)
[qemu.git] / 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 #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 }