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