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 <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
main(int argc,char * argv[])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
parse_opt(int key,char * arg,struct argp_state * state)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 *
symname(const char * name)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 *
get_diename(Dwarf_Die * die)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
print_dwarf_function(Dwfl_Module * mod,Dwarf_Addr addr)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
print_addrsym(Dwfl_Module * mod,GElf_Addr addr)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
see_one_module(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)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
find_symbol(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)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
adjust_to_section(const char * name,uintmax_t * addr,Dwfl * dwfl)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, _("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 _("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
print_src(const char * src,int lineno,int linecol,Dwarf_Die * cu)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
get_addr_width(Dwfl_Module * mod)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 inline void
show_note(int (* get)(Dwarf_Line *,bool *),Dwarf_Line * info,const char * note)602 show_note (int (*get) (Dwarf_Line *, bool *),
603 Dwarf_Line *info,
604 const char *note)
605 {
606 bool flag;
607 if ((*get) (info, &flag) == 0 && flag)
608 fputs (note, stdout);
609 }
610
611 static inline void
show_int(int (* get)(Dwarf_Line *,unsigned int *),Dwarf_Line * info,const char * name)612 show_int (int (*get) (Dwarf_Line *, unsigned int *),
613 Dwarf_Line *info,
614 const char *name)
615 {
616 unsigned int val;
617 if ((*get) (info, &val) == 0 && val != 0)
618 printf (" (%s %u)", name, val);
619 }
620
621 static int
handle_address(const char * string,Dwfl * dwfl)622 handle_address (const char *string, Dwfl *dwfl)
623 {
624 char *endp;
625 uintmax_t addr = strtoumax (string, &endp, 16);
626 if (endp == string || *endp != '\0')
627 {
628 bool parsed = false;
629 int i, j;
630 char *name = NULL;
631 if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2
632 && string[i] == '\0')
633 parsed = adjust_to_section (name, &addr, dwfl);
634 switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j))
635 {
636 default:
637 break;
638 case 1:
639 addr = 0;
640 j = i;
641 FALLTHROUGH;
642 case 2:
643 if (string[j] != '\0')
644 break;
645
646 /* It was symbol[+offset]. */
647 GElf_Sym sym;
648 GElf_Addr value = 0;
649 void *arg[3] = { name, &sym, &value };
650 (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0);
651 if (arg[0] != NULL)
652 error (0, 0, _("cannot find symbol '%s'"), name);
653 else
654 {
655 if (sym.st_size != 0 && addr >= sym.st_size)
656 error (0, 0,
657 _("offset %#" PRIxMAX " lies outside"
658 " contents of '%s'"),
659 addr, name);
660 addr += value;
661 parsed = true;
662 }
663 break;
664 }
665
666 free (name);
667 if (!parsed)
668 return 1;
669 }
670 else if (just_section != NULL
671 && !adjust_to_section (just_section, &addr, dwfl))
672 return 1;
673
674 Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr);
675
676 if (print_addresses)
677 {
678 int width = get_addr_width (mod);
679 printf ("0x%.*" PRIx64 "%s", width, addr, pretty ? ": " : "\n");
680 }
681
682 if (show_functions)
683 {
684 /* First determine the function name. Use the DWARF information if
685 possible. */
686 if (! print_dwarf_function (mod, addr) && !show_symbols)
687 {
688 const char *name = dwfl_module_addrname (mod, addr);
689 name = name != NULL ? symname (name) : "??";
690 printf ("%s%c", name, pretty ? ' ' : '\n');
691 }
692 }
693
694 if (show_symbols)
695 print_addrsym (mod, addr);
696
697 if ((show_functions || show_symbols) && pretty)
698 printf ("at ");
699
700 Dwfl_Line *line = dwfl_module_getsrc (mod, addr);
701
702 const char *src;
703 int lineno, linecol;
704
705 if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
706 NULL, NULL)) != NULL)
707 {
708 print_src (src, lineno, linecol, dwfl_linecu (line));
709 if (show_flags)
710 {
711 Dwarf_Addr bias;
712 Dwarf_Line *info = dwfl_dwarf_line (line, &bias);
713 assert (info != NULL);
714
715 show_note (&dwarf_linebeginstatement, info, " (is_stmt)");
716 show_note (&dwarf_lineblock, info, " (basic_block)");
717 show_note (&dwarf_lineprologueend, info, " (prologue_end)");
718 show_note (&dwarf_lineepiloguebegin, info, " (epilogue_begin)");
719 show_int (&dwarf_lineisa, info, "isa");
720 show_int (&dwarf_linediscriminator, info, "discriminator");
721 }
722 putchar ('\n');
723 }
724 else
725 puts ("??:0");
726
727 if (show_inlines)
728 {
729 Dwarf_Addr bias = 0;
730 Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias);
731
732 Dwarf_Die *scopes = NULL;
733 int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes);
734 if (nscopes < 0)
735 return 1;
736
737 if (nscopes > 0)
738 {
739 Dwarf_Die subroutine;
740 Dwarf_Off dieoff = dwarf_dieoffset (&scopes[0]);
741 dwarf_offdie (dwfl_module_getdwarf (mod, &bias),
742 dieoff, &subroutine);
743 free (scopes);
744 scopes = NULL;
745
746 nscopes = dwarf_getscopes_die (&subroutine, &scopes);
747 if (nscopes > 1)
748 {
749 Dwarf_Die cu;
750 Dwarf_Files *files;
751 if (dwarf_diecu (&scopes[0], &cu, NULL, NULL) != NULL
752 && dwarf_getsrcfiles (cudie, &files, NULL) == 0)
753 {
754 for (int i = 0; i < nscopes - 1; i++)
755 {
756 Dwarf_Word val;
757 Dwarf_Attribute attr;
758 Dwarf_Die *die = &scopes[i];
759 if (dwarf_tag (die) != DW_TAG_inlined_subroutine)
760 continue;
761
762 if (pretty)
763 printf (" (inlined by) ");
764
765 if (show_functions)
766 {
767 /* Search for the parent inline or function. It
768 might not be directly above this inline -- e.g.
769 there could be a lexical_block in between. */
770 for (int j = i + 1; j < nscopes; j++)
771 {
772 Dwarf_Die *parent = &scopes[j];
773 int tag = dwarf_tag (parent);
774 if (tag == DW_TAG_inlined_subroutine
775 || tag == DW_TAG_entry_point
776 || tag == DW_TAG_subprogram)
777 {
778 printf ("%s%s",
779 symname (get_diename (parent)),
780 pretty ? " at " : "\n");
781 break;
782 }
783 }
784 }
785
786 src = NULL;
787 lineno = 0;
788 linecol = 0;
789 if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file,
790 &attr), &val) == 0)
791 src = dwarf_filesrc (files, val, NULL, NULL);
792
793 if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line,
794 &attr), &val) == 0)
795 lineno = val;
796
797 if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column,
798 &attr), &val) == 0)
799 linecol = val;
800
801 if (src != NULL)
802 {
803 print_src (src, lineno, linecol, &cu);
804 putchar ('\n');
805 }
806 else
807 puts ("??:0");
808 }
809 }
810 }
811 }
812 free (scopes);
813 }
814
815 return 0;
816 }
817
818
819 #include "debugpred.h"
820