Home | History | Annotate | Download | only in src
      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