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