/* addr2line.c -- convert addresses to line number and function name
   Copyright 1997, 98, 99, 2000 Free Software Foundation, Inc.
   Contributed by Ulrich Lauther <Ulrich.Lauther@mchp.siemens.de>

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* Derived from objdump.c and nm.c by Ulrich.Lauther@mchp.siemens.de

   Usage: 
   addr2line [options] addr addr ...
   or
   addr2line [options] 

   both forms write results to stdout, the second form reads addresses
   to be converted from stdin.  */

#include <ctype.h>
#include <string.h>

#include "bfd.h"
#include "getopt.h"
#include "libiberty.h"
#include "demangle.h"
#include "bucomm.h"

extern char *program_version;

static boolean with_functions;	/* -f, show function names.  */
static boolean do_demangle;	/* -C, demangle names.  */
static boolean base_names;	/* -s, strip directory names.  */

static int naddr;		/* Number of addresses to process.  */
static char **addr;		/* Hex addresses to process.  */

static asymbol **syms;		/* Symbol table.  */

static struct option long_options[] =
{
  {"basenames", no_argument, NULL, 's'},
  {"demangle", optional_argument, NULL, 'C'},
  {"exe", required_argument, NULL, 'e'},
  {"functions", no_argument, NULL, 'f'},
  {"target", required_argument, NULL, 'b'},
  {"help", no_argument, NULL, 'H'},
  {"version", no_argument, NULL, 'V'},
  {0, no_argument, 0, 0}
};

static void usage PARAMS ((FILE *, int));
static void slurp_symtab PARAMS ((bfd *));
static void find_address_in_section PARAMS ((bfd *, asection *, PTR));
static void translate_addresses PARAMS ((bfd *));
static void process_file PARAMS ((const char *, const char *));

/* Print a usage message to STREAM and exit with STATUS.  */

static void
usage (stream, status)
     FILE *stream;
     int status;
{
  fprintf (stream, _("\
Usage: %s [-CfsHV] [-b bfdname] [--target=bfdname]\n\
       [-e executable] [--exe=executable] [--demangle[=style]]\n\
       [--basenames] [--functions] [addr addr ...]\n"),
	   program_name);
  list_supported_targets (program_name, stream);
  if (status == 0)
    fprintf (stream, _("Report bugs to %s\n"), REPORT_BUGS_TO);
  exit (status);
}

/* Read in the symbol table.  */

static void
slurp_symtab (abfd)
     bfd *abfd;
{
  long storage;
  long symcount;

  if ((bfd_get_file_flags (abfd) & HAS_SYMS) == 0)
    return;

  storage = bfd_get_symtab_upper_bound (abfd);
  if (storage < 0)
    bfd_fatal (bfd_get_filename (abfd));

  syms = (asymbol **) xmalloc (storage);

  symcount = bfd_canonicalize_symtab (abfd, syms);
  if (symcount < 0)
    bfd_fatal (bfd_get_filename (abfd));
}

/* These global variables are used to pass information between
   translate_addresses and find_address_in_section.  */

static bfd_vma pc;
static const char *filename;
static const char *functionname;
static unsigned int line;
static boolean found;

/* Look for an address in a section.  This is called via
   bfd_map_over_sections.  */

static void
find_address_in_section (abfd, section, data)
     bfd *abfd;
     asection *section;
     PTR data ATTRIBUTE_UNUSED;
{
  bfd_vma vma;
  bfd_size_type size;

  if (found)
    return;

  if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
    return;

  vma = bfd_get_section_vma (abfd, section);
  if (pc < vma)
    return;

  size = bfd_get_section_size_before_reloc (section);
  if (pc >= vma + size)
    return;

  found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
				 &filename, &functionname, &line);
}

/* Read hexadecimal addresses from stdin, translate into
   file_name:line_number and optionally function name.  */

