1 /* Disassemble support for GDB. 2 3 Copyright (C) 2000-2005, 2007-2012 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 "gdb_string.h" 25 #include "disasm.h" 26 #include "gdbcore.h" 27 #include "dis-asm.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. 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 38 struct dis_line_entry 39 { 40 int line; 41 CORE_ADDR start_pc; 42 CORE_ADDR end_pc; 43 }; 44 45 /* Like target_read_memory, but slightly different parameters. */ 46 static int 47 dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len, 48 struct disassemble_info *info) 49 { 50 return target_read_memory (memaddr, myaddr, len); 51 } 52 53 /* Like memory_error with slightly different parameters. */ 54 static void 55 dis_asm_memory_error (int status, bfd_vma memaddr, 56 struct disassemble_info *info) 57 { 58 memory_error (status, memaddr); 59 } 60 61 /* Like print_address with slightly different parameters. */ 62 static void 63 dis_asm_print_address (bfd_vma addr, struct disassemble_info *info) 64 { 65 struct gdbarch *gdbarch = info->application_data; 66 67 print_address (gdbarch, addr, info->stream); 68 } 69 70 static int 71 compare_lines (const void *mle1p, const void *mle2p) 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 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; 94 } 95 96 static int 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_stream *stb) 101 { 102 int num_displayed = 0; 103 CORE_ADDR pc; 104 105 /* parts of the symbolic representation of the address */ 106 int unmapped; 107 int offset; 108 int line; 109 struct cleanup *ui_out_chain; 110 111 for (pc = low; pc < high;) 112 { 113 char *filename = NULL; 114 char *name = NULL; 115 116 QUIT; 117 if (how_many >= 0) 118 { 119 if (num_displayed >= how_many) 120 break; 121 else 122 num_displayed++; 123 } 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); 127 128 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename, 129 &line, &unmapped)) 130 { 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"); 139 } 140 else 141 ui_out_text (uiout, ":\t"); 142 143 if (filename != NULL) 144 xfree (filename); 145 if (name != NULL) 146 xfree (name); 147 148 ui_file_rewind (stb->stream); 149 if (flags & DISASSEMBLY_RAW_INSN) 150 { 151 CORE_ADDR old_pc = pc; 152 bfd_byte data; 153 int status; 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. */ 158 struct ui_stream *opcode_stream = ui_out_stream_new (uiout); 159 struct cleanup *cleanups = 160 make_cleanup_ui_out_stream_delete (opcode_stream); 161 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); 168 fprintf_filtered (opcode_stream->stream, "%s%02x", 169 spacer, (unsigned) data); 170 spacer = " "; 171 } 172 ui_out_field_stream (uiout, "opcodes", opcode_stream); 173 ui_out_text (uiout, "\t"); 174 175 do_cleanups (cleanups); 176 } 177 else 178 pc += gdbarch_print_insn (gdbarch, pc, di); 179 ui_out_field_stream (uiout, "inst", stb); 180 ui_file_rewind (stb->stream); 181 do_cleanups (ui_out_chain); 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. */ 191 192 static void 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_stream *stb) 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; 206 int num_displayed = 0; 207 struct cleanup *ui_out_chain; 208 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0); 209 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0); 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) 227 continue; /* Ignore duplicates. */ 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 254 lines). */ 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 263 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); 264 265 for (i = 0; i < newlines; i++) 266 { 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 { 272 /* Just one line to print. */ 273 if (next_line == mle[i].line) 274 { 275 ui_out_tuple_chain 276 = make_cleanup_ui_out_tuple_begin_end (uiout, 277 "src_and_asm_line"); 278 print_source_lines (symtab, next_line, mle[i].line + 1, 0); 279 } 280 else 281 { 282 /* Several source lines w/o asm instructions associated. */ 283 for (; next_line < mle[i].line; next_line++) 284 { 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"); 291 print_source_lines (symtab, next_line, next_line + 1, 292 0); 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); 298 } 299 /* Print the last line and leave list open for 300 asm instructions to be added. */ 301 ui_out_tuple_chain 302 = make_cleanup_ui_out_tuple_begin_end (uiout, 303 "src_and_asm_line"); 304 print_source_lines (symtab, next_line, mle[i].line + 1, 0); 305 } 306 } 307 else 308 { 309 ui_out_tuple_chain 310 = make_cleanup_ui_out_tuple_begin_end (uiout, 311 "src_and_asm_line"); 312 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0); 313 } 314 315 next_line = mle[i].line + 1; 316 ui_out_list_chain 317 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn"); 318 } 319 320 num_displayed += dump_insns (gdbarch, uiout, di, 321 mle[i].start_pc, mle[i].end_pc, 322 how_many, flags, stb); 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) 327 { 328 do_cleanups (ui_out_list_chain); 329 do_cleanups (ui_out_tuple_chain); 330 ui_out_tuple_chain = make_cleanup (null_cleanup, 0); 331 ui_out_list_chain = make_cleanup (null_cleanup, 0); 332 ui_out_text (uiout, "\n"); 333 } 334 if (how_many >= 0 && num_displayed >= how_many) 335 break; 336 } 337 do_cleanups (ui_out_chain); 338 } 339 340 341 static void 342 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout, 343 struct disassemble_info * di, 344 CORE_ADDR low, CORE_ADDR high, 345 int how_many, int flags, struct ui_stream *stb) 346 { 347 int num_displayed = 0; 348 struct cleanup *ui_out_chain; 349 350 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); 351 352 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many, 353 flags, stb); 354 355 do_cleanups (ui_out_chain); 356 } 357 358 /* Initialize the disassemble info struct ready for the specified 359 stream. */ 360 361 static int ATTRIBUTE_PRINTF (2, 3) 362 fprintf_disasm (void *stream, const char *format, ...) 363 { 364 va_list args; 365 366 va_start (args, format); 367 vfprintf_filtered (stream, format, args); 368 va_end (args); 369 /* Something non -ve. */ 370 return 0; 371 } 372 373 static struct disassemble_info 374 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file) 375 { 376 struct disassemble_info di; 377 378 init_disassemble_info (&di, file, fprintf_disasm); 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 385 was a growing list of exceptions though). Unfortunately, the 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; 391 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch; 392 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach; 393 di.endian = gdbarch_byte_order (gdbarch); 394 di.endian_code = gdbarch_byte_order_for_code (gdbarch); 395 di.application_data = gdbarch; 396 disassemble_init_for_target (&di); 397 return di; 398 } 399 400 void 401 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout, 402 char *file_string, int flags, int how_many, 403 CORE_ADDR low, CORE_ADDR high) 404 { 405 struct ui_stream *stb = ui_out_stream_new (uiout); 406 struct cleanup *cleanups = make_cleanup_ui_out_stream_delete (stb); 407 struct disassemble_info di = gdb_disassemble_info (gdbarch, stb->stream); 408 /* To collect the instruction outputted from opcodes. */ 409 struct symtab *symtab = NULL; 410 struct linetable_entry *le = NULL; 411 int nlines = -1; 412 413 /* Assume symtab is valid for whole PC range. */ 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 423 if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0 424 || symtab == NULL || symtab->linetable == NULL) 425 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb); 426 427 else if (flags & DISASSEMBLY_SOURCE) 428 do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low, 429 high, symtab, how_many, flags, stb); 430 431 do_cleanups (cleanups); 432 gdb_flush (gdb_stdout); 433 } 434 435 /* Print the instruction at address MEMADDR in debugged memory, 436 on STREAM. Returns the length of the instruction, in bytes, 437 and, if requested, the number of branch delay slot instructions. */ 438 439 int 440 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr, 441 struct ui_file *stream, int *branch_delay_insns) 442 { 443 struct disassemble_info di; 444 int length; 445 446 di = gdb_disassemble_info (gdbarch, stream); 447 length = gdbarch_print_insn (gdbarch, memaddr, &di); 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; 456 } 457 458 static void 459 do_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 467 int 468 gdb_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 486 static int ATTRIBUTE_PRINTF (2, 3) 487 gdb_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 494 static void 495 gdb_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 520 int 521 gdb_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 } 530