]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/disasm.c
Revise signal mapping function in GDB interface for RX sim.
[thirdparty/binutils-gdb.git] / gdb / disasm.c
CommitLineData
92df71f0 1/* Disassemble support for GDB.
1bac305b 2
ecd75fc8 3 Copyright (C) 2000-2014 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"
0e9f083f 24#include <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{
283f7163 50 return target_read_code (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);
946287b7
MM
125
126 if ((flags & DISASSEMBLY_OMIT_PC) == 0)
127 ui_out_text (uiout, pc_prefix (pc));
5af949e3 128 ui_out_field_core_addr (uiout, "address", gdbarch, pc);
92df71f0 129
22e722e1 130 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
92df71f0
FN
131 &line, &unmapped))
132 {
133 /* We don't care now about line, filename and
0963b4bd 134 unmapped. But we might in the future. */
92df71f0 135 ui_out_text (uiout, " <");
9c419145
PP
136 if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
137 ui_out_field_string (uiout, "func-name", name);
92df71f0
FN
138 ui_out_text (uiout, "+");
139 ui_out_field_int (uiout, "offset", offset);
140 ui_out_text (uiout, ">:\t");
141 }
13adf674
DJ
142 else
143 ui_out_text (uiout, ":\t");
144
92df71f0
FN
145 if (filename != NULL)
146 xfree (filename);
147 if (name != NULL)
148 xfree (name);
149
f99d8bf4 150 ui_file_rewind (stb);
e6158f16
HZ
151 if (flags & DISASSEMBLY_RAW_INSN)
152 {
153 CORE_ADDR old_pc = pc;
154 bfd_byte data;
155 int status;
b716877b
AB
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. */
f99d8bf4 160 struct ui_file *opcode_stream = mem_fileopen ();
b716877b 161 struct cleanup *cleanups =
f99d8bf4 162 make_cleanup_ui_file_delete (opcode_stream);
9a619af0 163
e6158f16
HZ
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);
f99d8bf4 170 fprintf_filtered (opcode_stream, "%s%02x",
b716877b
AB
171 spacer, (unsigned) data);
172 spacer = " ";
e6158f16 173 }
b716877b 174 ui_out_field_stream (uiout, "opcodes", opcode_stream);
e6158f16 175 ui_out_text (uiout, "\t");
b716877b
AB
176
177 do_cleanups (cleanups);
e6158f16
HZ
178 }
179 else
180 pc += gdbarch_print_insn (gdbarch, pc, di);
92df71f0 181 ui_out_field_stream (uiout, "inst", stb);
f99d8bf4 182 ui_file_rewind (stb);
3b31d625 183 do_cleanups (ui_out_chain);
92df71f0
FN
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. */
0963b4bd 193
92df71f0 194static void
13274fc3 195do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
92df71f0
FN
196 struct disassemble_info *di, int nlines,
197 struct linetable_entry *le,
198 CORE_ADDR low, CORE_ADDR high,
199 struct symtab *symtab,
f99d8bf4 200 int how_many, int flags, struct ui_file *stb)
92df71f0
FN
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;
92df71f0 208 int num_displayed = 0;
4cd29721 209 enum print_source_lines_flags psl_flags = 0;
3b31d625 210 struct cleanup *ui_out_chain;
0127c0d3
JJ
211 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
212 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
92df71f0 213
4cd29721
MM
214 if (flags & DISASSEMBLY_FILENAME)
215 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
216
92df71f0
FN
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)
0963b4bd 233 continue; /* Ignore duplicates. */
92df71f0
FN
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
0963b4bd 260 lines). */
92df71f0
FN
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
3b31d625 269 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
92df71f0
FN
270
271 for (i = 0; i < newlines; i++)
272 {
92df71f0
FN
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 {
0963b4bd 278 /* Just one line to print. */
92df71f0
FN
279 if (next_line == mle[i].line)
280 {
3b31d625
EZ
281 ui_out_tuple_chain
282 = make_cleanup_ui_out_tuple_begin_end (uiout,
283 "src_and_asm_line");
4cd29721 284 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
92df71f0
FN
285 }
286 else
287 {
0963b4bd 288 /* Several source lines w/o asm instructions associated. */
92df71f0
FN
289 for (; next_line < mle[i].line; next_line++)
290 {
3b31d625
EZ
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");
92df71f0 297 print_source_lines (symtab, next_line, next_line + 1,
4cd29721 298 psl_flags);
3b31d625
EZ
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);
92df71f0
FN
304 }
305 /* Print the last line and leave list open for
0963b4bd 306 asm instructions to be added. */
3b31d625
EZ
307 ui_out_tuple_chain
308 = make_cleanup_ui_out_tuple_begin_end (uiout,
309 "src_and_asm_line");
4cd29721 310 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
92df71f0
FN
311 }
312 }
313 else
314 {
3b31d625 315 ui_out_tuple_chain
3e43a32a
MS
316 = make_cleanup_ui_out_tuple_begin_end (uiout,
317 "src_and_asm_line");
4cd29721 318 print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
92df71f0
FN
319 }
320
321 next_line = mle[i].line + 1;
3b31d625
EZ
322 ui_out_list_chain
323 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
92df71f0
FN
324 }
325
13274fc3
UW
326 num_displayed += dump_insns (gdbarch, uiout, di,
327 mle[i].start_pc, mle[i].end_pc,
e6158f16 328 how_many, flags, stb);
0127c0d3
JJ
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)
92df71f0 333 {
3b31d625
EZ
334 do_cleanups (ui_out_list_chain);
335 do_cleanups (ui_out_tuple_chain);
0127c0d3
JJ
336 ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
337 ui_out_list_chain = make_cleanup (null_cleanup, 0);
92df71f0 338 ui_out_text (uiout, "\n");
92df71f0 339 }
0127c0d3
JJ
340 if (how_many >= 0 && num_displayed >= how_many)
341 break;
92df71f0 342 }
3b31d625 343 do_cleanups (ui_out_chain);
92df71f0
FN
344}
345
346
347static void
13274fc3
UW
348do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
349 struct disassemble_info * di,
92df71f0 350 CORE_ADDR low, CORE_ADDR high,
f99d8bf4 351 int how_many, int flags, struct ui_file *stb)
92df71f0
FN
352{
353 int num_displayed = 0;
3b31d625 354 struct cleanup *ui_out_chain;
92df71f0 355
3b31d625 356 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
92df71f0 357
e6158f16
HZ
358 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
359 flags, stb);
92df71f0 360
3b31d625 361 do_cleanups (ui_out_chain);
92df71f0
FN
362}
363
92bf2b80
AC
364/* Initialize the disassemble info struct ready for the specified
365 stream. */
366
a0b31db1 367static int ATTRIBUTE_PRINTF (2, 3)
242e8be5
AC
368fprintf_disasm (void *stream, const char *format, ...)
369{
370 va_list args;
9a619af0 371
242e8be5
AC
372 va_start (args, format);
373 vfprintf_filtered (stream, format, args);
374 va_end (args);
375 /* Something non -ve. */
376 return 0;
377}
378
ed3ef339 379struct disassemble_info
92bf2b80 380gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
92df71f0 381{
a89aa300 382 struct disassemble_info di;
9a619af0 383
242e8be5 384 init_disassemble_info (&di, file, fprintf_disasm);
2b6fd0d8
AC
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
ce2826aa 391 was a growing list of exceptions though). Unfortunately, the
2b6fd0d8
AC
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;
22b0d388 397 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
92bf2b80
AC
398 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
399 di.endian = gdbarch_byte_order (gdbarch);
9d4fde75 400 di.endian_code = gdbarch_byte_order_for_code (gdbarch);
5af949e3 401 di.application_data = gdbarch;
2877b4cc 402 disassemble_init_for_target (&di);
92bf2b80
AC
403 return di;
404}
405
406void
13274fc3 407gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
9c419145
PP
408 char *file_string, int flags, int how_many,
409 CORE_ADDR low, CORE_ADDR high)
92bf2b80 410{
f99d8bf4
PA
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);
0963b4bd 414 /* To collect the instruction outputted from opcodes. */
92bf2b80
AC
415 struct symtab *symtab = NULL;
416 struct linetable_entry *le = NULL;
417 int nlines = -1;
92df71f0 418
0963b4bd 419 /* Assume symtab is valid for whole PC range. */
92df71f0
FN
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
e6158f16 429 if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0
92df71f0 430 || symtab == NULL || symtab->linetable == NULL)
e6158f16 431 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
92df71f0 432
e6158f16 433 else if (flags & DISASSEMBLY_SOURCE)
13274fc3 434 do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
e6158f16 435 high, symtab, how_many, flags, stb);
92df71f0 436
2b6fd0d8 437 do_cleanups (cleanups);
92df71f0
FN
438 gdb_flush (gdb_stdout);
439}
810ecf9f 440
92bf2b80 441/* Print the instruction at address MEMADDR in debugged memory,
a4642986
MR
442 on STREAM. Returns the length of the instruction, in bytes,
443 and, if requested, the number of branch delay slot instructions. */
92bf2b80
AC
444
445int
13274fc3
UW
446gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
447 struct ui_file *stream, int *branch_delay_insns)
92bf2b80 448{
a4642986
MR
449 struct disassemble_info di;
450 int length;
451
13274fc3
UW
452 di = gdb_disassemble_info (gdbarch, stream);
453 length = gdbarch_print_insn (gdbarch, memaddr, &di);
a4642986
MR
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;
92bf2b80 462}
eda5a4d7
PA
463
464static void
465do_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
473int
474gdb_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
492static int ATTRIBUTE_PRINTF (2, 3)
493gdb_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
500static void
501gdb_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
526int
527gdb_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}