disasm: split dump_insns
[deliverable/binutils-gdb.git] / gdb / disasm.c
1 /* Disassemble support for GDB.
2
3 Copyright (C) 2000-2015 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 "disasm.h"
25 #include "gdbcore.h"
26 #include "dis-asm.h"
27 #include "source.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 for the
34 deprecated /m option.
35 We need a different sort of line table from the normal one cuz we can't
36 depend upon implicit line-end pc's for lines to do the
37 reordering in this function. */
38
39 struct deprecated_dis_line_entry
40 {
41 int line;
42 CORE_ADDR start_pc;
43 CORE_ADDR end_pc;
44 };
45
46 /* This Structure is used to store line number information.
47 We need a different sort of line table from the normal one cuz we can't
48 depend upon implicit line-end pc's for lines to do the
49 reordering in this function. */
50
51 struct dis_line_entry
52 {
53 struct symtab *symtab;
54 int line;
55 };
56
57 /* Hash function for dis_line_entry. */
58
59 static hashval_t
60 hash_dis_line_entry (const void *item)
61 {
62 const struct dis_line_entry *dle = (const struct dis_line_entry *) item;
63
64 return htab_hash_pointer (dle->symtab) + dle->line;
65 }
66
67 /* Equal function for dis_line_entry. */
68
69 static int
70 eq_dis_line_entry (const void *item_lhs, const void *item_rhs)
71 {
72 const struct dis_line_entry *lhs = (const struct dis_line_entry *) item_lhs;
73 const struct dis_line_entry *rhs = (const struct dis_line_entry *) item_rhs;
74
75 return (lhs->symtab == rhs->symtab
76 && lhs->line == rhs->line);
77 }
78
79 /* Create the table to manage lines for mixed source/disassembly. */
80
81 static htab_t
82 allocate_dis_line_table (void)
83 {
84 return htab_create_alloc (41,
85 hash_dis_line_entry, eq_dis_line_entry,
86 xfree, xcalloc, xfree);
87 }
88
89 /* Add DLE to TABLE.
90 Returns 1 if added, 0 if already present. */
91
92 static void
93 maybe_add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
94 {
95 void **slot;
96 struct dis_line_entry dle, *dlep;
97
98 dle.symtab = symtab;
99 dle.line = line;
100 slot = htab_find_slot (table, &dle, INSERT);
101 if (*slot == NULL)
102 {
103 dlep = XNEW (struct dis_line_entry);
104 dlep->symtab = symtab;
105 dlep->line = line;
106 *slot = dlep;
107 }
108 }
109
110 /* Return non-zero if SYMTAB, LINE are in TABLE. */
111
112 static int
113 line_has_code_p (htab_t table, struct symtab *symtab, int line)
114 {
115 struct dis_line_entry dle;
116
117 dle.symtab = symtab;
118 dle.line = line;
119 return htab_find (table, &dle) != NULL;
120 }
121
122 /* Like target_read_memory, but slightly different parameters. */
123 static int
124 dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
125 struct disassemble_info *info)
126 {
127 return target_read_code (memaddr, myaddr, len);
128 }
129
130 /* Like memory_error with slightly different parameters. */
131 static void
132 dis_asm_memory_error (int err, bfd_vma memaddr,
133 struct disassemble_info *info)
134 {
135 memory_error (TARGET_XFER_E_IO, memaddr);
136 }
137
138 /* Like print_address with slightly different parameters. */
139 static void
140 dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
141 {
142 struct gdbarch *gdbarch = (struct gdbarch *) info->application_data;
143
144 print_address (gdbarch, addr, (struct ui_file *) info->stream);
145 }
146
147 static int
148 compare_lines (const void *mle1p, const void *mle2p)
149 {
150 struct deprecated_dis_line_entry *mle1, *mle2;
151 int val;
152
153 mle1 = (struct deprecated_dis_line_entry *) mle1p;
154 mle2 = (struct deprecated_dis_line_entry *) mle2p;
155
156 /* End of sequence markers have a line number of 0 but don't want to
157 be sorted to the head of the list, instead sort by PC. */
158 if (mle1->line == 0 || mle2->line == 0)
159 {
160 val = mle1->start_pc - mle2->start_pc;
161 if (val == 0)
162 val = mle1->line - mle2->line;
163 }
164 else
165 {
166 val = mle1->line - mle2->line;
167 if (val == 0)
168 val = mle1->start_pc - mle2->start_pc;
169 }
170 return val;
171 }
172
173 /* Prints the instruction at PC into UIOUT and returns the length of the
174 printed instruction in bytes. */
175
176 static int
177 gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
178 struct disassemble_info * di, CORE_ADDR pc, int flags,
179 struct ui_file *stb)
180 {
181 /* parts of the symbolic representation of the address */
182 int unmapped;
183 int offset;
184 int line;
185 int size;
186 struct cleanup *ui_out_chain;
187 char *filename = NULL;
188 char *name = NULL;
189
190 ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
191
192 if ((flags & DISASSEMBLY_OMIT_PC) == 0)
193 ui_out_text (uiout, pc_prefix (pc));
194 ui_out_field_core_addr (uiout, "address", gdbarch, pc);
195
196 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
197 &line, &unmapped))
198 {
199 /* We don't care now about line, filename and unmapped. But we might in
200 the future. */
201 ui_out_text (uiout, " <");
202 if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
203 ui_out_field_string (uiout, "func-name", name);
204 ui_out_text (uiout, "+");
205 ui_out_field_int (uiout, "offset", offset);
206 ui_out_text (uiout, ">:\t");
207 }
208 else
209 ui_out_text (uiout, ":\t");
210
211 if (filename != NULL)
212 xfree (filename);
213 if (name != NULL)
214 xfree (name);
215
216 ui_file_rewind (stb);
217 if (flags & DISASSEMBLY_RAW_INSN)
218 {
219 CORE_ADDR end_pc;
220 bfd_byte data;
221 int err;
222 const char *spacer = "";
223
224 /* Build the opcodes using a temporary stream so we can
225 write them out in a single go for the MI. */
226 struct ui_file *opcode_stream = mem_fileopen ();
227 struct cleanup *cleanups =
228 make_cleanup_ui_file_delete (opcode_stream);
229
230 size = gdbarch_print_insn (gdbarch, pc, di);
231 end_pc = pc + size;
232
233 for (;pc < end_pc; ++pc)
234 {
235 err = (*di->read_memory_func) (pc, &data, 1, di);
236 if (err != 0)
237 (*di->memory_error_func) (err, pc, di);
238 fprintf_filtered (opcode_stream, "%s%02x",
239 spacer, (unsigned) data);
240 spacer = " ";
241 }
242
243 ui_out_field_stream (uiout, "opcodes", opcode_stream);
244 ui_out_text (uiout, "\t");
245
246 do_cleanups (cleanups);
247 }
248 else
249 size = gdbarch_print_insn (gdbarch, pc, di);
250
251 ui_out_field_stream (uiout, "inst", stb);
252 ui_file_rewind (stb);
253 do_cleanups (ui_out_chain);
254 ui_out_text (uiout, "\n");
255
256 return size;
257 }
258
259 static int
260 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
261 struct disassemble_info * di,
262 CORE_ADDR low, CORE_ADDR high,
263 int how_many, int flags, struct ui_file *stb,
264 CORE_ADDR *end_pc)
265 {
266 int num_displayed = 0;
267
268 while (low < high && (how_many < 0 || num_displayed < how_many))
269 {
270 int size;
271
272 size = gdb_pretty_print_insn (gdbarch, uiout, di, low, flags, stb);
273 if (size <= 0)
274 break;
275
276 ++num_displayed;
277 low += size;
278
279 /* Allow user to bail out with ^C. */
280 QUIT;
281 }
282
283 if (end_pc != NULL)
284 *end_pc = low;
285
286 return num_displayed;
287 }
288
289 /* The idea here is to present a source-O-centric view of a
290 function to the user. This means that things are presented
291 in source order, with (possibly) out of order assembly
292 immediately following.
293
294 N.B. This view is deprecated. */
295
296 static void
297 do_mixed_source_and_assembly_deprecated
298 (struct gdbarch *gdbarch, struct ui_out *uiout,
299 struct disassemble_info *di, struct symtab *symtab,
300 CORE_ADDR low, CORE_ADDR high,
301 int how_many, int flags, struct ui_file *stb)
302 {
303 int newlines = 0;
304 int nlines;
305 struct linetable_entry *le;
306 struct deprecated_dis_line_entry *mle;
307 struct symtab_and_line sal;
308 int i;
309 int out_of_order = 0;
310 int next_line = 0;
311 int num_displayed = 0;
312 enum print_source_lines_flags psl_flags = 0;
313 struct cleanup *ui_out_chain;
314 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
315 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
316
317 gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
318
319 nlines = SYMTAB_LINETABLE (symtab)->nitems;
320 le = SYMTAB_LINETABLE (symtab)->item;
321
322 if (flags & DISASSEMBLY_FILENAME)
323 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
324
325 mle = (struct deprecated_dis_line_entry *)
326 alloca (nlines * sizeof (struct deprecated_dis_line_entry));
327
328 /* Copy linetable entries for this function into our data
329 structure, creating end_pc's and setting out_of_order as
330 appropriate. */
331
332 /* First, skip all the preceding functions. */
333
334 for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
335
336 /* Now, copy all entries before the end of this function. */
337
338 for (; i < nlines - 1 && le[i].pc < high; i++)
339 {
340 if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
341 continue; /* Ignore duplicates. */
342
343 /* Skip any end-of-function markers. */
344 if (le[i].line == 0)
345 continue;
346
347 mle[newlines].line = le[i].line;
348 if (le[i].line > le[i + 1].line)
349 out_of_order = 1;
350 mle[newlines].start_pc = le[i].pc;
351 mle[newlines].end_pc = le[i + 1].pc;
352 newlines++;
353 }
354
355 /* If we're on the last line, and it's part of the function,
356 then we need to get the end pc in a special way. */
357
358 if (i == nlines - 1 && le[i].pc < high)
359 {
360 mle[newlines].line = le[i].line;
361 mle[newlines].start_pc = le[i].pc;
362 sal = find_pc_line (le[i].pc, 0);
363 mle[newlines].end_pc = sal.end;
364 newlines++;
365 }
366
367 /* Now, sort mle by line #s (and, then by addresses within lines). */
368
369 if (out_of_order)
370 qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
371 compare_lines);
372
373 /* Now, for each line entry, emit the specified lines (unless
374 they have been emitted before), followed by the assembly code
375 for that line. */
376
377 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
378
379 for (i = 0; i < newlines; i++)
380 {
381 /* Print out everything from next_line to the current line. */
382 if (mle[i].line >= next_line)
383 {
384 if (next_line != 0)
385 {
386 /* Just one line to print. */
387 if (next_line == mle[i].line)
388 {
389 ui_out_tuple_chain
390 = make_cleanup_ui_out_tuple_begin_end (uiout,
391 "src_and_asm_line");
392 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
393 }
394 else
395 {
396 /* Several source lines w/o asm instructions associated. */
397 for (; next_line < mle[i].line; next_line++)
398 {
399 struct cleanup *ui_out_list_chain_line;
400 struct cleanup *ui_out_tuple_chain_line;
401
402 ui_out_tuple_chain_line
403 = make_cleanup_ui_out_tuple_begin_end (uiout,
404 "src_and_asm_line");
405 print_source_lines (symtab, next_line, next_line + 1,
406 psl_flags);
407 ui_out_list_chain_line
408 = make_cleanup_ui_out_list_begin_end (uiout,
409 "line_asm_insn");
410 do_cleanups (ui_out_list_chain_line);
411 do_cleanups (ui_out_tuple_chain_line);
412 }
413 /* Print the last line and leave list open for
414 asm instructions to be added. */
415 ui_out_tuple_chain
416 = make_cleanup_ui_out_tuple_begin_end (uiout,
417 "src_and_asm_line");
418 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
419 }
420 }
421 else
422 {
423 ui_out_tuple_chain
424 = make_cleanup_ui_out_tuple_begin_end (uiout,
425 "src_and_asm_line");
426 print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
427 }
428
429 next_line = mle[i].line + 1;
430 ui_out_list_chain
431 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
432 }
433
434 num_displayed += dump_insns (gdbarch, uiout, di,
435 mle[i].start_pc, mle[i].end_pc,
436 how_many, flags, stb, NULL);
437
438 /* When we've reached the end of the mle array, or we've seen the last
439 assembly range for this source line, close out the list/tuple. */
440 if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
441 {
442 do_cleanups (ui_out_list_chain);
443 do_cleanups (ui_out_tuple_chain);
444 ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
445 ui_out_list_chain = make_cleanup (null_cleanup, 0);
446 ui_out_text (uiout, "\n");
447 }
448 if (how_many >= 0 && num_displayed >= how_many)
449 break;
450 }
451 do_cleanups (ui_out_chain);
452 }
453
454 /* The idea here is to present a source-O-centric view of a
455 function to the user. This means that things are presented
456 in source order, with (possibly) out of order assembly
457 immediately following. */
458
459 static void
460 do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
461 struct disassemble_info *di,
462 struct symtab *main_symtab,
463 CORE_ADDR low, CORE_ADDR high,
464 int how_many, int flags, struct ui_file *stb)
465 {
466 int newlines = 0;
467 const struct linetable_entry *le, *first_le;
468 struct symtab_and_line sal;
469 int i, nlines;
470 int out_of_order = 0;
471 int next_line = 0;
472 int num_displayed = 0;
473 enum print_source_lines_flags psl_flags = 0;
474 struct cleanup *cleanups;
475 struct cleanup *ui_out_chain;
476 struct cleanup *ui_out_tuple_chain;
477 struct cleanup *ui_out_list_chain;
478 CORE_ADDR pc;
479 struct symtab *last_symtab;
480 int last_line;
481 htab_t dis_line_table;
482
483 gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
484
485 /* First pass: collect the list of all source files and lines.
486 We do this so that we can only print lines containing code once.
487 We try to print the source text leading up to the next instruction,
488 but if that text is for code that will be disassembled later, then
489 we'll want to defer printing it until later with its associated code. */
490
491 dis_line_table = allocate_dis_line_table ();
492 cleanups = make_cleanup_htab_delete (dis_line_table);
493
494 pc = low;
495
496 /* The prologue may be empty, but there may still be a line number entry
497 for the opening brace which is distinct from the first line of code.
498 If the prologue has been eliminated find_pc_line may return the source
499 line after the opening brace. We still want to print this opening brace.
500 first_le is used to implement this. */
501
502 nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
503 le = SYMTAB_LINETABLE (main_symtab)->item;
504 first_le = NULL;
505
506 /* Skip all the preceding functions. */
507 for (i = 0; i < nlines && le[i].pc < low; i++)
508 continue;
509
510 if (i < nlines && le[i].pc < high)
511 first_le = &le[i];
512
513 /* Add lines for every pc value. */
514 while (pc < high)
515 {
516 struct symtab_and_line sal;
517 int length;
518
519 sal = find_pc_line (pc, 0);
520 length = gdb_insn_length (gdbarch, pc);
521 pc += length;
522
523 if (sal.symtab != NULL)
524 maybe_add_dis_line_entry (dis_line_table, sal.symtab, sal.line);
525 }
526
527 /* Second pass: print the disassembly.
528
529 Output format, from an MI perspective:
530 The result is a ui_out list, field name "asm_insns", where elements have
531 name "src_and_asm_line".
532 Each element is a tuple of source line specs (field names line, file,
533 fullname), and field "line_asm_insn" which contains the disassembly.
534 Field "line_asm_insn" is a list of tuples: address, func-name, offset,
535 opcodes, inst.
536
537 CLI output works on top of this because MI ignores ui_out_text output,
538 which is where we put file name and source line contents output.
539
540 Cleanup usage:
541 cleanups:
542 For things created at the beginning of this function and need to be
543 kept until the end of this function.
544 ui_out_chain
545 Handles the outer "asm_insns" list.
546 ui_out_tuple_chain
547 The tuples for each group of consecutive disassemblies.
548 ui_out_list_chain
549 List of consecutive source lines or disassembled insns. */
550
551 if (flags & DISASSEMBLY_FILENAME)
552 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
553
554 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
555
556 ui_out_tuple_chain = NULL;
557 ui_out_list_chain = NULL;
558
559 last_symtab = NULL;
560 last_line = 0;
561 pc = low;
562
563 while (pc < high)
564 {
565 struct linetable_entry *le = NULL;
566 struct symtab_and_line sal;
567 CORE_ADDR end_pc;
568 int start_preceding_line_to_display = 0;
569 int end_preceding_line_to_display = 0;
570 int new_source_line = 0;
571
572 sal = find_pc_line (pc, 0);
573
574 if (sal.symtab != last_symtab)
575 {
576 /* New source file. */
577 new_source_line = 1;
578
579 /* If this is the first line of output, check for any preceding
580 lines. */
581 if (last_line == 0
582 && first_le != NULL
583 && first_le->line < sal.line)
584 {
585 start_preceding_line_to_display = first_le->line;
586 end_preceding_line_to_display = sal.line;
587 }
588 }
589 else
590 {
591 /* Same source file as last time. */
592 if (sal.symtab != NULL)
593 {
594 if (sal.line > last_line + 1 && last_line != 0)
595 {
596 int l;
597
598 /* Several preceding source lines. Print the trailing ones
599 not associated with code that we'll print later. */
600 for (l = sal.line - 1; l > last_line; --l)
601 {
602 if (line_has_code_p (dis_line_table, sal.symtab, l))
603 break;
604 }
605 if (l < sal.line - 1)
606 {
607 start_preceding_line_to_display = l + 1;
608 end_preceding_line_to_display = sal.line;
609 }
610 }
611 if (sal.line != last_line)
612 new_source_line = 1;
613 else
614 {
615 /* Same source line as last time. This can happen, depending
616 on the debug info. */
617 }
618 }
619 }
620
621 if (new_source_line)
622 {
623 /* Skip the newline if this is the first instruction. */
624 if (pc > low)
625 ui_out_text (uiout, "\n");
626 if (ui_out_tuple_chain != NULL)
627 {
628 gdb_assert (ui_out_list_chain != NULL);
629 do_cleanups (ui_out_list_chain);
630 do_cleanups (ui_out_tuple_chain);
631 }
632 if (sal.symtab != last_symtab
633 && !(flags & DISASSEMBLY_FILENAME))
634 {
635 /* Remember MI ignores ui_out_text.
636 We don't have to do anything here for MI because MI
637 output includes the source specs for each line. */
638 if (sal.symtab != NULL)
639 {
640 ui_out_text (uiout,
641 symtab_to_filename_for_display (sal.symtab));
642 }
643 else
644 ui_out_text (uiout, "unknown");
645 ui_out_text (uiout, ":\n");
646 }
647 if (start_preceding_line_to_display > 0)
648 {
649 /* Several source lines w/o asm instructions associated.
650 We need to preserve the structure of the output, so output
651 a bunch of line tuples with no asm entries. */
652 int l;
653 struct cleanup *ui_out_list_chain_line;
654 struct cleanup *ui_out_tuple_chain_line;
655
656 gdb_assert (sal.symtab != NULL);
657 for (l = start_preceding_line_to_display;
658 l < end_preceding_line_to_display;
659 ++l)
660 {
661 ui_out_tuple_chain_line
662 = make_cleanup_ui_out_tuple_begin_end (uiout,
663 "src_and_asm_line");
664 print_source_lines (sal.symtab, l, l + 1, psl_flags);
665 ui_out_list_chain_line
666 = make_cleanup_ui_out_list_begin_end (uiout,
667 "line_asm_insn");
668 do_cleanups (ui_out_list_chain_line);
669 do_cleanups (ui_out_tuple_chain_line);
670 }
671 }
672 ui_out_tuple_chain
673 = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
674 if (sal.symtab != NULL)
675 print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
676 else
677 ui_out_text (uiout, _("--- no source info for this pc ---\n"));
678 ui_out_list_chain
679 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
680 }
681 else
682 {
683 /* Here we're appending instructions to an existing line.
684 By construction the very first insn will have a symtab
685 and follow the new_source_line path above. */
686 gdb_assert (ui_out_tuple_chain != NULL);
687 gdb_assert (ui_out_list_chain != NULL);
688 }
689
690 if (sal.end != 0)
691 end_pc = min (sal.end, high);
692 else
693 end_pc = pc + 1;
694 num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
695 how_many, flags, stb, &end_pc);
696 pc = end_pc;
697
698 if (how_many >= 0 && num_displayed >= how_many)
699 break;
700
701 last_symtab = sal.symtab;
702 last_line = sal.line;
703 }
704
705 do_cleanups (ui_out_chain);
706 do_cleanups (cleanups);
707 }
708
709 static void
710 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
711 struct disassemble_info * di,
712 CORE_ADDR low, CORE_ADDR high,
713 int how_many, int flags, struct ui_file *stb)
714 {
715 int num_displayed = 0;
716 struct cleanup *ui_out_chain;
717
718 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
719
720 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
721 flags, stb, NULL);
722
723 do_cleanups (ui_out_chain);
724 }
725
726 /* Initialize the disassemble info struct ready for the specified
727 stream. */
728
729 static int ATTRIBUTE_PRINTF (2, 3)
730 fprintf_disasm (void *stream, const char *format, ...)
731 {
732 va_list args;
733
734 va_start (args, format);
735 vfprintf_filtered ((struct ui_file *) stream, format, args);
736 va_end (args);
737 /* Something non -ve. */
738 return 0;
739 }
740
741 struct disassemble_info
742 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
743 {
744 struct disassemble_info di;
745
746 init_disassemble_info (&di, file, fprintf_disasm);
747 di.flavour = bfd_target_unknown_flavour;
748 di.memory_error_func = dis_asm_memory_error;
749 di.print_address_func = dis_asm_print_address;
750 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
751 disassembler had a local optomization here. By default it would
752 access the executable file, instead of the target memory (there
753 was a growing list of exceptions though). Unfortunately, the
754 heuristic was flawed. Commands like "disassemble &variable"
755 didn't work as they relied on the access going to the target.
756 Further, it has been supperseeded by trust-read-only-sections
757 (although that should be superseeded by target_trust..._p()). */
758 di.read_memory_func = dis_asm_read_memory;
759 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
760 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
761 di.endian = gdbarch_byte_order (gdbarch);
762 di.endian_code = gdbarch_byte_order_for_code (gdbarch);
763 di.application_data = gdbarch;
764 disassemble_init_for_target (&di);
765 return di;
766 }
767
768 void
769 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
770 char *file_string, int flags, int how_many,
771 CORE_ADDR low, CORE_ADDR high)
772 {
773 struct ui_file *stb = mem_fileopen ();
774 struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
775 struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
776 struct symtab *symtab;
777 struct linetable_entry *le = NULL;
778 int nlines = -1;
779
780 /* Assume symtab is valid for whole PC range. */
781 symtab = find_pc_line_symtab (low);
782
783 if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
784 nlines = SYMTAB_LINETABLE (symtab)->nitems;
785
786 if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
787 || nlines <= 0)
788 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
789
790 else if (flags & DISASSEMBLY_SOURCE)
791 do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
792 how_many, flags, stb);
793
794 else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
795 do_mixed_source_and_assembly_deprecated (gdbarch, uiout, &di, symtab,
796 low, high, how_many, flags, stb);
797
798 do_cleanups (cleanups);
799 gdb_flush (gdb_stdout);
800 }
801
802 /* Print the instruction at address MEMADDR in debugged memory,
803 on STREAM. Returns the length of the instruction, in bytes,
804 and, if requested, the number of branch delay slot instructions. */
805
806 int
807 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
808 struct ui_file *stream, int *branch_delay_insns)
809 {
810 struct disassemble_info di;
811 int length;
812
813 di = gdb_disassemble_info (gdbarch, stream);
814 length = gdbarch_print_insn (gdbarch, memaddr, &di);
815 if (branch_delay_insns)
816 {
817 if (di.insn_info_valid)
818 *branch_delay_insns = di.branch_delay_insns;
819 else
820 *branch_delay_insns = 0;
821 }
822 return length;
823 }
824
825 static void
826 do_ui_file_delete (void *arg)
827 {
828 ui_file_delete ((struct ui_file *) arg);
829 }
830
831 /* Return the length in bytes of the instruction at address MEMADDR in
832 debugged memory. */
833
834 int
835 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
836 {
837 static struct ui_file *null_stream = NULL;
838
839 /* Dummy file descriptor for the disassembler. */
840 if (!null_stream)
841 {
842 null_stream = ui_file_new ();
843 make_final_cleanup (do_ui_file_delete, null_stream);
844 }
845
846 return gdb_print_insn (gdbarch, addr, null_stream, NULL);
847 }
848
849 /* fprintf-function for gdb_buffered_insn_length. This function is a
850 nop, we don't want to print anything, we just want to compute the
851 length of the insn. */
852
853 static int ATTRIBUTE_PRINTF (2, 3)
854 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
855 {
856 return 0;
857 }
858
859 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
860
861 static void
862 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
863 struct disassemble_info *di,
864 const gdb_byte *insn, int max_len,
865 CORE_ADDR addr)
866 {
867 init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
868
869 /* init_disassemble_info installs buffer_read_memory, etc.
870 so we don't need to do that here.
871 The cast is necessary until disassemble_info is const-ified. */
872 di->buffer = (gdb_byte *) insn;
873 di->buffer_length = max_len;
874 di->buffer_vma = addr;
875
876 di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
877 di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
878 di->endian = gdbarch_byte_order (gdbarch);
879 di->endian_code = gdbarch_byte_order_for_code (gdbarch);
880
881 disassemble_init_for_target (di);
882 }
883
884 /* Return the length in bytes of INSN. MAX_LEN is the size of the
885 buffer containing INSN. */
886
887 int
888 gdb_buffered_insn_length (struct gdbarch *gdbarch,
889 const gdb_byte *insn, int max_len, CORE_ADDR addr)
890 {
891 struct disassemble_info di;
892
893 gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
894
895 return gdbarch_print_insn (gdbarch, addr, &di);
896 }
This page took 0.051836 seconds and 5 git commands to generate.