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