1/* Locate source files and line information for given addresses 2 Copyright (C) 2005-2010, 2012, 2013, 2015 Red Hat, Inc. 3 This file is part of elfutils. 4 Written by Ulrich Drepper <drepper@redhat.com>, 2005. 5 6 This file is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 elfutils is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19#ifdef HAVE_CONFIG_H 20# include <config.h> 21#endif 22 23#include <argp.h> 24#include <assert.h> 25#include <errno.h> 26#include <error.h> 27#include <fcntl.h> 28#include <inttypes.h> 29#include <libdwfl.h> 30#include <dwarf.h> 31#include <libintl.h> 32#include <locale.h> 33#include <stdbool.h> 34#include <stdio.h> 35#include <stdio_ext.h> 36#include <stdlib.h> 37#include <string.h> 38#include <unistd.h> 39 40#include <system.h> 41 42 43/* Name and version of program. */ 44static void print_version (FILE *stream, struct argp_state *state); 45ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; 46 47/* Bug report address. */ 48ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; 49 50 51/* Values for the parameters which have no short form. */ 52#define OPT_DEMANGLER 0x100 53#define OPT_PRETTY 0x101 /* 'p' is already used to select the process. */ 54 55/* Definitions of arguments for argp functions. */ 56static const struct argp_option options[] = 57{ 58 { NULL, 0, NULL, 0, N_("Input format options:"), 2 }, 59 { "section", 'j', "NAME", 0, 60 N_("Treat addresses as offsets relative to NAME section."), 0 }, 61 62 { NULL, 0, NULL, 0, N_("Output format options:"), 3 }, 63 { "addresses", 'a', NULL, 0, N_("Print address before each entry"), 0 }, 64 { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 }, 65 { "absolute", 'A', NULL, 0, 66 N_("Show absolute file names using compilation directory"), 0 }, 67 { "functions", 'f', NULL, 0, N_("Also show function names"), 0 }, 68 { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 }, 69 { "symbols-sections", 'x', NULL, 0, N_("Also show symbol and the section names"), 0 }, 70 { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 }, 71 { "inlines", 'i', NULL, 0, 72 N_("Show all source locations that caused inline expansion of subroutines at the address."), 73 0 }, 74 { "demangle", 'C', "ARG", OPTION_ARG_OPTIONAL, 75 N_("Show demangled symbols (ARG is always ignored)"), 0 }, 76 { "pretty-print", OPT_PRETTY, NULL, 0, 77 N_("Print all information on one line, and indent inlines"), 0 }, 78 79 { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 }, 80 /* Unsupported options. */ 81 { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 }, 82 { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 }, 83 { NULL, 0, NULL, 0, NULL, 0 } 84}; 85 86/* Short description of program. */ 87static const char doc[] = N_("\ 88Locate source files and line information for ADDRs (in a.out by default)."); 89 90/* Strings for arguments in help texts. */ 91static const char args_doc[] = N_("[ADDR...]"); 92 93/* Prototype for option handler. */ 94static error_t parse_opt (int key, char *arg, struct argp_state *state); 95 96static struct argp_child argp_children[2]; /* [0] is set in main. */ 97 98/* Data structure to communicate with argp functions. */ 99static const struct argp argp = 100{ 101 options, parse_opt, args_doc, doc, argp_children, NULL, NULL 102}; 103 104 105/* Handle ADDR. */ 106static int handle_address (const char *addr, Dwfl *dwfl); 107 108/* True when we should print the address for each entry. */ 109static bool print_addresses; 110 111/* True if only base names of files should be shown. */ 112static bool only_basenames; 113 114/* True if absolute file names based on DW_AT_comp_dir should be shown. */ 115static bool use_comp_dir; 116 117/* True if line flags should be shown. */ 118static bool show_flags; 119 120/* True if function names should be shown. */ 121static bool show_functions; 122 123/* True if ELF symbol or section info should be shown. */ 124static bool show_symbols; 125 126/* True if section associated with a symbol address should be shown. */ 127static bool show_symbol_sections; 128 129/* If non-null, take address parameters as relative to named section. */ 130static const char *just_section; 131 132/* True if all inlined subroutines of the current address should be shown. */ 133static bool show_inlines; 134 135/* True if all names need to be demangled. */ 136static bool demangle; 137 138/* True if all information should be printed on one line. */ 139static bool pretty; 140 141#ifdef USE_DEMANGLE 142static size_t demangle_buffer_len = 0; 143static char *demangle_buffer = NULL; 144#endif 145 146int 147main (int argc, char *argv[]) 148{ 149 int remaining; 150 int result = 0; 151 152 /* We use no threads here which can interfere with handling a stream. */ 153 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER); 154 155 /* Set locale. */ 156 (void) setlocale (LC_ALL, ""); 157 158 /* Make sure the message catalog can be found. */ 159 (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR); 160 161 /* Initialize the message catalog. */ 162 (void) textdomain (PACKAGE_TARNAME); 163 164 /* Parse and process arguments. This includes opening the modules. */ 165 argp_children[0].argp = dwfl_standard_argp (); 166 argp_children[0].group = 1; 167 Dwfl *dwfl = NULL; 168 (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl); 169 assert (dwfl != NULL); 170 171 /* Now handle the addresses. In case none are given on the command 172 line, read from stdin. */ 173 if (remaining == argc) 174 { 175 /* We use no threads here which can interfere with handling a stream. */ 176 (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER); 177 178 char *buf = NULL; 179 size_t len = 0; 180 ssize_t chars; 181 while (!feof_unlocked (stdin)) 182 { 183 if ((chars = getline (&buf, &len, stdin)) < 0) 184 break; 185 186 if (buf[chars - 1] == '\n') 187 buf[chars - 1] = '\0'; 188 189 result = handle_address (buf, dwfl); 190 } 191 192 free (buf); 193 } 194 else 195 { 196 do 197 result = handle_address (argv[remaining], dwfl); 198 while (++remaining < argc); 199 } 200 201 dwfl_end (dwfl); 202 203#ifdef USE_DEMANGLE 204 free (demangle_buffer); 205#endif 206 207 return result; 208} 209 210 211/* Print the version information. */ 212static void 213print_version (FILE *stream, struct argp_state *state __attribute__ ((unused))) 214{ 215 fprintf (stream, "addr2line (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); 216 fprintf (stream, gettext ("\ 217Copyright (C) %s Red Hat, Inc.\n\ 218This is free software; see the source for copying conditions. There is NO\n\ 219warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ 220"), "2012"); 221 fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); 222} 223 224 225/* Handle program arguments. */ 226static error_t 227parse_opt (int key, char *arg, struct argp_state *state) 228{ 229 switch (key) 230 { 231 case ARGP_KEY_INIT: 232 state->child_inputs[0] = state->input; 233 break; 234 235 case 'a': 236 print_addresses = true; 237 break; 238 239 case 'b': 240 case 'C': 241 case OPT_DEMANGLER: 242 demangle = true; 243 break; 244 245 case 's': 246 only_basenames = true; 247 break; 248 249 case 'A': 250 use_comp_dir = true; 251 break; 252 253 case 'f': 254 show_functions = true; 255 break; 256 257 case 'F': 258 show_flags = true; 259 break; 260 261 case 'S': 262 show_symbols = true; 263 break; 264 265 case 'x': 266 show_symbols = true; 267 show_symbol_sections = true; 268 break; 269 270 case 'j': 271 just_section = arg; 272 break; 273 274 case 'i': 275 show_inlines = true; 276 break; 277 278 case OPT_PRETTY: 279 pretty = true; 280 break; 281 282 default: 283 return ARGP_ERR_UNKNOWN; 284 } 285 return 0; 286} 287 288static const char * 289symname (const char *name) 290{ 291#ifdef USE_DEMANGLE 292 // Require GNU v3 ABI by the "_Z" prefix. 293 if (demangle && name[0] == '_' && name[1] == 'Z') 294 { 295 int status = -1; 296 char *dsymname = __cxa_demangle (name, demangle_buffer, 297 &demangle_buffer_len, &status); 298 if (status == 0) 299 name = demangle_buffer = dsymname; 300 } 301#endif 302 return name; 303} 304 305static const char * 306get_diename (Dwarf_Die *die) 307{ 308 Dwarf_Attribute attr; 309 const char *name; 310 311 name = dwarf_formstring (dwarf_attr_integrate (die, DW_AT_MIPS_linkage_name, 312 &attr) 313 ?: dwarf_attr_integrate (die, DW_AT_linkage_name, 314 &attr)); 315 316 if (name == NULL) 317 name = dwarf_diename (die) ?: "??"; 318 319 return name; 320} 321 322static bool 323print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr) 324{ 325 Dwarf_Addr bias = 0; 326 Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias); 327 328 Dwarf_Die *scopes; 329 int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes); 330 if (nscopes <= 0) 331 return false; 332 333 bool res = false; 334 for (int i = 0; i < nscopes; ++i) 335 switch (dwarf_tag (&scopes[i])) 336 { 337 case DW_TAG_subprogram: 338 { 339 const char *name = get_diename (&scopes[i]); 340 if (name == NULL) 341 goto done; 342 printf ("%s%c", symname (name), pretty ? ' ' : '\n'); 343 res = true; 344 goto done; 345 } 346 347 case DW_TAG_inlined_subroutine: 348 { 349 const char *name = get_diename (&scopes[i]); 350 if (name == NULL) 351 goto done; 352 353 /* When using --pretty-print we only show inlines on their 354 own line. Just print the first subroutine name. */ 355 if (pretty) 356 { 357 printf ("%s ", symname (name)); 358 res = true; 359 goto done; 360 } 361 else 362 printf ("%s inlined", symname (name)); 363 364 Dwarf_Files *files; 365 if (dwarf_getsrcfiles (cudie, &files, NULL) == 0) 366 { 367 Dwarf_Attribute attr_mem; 368 Dwarf_Word val; 369 if (dwarf_formudata (dwarf_attr (&scopes[i], 370 DW_AT_call_file, 371 &attr_mem), &val) == 0) 372 { 373 const char *file = dwarf_filesrc (files, val, NULL, NULL); 374 unsigned int lineno = 0; 375 unsigned int colno = 0; 376 if (dwarf_formudata (dwarf_attr (&scopes[i], 377 DW_AT_call_line, 378 &attr_mem), &val) == 0) 379 lineno = val; 380 if (dwarf_formudata (dwarf_attr (&scopes[i], 381 DW_AT_call_column, 382 &attr_mem), &val) == 0) 383 colno = val; 384 385 const char *comp_dir = ""; 386 const char *comp_dir_sep = ""; 387 388 if (file == NULL) 389 file = "???"; 390 else if (only_basenames) 391 file = basename (file); 392 else if (use_comp_dir && file[0] != '/') 393 { 394 const char *const *dirs; 395 size_t ndirs; 396 if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0 397 && dirs[0] != NULL) 398 { 399 comp_dir = dirs[0]; 400 comp_dir_sep = "/"; 401 } 402 } 403 404 if (lineno == 0) 405 printf (" from %s%s%s", 406 comp_dir, comp_dir_sep, file); 407 else if (colno == 0) 408 printf (" at %s%s%s:%u", 409 comp_dir, comp_dir_sep, file, lineno); 410 else 411 printf (" at %s%s%s:%u:%u", 412 comp_dir, comp_dir_sep, file, lineno, colno); 413 } 414 } 415 printf (" in "); 416 continue; 417 } 418 } 419 420done: 421 free (scopes); 422 return res; 423} 424 425static void 426print_addrsym (Dwfl_Module *mod, GElf_Addr addr) 427{ 428 GElf_Sym s; 429 GElf_Off off; 430 const char *name = dwfl_module_addrinfo (mod, addr, &off, &s, 431 NULL, NULL, NULL); 432 if (name == NULL) 433 { 434 /* No symbol name. Get a section name instead. */ 435 int i = dwfl_module_relocate_address (mod, &addr); 436 if (i >= 0) 437 name = dwfl_module_relocation_info (mod, i, NULL); 438 if (name == NULL) 439 printf ("??%c", pretty ? ' ': '\n'); 440 else 441 printf ("(%s)+%#" PRIx64 "%c", name, addr, pretty ? ' ' : '\n'); 442 } 443 else 444 { 445 name = symname (name); 446 if (off == 0) 447 printf ("%s", name); 448 else 449 printf ("%s+%#" PRIx64 "", name, off); 450 451 // Also show section name for address. 452 if (show_symbol_sections) 453 { 454 Dwarf_Addr ebias; 455 Elf_Scn *scn = dwfl_module_address_section (mod, &addr, &ebias); 456 if (scn != NULL) 457 { 458 GElf_Shdr shdr_mem; 459 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 460 if (shdr != NULL) 461 { 462 Elf *elf = dwfl_module_getelf (mod, &ebias); 463 GElf_Ehdr ehdr; 464 if (gelf_getehdr (elf, &ehdr) != NULL) 465 printf (" (%s)", elf_strptr (elf, ehdr.e_shstrndx, 466 shdr->sh_name)); 467 } 468 } 469 } 470 printf ("%c", pretty ? ' ' : '\n'); 471 } 472} 473 474static int 475see_one_module (Dwfl_Module *mod, 476 void **userdata __attribute__ ((unused)), 477 const char *name __attribute__ ((unused)), 478 Dwarf_Addr start __attribute__ ((unused)), 479 void *arg) 480{ 481 Dwfl_Module **result = arg; 482 if (*result != NULL) 483 return DWARF_CB_ABORT; 484 *result = mod; 485 return DWARF_CB_OK; 486} 487 488static int 489find_symbol (Dwfl_Module *mod, 490 void **userdata __attribute__ ((unused)), 491 const char *name __attribute__ ((unused)), 492 Dwarf_Addr start __attribute__ ((unused)), 493 void *arg) 494{ 495 const char *looking_for = ((void **) arg)[0]; 496 GElf_Sym *symbol = ((void **) arg)[1]; 497 GElf_Addr *value = ((void **) arg)[2]; 498 499 int n = dwfl_module_getsymtab (mod); 500 for (int i = 1; i < n; ++i) 501 { 502 const char *symbol_name = dwfl_module_getsym_info (mod, i, symbol, 503 value, NULL, NULL, 504 NULL); 505 if (symbol_name == NULL || symbol_name[0] == '\0') 506 continue; 507 switch (GELF_ST_TYPE (symbol->st_info)) 508 { 509 case STT_SECTION: 510 case STT_FILE: 511 case STT_TLS: 512 break; 513 default: 514 if (!strcmp (symbol_name, looking_for)) 515 { 516 ((void **) arg)[0] = NULL; 517 return DWARF_CB_ABORT; 518 } 519 } 520 } 521 522 return DWARF_CB_OK; 523} 524 525static bool 526adjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl) 527{ 528 /* It was (section)+offset. This makes sense if there is 529 only one module to look in for a section. */ 530 Dwfl_Module *mod = NULL; 531 if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0 532 || mod == NULL) 533 error (EXIT_FAILURE, 0, gettext ("Section syntax requires" 534 " exactly one module")); 535 536 int nscn = dwfl_module_relocations (mod); 537 for (int i = 0; i < nscn; ++i) 538 { 539 GElf_Word shndx; 540 const char *scn = dwfl_module_relocation_info (mod, i, &shndx); 541 if (unlikely (scn == NULL)) 542 break; 543 if (!strcmp (scn, name)) 544 { 545 /* Found the section. */ 546 GElf_Shdr shdr_mem; 547 GElf_Addr shdr_bias; 548 GElf_Shdr *shdr = gelf_getshdr 549 (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx), 550 &shdr_mem); 551 if (unlikely (shdr == NULL)) 552 break; 553 554 if (*addr >= shdr->sh_size) 555 error (0, 0, 556 gettext ("offset %#" PRIxMAX " lies outside" 557 " section '%s'"), 558 *addr, scn); 559 560 *addr += shdr->sh_addr + shdr_bias; 561 return true; 562 } 563 } 564 565 return false; 566} 567 568static void 569print_src (const char *src, int lineno, int linecol, Dwarf_Die *cu) 570{ 571 const char *comp_dir = ""; 572 const char *comp_dir_sep = ""; 573 574 if (only_basenames) 575 src = basename (src); 576 else if (use_comp_dir && src[0] != '/') 577 { 578 Dwarf_Attribute attr; 579 comp_dir = dwarf_formstring (dwarf_attr (cu, DW_AT_comp_dir, &attr)); 580 if (comp_dir != NULL) 581 comp_dir_sep = "/"; 582 } 583 584 if (linecol != 0) 585 printf ("%s%s%s:%d:%d", 586 comp_dir, comp_dir_sep, src, lineno, linecol); 587 else 588 printf ("%s%s%s:%d", 589 comp_dir, comp_dir_sep, src, lineno); 590} 591 592static int 593get_addr_width (Dwfl_Module *mod) 594{ 595 // Try to find the address width if possible. 596 static int width = 0; 597 if (width == 0 && mod != NULL) 598 { 599 Dwarf_Addr bias; 600 Elf *elf = dwfl_module_getelf (mod, &bias); 601 if (elf != NULL) 602 { 603 GElf_Ehdr ehdr_mem; 604 GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 605 if (ehdr != NULL) 606 width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16; 607 } 608 } 609 if (width == 0) 610 width = 16; 611 612 return width; 613} 614 615static int 616handle_address (const char *string, Dwfl *dwfl) 617{ 618 char *endp; 619 uintmax_t addr = strtoumax (string, &endp, 16); 620 if (endp == string || *endp != '\0') 621 { 622 bool parsed = false; 623 int i, j; 624 char *name = NULL; 625 if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2 626 && string[i] == '\0') 627 parsed = adjust_to_section (name, &addr, dwfl); 628 switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j)) 629 { 630 default: 631 break; 632 case 1: 633 addr = 0; 634 j = i; 635 case 2: 636 if (string[j] != '\0') 637 break; 638 639 /* It was symbol[+offset]. */ 640 GElf_Sym sym; 641 GElf_Addr value = 0; 642 void *arg[3] = { name, &sym, &value }; 643 (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0); 644 if (arg[0] != NULL) 645 error (0, 0, gettext ("cannot find symbol '%s'"), name); 646 else 647 { 648 if (sym.st_size != 0 && addr >= sym.st_size) 649 error (0, 0, 650 gettext ("offset %#" PRIxMAX " lies outside" 651 " contents of '%s'"), 652 addr, name); 653 addr += value; 654 parsed = true; 655 } 656 break; 657 } 658 659 free (name); 660 if (!parsed) 661 return 1; 662 } 663 else if (just_section != NULL 664 && !adjust_to_section (just_section, &addr, dwfl)) 665 return 1; 666 667 Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr); 668 669 if (print_addresses) 670 { 671 int width = get_addr_width (mod); 672 printf ("0x%.*" PRIx64 "%s", width, addr, pretty ? ": " : "\n"); 673 } 674 675 if (show_functions) 676 { 677 /* First determine the function name. Use the DWARF information if 678 possible. */ 679 if (! print_dwarf_function (mod, addr) && !show_symbols) 680 { 681 const char *name = dwfl_module_addrname (mod, addr); 682 name = name != NULL ? symname (name) : "??"; 683 printf ("%s%c", name, pretty ? ' ' : '\n'); 684 } 685 } 686 687 if (show_symbols) 688 print_addrsym (mod, addr); 689 690 if ((show_functions || show_symbols) && pretty) 691 printf ("at "); 692 693 Dwfl_Line *line = dwfl_module_getsrc (mod, addr); 694 695 const char *src; 696 int lineno, linecol; 697 698 if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol, 699 NULL, NULL)) != NULL) 700 { 701 print_src (src, lineno, linecol, dwfl_linecu (line)); 702 if (show_flags) 703 { 704 Dwarf_Addr bias; 705 Dwarf_Line *info = dwfl_dwarf_line (line, &bias); 706 assert (info != NULL); 707 708 inline void show (int (*get) (Dwarf_Line *, bool *), 709 const char *note) 710 { 711 bool flag; 712 if ((*get) (info, &flag) == 0 && flag) 713 fputs (note, stdout); 714 } 715 inline void show_int (int (*get) (Dwarf_Line *, unsigned int *), 716 const char *name) 717 { 718 unsigned int val; 719 if ((*get) (info, &val) == 0 && val != 0) 720 printf (" (%s %u)", name, val); 721 } 722 723 show (&dwarf_linebeginstatement, " (is_stmt)"); 724 show (&dwarf_lineblock, " (basic_block)"); 725 show (&dwarf_lineprologueend, " (prologue_end)"); 726 show (&dwarf_lineepiloguebegin, " (epilogue_begin)"); 727 show_int (&dwarf_lineisa, "isa"); 728 show_int (&dwarf_linediscriminator, "discriminator"); 729 } 730 putchar ('\n'); 731 } 732 else 733 puts ("??:0"); 734 735 if (show_inlines) 736 { 737 Dwarf_Addr bias = 0; 738 Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias); 739 740 Dwarf_Die *scopes = NULL; 741 int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes); 742 if (nscopes < 0) 743 return 1; 744 745 if (nscopes > 0) 746 { 747 Dwarf_Die subroutine; 748 Dwarf_Off dieoff = dwarf_dieoffset (&scopes[0]); 749 dwarf_offdie (dwfl_module_getdwarf (mod, &bias), 750 dieoff, &subroutine); 751 free (scopes); 752 scopes = NULL; 753 754 nscopes = dwarf_getscopes_die (&subroutine, &scopes); 755 if (nscopes > 1) 756 { 757 Dwarf_Die cu; 758 Dwarf_Files *files; 759 if (dwarf_diecu (&scopes[0], &cu, NULL, NULL) != NULL 760 && dwarf_getsrcfiles (cudie, &files, NULL) == 0) 761 { 762 for (int i = 0; i < nscopes - 1; i++) 763 { 764 Dwarf_Word val; 765 Dwarf_Attribute attr; 766 Dwarf_Die *die = &scopes[i]; 767 if (dwarf_tag (die) != DW_TAG_inlined_subroutine) 768 continue; 769 770 if (pretty) 771 printf (" (inlined by) "); 772 773 if (show_functions) 774 { 775 /* Search for the parent inline or function. It 776 might not be directly above this inline -- e.g. 777 there could be a lexical_block in between. */ 778 for (int j = i + 1; j < nscopes; j++) 779 { 780 Dwarf_Die *parent = &scopes[j]; 781 int tag = dwarf_tag (parent); 782 if (tag == DW_TAG_inlined_subroutine 783 || tag == DW_TAG_entry_point 784 || tag == DW_TAG_subprogram) 785 { 786 printf ("%s%s", 787 symname (get_diename (parent)), 788 pretty ? " at " : "\n"); 789 break; 790 } 791 } 792 } 793 794 src = NULL; 795 lineno = 0; 796 linecol = 0; 797 if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file, 798 &attr), &val) == 0) 799 src = dwarf_filesrc (files, val, NULL, NULL); 800 801 if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line, 802 &attr), &val) == 0) 803 lineno = val; 804 805 if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column, 806 &attr), &val) == 0) 807 linecol = val; 808 809 if (src != NULL) 810 { 811 print_src (src, lineno, linecol, &cu); 812 putchar ('\n'); 813 } 814 else 815 puts ("??:0"); 816 } 817 } 818 } 819 } 820 free (scopes); 821 } 822 823 return 0; 824} 825 826 827#include "debugpred.h" 828