Blame libdw/dwarf_end.c

Packit Service 97d2fb
/* Release debugging handling context.
Packit Service 97d2fb
   Copyright (C) 2002-2011, 2014, 2018 Red Hat, Inc.
Packit Service 97d2fb
   This file is part of elfutils.
Packit Service 97d2fb
   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
Packit Service 97d2fb
Packit Service 97d2fb
   This file is free software; you can redistribute it and/or modify
Packit Service 97d2fb
   it under the terms of either
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU Lesser General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 3 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or
Packit Service 97d2fb
Packit Service 97d2fb
     * the GNU General Public License as published by the Free
Packit Service 97d2fb
       Software Foundation; either version 2 of the License, or (at
Packit Service 97d2fb
       your option) any later version
Packit Service 97d2fb
Packit Service 97d2fb
   or both in parallel, as here.
Packit Service 97d2fb
Packit Service 97d2fb
   elfutils is distributed in the hope that it will be useful, but
Packit Service 97d2fb
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 97d2fb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 97d2fb
   General Public License for more details.
Packit Service 97d2fb
Packit Service 97d2fb
   You should have received copies of the GNU General Public License and
Packit Service 97d2fb
   the GNU Lesser General Public License along with this program.  If
Packit Service 97d2fb
   not, see <http://www.gnu.org/licenses/>.  */
Packit Service 97d2fb
Packit Service 97d2fb
#ifdef HAVE_CONFIG_H
Packit Service 97d2fb
# include <config.h>
Packit Service 97d2fb
#endif
Packit Service 97d2fb
Packit Service 97d2fb
#include <search.h>
Packit Service 97d2fb
#include <stdlib.h>
Packit Service 97d2fb
#include <assert.h>
Packit Service 97d2fb
#include <string.h>
Packit Service 97d2fb
#include <unistd.h>
Packit Service 97d2fb
Packit Service 97d2fb
#include "libdwP.h"
Packit Service 97d2fb
#include "cfi.h"
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
static void
Packit Service 97d2fb
noop_free (void *arg __attribute__ ((unused)))
Packit Service 97d2fb
{
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
static void
Packit Service 97d2fb
cu_free (void *arg)
Packit Service 97d2fb
{
Packit Service 97d2fb
  struct Dwarf_CU *p = (struct Dwarf_CU *) arg;
Packit Service 97d2fb
Packit Service 97d2fb
  tdestroy (p->locs, noop_free);
Packit Service 97d2fb
Packit Service 97d2fb
  /* Only free the CU internals if its not a fake CU.  */
Packit Service 97d2fb
  if(p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu
Packit Service 97d2fb
     && p != p->dbg->fake_addr_cu)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Free split dwarf one way (from skeleton to split).  */
Packit Service 97d2fb
      if (p->unit_type == DW_UT_skeleton
Packit Service 97d2fb
	  && p->split != NULL && p->split != (void *)-1)
Packit Service 97d2fb
	{
Packit Service 97d2fb
	  /* The fake_addr_cu might be shared, only release one.  */
Packit Service 97d2fb
	  if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu)
Packit Service 97d2fb
	    p->split->dbg->fake_addr_cu = NULL;
Packit Service 97d2fb
	  INTUSE(dwarf_end) (p->split->dbg);
Packit Service 97d2fb
	}
Packit Service 97d2fb
    }
