1da0c48c4Sopenharmony_ci/* Release debugging handling context. 2da0c48c4Sopenharmony_ci Copyright (C) 2002-2011, 2014, 2018 Red Hat, Inc. 3da0c48c4Sopenharmony_ci This file is part of elfutils. 4da0c48c4Sopenharmony_ci Written by Ulrich Drepper <drepper@redhat.com>, 2002. 5da0c48c4Sopenharmony_ci 6da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 7da0c48c4Sopenharmony_ci it under the terms of either 8da0c48c4Sopenharmony_ci 9da0c48c4Sopenharmony_ci * the GNU Lesser General Public License as published by the Free 10da0c48c4Sopenharmony_ci Software Foundation; either version 3 of the License, or (at 11da0c48c4Sopenharmony_ci your option) any later version 12da0c48c4Sopenharmony_ci 13da0c48c4Sopenharmony_ci or 14da0c48c4Sopenharmony_ci 15da0c48c4Sopenharmony_ci * the GNU General Public License as published by the Free 16da0c48c4Sopenharmony_ci Software Foundation; either version 2 of the License, or (at 17da0c48c4Sopenharmony_ci your option) any later version 18da0c48c4Sopenharmony_ci 19da0c48c4Sopenharmony_ci or both in parallel, as here. 20da0c48c4Sopenharmony_ci 21da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 22da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 23da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24da0c48c4Sopenharmony_ci General Public License for more details. 25da0c48c4Sopenharmony_ci 26da0c48c4Sopenharmony_ci You should have received copies of the GNU General Public License and 27da0c48c4Sopenharmony_ci the GNU Lesser General Public License along with this program. If 28da0c48c4Sopenharmony_ci not, see <http://www.gnu.org/licenses/>. */ 29da0c48c4Sopenharmony_ci 30da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H 31da0c48c4Sopenharmony_ci# include <config.h> 32da0c48c4Sopenharmony_ci#endif 33da0c48c4Sopenharmony_ci 34da0c48c4Sopenharmony_ci#include <search.h> 35da0c48c4Sopenharmony_ci#include <stdlib.h> 36da0c48c4Sopenharmony_ci#include <assert.h> 37da0c48c4Sopenharmony_ci#include <string.h> 38da0c48c4Sopenharmony_ci 39da0c48c4Sopenharmony_ci#include "libdwP.h" 40da0c48c4Sopenharmony_ci#include "cfi.h" 41da0c48c4Sopenharmony_ci 42da0c48c4Sopenharmony_ci 43da0c48c4Sopenharmony_cistatic void 44da0c48c4Sopenharmony_cinoop_free (void *arg __attribute__ ((unused))) 45da0c48c4Sopenharmony_ci{ 46da0c48c4Sopenharmony_ci} 47da0c48c4Sopenharmony_ci 48da0c48c4Sopenharmony_ci 49da0c48c4Sopenharmony_cistatic void 50da0c48c4Sopenharmony_cicu_free (void *arg) 51da0c48c4Sopenharmony_ci{ 52da0c48c4Sopenharmony_ci struct Dwarf_CU *p = (struct Dwarf_CU *) arg; 53da0c48c4Sopenharmony_ci 54da0c48c4Sopenharmony_ci tdestroy (p->locs, noop_free); 55da0c48c4Sopenharmony_ci 56da0c48c4Sopenharmony_ci /* Only free the CU internals if its not a fake CU. */ 57da0c48c4Sopenharmony_ci if(p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu 58da0c48c4Sopenharmony_ci && p != p->dbg->fake_addr_cu) 59da0c48c4Sopenharmony_ci { 60da0c48c4Sopenharmony_ci Dwarf_Abbrev_Hash_free (&p->abbrev_hash); 61da0c48c4Sopenharmony_ci 62da0c48c4Sopenharmony_ci /* Free split dwarf one way (from skeleton to split). */ 63da0c48c4Sopenharmony_ci if (p->unit_type == DW_UT_skeleton 64da0c48c4Sopenharmony_ci && p->split != NULL && p->split != (void *)-1) 65da0c48c4Sopenharmony_ci { 66da0c48c4Sopenharmony_ci /* The fake_addr_cu might be shared, only release one. */ 67da0c48c4Sopenharmony_ci if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu) 68da0c48c4Sopenharmony_ci p->split->dbg->fake_addr_cu = NULL; 69da0c48c4Sopenharmony_ci INTUSE(dwarf_end) (p->split->dbg); 70da0c48c4Sopenharmony_ci } 71da0c48c4Sopenharmony_ci } 72da0c48c4Sopenharmony_ci} 73da0c48c4Sopenharmony_ci 74da0c48c4Sopenharmony_ci 75da0c48c4Sopenharmony_ciint 76da0c48c4Sopenharmony_cidwarf_end (Dwarf *dwarf) 77da0c48c4Sopenharmony_ci{ 78da0c48c4Sopenharmony_ci if (dwarf != NULL) 79da0c48c4Sopenharmony_ci { 80da0c48c4Sopenharmony_ci if (dwarf->cfi != NULL) 81da0c48c4Sopenharmony_ci /* Clean up the CFI cache. */ 82da0c48c4Sopenharmony_ci __libdw_destroy_frame_cache (dwarf->cfi); 83da0c48c4Sopenharmony_ci 84da0c48c4Sopenharmony_ci Dwarf_Sig8_Hash_free (&dwarf->sig8_hash); 85da0c48c4Sopenharmony_ci 86da0c48c4Sopenharmony_ci /* The search tree for the CUs. NB: the CU data itself is 87da0c48c4Sopenharmony_ci allocated separately, but the abbreviation hash tables need 88da0c48c4Sopenharmony_ci to be handled. */ 89da0c48c4Sopenharmony_ci tdestroy (dwarf->cu_tree, cu_free); 90da0c48c4Sopenharmony_ci tdestroy (dwarf->tu_tree, cu_free); 91da0c48c4Sopenharmony_ci 92da0c48c4Sopenharmony_ci /* Search tree for macro opcode tables. */ 93da0c48c4Sopenharmony_ci tdestroy (dwarf->macro_ops, noop_free); 94da0c48c4Sopenharmony_ci 95da0c48c4Sopenharmony_ci /* Search tree for decoded .debug_lines units. */ 96da0c48c4Sopenharmony_ci tdestroy (dwarf->files_lines, noop_free); 97da0c48c4Sopenharmony_ci 98da0c48c4Sopenharmony_ci /* And the split Dwarf. */ 99da0c48c4Sopenharmony_ci tdestroy (dwarf->split_tree, noop_free); 100da0c48c4Sopenharmony_ci 101da0c48c4Sopenharmony_ci /* Free the internally allocated memory. */ 102da0c48c4Sopenharmony_ci for (size_t i = 0; i < dwarf->mem_stacks; i++) 103da0c48c4Sopenharmony_ci { 104da0c48c4Sopenharmony_ci struct libdw_memblock *memp = dwarf->mem_tails[i]; 105da0c48c4Sopenharmony_ci while (memp != NULL) 106da0c48c4Sopenharmony_ci { 107da0c48c4Sopenharmony_ci struct libdw_memblock *prevp = memp->prev; 108da0c48c4Sopenharmony_ci free (memp); 109da0c48c4Sopenharmony_ci memp = prevp; 110da0c48c4Sopenharmony_ci } 111da0c48c4Sopenharmony_ci } 112da0c48c4Sopenharmony_ci if (dwarf->mem_tails != NULL) 113da0c48c4Sopenharmony_ci free (dwarf->mem_tails); 114da0c48c4Sopenharmony_ci pthread_rwlock_destroy (&dwarf->mem_rwl); 115da0c48c4Sopenharmony_ci 116da0c48c4Sopenharmony_ci /* Free the pubnames helper structure. */ 117da0c48c4Sopenharmony_ci free (dwarf->pubnames_sets); 118da0c48c4Sopenharmony_ci 119da0c48c4Sopenharmony_ci /* Free the ELF descriptor if necessary. */ 120da0c48c4Sopenharmony_ci if (dwarf->free_elf) 121da0c48c4Sopenharmony_ci elf_end (dwarf->elf); 122da0c48c4Sopenharmony_ci 123da0c48c4Sopenharmony_ci /* Free the fake location list CU. */ 124da0c48c4Sopenharmony_ci if (dwarf->fake_loc_cu != NULL) 125da0c48c4Sopenharmony_ci { 126da0c48c4Sopenharmony_ci cu_free (dwarf->fake_loc_cu); 127da0c48c4Sopenharmony_ci free (dwarf->fake_loc_cu); 128da0c48c4Sopenharmony_ci } 129da0c48c4Sopenharmony_ci if (dwarf->fake_loclists_cu != NULL) 130da0c48c4Sopenharmony_ci { 131da0c48c4Sopenharmony_ci cu_free (dwarf->fake_loclists_cu); 132da0c48c4Sopenharmony_ci free (dwarf->fake_loclists_cu); 133da0c48c4Sopenharmony_ci } 134da0c48c4Sopenharmony_ci if (dwarf->fake_addr_cu != NULL) 135da0c48c4Sopenharmony_ci { 136da0c48c4Sopenharmony_ci cu_free (dwarf->fake_addr_cu); 137da0c48c4Sopenharmony_ci free (dwarf->fake_addr_cu); 138da0c48c4Sopenharmony_ci } 139da0c48c4Sopenharmony_ci 140da0c48c4Sopenharmony_ci /* Did we find and allocate the alt Dwarf ourselves? */ 141da0c48c4Sopenharmony_ci if (dwarf->alt_fd != -1) 142da0c48c4Sopenharmony_ci { 143da0c48c4Sopenharmony_ci INTUSE(dwarf_end) (dwarf->alt_dwarf); 144da0c48c4Sopenharmony_ci close (dwarf->alt_fd); 145da0c48c4Sopenharmony_ci } 146da0c48c4Sopenharmony_ci 147da0c48c4Sopenharmony_ci /* The cached dir we found the Dwarf ELF file in. */ 148da0c48c4Sopenharmony_ci free (dwarf->debugdir); 149da0c48c4Sopenharmony_ci 150da0c48c4Sopenharmony_ci /* Free the context descriptor. */ 151da0c48c4Sopenharmony_ci free (dwarf); 152da0c48c4Sopenharmony_ci } 153da0c48c4Sopenharmony_ci 154da0c48c4Sopenharmony_ci return 0; 155da0c48c4Sopenharmony_ci} 156da0c48c4Sopenharmony_ciINTDEF(dwarf_end) 157