1  /* addr2line.c -- convert addresses to line number and function name
       2     Copyright (C) 1997-2023 Free Software Foundation, Inc.
       3     Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>
       4  
       5     This file is part of GNU Binutils.
       6  
       7     This program 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, or (at your option)
      10     any later version.
      11  
      12     This program is distributed in the hope that it will be useful,
      13     but 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, write to the Free Software
      19     Foundation, 51 Franklin Street - Fifth Floor, Boston,
      20     MA 02110-1301, USA.  */
      21  
      22  
      23  /* Derived from objdump.c and nm.c by Ulrich.Lauther@mchp.siemens.de
      24  
      25     Usage:
      26     addr2line [options] addr addr ...
      27     or
      28     addr2line [options]
      29  
      30     both forms write results to stdout, the second form reads addresses
      31     to be converted from stdin.  */
      32  
      33  #include "sysdep.h"
      34  #include "bfd.h"
      35  #include "getopt.h"
      36  #include "libiberty.h"
      37  #include "demangle.h"
      38  #include "bucomm.h"
      39  #include "elf-bfd.h"
      40  #include "safe-ctype.h"
      41  
      42  static bool unwind_inlines;	/* -i, unwind inlined functions. */
      43  static bool with_addresses;	/* -a, show addresses.  */
      44  static bool with_functions;	/* -f, show function names.  */
      45  static bool do_demangle;	/* -C, demangle names.  */
      46  static bool pretty_print;	/* -p, print on one line.  */
      47  static bool base_names;		/* -s, strip directory names.  */
      48  
      49  /* Flags passed to the name demangler.  */
      50  static int demangle_flags = DMGL_PARAMS | DMGL_ANSI;
      51  
      52  static int naddr;		/* Number of addresses to process.  */
      53  static char **addr;		/* Hex addresses to process.  */
      54  
      55  static long symcount;
      56  static asymbol **syms;		/* Symbol table.  */
      57  
      58  static struct option long_options[] =
      59  {
      60    {"addresses", no_argument, NULL, 'a'},
      61    {"basenames", no_argument, NULL, 's'},
      62    {"demangle", optional_argument, NULL, 'C'},
      63    {"exe", required_argument, NULL, 'e'},
      64    {"functions", no_argument, NULL, 'f'},
      65    {"inlines", no_argument, NULL, 'i'},
      66    {"pretty-print", no_argument, NULL, 'p'},
      67    {"recurse-limit", no_argument, NULL, 'R'},
      68    {"recursion-limit", no_argument, NULL, 'R'},  
      69    {"no-recurse-limit", no_argument, NULL, 'r'},
      70    {"no-recursion-limit", no_argument, NULL, 'r'},  
      71    {"section", required_argument, NULL, 'j'},
      72    {"target", required_argument, NULL, 'b'},
      73    {"help", no_argument, NULL, 'H'},
      74    {"version", no_argument, NULL, 'V'},
      75    {0, no_argument, 0, 0}
      76  };
      77  
      78  static void usage (FILE *, int);
      79  static void slurp_symtab (bfd *);
      80  static void find_address_in_section (bfd *, asection *, void *);
      81  static void find_offset_in_section (bfd *, asection *);
      82  static void translate_addresses (bfd *, asection *);
      83  
      84  /* Print a usage message to STREAM and exit with STATUS.  */
      85  
      86  static void
      87  usage (FILE *stream, int status)
      88  {
      89    fprintf (stream, _("Usage: %s [option(s)] [addr(s)]\n"), program_name);
      90    fprintf (stream, _(" Convert addresses into line number/file name pairs.\n"));
      91    fprintf (stream, _(" If no addresses are specified on the command line, they will be read from stdin\n"));
      92    fprintf (stream, _(" The options are:\n\
      93    @<file>                Read options from <file>\n\
      94    -a --addresses         Show addresses\n\
      95    -b --target=<bfdname>  Set the binary file format\n\
      96    -e --exe=<executable>  Set the input file name (default is a.out)\n\
      97    -i --inlines           Unwind inlined functions\n\
      98    -j --section=<name>    Read section-relative offsets instead of addresses\n\
      99    -p --pretty-print      Make the output easier to read for humans\n\
     100    -s --basenames         Strip directory names\n\
     101    -f --functions         Show function names\n\
     102    -C --demangle[=style]  Demangle function names\n\
     103    -R --recurse-limit     Enable a limit on recursion whilst demangling.  [Default]\n\
     104    -r --no-recurse-limit  Disable a limit on recursion whilst demangling\n\
     105    -h --help              Display this information\n\
     106    -v --version           Display the program's version\n\
     107  \n"));
     108  
     109    list_supported_targets (program_name, stream);
     110    if (REPORT_BUGS_TO[0] && status == 0)
     111      fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
     112    exit (status);
     113  }
     114  
     115  /* Read in the symbol table.  */
     116  
     117  static void
     118  slurp_symtab (bfd *abfd)
     119  {
     120    long storage;
     121    bool dynamic = false;
     122  
     123    if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
     124      return;
     125  
     126    storage = bfd_get_symtab_upper_bound (abfd);
     127    if (storage == 0)
     128      {
     129        storage = bfd_get_dynamic_symtab_upper_bound (abfd);
     130        dynamic = true;
     131      }
     132    if (storage < 0)
     133      {
     134        bfd_nonfatal (bfd_get_filename (abfd));
     135        return;
     136      }
     137  
     138    syms = (asymbol **) xmalloc (storage);
     139    if (dynamic)
     140      symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
     141    else
     142      symcount = bfd_canonicalize_symtab (abfd, syms);
     143    if (symcount < 0)
     144      bfd_nonfatal (bfd_get_filename (abfd));
     145  
     146    /* If there are no symbols left after canonicalization and
     147       we have not tried the dynamic symbols then give them a go.  */
     148    if (symcount == 0
     149        && ! dynamic
     150        && (storage = bfd_get_dynamic_symtab_upper_bound (abfd)) > 0)
     151      {
     152        free (syms);
     153        syms = xmalloc (storage);
     154        symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
     155      }
     156  
     157    /* PR 17512: file: 2a1d3b5b.
     158       Do not pretend that we have some symbols when we don't.  */
     159    if (symcount <= 0)
     160      {
     161        free (syms);
     162        syms = NULL;
     163      }
     164  }
     165  
     166  /* These global variables are used to pass information between
     167     translate_addresses and find_address_in_section.  */
     168  
     169  static bfd_vma pc;
     170  static const char *filename;
     171  static const char *functionname;
     172  static unsigned int line;
     173  static unsigned int discriminator;
     174  static bool found;
     175  
     176  /* Look for an address in a section.  This is called via
     177     bfd_map_over_sections.  */
     178  
     179  static void
     180  find_address_in_section (bfd *abfd, asection *section,
     181  			 void *data ATTRIBUTE_UNUSED)
     182  {
     183    bfd_vma vma;
     184    bfd_size_type size;
     185  
     186    if (found)
     187      return;
     188  
     189    if ((bfd_section_flags (section) & SEC_ALLOC) == 0)
     190      return;
     191  
     192    vma = bfd_section_vma (section);
     193    if (pc < vma)
     194      return;
     195  
     196    size = bfd_section_size (section);
     197    if (pc >= vma + size)
     198      return;
     199  
     200    found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc - vma,
     201                                                 &filename, &functionname,
     202                                                 &line, &discriminator);
     203  }
     204  
     205  /* Look for an offset in a section.  This is directly called.  */
     206  
     207  static void
     208  find_offset_in_section (bfd *abfd, asection *section)
     209  {
     210    bfd_size_type size;
     211  
     212    if (found)
     213      return;
     214  
     215    if ((bfd_section_flags (section) & SEC_ALLOC) == 0)
     216      return;
     217  
     218    size = bfd_section_size (section);
     219    if (pc >= size)
     220      return;
     221  
     222    found = bfd_find_nearest_line_discriminator (abfd, section, syms, pc,
     223                                                 &filename, &functionname,
     224                                                 &line, &discriminator);
     225  }
     226  
     227  /* Lookup a symbol with offset in symbol table.  */
     228  
     229  static bfd_vma
     230  lookup_symbol (bfd *abfd, char *sym, size_t offset)
     231  {
     232    long i;
     233  
     234    for (i = 0; i < symcount; i++)
     235      {
     236        if (!strcmp (syms[i]->name, sym))
     237  	return syms[i]->value + offset + bfd_asymbol_section (syms[i])->vma;
     238      }
     239    /* Try again mangled */
     240    for (i = 0; i < symcount; i++)
     241      {
     242        char *d = bfd_demangle (abfd, syms[i]->name, demangle_flags);
     243        bool match = d && !strcmp (d, sym);
     244        free (d);
     245  
     246        if (match)
     247  	return syms[i]->value + offset + bfd_asymbol_section (syms[i])->vma;
     248      }
     249    return 0;
     250  }
     251  
     252  /* Split an symbol+offset expression. adr is modified.  */
     253  
     254  static bool
     255  is_symbol (char *adr, char **symp, size_t *offset)
     256  {
     257    char *end;
     258  
     259    while (ISSPACE (*adr))
     260      adr++;
     261    if (ISDIGIT (*adr) || *adr == 0)
     262      return false;
     263    /* Could be either symbol or hex number. Check if it has +.  */
     264    if (TOUPPER(*adr) >= 'A' && TOUPPER(*adr) <= 'F' && !strchr (adr, '+'))
     265      return false;
     266  
     267    *symp = adr;
     268    while (*adr && !ISSPACE (*adr) && *adr != '+')
     269      adr++;
     270    end = adr;
     271    while (ISSPACE (*adr))
     272      adr++;
     273    *offset = 0;
     274    if (*adr == '+')
     275      {
     276        adr++;
     277        *offset = strtoul(adr, NULL, 0);
     278      }
     279    *end = 0;
     280    return true;
     281  }
     282  
     283  /* Read hexadecimal or symbolic with offset addresses from stdin, translate into
     284     file_name:line_number and optionally function name.  */
     285  
     286  static void
     287  translate_addresses (bfd *abfd, asection *section)
     288  {
     289    int read_stdin = (naddr == 0);
     290    char *adr;
     291    char addr_hex[100];
     292    char *symp;
     293    size_t offset;
     294  
     295    for (;;)
     296      {
     297        if (read_stdin)
     298  	{
     299  	  if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
     300  	    break;
     301  	  adr = addr_hex;
     302  	}
     303        else
     304  	{
     305  	  if (naddr <= 0)
     306  	    break;
     307  	  --naddr;
     308  	  adr = *addr++;
     309  	}
     310  
     311        if (is_symbol (adr, &symp, &offset))
     312          pc = lookup_symbol (abfd, symp, offset);
     313        else
     314          pc = bfd_scan_vma (adr, NULL, 16);
     315        if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
     316  	{
     317  	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
     318  	  bfd_vma sign = (bfd_vma) 1 << (bed->s->arch_size - 1);
     319  
     320  	  pc &= (sign << 1) - 1;
     321  	  if (bed->sign_extend_vma)
     322  	    pc = (pc ^ sign) - sign;
     323  	}
     324  
     325        if (with_addresses)
     326          {
     327            printf ("0x");
     328            bfd_printf_vma (abfd, pc);
     329  
     330            if (pretty_print)
     331              printf (": ");
     332            else
     333              printf ("\n");
     334          }
     335  
     336        found = false;
     337        if (section)
     338  	find_offset_in_section (abfd, section);
     339        else
     340  	bfd_map_over_sections (abfd, find_address_in_section, NULL);
     341  
     342        if (! found)
     343  	{
     344  	  if (with_functions)
     345  	    {
     346  	      if (pretty_print)
     347  		printf ("?? ");
     348  	      else
     349  		printf ("??\n");
     350  	    }
     351  	  printf ("??:0\n");
     352  	}
     353        else
     354  	{
     355  	  while (1)
     356              {
     357                if (with_functions)
     358                  {
     359                    const char *name;
     360                    char *alloc = NULL;
     361  
     362                    name = functionname;
     363                    if (name == NULL || *name == '\0')
     364                      name = "??";
     365                    else if (do_demangle)
     366                      {
     367                        alloc = bfd_demangle (abfd, name, demangle_flags);
     368                        if (alloc != NULL)
     369                          name = alloc;
     370                      }
     371  
     372                    printf ("%s", name);
     373                    if (pretty_print)
     374  		    /* Note for translators:  This printf is used to join the
     375  		       function name just printed above to the line number/
     376  		       file name pair that is about to be printed below.  Eg:
     377  
     378  		         foo at 123:bar.c  */
     379                      printf (_(" at "));
     380                    else
     381                      printf ("\n");
     382  
     383  		  free (alloc);
     384                  }
     385  
     386                if (base_names && filename != NULL)
     387                  {
     388                    char *h;
     389  
     390                    h = strrchr (filename, '/');
     391                    if (h != NULL)
     392                      filename = h + 1;
     393                  }
     394  
     395                printf ("%s:", filename ? filename : "??");
     396  	      if (line != 0)
     397                  {
     398                    if (discriminator != 0)
     399                      printf ("%u (discriminator %u)\n", line, discriminator);
     400                    else
     401                      printf ("%u\n", line);
     402                  }
     403  	      else
     404  		printf ("?\n");
     405                if (!unwind_inlines)
     406                  found = false;
     407                else
     408                  found = bfd_find_inliner_info (abfd, &filename, &functionname,
     409  					       &line);
     410                if (! found)
     411                  break;
     412                if (pretty_print)
     413  		/* Note for translators: This printf is used to join the
     414  		   line number/file name pair that has just been printed with
     415  		   the line number/file name pair that is going to be printed
     416  		   by the next iteration of the while loop.  Eg:
     417  
     418  		     123:bar.c (inlined by) 456:main.c  */
     419                  printf (_(" (inlined by) "));
     420              }
     421  	}
     422  
     423        /* fflush() is essential for using this command as a server
     424           child process that reads addresses from a pipe and responds
     425           with line number information, processing one address at a
     426           time.  */
     427        fflush (stdout);
     428      }
     429  }
     430  
     431  /* Process a file.  Returns an exit value for main().  */
     432  
     433  static int
     434  process_file (const char *file_name, const char *section_name,
     435  	      const char *target)
     436  {
     437    bfd *abfd;
     438    asection *section;
     439    char **matching;
     440  
     441    if (get_file_size (file_name) < 1)
     442      return 1;
     443  
     444    abfd = bfd_openr (file_name, target);
     445    if (abfd == NULL)
     446      bfd_fatal (file_name);
     447  
     448    /* Decompress sections.  */
     449    abfd->flags |= BFD_DECOMPRESS;
     450  
     451    if (bfd_check_format (abfd, bfd_archive))
     452      {
     453        non_fatal (_("%s: cannot get addresses from archive"), file_name);
     454        bfd_close (abfd);
     455        return 1;
     456      }
     457  
     458    if (! bfd_check_format_matches (abfd, bfd_object, &matching))
     459      {
     460        bfd_nonfatal (bfd_get_filename (abfd));
     461        if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
     462  	list_matching_formats (matching);
     463        bfd_close (abfd);
     464        return 1;
     465      }
     466  
     467    if (section_name != NULL)
     468      {
     469        section = bfd_get_section_by_name (abfd, section_name);
     470        if (section == NULL)
     471  	{
     472  	  non_fatal (_("%s: cannot find section %s"), file_name, section_name);
     473  	  bfd_close (abfd);
     474  	  return 1;
     475  	}
     476      }
     477    else
     478      section = NULL;
     479  
     480    slurp_symtab (abfd);
     481  
     482    translate_addresses (abfd, section);
     483  
     484    free (syms);
     485    syms = NULL;
     486  
     487    bfd_close (abfd);
     488  
     489    return 0;
     490  }
     491  
     492  int
     493  main (int argc, char **argv)
     494  {
     495    const char *file_name;
     496    const char *section_name;
     497    char *target;
     498    int c;
     499  
     500  #ifdef HAVE_LC_MESSAGES
     501    setlocale (LC_MESSAGES, "");
     502  #endif
     503    setlocale (LC_CTYPE, "");
     504    bindtextdomain (PACKAGE, LOCALEDIR);
     505    textdomain (PACKAGE);
     506  
     507    program_name = *argv;
     508    xmalloc_set_program_name (program_name);
     509    bfd_set_error_program_name (program_name);
     510  
     511    expandargv (&argc, &argv);
     512  
     513    if (bfd_init () != BFD_INIT_MAGIC)
     514      fatal (_("fatal error: libbfd ABI mismatch"));
     515    set_default_bfd_target ();
     516  
     517    file_name = NULL;
     518    section_name = NULL;
     519    target = NULL;
     520    while ((c = getopt_long (argc, argv, "ab:Ce:rRsfHhij:pVv", long_options, (int *) 0))
     521  	 != EOF)
     522      {
     523        switch (c)
     524  	{
     525  	case 0:
     526  	  break;		/* We've been given a long option.  */
     527  	case 'a':
     528  	  with_addresses = true;
     529  	  break;
     530  	case 'b':
     531  	  target = optarg;
     532  	  break;
     533  	case 'C':
     534  	  do_demangle = true;
     535  	  if (optarg != NULL)
     536  	    {
     537  	      enum demangling_styles style;
     538  
     539  	      style = cplus_demangle_name_to_style (optarg);
     540  	      if (style == unknown_demangling)
     541  		fatal (_("unknown demangling style `%s'"),
     542  		       optarg);
     543  
     544  	      cplus_demangle_set_style (style);
     545  	    }
     546  	  break;
     547  	case 'r':
     548  	  demangle_flags |= DMGL_NO_RECURSE_LIMIT;
     549  	  break;
     550  	case 'R':
     551  	  demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
     552  	  break;
     553  	case 'e':
     554  	  file_name = optarg;
     555  	  break;
     556  	case 's':
     557  	  base_names = true;
     558  	  break;
     559  	case 'f':
     560  	  with_functions = true;
     561  	  break;
     562          case 'p':
     563            pretty_print = true;
     564            break;
     565  	case 'v':
     566  	case 'V':
     567  	  print_version ("addr2line");
     568  	  break;
     569  	case 'h':
     570  	case 'H':
     571  	  usage (stdout, 0);
     572  	  break;
     573  	case 'i':
     574  	  unwind_inlines = true;
     575  	  break;
     576  	case 'j':
     577  	  section_name = optarg;
     578  	  break;
     579  	default:
     580  	  usage (stderr, 1);
     581  	  break;
     582  	}
     583      }
     584  
     585    if (file_name == NULL)
     586      file_name = "a.out";
     587  
     588    addr = argv + optind;
     589    naddr = argc - optind;
     590  
     591    return process_file (file_name, section_name, target);
     592  }