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

   This file 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 3 of the License, or
   (at your option) any later version.

   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 this program.  If not, see <http://www.gnu.org/licenses/>.  */

#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
list_module (Dwfl_Module *mod __attribute__ ((unused)),
	     void **userdata __attribute__ ((unused)),
	     const char *name, Dwarf_Addr base,
	     void *arg __attribute__ ((unused)))
{
  Dwarf_Addr start;
  Dwarf_Addr end;
  const char *file;
  const char *debug;
  if (dwfl_module_info (mod, NULL, &start, &end,
			NULL, NULL, &file, &debug) != name
      || start != base)
    abort ();
  printf ("module: %30s %08" PRIx64 "..%08" PRIx64 " %s %s\n",
	  name, start, end, file, debug);
  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 " %s %" PRIx64 " (%s)\n",
	  name, base, dw == NULL ? "no" : "DWARF", 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_getmodules (dwfl, &list_module, NULL, p);
  while (p > 0);
  if (p < 0)
    error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));

  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));

  p = 0;
  do
    p = dwfl_getmodules (dwfl, &list_module, NULL, p);
  while (p > 0);
  if (p < 0)
    error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));

  dwfl_end (dwfl);

  return 0;
}
