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. */
44 static void print_version (FILE *stream, struct argp_state *state);
45 ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
46
47 /* Bug report address. */
48 ARGP_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. */
56 static 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. */
87 static const char doc[] = N_("\
88 Locate source files and line information for ADDRs (in a.out by default).");
89
90 /* Strings for arguments in help texts. */
91 static const char args_doc[] = N_("[ADDR...]");
92
93 /* Prototype for option handler. */
94 static error_t parse_opt (int key, char *arg, struct argp_state *state);
95
96 static struct argp_child argp_children[2]; /* [0] is set in main. */
97
98 /* Data structure to communicate with argp functions. */
99 static const struct argp argp =
100 {
101 options, parse_opt, args_doc, doc, argp_children, NULL, NULL
102 };
103
104
105 /* Handle ADDR. */
106 static int handle_address (const char *addr, Dwfl *dwfl);
107
108 /* True when we should print the address for each entry. */
109 static bool print_addresses;
110
111 /* True if only base names of files should be shown. */
112 static bool only_basenames;
113
114 /* True if absolute file names based on DW_AT_comp_dir should be shown. */
115 static bool use_comp_dir;
116
117 /* True if line flags should be shown. */
118 static bool show_flags;
119
120 /* True if function names should be shown. */
121 static bool show_functions;
122
123 /* True if ELF symbol or section info should be shown. */
124 static bool show_symbols;
125
126 /* True if section associated with a symbol address should be shown. */
127 static bool show_symbol_sections;
128
129 /* If non-null, take address parameters as relative to named section. */
130 static const char *just_section;
131
132 /* True if all inlined subroutines of the current address should be shown. */
133 static bool show_inlines;
134
135 /* True if all names need to be demangled. */
136 static bool demangle;
137
138 /* True if all information should be printed on one line. */
139 static bool pretty;
140
141 #ifdef USE_DEMANGLE
142 static size_t demangle_buffer_len = 0;
143 static char *demangle_buffer = NULL;
144 #endif
145
146 int
main(int argc,char * argv[])147 main (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. */
212 static void
print_version(FILE * stream,struct argp_state * state)213 print_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 ("\
217 Copyright (C) %s Red Hat, Inc.\n\
218 This is free software; see the source for copying conditions. There is NO\n\
219 warranty; 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. */
226 static error_t
parse_opt(int key,char * arg,struct argp_state * state)227 parse_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
288 static const char *
symname(const char * name)289 symname (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
305 static const char *
get_diename(Dwarf_Die * die)306 get_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
322 static bool
print_dwarf_function(Dwfl_Module * mod,Dwarf_Addr addr)323 print_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
420 done:
421 free (scopes);
422 return res;
423 }
424
425 static void
print_addrsym(Dwfl_Module * mod,GElf_Addr addr)426 print_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
474 static int
see_one_module(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)475 see_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
488 static int
find_symbol(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr start,void * arg)489 find_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
525 static bool
adjust_to_section(const char * name,uintmax_t * addr,Dwfl * dwfl)526 adjust_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
568 static void
print_src(const char * src,int lineno,int linecol,Dwarf_Die * cu)569 print_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
592 static int
get_addr_width(Dwfl_Module * mod)593 get_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
615 static int
handle_address(const char * string,Dwfl * dwfl)616 handle_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