/* Locate source files and line information for given addresses
   Copyright (C) 2005 Red Hat, Inc.
   Written by Ulrich Drepper <drepper@redhat.com>, 2005.

   This program is Open Source software; you can redistribute it and/or
   modify it under the terms of the Open Software License version 1.0 as
   published by the Open Source Initiative.

   You should have received a copy of the Open Software License along
   with this program; if not, you may obtain a copy of the Open Software
   License version 1.0 from http://www.opensource.org/licenses/osl.php or
   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
   3001 King Ranch Road, Ukiah, CA 95482.   */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <argp.h>
#include <assert.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <inttypes.h>
#include <libdwfl.h>
#include <dwarf.h>
#include <libintl.h>
#include <locale.h>
#include <mcheck.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


/* Name and version of program.  */
static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;

/* Bug report address.  */
const char *argp_program_bug_address = PACKAGE_BUGREPORT;


/* Values for the parameters which have no short form.  */
#define OPT_DEMANGLER 0x100

/* Definitions of arguments for argp functions.  */
static const struct argp_option options[] =
{
  { NULL, 0, NULL, 0, N_("Output Selection:"), 0 },
  { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 },
  { "functions", 'f', NULL, 0, N_("Additional show function names"), 0 },

  { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
  /* Unsupported options.  */
  { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 },
  { "demangle", 'C', "ARG", OPTION_HIDDEN | OPTION_ARG_OPTIONAL, NULL, 0 },
  { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 },
  { NULL, 0, NULL, 0, NULL, 0 }
};

/* Short description of program.  */
static const char doc[] = N_("\
Locate source files and line information for ADDRs (in a.out by default).");

/* Strings for arguments in help texts.  */
static const char args_doc[] = N_("[ADDR...]");

/* Prototype for option handler.  */
static error_t parse_opt (int key, char *arg, struct argp_state *state);

static struct argp_child argp_children[2]; /* [0] is set in main.  */

/* Data structure to communicate with argp functions.  */
static const struct argp argp =
{
  options, parse_opt, args_doc, doc, argp_children, NULL, NULL
};


/* Handle ADDR.  */
static void handle_address (GElf_Addr addr, Dwfl *dwfl);


/* True if only base names of files should be shown.  */
static bool only_basenames;

/* True if function names should be shown.  */
static bool show_functions;


int
main (int argc, char *argv[])
{
  int remaining;
  int result = 0;

  /* Make memory leak detection possible.  */
  mtrace ();

  /* We use no threads here which can interfere with handling a stream.  */
  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);

  /* Set locale.  */
  (void) setlocale (LC_ALL, "");

  /* Make sure the message catalog can be found.  */
  (void) bindtextdomain (PACKAGE, LOCALEDIR);

  /* Initialize the message catalog.  */
  (void) textdomain (PACKAGE);

  /* Parse and process arguments.  This includes opening the modules.  */
  argp_children[0].argp = dwfl_standard_argp ();
  Dwfl *dwfl = NULL;
  (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl);
  assert (dwfl != NULL);

  /* Now handle the addresses.  In case none are given on the command
     line, read from stdin.  */
  if (remaining == argc)
    {
      /* We use no threads here which can interfere with handling a stream.  */
      (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);

      char *buf = NULL;
      size_t len = 0;
      while (!feof_unlocked (stdin))
	{
	  if (getline (&buf, &len, stdin) < 0)
	    break;

	  char *endp;
	  uintmax_t addr = strtoumax (buf, &endp, 0);
	  if (endp != buf)
	    handle_address (addr, dwfl);
	  else
	    result = 1;
	}

      free (buf);
    }
  else
    {
      do
	{
	  char *endp;
	  uintmax_t addr = strtoumax (argv[remaining], &endp, 0);
	  if (endp != argv[remaining])
	    handle_address (addr, dwfl);
	  else
	    result = 1;
	}
      while (++remaining < argc);
    }

  return result;
}


/* Print the version information.  */
static void
print_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
{
  fprintf (stream, "addr2line (%s) %s\n", PACKAGE_NAME, VERSION);
  fprintf (stream, gettext ("\
Copyright (C) %s Red Hat, Inc.\n\
This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "2005");
  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
}


/* Handle program arguments.  */
static error_t
parse_opt (int key, char *arg __attribute__ ((unused)),
	   struct argp_state *state)
{
  switch (key)
    {
    case ARGP_KEY_INIT:
      state->child_inputs[0] = state->input;
      break;

    case 'b':
    case 'C':
    case OPT_DEMANGLER:
      /* Ignored for compatibility.  */
      break;

    case 's':
      only_basenames = true;
      break;

    case 'f':
      show_functions = true;
      break;

    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}


static const char *
dwarf_diename_integrate (Dwarf_Die *die)
{
  Dwarf_Attribute attr_mem;
  return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem));
}

static bool
print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
{
  Dwarf_Addr bias = 0;
  Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias);

  Dwarf_Die *scopes;
  int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes);
  if (nscopes <= 0)
    return false;

  for (int i = 0; i < nscopes; ++i)
    switch (dwarf_tag (&scopes[i]))
      {
      case DW_TAG_subprogram:
	{
	  const char *name = dwarf_diename_integrate (&scopes[i]);
	  if (name == NULL)
	    return false;
	  puts (name);
	  return true;
	}

      case DW_TAG_inlined_subroutine:
	{
	  const char *name = dwarf_diename_integrate (&scopes[i]);
	  if (name == NULL)
	    return false;
	  printf ("%s inlined", name);

	  Dwarf_Files *files;
	  if (dwarf_getsrcfiles (cudie, &files, NULL) == 0)
	    {
	      Dwarf_Attribute attr_mem;
	      Dwarf_Word val;
	      if (dwarf_formudata (dwarf_attr (&scopes[i],
					       DW_AT_call_file,
					       &attr_mem), &val) == 0)
		{
		  const char *file = dwarf_filesrc (files, val, NULL, NULL);
		  int lineno = 0, colno = 0;
		  if (dwarf_formudata (dwarf_attr (&scopes[i],
						   DW_AT_call_line,
						   &attr_mem), &val) == 0)
		    lineno = val;
		  if (dwarf_formudata (dwarf_attr (&scopes[i],
						   DW_AT_call_column,
						   &attr_mem), &val) == 0)
		    colno = val;
		  if (lineno == 0)
		    {
		      if (file != NULL)
			printf (" from %s", file);
		    }
		  else if (colno == 0)
		    printf (" at %s:%u", file, lineno);
		  else
		    printf (" at %s:%u:%u", file, lineno, colno);
		}
	    }
	  printf (" in ");
	  continue;
	}
      }

  return false;
}

static void
handle_address (GElf_Addr addr, Dwfl *dwfl)
{
  Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr);

  if (show_functions)
    {
      /* First determine the function name.  Use the DWARF information if
	 possible.  */
      if (! print_dwarf_function (mod, addr))
	puts (dwfl_module_addrname (mod, addr) ?: "??");
    }

  Dwfl_Line *line = dwfl_module_getsrc (mod, addr);

  const char *src;
  int lineno, linecol;
  if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
					    NULL, NULL)) != NULL)
    {
      if (only_basenames)
	src = basename (src);

      if (linecol != 0)
	printf ("%s:%d:%d\n", src, lineno, linecol);
      else
	printf ("%s:%d\n", src, lineno);
    }
  else
    puts ("??:0");
}
