test suite fixlet for gdb.trace
[deliverable/binutils-gdb.git] / gdb / disasm.c
1 /* Disassemble support for GDB.
2
3 Copyright (C) 2000-2013 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
126 if ((flags & DISASSEMBLY_OMIT_PC) == 0)
127 ui_out_text (uiout, pc_prefix (pc));
128 ui_out_field_core_addr (uiout, "address", gdbarch, pc);
129
130 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
131 &line, &unmapped))
132 {
133 /* We don't care now about line, filename and
134 unmapped. But we might in the future. */
135 ui_out_text (uiout, " <");
136 if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
137 ui_out_field_string (uiout, "func-name", name);
138 ui_out_text (uiout, "+");
139 ui_out_field_int (uiout, "offset", offset);
140 ui_out_text (uiout, ">:\t");
141 }
142 else
143 ui_out_text (uiout, ":\t");
144
145 if (filename != NULL)
146 xfree (filename);
147 if (name != NULL)
148 xfree (name);
149
150 ui_file_rewind (stb);
151 if (flags & DISASSEMBLY_RAW_INSN)
152 {
153 CORE_ADDR old_pc = pc;
154 bfd_byte data;
155 int status;
156 const char *spacer = "";
157
158 /* Build the opcodes using a temporary stream so we can
159 write them out in a single go for the MI. */
160 struct ui_file *opcode_stream = mem_fileopen ();
161 struct cleanup *cleanups =
162 make_cleanup_ui_file_delete (opcode_stream);
163
164 pc += gdbarch_print_insn (gdbarch, pc, di);
165 for (;old_pc < pc; old_pc++)
166 {
167 status = (*di->read_memory_func) (old_pc, &data, 1, di);
168 if (status != 0)
169 (*di->memory_error_func) (status, old_pc, di);
170 fprintf_filtered (opcode_stream, "%s%02x",
171 spacer, (unsigned) data);
172 spacer = " ";
173 }
174 ui_out_field_stream (uiout, "opcodes", opcode_stream);
175 ui_out_text (uiout, "\t");
176
177 do_cleanups (cleanups);
178 }
179 else
180 pc += gdbarch_print_insn (gdbarch, pc, di);
181 ui_out_field_stream (uiout, "inst", stb);
182 ui_file_rewind (stb);
183 do_cleanups (ui_out_chain);
184 ui_out_text (uiout, "\n");
185 }
186 return num_displayed;
187 }
188
189 /* The idea here is to present a source-O-centric view of a
190 function to the user. This means that things are presented
191 in source order, with (possibly) out of order assembly
192 immediately following. */
193
194 static void
195 do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
196 struct disassemble_info *di, int nlines,
197 struct linetable_entry *le,
198 CORE_ADDR low, CORE_ADDR high,
199 struct symtab *symtab,
200 int how_many, int flags, struct ui_file *stb)
201 {
202 int newlines = 0;
203 struct dis_line_entry *mle;
204 struct symtab_and_line sal;
205 int i;
206 int out_of_order = 0;
207 int next_line = 0;
208 int num_displayed = 0;
209 enum print_source_lines_flags psl_flags = 0;
210 struct cleanup *ui_out_chain;
211 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
212 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
213
214 if (flags & DISASSEMBLY_FILENAME)
215 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
216
217 mle = (struct dis_line_entry *) alloca (nlines
218 * sizeof (struct dis_line_entry));
219
220 /* Copy linetable entries for this function into our data
221 structure, creating end_pc's and setting out_of_order as
222 appropriate. */
223
224 /* First, skip all the preceding functions. */
225
226 for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
227
228 /* Now, copy all entries before the end of this function. */
229
230 for (; i < nlines - 1 && le[i].pc < high; i++)
231 {
232 if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
233 continue; /* Ignore duplicates. */
234
235 /* Skip any end-of-function markers. */
236 if (le[i].line == 0)
237 continue;
238
239 mle[newlines].line = le[i].line;
240 if (le[i].line > le[i + 1].line)
241 out_of_order = 1;
242 mle[newlines].start_pc = le[i].pc;
243 mle[newlines].end_pc = le[i + 1].pc;
244 newlines++;
245 }
246
247 /* If we're on the last line, and it's part of the function,
248 then we need to get the end pc in a special way. */
249
250 if (i == nlines - 1 && le[i].pc < high)
251 {
252 mle[newlines].line = le[i].line;
253 mle[newlines].start_pc = le[i].pc;
254 sal = find_pc_line (le[i].pc, 0);
255 mle[newlines].end_pc = sal.end;
256 newlines++;
257 }
258
259 /* Now, sort mle by line #s (and, then by addresses within
260 lines). */
261
262 if (out_of_order)
263 qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
264
265 /* Now, for each line entry, emit the specified lines (unless
266 they have been emitted before), followed by the assembly code
267 for that line. */
268
269 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
270
271 for (i = 0; i < newlines; i++)
272 {
273 /* Print out everything from next_line to the current line. */
274 if (mle[i].line >= next_line)
275 {
276 if (next_line != 0)
277 {
278 /* Just one line to print. */
279 if (next_line == mle[i].line)
280 {
281 ui_out_tuple_chain
282 = make_cleanup_ui_out_tuple_begin_end (uiout,
283 "src_and_asm_line");
284 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
285 }
286 else
287 {
288 /* Several source lines w/o asm instructions associated. */
289 for (; next_line < mle[i].line; next_line++)
290 {
291 struct cleanup *ui_out_list_chain_line;
292 struct cleanup *ui_out_tuple_chain_line;
293
294 ui_out_tuple_chain_line
295 = make_cleanup_ui_out_tuple_begin_end (uiout,
296 "src_and_asm_line");
297 print_source_lines (symtab, next_line, next_line + 1,
298 psl_flags);
299 ui_out_list_chain_line
300 = make_cleanup_ui_out_list_begin_end (uiout,
301 "line_asm_insn");
302 do_cleanups (ui_out_list_chain_line);
303 do_cleanups (ui_out_tuple_chain_line);
304 }
305 /* Print the last line and leave list open for
306 asm instructions to be added. */
307 ui_out_tuple_chain
308 = make_cleanup_ui_out_tuple_begin_end (uiout,
309 "src_and_asm_line");
310 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
311 }
312 }
313 else
314 {
315 ui_out_tuple_chain
316 = make_cleanup_ui_out_tuple_begin_end (uiout,
317 "src_and_asm_line");
318 print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
319 }
320
321 next_line = mle[i].line + 1;
322 ui_out_list_chain
323 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
324 }
325
326 num_displayed += dump_insns (gdbarch, uiout, di,
327 mle[i].start_pc, mle[i].end_pc,
328 how_many, flags, stb);
329
330 /* When we've reached the end of the mle array, or we've seen the last
331 assembly range for this source line, close out the list/tuple. */
332 if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
333 {
334 do_cleanups (ui_out_list_chain);
335 do_cleanups (ui_out_tuple_chain);
336 ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
337 ui_out_list_chain = make_cleanup (null_cleanup, 0);
338 ui_out_text (uiout, "\n");
339 }
340 if (how_many >= 0 && num_displayed >= how_many)
341 break;
342 }
343 do_cleanups (ui_out_chain);
344 }
345
346
347 static void
348 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
349 struct disassemble_info * di,
350 CORE_ADDR low, CORE_ADDR high,
351 int how_many, int flags, struct ui_file *stb)
352 {
353 int num_displayed = 0;
354 struct cleanup *ui_out_chain;
355
356 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
357
358 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
359 flags, stb);
360
361 do_cleanups (ui_out_chain);
362 }
363
364 /* Initialize the disassemble info struct ready for the specified
365 stream. */
366
367 static int ATTRIBUTE_PRINTF (2, 3)
368 fprintf_disasm (void *stream, const char *format, ...)
369 {
370 va_list args;
371
372 va_start (args, format);
373 vfprintf_filtered (stream, format, args);
374 va_end (args);
375 /* Something non -ve. */
376 return 0;
377 }
378
379 static struct disassemble_info
380 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
381 {
382 struct disassemble_info di;
383
384 init_disassemble_info (&di, file, fprintf_disasm);
385 di.flavour = bfd_target_unknown_flavour;
386 di.memory_error_func = dis_asm_memory_error;
387 di.print_address_func = dis_asm_print_address;
388 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
389 disassembler had a local optomization here. By default it would
390 access the executable file, instead of the target memory (there
391 was a growing list of exceptions though). Unfortunately, the
392 heuristic was flawed. Commands like "disassemble &variable"
393 didn't work as they relied on the access going to the target.
394 Further, it has been supperseeded by trust-read-only-sections
395 (although that should be superseeded by target_trust..._p()). */
396 di.read_memory_func = dis_asm_read_memory;
397 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
398 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
399 di.endian = gdbarch_byte_order (gdbarch);
400 di.endian_code = gdbarch_byte_order_for_code (gdbarch);
401 di.application_data = gdbarch;
402 disassemble_init_for_target (&di);
403 return di;
404 }
405
406 void
407 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
408 char *file_string, int flags, int how_many,
409 CORE_ADDR low, CORE_ADDR high)
410 {
411 struct ui_file *stb = mem_fileopen ();
412 struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
413 struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
414 /* To collect the instruction outputted from opcodes. */
415 struct symtab *symtab = NULL;
416 struct linetable_entry *le = NULL;
417 int nlines = -1;
418
419 /* Assume symtab is valid for whole PC range. */
420 symtab = find_pc_symtab (low);
421
422 if (symtab != NULL && symtab->linetable != NULL)
423 {
424 /* Convert the linetable to a bunch of my_line_entry's. */
425 le = symtab->linetable->item;
426 nlines = symtab->linetable->nitems;
427 }
428
429 if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0
430 || symtab == NULL || symtab->linetable == NULL)
431 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
432
433 else if (flags & DISASSEMBLY_SOURCE)
434 do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
435 high, symtab, how_many, flags, stb);
436
437 do_cleanups (cleanups);
438 gdb_flush (gdb_stdout);
439 }
440
441 /* Print the instruction at address MEMADDR in debugged memory,
442 on STREAM. Returns the length of the instruction, in bytes,
443 and, if requested, the number of branch delay slot instructions. */
444
445 int
446 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
447 struct ui_file *stream, int *branch_delay_insns)
448 {
449 struct disassemble_info di;
450 int length;
451
452 di = gdb_disassemble_info (gdbarch, stream);
453 length = gdbarch_print_insn (gdbarch, memaddr, &di);
454 if (branch_delay_insns)
455 {
456 if (di.insn_info_valid)
457 *branch_delay_insns = di.branch_delay_insns;
458 else
459 *branch_delay_insns = 0;
460 }
461 return length;
462 }
463
464 static void
465 do_ui_file_delete (void *arg)
466 {
467 ui_file_delete (arg);
468 }
469
470 /* Return the length in bytes of the instruction at address MEMADDR in
471 debugged memory. */
472
473 int
474 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
475 {
476 static struct ui_file *null_stream = NULL;
477
478 /* Dummy file descriptor for the disassembler. */
479 if (!null_stream)
480 {
481 null_stream = ui_file_new ();
482 make_final_cleanup (do_ui_file_delete, null_stream);
483 }
484
485 return gdb_print_insn (gdbarch, addr, null_stream, NULL);
486 }
487
488 /* fprintf-function for gdb_buffered_insn_length. This function is a
489 nop, we don't want to print anything, we just want to compute the
490 length of the insn. */
491
492 static int ATTRIBUTE_PRINTF (2, 3)
493 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
494 {
495 return 0;
496 }
497
498 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
499
500 static void
501 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
502 struct disassemble_info *di,
503 const gdb_byte *insn, int max_len,
504 CORE_ADDR addr)
505 {
506 init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
507
508 /* init_disassemble_info installs buffer_read_memory, etc.
509 so we don't need to do that here.
510 The cast is necessary until disassemble_info is const-ified. */
511 di->buffer = (gdb_byte *) insn;
512 di->buffer_length = max_len;
513 di->buffer_vma = addr;
514
515 di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
516 di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
517 di->endian = gdbarch_byte_order (gdbarch);
518 di->endian_code = gdbarch_byte_order_for_code (gdbarch);
519
520 disassemble_init_for_target (di);
521 }
522
523 /* Return the length in bytes of INSN. MAX_LEN is the size of the
524 buffer containing INSN. */
525
526 int
527 gdb_buffered_insn_length (struct gdbarch *gdbarch,
528 const gdb_byte *insn, int max_len, CORE_ADDR addr)
529 {
530 struct disassemble_info di;
531
532 gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
533
534 return gdbarch_print_insn (gdbarch, addr, &di);
535 }
This page took 0.041327 seconds and 4 git commands to generate.