Packit Service 97d2fb
}
Packit Service 97d2fb
Packit Service 97d2fb
Packit Service 97d2fb
int
Packit Service 97d2fb
dwarf_end (Dwarf *dwarf)
Packit Service 97d2fb
{
Packit Service 97d2fb
  if (dwarf != NULL)
Packit Service 97d2fb
    {
Packit Service 97d2fb
      if (dwarf->cfi != NULL)
Packit Service 97d2fb
	/* Clean up the CFI cache.  */
Packit Service 97d2fb
	__libdw_destroy_frame_cache (dwarf->cfi);
Packit Service 97d2fb
Packit Service 97d2fb
      Dwarf_Sig8_Hash_free (&dwarf->sig8_hash);
Packit Service 97d2fb
Packit Service 97d2fb
      /* The search tree for the CUs.  NB: the CU data itself is
Packit Service 97d2fb
	 allocated separately, but the abbreviation hash tables need
Packit Service 97d2fb
	 to be handled.  */
Packit Service 97d2fb
      tdestroy (dwarf->cu_tree, cu_free);
Packit Service 97d2fb
      tdestroy (dwarf->tu_tree, cu_free);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Search tree for macro opcode tables.  */
Packit Service 97d2fb
      tdestroy (dwarf->macro_ops, noop_free);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Search tree for decoded .debug_lines units.  */
Packit Service 97d2fb
      tdestroy (dwarf->files_lines, noop_free);
Packit Service 97d2fb
Packit Service 97d2fb
      /* And the split Dwarf.  */
Packit Service 97d2fb
      tdestroy (dwarf->split_tree, noop_free);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Free the internally allocated memory.  */
Packit Service 97d2fb
      for (size_t i = 0; i < dwarf->mem_stacks; i++)
Packit Service 97d2fb
        {
Packit Service 97d2fb
          struct libdw_memblock *memp = dwarf->mem_tails[i];
Packit Service 97d2fb
          while (memp != NULL)
Packit Service 97d2fb
	    {
Packit Service 97d2fb
	      struct libdw_memblock *prevp = memp->prev;
Packit Service 97d2fb
	      free (memp);
Packit Service 97d2fb
	      memp = prevp;
Packit Service 97d2fb
	    }
Packit Service 97d2fb
        }
Packit Service 97d2fb
      if (dwarf->mem_tails != NULL)
Packit Service 97d2fb
        free (dwarf->mem_tails);
Packit Service 97d2fb
      pthread_rwlock_destroy (&dwarf->mem_rwl);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Free the pubnames helper structure.  */
Packit Service 97d2fb
      free (dwarf->pubnames_sets);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Free the ELF descriptor if necessary.  */
Packit Service 97d2fb
      if (dwarf->free_elf)
Packit Service 97d2fb
	elf_end (dwarf->elf);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Free the fake location list CU.  */
Packit Service 97d2fb
      if (dwarf->fake_loc_cu != NULL)
Packit Service 97d2fb
	{
Packit Service 97d2fb
	  cu_free (dwarf->fake_loc_cu);
Packit Service 97d2fb
	  free (dwarf->fake_loc_cu);
Packit Service 97d2fb
	}
Packit Service 97d2fb
      if (dwarf->fake_loclists_cu != NULL)
Packit Service 97d2fb
	{
Packit Service 97d2fb
	  cu_free (dwarf->fake_loclists_cu);
Packit Service 97d2fb
	  free (dwarf->fake_loclists_cu);
Packit Service 97d2fb
	}
Packit Service 97d2fb
      if (dwarf->fake_addr_cu != NULL)
Packit Service 97d2fb
	{
Packit Service 97d2fb
	  cu_free (dwarf->fake_addr_cu);
Packit Service 97d2fb
	  free (dwarf->fake_addr_cu);
Packit Service 97d2fb
	}
Packit Service 97d2fb
Packit Service 97d2fb
      /* Did we find and allocate the alt Dwarf ourselves?  */
Packit Service 97d2fb
      if (dwarf->alt_fd != -1)
Packit Service 97d2fb
	{
Packit Service 97d2fb
	  INTUSE(dwarf_end) (dwarf->alt_dwarf);
Packit Service 97d2fb
	  close (dwarf->alt_fd);
Packit Service 97d2fb
	}
Packit Service 97d2fb
Packit Service 97d2fb
      /* The cached dir we found the Dwarf ELF file in.  */
Packit Service 97d2fb
      free (dwarf->debugdir);
Packit Service 97d2fb
Packit Service 97d2fb
      /* Free the context descriptor.  */
Packit Service 97d2fb
      free (dwarf);
Packit Service 97d2fb
    }
Packit Service 97d2fb
Packit Service 97d2fb
  return 0;
Packit Service 97d2fb
}
Packit Service 97d2fb
INTDEF(dwarf_end)