6 #include "include/dis-asm.h"
13 static struct Space *dis_task;
14 static disassemble_info dis_info;
15 static Peek_task dis_peek_task;
16 static Get_symbol dis_get_symbol;
18 extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*));
20 /* read <length> bytes starting at memaddr */
22 my_read_memory(bfd_vma memaddr, bfd_byte *myaddr, unsigned length,
23 struct disassemble_info *info __attribute__ ((unused)))
27 for (i=0; i<length; i++)
30 if (dis_peek_task(memaddr+i, dis_task, &value, 1) == -1)
32 *myaddr++ = (bfd_byte)value;
38 /* XXX return byte without range check */
40 my_get_data(bfd_vma memaddr)
43 if (dis_peek_task(memaddr, dis_task, &value, 1) == -1)
49 /* print address (using symbols if possible) */
51 my_print_address(bfd_vma memaddr, struct disassemble_info *info)
55 if (use_syms && dis_get_symbol
56 && (symbol = dis_get_symbol(memaddr, dis_task)))
64 for (i=2, s=symbol; i<(sizeof(buf)-3); )
66 if (*s=='\0' || *s=='\n')
70 while ((*s != ')') && (*s != '\n') && (*s != '\0'))
76 (*info->fprintf_func)(info->stream, "%s", buf);
81 my_printf(void* stream __attribute__ ((unused)), const char *format, ...)
88 va_start(list, format);
89 len = vsnprintf(out_buf, out_len, format, list);
110 /* check for special L4 int3-opcodes */
112 special_l4_ops(bfd_vma memaddr)
118 switch (my_get_data(memaddr))
122 len = my_get_data(memaddr+1);
127 if (my_get_data(memaddr+1) != 0xeb)
130 len = my_get_data(memaddr+2);
134 /* do a quick test if it is really an int3-str function by
135 * analyzing the bytes we shall display. */
136 for (i=len, s=str; i--; )
137 if (my_get_data(s++) > 126)
140 my_printf(0, "<%s (\"", op);
141 if ((out_len > 2) && (len > 0))
146 /* do not use my_printf here because the string
147 * can contain special characters (e.g. tabs) which
148 * we do not want to display */
151 unsigned char c = my_get_data(str++);
152 my_putchar((c<' ') ? ' ' : c);
156 my_printf(0, "\")>");
160 switch (my_get_data(memaddr+1))
162 case 0: op = "outchar (%al)"; break;
163 case 2: op = "outstring (*%eax)"; break;
164 case 5: op = "outhex32 (%eax)"; break;
165 case 6: op = "outhex20 (%eax)"; break;
166 case 7: op = "outhex16 (%eax)"; break;
167 case 8: op = "outhex12 (%eax)"; break;
168 case 9: op = "outhex8 (%al)"; break;
169 case 11: op = "outdec (%eax)"; break;
170 case 13: op = "%al = inchar ()"; break;
171 case 24: op = "fiasco_start_profile()"; break;
172 case 25: op = "fiasco_stop_and_dump()"; break;
173 case 26: op = "fiasco_stop_profile()"; break;
174 case 29: op = "fiasco_tbuf (%eax)"; break;
175 case 30: op = "fiasco_register (%eax, %ecx)"; break;
178 my_printf(0, "<%s>", op);
179 else if (my_get_data(memaddr+1) >= ' ')
180 my_printf(0, "<ko ('%c')>", my_get_data(memaddr+1));
188 /* WARNING: This function is not reentrant because it accesses some
189 * global static variables (out_buf, out_len, dis_task, ...) */
191 disasm_bytes(char *buffer, unsigned len, Address addr,
192 struct Space *task, int show_symbols, int show_intel_syntax,
193 Peek_task peek_task, Get_symbol get_symbol)
195 use_syms = show_symbols;
199 dis_peek_task = peek_task;
200 dis_get_symbol = get_symbol;
202 /* terminate string */
204 out_buf[--out_len] = '\0';
206 /* test for special L4 opcodes */
207 if (my_get_data(addr) == 0xcc && (len = special_l4_ops(addr+1)))
210 /* one step back for special L4 opcodes */
211 if (my_get_data(addr-1) == 0xcc && (len = special_l4_ops(addr)))
214 INIT_DISASSEMBLE_INFO(dis_info, NULL, my_printf);
216 dis_info.print_address_func = my_print_address;
217 dis_info.read_memory_func = my_read_memory;
218 dis_info.buffer = (bfd_byte*)addr;
219 dis_info.buffer_length = 99; /* XXX */
220 dis_info.buffer_vma = addr;
221 #if defined CONFIG_ARM
222 dis_info.mach = bfd_mach_arm_5;
223 #elif defined CONFIG_PPC32
224 dis_info.mach = bfd_mach_ppc_ec603e;
225 (void)show_intel_syntax;
226 #elif defined CONFIG_IA32
227 dis_info.mach = show_intel_syntax ? bfd_mach_i386_i386_intel_syntax
228 : bfd_mach_i386_i386;
230 dis_info.mach = show_intel_syntax ? bfd_mach_x86_64_intel_syntax
235 #if defined CONFIG_ARM
236 return print_insn_little_arm (addr, &dis_info);
237 #elif defined CONFIG_PPC32
238 return print_insn_big_powerpc(addr, &dis_info);
240 return print_insn_i386 (addr, &dis_info);