Add ravenscar-thread support for powerpc.
[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;
4cd29721 207 enum print_source_lines_flags psl_flags = 0;
3b31d625 208 struct cleanup *ui_out_chain;
0127c0d3
JJ
209 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
210 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
92df71f0 211
4cd29721
MM
212 if (flags & DISASSEMBLY_FILENAME)
213 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
214
92df71f0
FN
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)
0963b4bd 231 continue; /* Ignore duplicates. */
92df71f0
FN
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
0963b4bd 258 lines). */
92df71f0
FN
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
3b31d625 267 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
92df71f0
FN
268
269 for (i = 0; i < newlines; i++)
270 {
92df71f0
FN
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 {
0963b4bd 276 /* Just one line to print. */
92df71f0
FN
277 if (next_line == mle[i].line)
278 {
3b31d625
EZ
279 ui_out_tuple_chain
280 = make_cleanup_ui_out_tuple_begin_end (uiout,
281 "src_and_asm_line");
4cd29721 282 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
92df71f0
FN
283 }
284 else
285 {
0963b4bd 286 /* Several source lines w/o asm instructions associated. */
92df71f0
FN
287 for (; next_line < mle[i].line; next_line++)
288 {
3b31d625
EZ
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");
92df71f0 295 print_source_lines (symtab, next_line, next_line + 1,
4cd29721 296 psl_flags);
3b31d625
EZ
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);
92df71f0
FN
302 }
303 /* Print the last line and leave list open for
0963b4bd 304 asm instructions to be added. */
3b31d625
EZ
305 ui_out_tuple_chain
306 = make_cleanup_ui_out_tuple_begin_end (uiout,
307 "src_and_asm_line");
4cd29721 308 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
92df71f0
FN
309 }
310 }
311 else
312 {
3b31d625 313 ui_out_tuple_chain
3e43a32a
MS
314 = make_cleanup_ui_out_tuple_begin_end (uiout,
315 "src_and_asm_line");
4cd29721 316 print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
92df71f0
FN
317 }
318
319 next_line = mle[i].line + 1;
3b31d625
EZ
320 ui_out_list_chain
321 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
92df71f0
FN
322 }
323
13274fc3
UW
324 num_displayed += dump_insns (gdbarch, uiout, di,
325 mle[i].start_pc, mle[i].end_pc,
e6158f16 326 how_many, flags, stb);
0127c0d3
JJ
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)
92df71f0 331 {
3b31d625
EZ
332 do_cleanups (ui_out_list_chain);
333 do_cleanups (ui_out_tuple_chain);
0127c0d3
JJ
334 ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
335 ui_out_list_chain = make_cleanup (null_cleanup, 0);
92df71f0 336 ui_out_text (uiout, "\n");
92df71f0 337 }
0127c0d3
JJ
338 if (how_many >= 0 && num_displayed >= how_many)
339 break;
92df71f0 340 }
3b31d625 341 do_cleanups (ui_out_chain);
92df71f0
FN
342}
343
344
345static void
13274fc3
UW
346do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
347 struct disassemble_info * di,
92df71f0 348 CORE_ADDR low, CORE_ADDR high,
f99d8bf4 349 int how_many, int flags, struct ui_file *stb)
92df71f0
FN
350{
351 int num_displayed = 0;
3b31d625 352 struct cleanup *ui_out_chain;
92df71f0 353
3b31d625 354 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
92df71f0 355
e6158f16
HZ
356 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
357 flags, stb);
92df71f0 358
3b31d625 359 do_cleanups (ui_out_chain);
92df71f0
FN
360}
361
92bf2b80
AC
362/* Initialize the disassemble info struct ready for the specified
363 stream. */
364
a0b31db1 365static int ATTRIBUTE_PRINTF (2, 3)
242e8be5
AC
366fprintf_disasm (void *stream, const char *format, ...)
367{
368 va_list args;
9a619af0 369
242e8be5
AC
370 va_start (args, format);
371 vfprintf_filtered (stream, format, args);
372 va_end (args);
373 /* Something non -ve. */
374 return 0;
375}
376
a89aa300 377static struct disassemble_info
92bf2b80 378gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
92df71f0 379{
a89aa300 380 struct disassemble_info di;
9a619af0 381
242e8be5 382 init_disassemble_info (&di, file, fprintf_disasm);
2b6fd0d8
AC
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
ce2826aa 389 was a growing list of exceptions though). Unfortunately, the
2b6fd0d8
AC
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;
22b0d388 395 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
92bf2b80
AC
396 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
397 di.endian = gdbarch_byte_order (gdbarch);
9d4fde75 398 di.endian_code = gdbarch_byte_order_for_code (gdbarch);
5af949e3 399 di.application_data = gdbarch;
2877b4cc 400 disassemble_init_for_target (&di);
92bf2b80
AC
401 return di;
402}
403
404void
13274fc3 405gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
9c419145
PP
406 char *file_string, int flags, int how_many,
407 CORE_ADDR low, CORE_ADDR high)
92bf2b80 408{
f99d8bf4
PA
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);
0963b4bd 412 /* To collect the instruction outputted from opcodes. */
92bf2b80
AC
413 struct symtab *symtab = NULL;
414 struct linetable_entry *le = NULL;
415 int nlines = -1;
92df71f0 416
0963b4bd 417 /* Assume symtab is valid for whole PC range. */
92df71f0
FN
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
e6158f16 427 if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0
92df71f0 428 || symtab == NULL || symtab->linetable == NULL)
e6158f16 429 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
92df71f0 430
e6158f16 431 else if (flags & DISASSEMBLY_SOURCE)
13274fc3 432 do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
e6158f16 433 high, symtab, how_many, flags, stb);
92df71f0 434
2b6fd0d8 435 do_cleanups (cleanups);
92df71f0
FN
436 gdb_flush (gdb_stdout);
437}
810ecf9f 438
92bf2b80 439/* Print the instruction at address MEMADDR in debugged memory,
a4642986
MR
440 on STREAM. Returns the length of the instruction, in bytes,
441 and, if requested, the number of branch delay slot instructions. */
92bf2b80
AC
442
443int
13274fc3
UW
444gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
445 struct ui_file *stream, int *branch_delay_insns)
92bf2b80 446{
a4642986
MR
447 struct disassemble_info di;
448 int length;
449
13274fc3
UW
450 di = gdb_disassemble_info (gdbarch, stream);
451 length = gdbarch_print_insn (gdbarch, memaddr, &di);
a4642986
MR
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;
92bf2b80 460}
eda5a4d7
PA
461
462static void
463do_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
471int
472gdb_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
490static int ATTRIBUTE_PRINTF (2, 3)
491gdb_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
498static void
499gdb_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
524int
525gdb_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.712549 seconds and 4 git commands to generate.