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