]> git.proxmox.com Git - mirror_qemu.git/blame - disas.c
fixed from 2.4.20 kernel
[mirror_qemu.git] / disas.c
CommitLineData
b9adb4a6
FB
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. */
7unsigned int disas_num_syms;
8void *disas_symtab;
9const char *disas_strtab;
10
11/* Disassemble this for me please... (debugging). */
12void 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. */
60const 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}