Revision c27004ec disas.c
b/disas.c | ||
---|---|---|
28 | 28 |
return 0; |
29 | 29 |
} |
30 | 30 |
|
31 |
#if !defined(CONFIG_USER_ONLY) |
|
32 | 31 |
/* Get LENGTH bytes from info's buffer, at target address memaddr. |
33 | 32 |
Transfer them to myaddr. */ |
34 | 33 |
static int |
35 |
target_read_memory (memaddr, myaddr, length, info) |
|
36 |
bfd_vma memaddr; |
|
37 |
bfd_byte *myaddr; |
|
38 |
int length; |
|
39 |
struct disassemble_info *info; |
|
34 |
target_read_memory (bfd_vma memaddr, |
|
35 |
bfd_byte *myaddr, |
|
36 |
int length, |
|
37 |
struct disassemble_info *info) |
|
40 | 38 |
{ |
41 | 39 |
int i; |
42 | 40 |
for(i = 0; i < length; i++) { |
43 |
myaddr[i] = ldub_code((void *)((long)memaddr + i));
|
|
41 |
myaddr[i] = ldub_code(memaddr + i);
|
|
44 | 42 |
} |
45 | 43 |
return 0; |
46 | 44 |
} |
47 |
#endif |
|
48 | 45 |
|
49 | 46 |
/* Print an error message. We can assume that this is in response to |
50 | 47 |
an error return from buffer_read_memory. */ |
... | ... | |
113 | 110 |
|
114 | 111 |
/* Disassemble this for me please... (debugging). 'flags' is only used |
115 | 112 |
for i386: non zero means 16 bit code */ |
116 |
void disas(FILE *out, void *code, unsigned long size, int is_host, int flags)
|
|
113 |
void target_disas(FILE *out, target_ulong code, unsigned long size, int flags)
|
|
117 | 114 |
{ |
118 |
uint8_t *pc;
|
|
115 |
target_ulong pc;
|
|
119 | 116 |
int count; |
120 | 117 |
struct disassemble_info disasm_info; |
121 | 118 |
int (*print_insn)(bfd_vma pc, disassemble_info *info); |
122 | 119 |
|
123 | 120 |
INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf); |
124 | 121 |
|
125 |
#if !defined(CONFIG_USER_ONLY) |
|
126 |
if (!is_host) { |
|
127 |
disasm_info.read_memory_func = target_read_memory; |
|
128 |
} |
|
122 |
disasm_info.read_memory_func = target_read_memory; |
|
123 |
disasm_info.buffer_vma = code; |
|
124 |
disasm_info.buffer_length = size; |
|
125 |
|
|
126 |
#ifdef TARGET_WORDS_BIGENDIAN |
|
127 |
disasm_info.endian = BFD_ENDIAN_BIG; |
|
128 |
#else |
|
129 |
disasm_info.endian = BFD_ENDIAN_LITTLE; |
|
130 |
#endif |
|
131 |
#if defined(TARGET_I386) |
|
132 |
if (flags == 2) |
|
133 |
disasm_info.mach = bfd_mach_x86_64; |
|
134 |
else if (flags == 1) |
|
135 |
disasm_info.mach = bfd_mach_i386_i8086; |
|
136 |
else |
|
137 |
disasm_info.mach = bfd_mach_i386_i386; |
|
138 |
print_insn = print_insn_i386; |
|
139 |
#elif defined(TARGET_ARM) |
|
140 |
print_insn = print_insn_arm; |
|
141 |
#elif defined(TARGET_SPARC) |
|
142 |
print_insn = print_insn_sparc; |
|
143 |
#elif defined(TARGET_PPC) |
|
144 |
print_insn = print_insn_ppc; |
|
145 |
#else |
|
146 |
fprintf(out, "Asm output not supported on this arch\n"); |
|
147 |
return; |
|
129 | 148 |
#endif |
130 | 149 |
|
150 |
for (pc = code; pc < code + size; pc += count) { |
|
151 |
#if TARGET_LONG_BITS == 64 |
|
152 |
fprintf(out, "0x%016llx: ", pc); |
|
153 |
#else |
|
154 |
fprintf(out, "0x%08x: ", pc); |
|
155 |
#endif |
|
156 |
count = print_insn(pc, &disasm_info); |
|
157 |
#if 0 |
|
158 |
{ |
|
159 |
int i; |
|
160 |
uint8_t b; |
|
161 |
fprintf(out, " {"); |
|
162 |
for(i = 0; i < count; i++) { |
|
163 |
target_read_memory(pc + i, &b, 1, &disasm_info); |
|
164 |
fprintf(out, " %02x", b); |
|
165 |
} |
|
166 |
fprintf(out, " }"); |
|
167 |
} |
|
168 |
#endif |
|
169 |
fprintf(out, "\n"); |
|
170 |
if (count < 0) |
|
171 |
break; |
|
172 |
} |
|
173 |
} |
|
174 |
|
|
175 |
/* Disassemble this for me please... (debugging). */ |
|
176 |
void disas(FILE *out, void *code, unsigned long size) |
|
177 |
{ |
|
178 |
unsigned long pc; |
|
179 |
int count; |
|
180 |
struct disassemble_info disasm_info; |
|
181 |
int (*print_insn)(bfd_vma pc, disassemble_info *info); |
|
182 |
|
|
183 |
INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf); |
|
184 |
|
|
131 | 185 |
disasm_info.buffer = code; |
132 | 186 |
disasm_info.buffer_vma = (unsigned long)code; |
133 | 187 |
disasm_info.buffer_length = size; |
134 | 188 |
|
135 |
if (is_host) { |
|
136 | 189 |
#ifdef WORDS_BIGENDIAN |
137 |
disasm_info.endian = BFD_ENDIAN_BIG;
|
|
190 |
disasm_info.endian = BFD_ENDIAN_BIG;
|
|
138 | 191 |
#else |
139 |
disasm_info.endian = BFD_ENDIAN_LITTLE;
|
|
192 |
disasm_info.endian = BFD_ENDIAN_LITTLE;
|
|
140 | 193 |
#endif |
141 | 194 |
#if defined(__i386__) |
142 |
disasm_info.mach = bfd_mach_i386_i386;
|
|
143 |
print_insn = print_insn_i386;
|
|
195 |
disasm_info.mach = bfd_mach_i386_i386;
|
|
196 |
print_insn = print_insn_i386;
|
|
144 | 197 |
#elif defined(__x86_64__) |
145 |
disasm_info.mach = bfd_mach_x86_64;
|
|
146 |
print_insn = print_insn_i386;
|
|
198 |
disasm_info.mach = bfd_mach_x86_64;
|
|
199 |
print_insn = print_insn_i386;
|
|
147 | 200 |
#elif defined(__powerpc__) |
148 |
print_insn = print_insn_ppc;
|
|
201 |
print_insn = print_insn_ppc;
|
|
149 | 202 |
#elif defined(__alpha__) |
150 |
print_insn = print_insn_alpha;
|
|
203 |
print_insn = print_insn_alpha;
|
|
151 | 204 |
#elif defined(__sparc__) |
152 |
print_insn = print_insn_sparc;
|
|
205 |
print_insn = print_insn_sparc;
|
|
153 | 206 |
#elif defined(__arm__) |
154 |
print_insn = print_insn_arm; |
|
155 |
#else |
|
156 |
fprintf(out, "Asm output not supported on this arch\n"); |
|
157 |
return; |
|
158 |
#endif |
|
159 |
} else { |
|
160 |
#ifdef TARGET_WORDS_BIGENDIAN |
|
161 |
disasm_info.endian = BFD_ENDIAN_BIG; |
|
162 |
#else |
|
163 |
disasm_info.endian = BFD_ENDIAN_LITTLE; |
|
164 |
#endif |
|
165 |
#if defined(TARGET_I386) |
|
166 |
if (!flags) |
|
167 |
disasm_info.mach = bfd_mach_i386_i386; |
|
168 |
else |
|
169 |
disasm_info.mach = bfd_mach_i386_i8086; |
|
170 |
print_insn = print_insn_i386; |
|
171 |
#elif defined(TARGET_ARM) |
|
172 |
print_insn = print_insn_arm; |
|
173 |
#elif defined(TARGET_SPARC) |
|
174 |
print_insn = print_insn_sparc; |
|
175 |
#elif defined(TARGET_PPC) |
|
176 |
print_insn = print_insn_ppc; |
|
207 |
print_insn = print_insn_arm; |
|
177 | 208 |
#else |
178 |
fprintf(out, "Asm output not supported on this arch\n");
|
|
179 |
return;
|
|
209 |
fprintf(out, "Asm output not supported on this arch\n");
|
|
210 |
return;
|
|
180 | 211 |
#endif |
181 |
} |
|
182 |
|
|
183 |
for (pc = code; pc < (uint8_t *)code + size; pc += count) { |
|
184 |
fprintf(out, "0x%08lx: ", (long)pc); |
|
212 |
for (pc = (unsigned long)code; pc < (unsigned long)code + size; pc += count) { |
|
213 |
fprintf(out, "0x%08lx: ", pc); |
|
185 | 214 |
#ifdef __arm__ |
186 | 215 |
/* since data are included in the code, it is better to |
187 | 216 |
display code data too */ |
... | ... | |
189 | 218 |
fprintf(out, "%08x ", (int)bfd_getl32((const bfd_byte *)pc)); |
190 | 219 |
} |
191 | 220 |
#endif |
192 |
count = print_insn((unsigned long)pc, &disasm_info);
|
|
221 |
count = print_insn(pc, &disasm_info); |
|
193 | 222 |
fprintf(out, "\n"); |
194 | 223 |
if (count < 0) |
195 | 224 |
break; |
... | ... | |
197 | 226 |
} |
198 | 227 |
|
199 | 228 |
/* Look up symbol for debugging purpose. Returns "" if unknown. */ |
200 |
const char *lookup_symbol(void *orig_addr)
|
|
229 |
const char *lookup_symbol(target_ulong orig_addr)
|
|
201 | 230 |
{ |
202 | 231 |
unsigned int i; |
203 | 232 |
/* Hack, because we know this is x86. */ |
... | ... | |
214 | 243 |
if (ELF_ST_TYPE(sym[i].st_info) != STT_FUNC) |
215 | 244 |
continue; |
216 | 245 |
|
217 |
if ((long)orig_addr >= sym[i].st_value
|
|
218 |
&& (long)orig_addr < sym[i].st_value + sym[i].st_size)
|
|
246 |
if (orig_addr >= sym[i].st_value |
|
247 |
&& orig_addr < sym[i].st_value + sym[i].st_size) |
|
219 | 248 |
return s->disas_strtab + sym[i].st_name; |
220 | 249 |
} |
221 | 250 |
} |
Also available in: Unified diff