1 /* Disassemble support for GDB.
3 Copyright (C) 2000-2013 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
24 #include "gdb_string.h"
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. */
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. */
45 /* Like target_read_memory, but slightly different parameters. */
47 dis_asm_read_memory (bfd_vma memaddr
, gdb_byte
*myaddr
, unsigned int len
,
48 struct disassemble_info
*info
)
50 return target_read_memory (memaddr
, myaddr
, len
);
53 /* Like memory_error with slightly different parameters. */
55 dis_asm_memory_error (int status
, bfd_vma memaddr
,
56 struct disassemble_info
*info
)
58 memory_error (status
, memaddr
);
61 /* Like print_address with slightly different parameters. */
63 dis_asm_print_address (bfd_vma addr
, struct disassemble_info
*info
)
65 struct gdbarch
*gdbarch
= info
->application_data
;
67 print_address (gdbarch
, addr
, info
->stream
);
71 compare_lines (const void *mle1p
, const void *mle2p
)
73 struct dis_line_entry
*mle1
, *mle2
;
76 mle1
= (struct dis_line_entry
*) mle1p
;
77 mle2
= (struct dis_line_entry
*) mle2p
;
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)
83 val
= mle1
->start_pc
- mle2
->start_pc
;
85 val
= mle1
->line
- mle2
->line
;
89 val
= mle1
->line
- mle2
->line
;
91 val
= mle1
->start_pc
- mle2
->start_pc
;
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
)
102 int num_displayed
= 0;
105 /* parts of the symbolic representation of the address */
109 struct cleanup
*ui_out_chain
;
111 for (pc
= low
; pc
< high
;)
113 char *filename
= NULL
;
119 if (num_displayed
>= how_many
)
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
);
128 if (!build_address_symbolic (gdbarch
, pc
, 0, &name
, &offset
, &filename
,
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");
141 ui_out_text (uiout
, ":\t");
143 if (filename
!= NULL
)
148 ui_file_rewind (stb
);
149 if (flags
& DISASSEMBLY_RAW_INSN
)
151 CORE_ADDR old_pc
= pc
;
154 const char *spacer
= "";
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
);
162 pc
+= gdbarch_print_insn (gdbarch
, pc
, di
);
163 for (;old_pc
< pc
; old_pc
++)
165 status
= (*di
->read_memory_func
) (old_pc
, &data
, 1, di
);
167 (*di
->memory_error_func
) (status
, old_pc
, di
);
168 fprintf_filtered (opcode_stream
, "%s%02x",
169 spacer
, (unsigned) data
);
172 ui_out_field_stream (uiout
, "opcodes", opcode_stream
);
173 ui_out_text (uiout
, "\t");
175 do_cleanups (cleanups
);
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");
184 return num_displayed
;
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. */
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
)
201 struct dis_line_entry
*mle
;
202 struct symtab_and_line sal
;
204 int out_of_order
= 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);
212 if (flags
& DISASSEMBLY_FILENAME
)
213 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
215 mle
= (struct dis_line_entry
*) alloca (nlines
216 * sizeof (struct dis_line_entry
));
218 /* Copy linetable entries for this function into our data
219 structure, creating end_pc's and setting out_of_order as
222 /* First, skip all the preceding functions. */
224 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++);
226 /* Now, copy all entries before the end of this function. */
228 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
230 if (le
[i
].line
== le
[i
+ 1].line
&& le
[i
].pc
== le
[i
+ 1].pc
)
231 continue; /* Ignore duplicates. */
233 /* Skip any end-of-function markers. */
237 mle
[newlines
].line
= le
[i
].line
;
238 if (le
[i
].line
> le
[i
+ 1].line
)
240 mle
[newlines
].start_pc
= le
[i
].pc
;
241 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
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. */
248 if (i
== nlines
- 1 && le
[i
].pc
< high
)
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
;
257 /* Now, sort mle by line #s (and, then by addresses within
261 qsort (mle
, newlines
, sizeof (struct dis_line_entry
), compare_lines
);
263 /* Now, for each line entry, emit the specified lines (unless
264 they have been emitted before), followed by the assembly code
267 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
269 for (i
= 0; i
< newlines
; i
++)
271 /* Print out everything from next_line to the current line. */
272 if (mle
[i
].line
>= next_line
)
276 /* Just one line to print. */
277 if (next_line
== mle
[i
].line
)
280 = make_cleanup_ui_out_tuple_begin_end (uiout
,
282 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
286 /* Several source lines w/o asm instructions associated. */
287 for (; next_line
< mle
[i
].line
; next_line
++)
289 struct cleanup
*ui_out_list_chain_line
;
290 struct cleanup
*ui_out_tuple_chain_line
;
292 ui_out_tuple_chain_line
293 = make_cleanup_ui_out_tuple_begin_end (uiout
,
295 print_source_lines (symtab
, next_line
, next_line
+ 1,
297 ui_out_list_chain_line
298 = make_cleanup_ui_out_list_begin_end (uiout
,
300 do_cleanups (ui_out_list_chain_line
);
301 do_cleanups (ui_out_tuple_chain_line
);
303 /* Print the last line and leave list open for
304 asm instructions to be added. */
306 = make_cleanup_ui_out_tuple_begin_end (uiout
,
308 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
314 = make_cleanup_ui_out_tuple_begin_end (uiout
,
316 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, psl_flags
);
319 next_line
= mle
[i
].line
+ 1;
321 = make_cleanup_ui_out_list_begin_end (uiout
, "line_asm_insn");
324 num_displayed
+= dump_insns (gdbarch
, uiout
, di
,
325 mle
[i
].start_pc
, mle
[i
].end_pc
,
326 how_many
, flags
, stb
);
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
)
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");
338 if (how_many
>= 0 && num_displayed
>= how_many
)
341 do_cleanups (ui_out_chain
);
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
)
351 int num_displayed
= 0;
352 struct cleanup
*ui_out_chain
;
354 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
356 num_displayed
= dump_insns (gdbarch
, uiout
, di
, low
, high
, how_many
,
359 do_cleanups (ui_out_chain
);
362 /* Initialize the disassemble info struct ready for the specified
365 static int ATTRIBUTE_PRINTF (2, 3)
366 fprintf_disasm (void *stream
, const char *format
, ...)
370 va_start (args
, format
);
371 vfprintf_filtered (stream
, format
, args
);
373 /* Something non -ve. */
377 static struct disassemble_info
378 gdb_disassemble_info (struct gdbarch
*gdbarch
, struct ui_file
*file
)
380 struct disassemble_info di
;
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
);
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
)
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
;
417 /* Assume symtab is valid for whole PC range. */
418 symtab
= find_pc_symtab (low
);
420 if (symtab
!= NULL
&& symtab
->linetable
!= NULL
)
422 /* Convert the linetable to a bunch of my_line_entry's. */
423 le
= symtab
->linetable
->item
;
424 nlines
= symtab
->linetable
->nitems
;
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
);
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
);
435 do_cleanups (cleanups
);
436 gdb_flush (gdb_stdout
);
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. */
444 gdb_print_insn (struct gdbarch
*gdbarch
, CORE_ADDR memaddr
,
445 struct ui_file
*stream
, int *branch_delay_insns
)
447 struct disassemble_info di
;
450 di
= gdb_disassemble_info (gdbarch
, stream
);
451 length
= gdbarch_print_insn (gdbarch
, memaddr
, &di
);
452 if (branch_delay_insns
)
454 if (di
.insn_info_valid
)
455 *branch_delay_insns
= di
.branch_delay_insns
;
457 *branch_delay_insns
= 0;
463 do_ui_file_delete (void *arg
)
465 ui_file_delete (arg
);
468 /* Return the length in bytes of the instruction at address MEMADDR in
472 gdb_insn_length (struct gdbarch
*gdbarch
, CORE_ADDR addr
)
474 static struct ui_file
*null_stream
= NULL
;
476 /* Dummy file descriptor for the disassembler. */
479 null_stream
= ui_file_new ();
480 make_final_cleanup (do_ui_file_delete
, null_stream
);
483 return gdb_print_insn (gdbarch
, addr
, null_stream
, NULL
);
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. */
490 static int ATTRIBUTE_PRINTF (2, 3)
491 gdb_buffered_insn_length_fprintf (void *stream
, const char *format
, ...)
496 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
499 gdb_buffered_insn_length_init_dis (struct gdbarch
*gdbarch
,
500 struct disassemble_info
*di
,
501 const gdb_byte
*insn
, int max_len
,
504 init_disassemble_info (di
, NULL
, gdb_buffered_insn_length_fprintf
);
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
;
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
);
518 disassemble_init_for_target (di
);
521 /* Return the length in bytes of INSN. MAX_LEN is the size of the
522 buffer containing INSN. */
525 gdb_buffered_insn_length (struct gdbarch
*gdbarch
,
526 const gdb_byte
*insn
, int max_len
, CORE_ADDR addr
)
528 struct disassemble_info di
;
530 gdb_buffered_insn_length_init_dis (gdbarch
, &di
, insn
, max_len
, addr
);
532 return gdbarch_print_insn (gdbarch
, addr
, &di
);