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