/* Copyright (C) 2005, 2007, 2008 Red Hat, Inc.
   This file is part of elfutils.
   Written by Ulrich Drepper <drepper@redhat.com>, 2005.

   This file is free software; you can redistribute it and/or modify
   it under the terms of either

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at
       your option) any later version

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at
       your option) any later version

   or both in parallel, as here.

   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 copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see <http://www.gnu.org/licenses/>.  */

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

#include <string.h>

#include "libasmP.h"
#include "../libebl/libeblP.h"


struct symtoken
{
  DisasmCtx_t *ctx;
  void *symcbarg;
};


static int
default_elf_getsym (GElf_Addr addr, Elf32_Word scnndx, GElf_Addr value,
		    char **buf, size_t *buflen, void *arg)
{
  struct symtoken *symtoken = (struct symtoken *) arg;

  /* First try the user provided function.  */
  if (symtoken->ctx->symcb != NULL)
    {
      int res = symtoken->ctx->symcb (addr, scnndx, value, buf, buflen,
				      symtoken->symcbarg);
      if (res >= 0)
	return res;
    }

  // XXX Look up in ELF file.

  return -1;
}


struct symaddrpair
{
  GElf_Addr addr;
  const char *name;
};


static void
read_symtab_exec (DisasmCtx_t *ctx)
{
  /* We simply use all we can get our hands on.  This will produce
     some duplicate information but this is no problem, we simply
     ignore the latter definitions.  */
  Elf_Scn *scn= NULL;
  while ((scn = elf_nextscn (ctx->elf, scn)) != NULL)
    {
      GElf_Shdr shdr_mem;
      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
      Elf_Data *data;
      if (shdr == NULL || shdr->sh_type != SHT_SYMTAB
	  || (data = elf_getdata (scn, NULL)) == NULL)
	continue;

      int xndxscnidx = elf_scnshndx (scn);
      Elf_Data *xndxdata = NULL;
      if (xndxscnidx > 0)
	xndxdata = elf_getdata (elf_getscn (ctx->elf, xndxscnidx), NULL);

      /* Iterate over all symbols.  Add all defined symbols.  */
      int nsyms = shdr->sh_size / shdr->sh_entsize;
      for (int cnt = 1; cnt < nsyms; ++cnt)
	{
	  Elf32_Word xshndx;
	  GElf_Sym sym_mem;
	  GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem,
					    &xshndx);
	  if (sym == NULL)
	    continue;

	  /* Undefined symbols are useless here.  */
	  if (sym->st_shndx == SHN_UNDEF)
	    continue;


	}
    }
}


static void
read_symtab (DisasmCtx_t *ctx)
{
  /* Find the symbol table(s).  */
  GElf_Ehdr ehdr_mem;
  GElf_Ehdr *ehdr = gelf_getehdr (ctx->elf, &ehdr_mem);
  if (ehdr == NULL)
    return;

  switch (ehdr->e_type)
    {
    case ET_EXEC:
    case ET_DYN:
      read_symtab_exec (ctx);
      break;

    case ET_REL:
      // XXX  Handle
      break;

    default:
      break;
    }
}


static int
null_elf_getsym (GElf_Addr addr __attribute__ ((unused)),
		 Elf32_Word scnndx __attribute__ ((unused)),
		 GElf_Addr value __attribute__ ((unused)),
		 char **buf __attribute__ ((unused)),
		 size_t *buflen __attribute__ ((unused)),
		 void *arg __attribute__ ((unused)))
{
  return -1;
}


int
disasm_cb (DisasmCtx_t *ctx, const uint8_t **startp, const uint8_t *end,
	   GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb,
	   void *outcbarg, void *symcbarg)
{
  struct symtoken symtoken;
  DisasmGetSymCB_t getsym = ctx->symcb ?: null_elf_getsym;

  if (ctx->elf != NULL)
    {
      /* Read all symbols of the ELF file and stuff them into a hash
	 table.  The key is the address and the section index.  */
      read_symtab (ctx);

      symtoken.ctx = ctx;
      symtoken.symcbarg = symcbarg;

      symcbarg = &symtoken;

      getsym = default_elf_getsym;
    }

  return ctx->ebl->disasm (startp, end, addr, fmt, outcb, getsym, outcbarg,
			   symcbarg);
}
INTDEF (disasm_cb)
