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