* disasm.h (DISASSEMBLY_FILENAME): New macro.
[deliverable/binutils-gdb.git] / gdb / disasm.c
1 /* Disassemble support for GDB.
2
3 Copyright (C) 2000-2005, 2007-2012 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "defs.h"
21 #include "target.h"
22 #include "value.h"
23 #include "ui-out.h"
24 #include "gdb_string.h"
25 #include "disasm.h"
26 #include "gdbcore.h"
27 #include "dis-asm.h"
28
29 /* Disassemble functions.
30 FIXME: We should get rid of all the duplicate code in gdb that does
31 the same thing: disassemble_command() and the gdbtk variation. */
32
33 /* This Structure is used to store line number information.
34 We need a different sort of line table from the normal one cuz we can't
35 depend upon implicit line-end pc's for lines to do the
36 reordering in this function. */
37
38 struct dis_line_entry
39 {
40 int line;
41 CORE_ADDR start_pc;
42 CORE_ADDR end_pc;
43 };
44
45 /* Like target_read_memory, but slightly different parameters. */
46 static int
47 dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
48 struct disassemble_info *info)
49 {
50 return target_read_memory (memaddr, myaddr, len);
51 }
52
53 /* Like memory_error with slightly different parameters. */
54 static void
55 dis_asm_memory_error (int status, bfd_vma memaddr,
56 struct disassemble_info *info)
57 {
58 memory_error (status, memaddr);
59 }
60
61 /* Like print_address with slightly different parameters. */
62 static void
63 dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
64 {
65 struct gdbarch *gdbarch = info->application_data;
66
67 print_address (gdbarch, addr, info->stream);
68 }
69
70 static int
71 compare_lines (const void *mle1p, const void *mle2p)
72 {
73 struct dis_line_entry *mle1, *mle2;
74 int val;
75
76 mle1 = (struct dis_line_entry *) mle1p;
77 mle2 = (struct dis_line_entry *) mle2p;
78
79 /* End of sequence markers have a line number of 0 but don't want to
80 be sorted to the head of the list, instead sort by PC. */
81 if (mle1->line == 0 || mle2->line == 0)
82 {
83 val = mle1->start_pc - mle2->start_pc;
84 if (val == 0)
85 val = mle1->line - mle2->line;
86 }
87 else
88 {
89 val = mle1->line - mle2->line;
90 if (val == 0)
91 val = mle1->start_pc - mle2->start_pc;
92 }
93 return val;
94 }
95
96 static int
97 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
98 struct disassemble_info * di,
99 CORE_ADDR low, CORE_ADDR high,
100 int how_many, int flags, struct ui_file *stb)
101 {
102 int num_displayed = 0;
103 CORE_ADDR pc;
104
105 /* parts of the symbolic representation of the address */
106 int unmapped;
107 int offset;
108 int line;
109 struct cleanup *ui_out_chain;
110
111 for (pc = low; pc < high;)
112 {
113 char *filename = NULL;
114 char *name = NULL;
115
116 QUIT;
117 if (how_many >= 0)
118 {
119 if (num_displayed >= how_many)
120 break;
121 else
122 num_displayed++;
123 }
124 ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
125 ui_out_text (uiout, pc_prefix (pc));
126 ui_out_field_core_addr (uiout, "address", gdbarch, pc);
127
128 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
129 &line, &unmapped))
130 {
131 /* We don't care now about line, filename and
132 unmapped. But we might in the future. */
133 ui_out_text (uiout, " <");
134 if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
135 ui_out_field_string (uiout, "func-name", name);
136 ui_out_text (uiout, "+");
137 ui_out_field_int (uiout, "offset", offset);
138 ui_out_text (uiout, ">:\t");
139 }
140 else
141 ui_out_text (uiout, ":\t");
142
143 if (filename != NULL)
144 xfree (filename);
145 if (name != NULL)
146 xfree (name);
147
148 ui_file_rewind (stb);
149 if (flags & DISASSEMBLY_RAW_INSN)
150 {
151 CORE_ADDR old_pc = pc;
152 bfd_byte data;
153 int status;
154 const char *spacer = "";
155
156 /* Build the opcodes using a temporary stream so we can
157 write them out in a single go for the MI. */
158 struct ui_file *opcode_stream = mem_fileopen ();
159 struct cleanup *cleanups =
160 make_cleanup_ui_file_delete (opcode_stream);
161
162 pc += gdbarch_print_insn (gdbarch, pc, di);
163 for (;old_pc < pc; old_pc++)
164 {
165 status = (*di->read_memory_func) (old_pc, &data, 1, di);
166 if (status != 0)
167 (*di->memory_error_func) (status, old_pc, di);
168 fprintf_filtered (opcode_stream, "%s%02x",
169 spacer, (unsigned) data);
170 spacer = " ";
171 }
172 ui_out_field_stream (uiout, "opcodes", opcode_stream);
173 ui_out_text (uiout, "\t");
174
175 do_cleanups (cleanups);
176 }
177 else
178 pc += gdbarch_print_insn (gdbarch, pc, di);
179 ui_out_field_stream (uiout, "inst", stb);
180 ui_file_rewind (stb);
181 do_cleanups (ui_out_chain);
182 ui_out_text (uiout, "\n");
183 }
184 return num_displayed;
185 }
186
187 /* The idea here is to present a source-O-centric view of a
188 function to the user. This means that things are presented
189 in source order, with (possibly) out of order assembly
190 immediately following. */
191
192 static void
193 do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
194 struct disassemble_info *di, int nlines,
195 struct linetable_entry *le,
196 CORE_ADDR low, CORE_ADDR high,
197 struct symtab *symtab,
198 int how_many, int flags, struct ui_file *stb)
199 {
200 int newlines = 0;
201 struct dis_line_entry *mle;
202 struct symtab_and_line sal;
203 int i;
204 int out_of_order = 0;
205 int next_line = 0;
206 int num_displayed = 0;
207 enum print_source_lines_flags psl_flags = 0;
208 struct cleanup *ui_out_chain;
209 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
210 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
211
212 if (flags & DISASSEMBLY_FILENAME)
213 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
214
215 mle = (struct dis_line_entry *) alloca (nlines
216 * sizeof (struct dis_line_entry));
217
218 /* Copy linetable entries for this function into our data
219 structure, creating end_pc's and setting out_of_order as
220 appropriate. */
221
222 /* First, skip all the preceding functions. */
223
224 for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
225
226 /* Now, copy all entries before the end of this function. */
227
228 for (; i < nlines - 1 && le[i].pc < high; i++)
229 {
230 if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
231 continue; /* Ignore duplicates. */
232
233 /* Skip any end-of-function markers. */
234 if (le[i].line == 0)
235 continue;
236
237 mle[newlines].line = le[i].line;
238 if (le[i].line > le[i + 1].line)
239 out_of_order = 1;
240 mle[newlines].start_pc = le[i].pc;
241 mle[newlines].end_pc = le[i + 1].pc;
242 newlines++;
243 }
244
245 /* If we're on the last line, and it's part of the function,
246 then we need to get the end pc in a special way. */
247
248 if (i == nlines - 1 && le[i].pc < high)
249 {
250 mle[newlines].line = le[i].line;
251 mle[newlines].start_pc = le[i].pc;
252 sal = find_pc_line (le[i].pc, 0);
253 mle[newlines].end_pc = sal.end;
254 newlines++;
255 }
256
257 /* Now, sort mle by line #s (and, then by addresses within
258 lines). */
259
260 if (out_of_order)
261 qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
262
263 /* Now, for each line entry, emit the specified lines (unless
264 they have been emitted before), followed by the assembly code
265 for that line. */
266
267 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
268
269 for (i = 0; i < newlines; i++)
270 {
271 /* Print out everything from next_line to the current line. */
272 if (mle[i].line >= next_line)
273 {
274 if (next_line != 0)
275 {
276 /* Just one line to print. */
277 if (next_line == mle[i].line)
278 {
279 ui_out_tuple_chain
280 = make_cleanup_ui_out_tuple_begin_end (uiout,
281 "src_and_asm_line");
282 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
283 }
284 else
285 {
286 /* Several source lines w/o asm instructions associated. */
287 for (; next_line < mle[i].line; next_line++)
288 {
289 struct cleanup *ui_out_list_chain_line;
290 struct cleanup *ui_out_tuple_chain_line;
291
292 ui_out_tuple_chain_line
293 = make_cleanup_ui_out_tuple_begin_end (uiout,
294 "src_and_asm_line");
295 print_source_lines (symtab, next_line, next_line + 1,
296 psl_flags);
297 ui_out_list_chain_line
298 = make_cleanup_ui_out_list_begin_end (uiout,
299 "line_asm_insn");
300 do_cleanups (ui_out_list_chain_line);
301 do_cleanups (ui_out_tuple_chain_line);
302 }
303 /* Print the last line and leave list open for
304 asm instructions to be added. */
305 ui_out_tuple_chain
306 = make_cleanup_ui_out_tuple_begin_end (uiout,
307 "src_and_asm_line");
308 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
309 }
310 }
311 else
312 {
313 ui_out_tuple_chain
314 = make_cleanup_ui_out_tuple_begin_end (uiout,
315 "src_and_asm_line");
316 print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
317 }
318
319 next_line = mle[i].line + 1;
320 ui_out_list_chain
321 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
322 }
323
324 num_displayed += dump_insns (gdbarch, uiout, di,
325 mle[i].start_pc, mle[i].end_pc,
326 how_many, flags, stb);
327
328 /* When we've reached the end of the mle array, or we've seen the last
329 assembly range for this source line, close out the list/tuple. */
330 if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
331 {
332 do_cleanups (ui_out_list_chain);
333 do_cleanups (ui_out_tuple_chain);
334 ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
335 ui_out_list_chain = make_cleanup (null_cleanup, 0);
336 ui_out_text (uiout, "\n");
337 }
338 if (how_many >= 0 && num_displayed >= how_many)
339 break;
340 }
341 do_cleanups (ui_out_chain);
342 }
343
344
345 static void
346 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
347 struct disassemble_info * di,
348 CORE_ADDR low, CORE_ADDR high,
349 int how_many, int flags, struct ui_file *stb)
350 {
351 int num_displayed = 0;
352 struct cleanup *ui_out_chain;
353
354 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
355
356 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
357 flags, stb);
358
359 do_cleanups (ui_out_chain);
360 }
361
362 /* Initialize the disassemble info struct ready for the specified
363 stream. */
364
365 static int ATTRIBUTE_PRINTF (2, 3)
366 fprintf_disasm (void *stream, const char *format, ...)
367 {
368 va_list args;
369
370 va_start (args, format);
371 vfprintf_filtered (stream, format, args);
372 va_end (args);
373 /* Something non -ve. */
374 return 0;
375 }
376
377 static struct disassemble_info
378 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
379 {
380 struct disassemble_info di;
381
382 init_disassemble_info (&di, file, fprintf_disasm);
383 di.flavour = bfd_target_unknown_flavour;
384 di.memory_error_func = dis_asm_memory_error;
385 di.print_address_func = dis_asm_print_address;
386 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
387 disassembler had a local optomization here. By default it would
388 access the executable file, instead of the target memory (there
389 was a growing list of exceptions though). Unfortunately, the
390 heuristic was flawed. Commands like "disassemble &variable"
391 didn't work as they relied on the access going to the target.
392 Further, it has been supperseeded by trust-read-only-sections
393 (although that should be superseeded by target_trust..._p()). */
394 di.read_memory_func = dis_asm_read_memory;
395 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
396 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
397 di.endian = gdbarch_byte_order (gdbarch);
398 di.endian_code = gdbarch_byte_order_for_code (gdbarch);
399 di.application_data = gdbarch;
400 disassemble_init_for_target (&di);
401 return di;
402 }
403
404 void
405 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
406 char *file_string, int flags, int how_many,
407 CORE_ADDR low, CORE_ADDR high)
408 {
409 struct ui_file *stb = mem_fileopen ();
410 struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
411 struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
412 /* To collect the instruction outputted from opcodes. */
413 struct symtab *symtab = NULL;
414 struct linetable_entry *le = NULL;
415 int nlines = -1;
416
417 /* Assume symtab is valid for whole PC range. */
418 symtab = find_pc_symtab (low);
419
420 if (symtab != NULL && symtab->linetable != NULL)
421 {
422 /* Convert the linetable to a bunch of my_line_entry's. */
423 le = symtab->linetable->item;
424 nlines = symtab->linetable->nitems;
425 }
426
427 if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0
428 || symtab == NULL || symtab->linetable == NULL)
429 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
430
431 else if (flags & DISASSEMBLY_SOURCE)
432 do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
433 high, symtab, how_many, flags, stb);
434
435 do_cleanups (cleanups);
436 gdb_flush (gdb_stdout);
437 }
438
439 /* Print the instruction at address MEMADDR in debugged memory,
440 on STREAM. Returns the length of the instruction, in bytes,
441 and, if requested, the number of branch delay slot instructions. */
442
443 int
444 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
445 struct ui_file *stream, int *branch_delay_insns)
446 {
447 struct disassemble_info di;
448 int length;
449
450 di = gdb_disassemble_info (gdbarch, stream);
451 length = gdbarch_print_insn (gdbarch, memaddr, &di);
452 if (branch_delay_insns)
453 {
454 if (di.insn_info_valid)
455 *branch_delay_insns = di.branch_delay_insns;
456 else
457 *branch_delay_insns = 0;
458 }
459 return length;
460 }
461
462 static void
463 do_ui_file_delete (void *arg)
464 {
465 ui_file_delete (arg);
466 }
467
468 /* Return the length in bytes of the instruction at address MEMADDR in
469 debugged memory. */
470
471 int
472 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
473 {
474 static struct ui_file *null_stream = NULL;
475
476 /* Dummy file descriptor for the disassembler. */
477 if (!null_stream)
478 {
479 null_stream = ui_file_new ();
480 make_final_cleanup (do_ui_file_delete, null_stream);
481 }
482
483 return gdb_print_insn (gdbarch, addr, null_stream, NULL);
484 }
485
486 /* fprintf-function for gdb_buffered_insn_length. This function is a
487 nop, we don't want to print anything, we just want to compute the
488 length of the insn. */
489
490 static int ATTRIBUTE_PRINTF (2, 3)
491 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
492 {
493 return 0;
494 }
495
496 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
497
498 static void
499 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
500 struct disassemble_info *di,
501 const gdb_byte *insn, int max_len,
502 CORE_ADDR addr)
503 {
504 init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
505
506 /* init_disassemble_info installs buffer_read_memory, etc.
507 so we don't need to do that here.
508 The cast is necessary until disassemble_info is const-ified. */
509 di->buffer = (gdb_byte *) insn;
510 di->buffer_length = max_len;
511 di->buffer_vma = addr;
512
513 di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
514 di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
515 di->endian = gdbarch_byte_order (gdbarch);
516 di->endian_code = gdbarch_byte_order_for_code (gdbarch);
517
518 disassemble_init_for_target (di);
519 }
520
521 /* Return the length in bytes of INSN. MAX_LEN is the size of the
522 buffer containing INSN. */
523
524 int
525 gdb_buffered_insn_length (struct gdbarch *gdbarch,
526 const gdb_byte *insn, int max_len, CORE_ADDR addr)
527 {
528 struct disassemble_info di;
529
530 gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
531
532 return gdbarch_print_insn (gdbarch, addr, &di);
533 }
This page took 0.041424 seconds and 5 git commands to generate.