static void
translate_addresses (abfd)
     bfd *abfd;
{
  int read_stdin = (naddr == 0);

  for (;;)
    {
      if (read_stdin)
	{
	  char addr_hex[100];

	  if (fgets (addr_hex, sizeof addr_hex, stdin) == NULL)
	    break;
	  pc = bfd_scan_vma (addr_hex, NULL, 16);
	}
      else
	{
	  if (naddr <= 0)
	    break;
	  --naddr;
	  pc = bfd_scan_vma (*addr++, NULL, 16);
	}

      found = false;
      bfd_map_over_sections (abfd, find_address_in_section, (PTR) NULL);

      if (! found)
	{
	  if (with_functions)
	    printf ("??\n");
	  printf ("??:0\n");
	}
      else
	{
	  if (with_functions)
	    {
	      if (functionname == NULL || *functionname == '\0')
		printf ("??\n");
	      else if (! do_demangle)
		printf ("%s\n", functionname);
	      else
		{
		  char *res;

		  res = cplus_demangle (functionname, DMGL_ANSI | DMGL_PARAMS);
		  if (res == NULL)
		    printf ("%s\n", functionname);
		  else
		    {
		      printf ("%s\n", res);
		      free (res);
		    }
		}
	    }

	  if (base_names && filename != NULL)
	    {
	      char *h;

	      h = strrchr (filename, '/');
	      if (h != NULL)
		filename = h + 1;
	    }

	  printf ("%s:%u\n", filename ? filename : "??", line);
	}

      /* fflush() is essential for using this command as a server
         child process that reads addresses from a pipe and responds
         with line number information, processing one address at a
         time.  */
      fflush (stdout);
    }
}

/* Process a file.  */

static void
process_file (filename, target)
     const char *filename;
     const char *target;
{
  bfd *abfd;
  char **matching;

  abfd = bfd_openr (filename, target);
  if (abfd == NULL)
    bfd_fatal (filename);

  if (bfd_check_format (abfd, bfd_archive))
    fatal (_("%s: can not get addresses from archive"), filename);

  if (! bfd_check_format_matches (abfd, bfd_object, &matching))
    {
      bfd_nonfatal (bfd_get_filename (abfd));
      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
	{
	  list_matching_formats (matching);
	  free (matching);
	}
      xexit (1);
    }

  slurp_symtab (abfd);

  translate_addresses (abfd);

  if (syms != NULL)
    {
      free (syms);
      syms = NULL;
    }

  bfd_close (abfd);
}

int
main (argc, argv)
     int argc;
     char **argv;
{
  const char *filename;
  char *target;
  int c;

#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
  setlocale (LC_MESSAGES, "");
#endif
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  program_name = *argv;
  xmalloc_set_program_name (program_name);

  bfd_init ();
  set_default_bfd_target ();

  filename = NULL;
  target = NULL;
  while ((c = getopt_long (argc, argv, "b:Ce:sfHV", long_options, (int *) 0))
	 != EOF)
    {
      switch (c)
	{
	case 0:
	  break;		/* we've been given a long option */
	case 'b':
	  target = optarg;
	  break;
	case 'C':
	  do_demangle = true;
	  if (optarg != NULL)
	    {
	      enum demangling_styles style;
	      
	      style = cplus_demangle_name_to_style (optarg);
	      if (style == unknown_demangling) 
		fatal (_("unknown demangling style `%s'"),
		       optarg);
	      
	      cplus_demangle_set_style (style);
           }
	  break;
	case 'e':
	  filename = optarg;
	  break;
	case 's':
	  base_names = true;
	  break;
	case 'f':
	  with_functions = true;
	  break;
	case 'V':
	  print_version ("addr2line");
	  break;
	case 'H':
	  usage (stdout, 0);
	  break;
	default:
	  usage (stderr, 1);
	  break;
	}
    }

  if (filename == NULL)
    filename = "a.out";

  addr = argv + optind;
  naddr = argc - optind;

  process_file (filename, target);

  return 0;
}
