/* Test program for libdwfl basic module tracking, relocation.
   Copyright (C) 2005 Red Hat, Inc.
   This file is part of Red Hat elfutils.

   Red Hat elfutils 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; version 2 of the License.

   Red Hat elfutils 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 Red Hat elfutils; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.

   Red Hat elfutils is an included package of the Open Invention Network.
   An included package of the Open Invention Network is a package for which
   Open Invention Network licensees cross-license their patents.  No patent
   license is granted, either expressly or impliedly, by designation as an
   included package.  Should you wish to participate in the Open Invention
   Network licensing program, please visit www.openinventionnetwork.com
   <http://www.openinventionnetwork.com>.  */

#include <config.h>
#include <assert.h>
#include <inttypes.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <locale.h>
#include <argp.h>
#include ELFUTILS_HEADER(dwfl)
#include <dwarf.h>

static bool show_inlines;

struct info
{
  Dwarf_Die *cudie;
  Dwarf_Addr dwbias;
};

static int
print_instance (Dwarf_Die *instance, void *arg)
{
  const struct info *info = arg;

  printf ("    inlined");

  Dwarf_Files *files;
  if (dwarf_getsrcfiles (info->cudie, &files, NULL) == 0)
    {
      Dwarf_Attribute attr_mem;
      Dwarf_Word val;
      if (dwarf_formudata (dwarf_attr (instance, 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 (instance, DW_AT_call_line,
					   &attr_mem), &val) == 0)
	    lineno = val;
	  if (dwarf_formudata (dwarf_attr (instance, 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);
	}
    }

  Dwarf_Addr lo = -1, hi = -1, entry = -1;
  if (dwarf_lowpc (instance, &lo) == 0)
    lo += info->dwbias;
  else
    printf (" (lowpc => %s)", dwarf_errmsg (-1));
  if (dwarf_highpc (instance, &hi) == 0)
    hi += info->dwbias;
  else
    printf (" (highpc => %s)", dwarf_errmsg (-1));

  Dwarf_Attribute attr_mem;
  Dwarf_Attribute *attr = dwarf_attr (instance, DW_AT_entry_pc, &attr_mem);
  if (attr != NULL)
    {
      if (dwarf_formaddr (attr, &entry) == 0)
	entry += info->dwbias;
      else
	printf (" (entrypc => %s)", dwarf_errmsg (-1));
    }

  if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1)
    printf (" %#" PRIx64 "..%#" PRIx64, lo, hi);
  if (entry != (Dwarf_Addr) -1)
    printf (" => %#" PRIx64 "\n", entry);
  else
    puts ("");

  return DWARF_CB_OK;
}

static void
print_inline (Dwarf_Die *func, void *arg)
{
  if (dwarf_func_inline_instances (func, &print_instance, arg) != 0)
    printf ("  error finding instances: %s\n", dwarf_errmsg (-1));
}

static int
print_func (Dwarf_Die *func, void *arg)
{
  const struct info *info = arg;

  const char *file = dwarf_decl_file (func);
  int line = -1;
  dwarf_decl_line (func, &line);
  const char *fct = dwarf_diename (func);

  printf ("  %s:%d: %s:", file, line, fct);

  if (dwarf_func_inline (func))
    {
      puts (" inline function");
      if (show_inlines)
	print_inline (func, arg);
    }
  else
    {
      Dwarf_Addr lo = -1, hi = -1, entry = -1;
      if (dwarf_lowpc (func, &lo) == 0)
	lo += info->dwbias;
      else
	printf (" (lowpc => %s)", dwarf_errmsg (-1));
      if (dwarf_highpc (func, &hi) == 0)
	hi += info->dwbias;
      else
	printf (" (highpc => %s)", dwarf_errmsg (-1));
      if (dwarf_entrypc (func, &entry) == 0)
	entry += info->dwbias;
      else
	printf (" (entrypc => %s)", dwarf_errmsg (-1));

      if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
	  || entry != (Dwarf_Addr) -1)
	printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
		lo, hi, entry);
      else
	puts ("");
    }

  return DWARF_CB_OK;
}

static int
print_module (Dwfl_Module *mod __attribute__ ((unused)),
	      void **userdata __attribute__ ((unused)),
	      const char *name, Dwarf_Addr base,
	      Dwarf *dw, Dwarf_Addr bias,
	      void *arg)
{
  printf ("module: %30s %08" PRIx64 " %12p %" PRIx64 " (%s)\n",
	  name, base, dw, bias, dwfl_errmsg (-1));

  if (dw != NULL && *(const bool *) arg)
    {
      Dwarf_Off off = 0;
      size_t cuhl;
      Dwarf_Off noff;

      while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
	{
	  Dwarf_Die die_mem;
	  struct info info = { dwarf_offdie (dw, off + cuhl, &die_mem), bias };
	  (void) dwarf_getfuncs (info.cudie, print_func, &info, 0);

	  off = noff;
	}
    }

  return DWARF_CB_OK;
}

static bool show_functions;

/* gettext helper macro.  */
#undef	N_
#define N_(Str) Str

static const struct argp_option options[] =
  {
    { "functions", 'f', NULL, 0, N_("Additionally show function names"), 0 },
    { "inlines", 'i', NULL, 0, N_("Show instances of inlined functions"), 0 },
    { NULL, 0, NULL, 0, NULL, 0 }
  };

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

    case 'f':
      show_functions = true;
      break;

    case 'i':
      show_inlines = show_functions = true;
      break;

    default:
      return ARGP_ERR_UNKNOWN;
    }
  return 0;
}

int
main (int argc, char **argv)
{
  /* We use no threads here which can interfere with handling a stream.  */
  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);

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

  Dwfl *dwfl = NULL;
  const struct argp_child argp_children[] =
    {
      { .argp = dwfl_standard_argp () },
      { .argp = NULL }
    };
  const struct argp argp =
    {
      options, parse_opt, NULL, NULL, argp_children, NULL, NULL
    };
  (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
  assert (dwfl != NULL);

  ptrdiff_t p = 0;
  do
    p = dwfl_getdwarf (dwfl, &print_module, &show_functions, p);
  while (p > 0);
  if (p < 0)
    error (2, 0, "dwfl_getdwarf: %s", dwfl_errmsg (-1));

  dwfl_end (dwfl);

  return 0;
}
