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 <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
    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
    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
    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 *
    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 *
    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
    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
    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
    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
    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
    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
    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
    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
    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