/* Maintenance of module list in libdwfl.
   Copyright (C) 2005, 2006, 2007, 2008, 2014, 2015 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 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/>.  */

#include "libdwflP.h"
#include "../libdw/cfi.h"
#include <search.h>
#include <unistd.h>

static void
free_cu (struct dwfl_cu *cu)
{
  if (cu->lines != NULL)
    free (cu->lines);
  free (cu);
}

static void
nofree (void *arg __attribute__ ((unused)))
{
}

static void
free_file (struct dwfl_file *file)
{
  free (file->name);

  /* Close the fd only on the last reference.  */
  if (file->elf != NULL && elf_end (file->elf) == 0 && file->fd != -1)
    close (file->fd);
}

void
internal_function
__libdwfl_module_free (Dwfl_Module *mod)
{
  if (mod->lazy_cu_root != NULL)
    tdestroy (mod->lazy_cu_root, nofree);

  if (mod->aranges != NULL)
    free (mod->aranges);

  if (mod->cu != NULL)
    {
      for (size_t i = 0; i < mod->ncu; ++i)
	free_cu (mod->cu[i]);
      free (mod->cu);
    }

  /* We might have primed the Dwarf_CFI ebl cache with our own ebl
     in __libdwfl_set_cfi. Make sure we don't free it twice.  */
  if (mod->eh_cfi != NULL)
    {
      if (mod->eh_cfi->ebl != NULL && mod->eh_cfi->ebl == mod->ebl)
	mod->eh_cfi->ebl = NULL;
      dwarf_cfi_end (mod->eh_cfi);
    }

  if (mod->dwarf_cfi != NULL)
    {
      if (mod->dwarf_cfi->ebl != NULL && mod->dwarf_cfi->ebl == mod->ebl)
	mod->dwarf_cfi->ebl = NULL;
      /* We don't need to explicitly destroy the dwarf_cfi.
	 That will be done by dwarf_end.  */
    }

  if (mod->dw != NULL)
    {
      INTUSE(dwarf_end) (mod->dw);
      if (mod->alt != NULL)
	{
	  INTUSE(dwarf_end) (mod->alt);
	  if (mod->alt_elf != NULL)
	    elf_end (mod->alt_elf);
	  if (mod->alt_fd != -1)
	    close (mod->alt_fd);
	}
    }

  if (mod->ebl != NULL)
    ebl_closebackend (mod->ebl);

  if (mod->debug.elf != mod->main.elf)
    free_file (&mod->debug);
  free_file (&mod->main);
  free_file (&mod->aux_sym);

  if (mod->build_id_bits != NULL)
    free (mod->build_id_bits);

  if (mod->reloc_info != NULL)
    free (mod->reloc_info);

  free (mod->name);
  free (mod);
}

void
dwfl_report_begin_add (Dwfl *dwfl __attribute__ ((unused)))
{
  /* The lookup table will be cleared on demand, there is nothing we need
     to do here.  */
}
INTDEF (dwfl_report_begin_add)

void
dwfl_report_begin (Dwfl *dwfl)
{
  /* Clear the segment lookup table.  */
  dwfl->lookup_elts = 0;

  for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
    m->gc = true;

  dwfl->offline_next_address = OFFLINE_REDZONE;
}
INTDEF (dwfl_report_begin)

static inline Dwfl_Module *
use (Dwfl_Module *mod, Dwfl_Module **tailp, Dwfl *dwfl)
{
  mod->next = *tailp;
  *tailp = mod;

  if (unlikely (dwfl->lookup_module != NULL))
    {
      free (dwfl->lookup_module);
      dwfl->lookup_module = NULL;
    }

  return mod;
}

/* Report that a module called NAME spans addresses [START, END).
   Returns the module handle, either existing or newly allocated,
   or returns a null pointer for an allocation error.  */
Dwfl_Module *
dwfl_report_module (Dwfl *dwfl, const char *name,
		    GElf_Addr start, GElf_Addr end)
{
  Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;

  for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
    {
      if (m->low_addr == start && m->high_addr == end
	  && !strcmp (m->name, name))
	{
	  /* This module is still here.  Move it to the place in the list
	     after the last module already reported.  */
	  *prevp = m->next;
	  m->gc = false;
	  return use (m, tailp, dwfl);
	}

      if (! m->gc)
	tailp = &m->next;
    }

  Dwfl_Module *mod = calloc (1, sizeof *mod);
  if (mod == NULL)
    goto nomem;

  mod->name = strdup (name);
  if (mod->name == NULL)
    {
      free (mod);
    nomem:
      __libdwfl_seterrno (DWFL_E_NOMEM);
      return NULL;
    }

  mod->low_addr = start;
  mod->high_addr = end;
  mod->dwfl = dwfl;

  return use (mod, tailp, dwfl);
}
INTDEF (dwfl_report_module)


/* Finish reporting the current set of modules to the library.
   If REMOVED is not null, it's called for each module that
   existed before but was not included in the current report.
   Returns a nonzero return value from the callback.
   DWFL cannot be used until this function has returned zero.  */
int
dwfl_report_end (Dwfl *dwfl,
		 int (*removed) (Dwfl_Module *, void *,
				 const char *, Dwarf_Addr,
				 void *arg),
		 void *arg)
{
  Dwfl_Module **tailp = &dwfl->modulelist;
  while (*tailp != NULL)
    {
      Dwfl_Module *m = *tailp;
      if (m->gc && removed != NULL)
	{
	  int result = (*removed) (MODCB_ARGS (m), arg);
	  if (result != 0)
	    return result;
	}
      if (m->gc)
	{
	  *tailp = m->next;
	  __libdwfl_module_free (m);
	}
      else
	tailp = &m->next;
    }

  return 0;
}
INTDEF (dwfl_report_end)
