Line data Source code
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 <drepper@redhat.com>, 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 : #include <unistd.h>
39 :
40 : #include "libdwP.h"
41 : #include "cfi.h"
42 :
43 :
44 : static void
45 612938 : noop_free (void *arg __attribute__ ((unused)))
46 : {
47 612938 : }
48 :
49 :
50 : static void
51 26866 : cu_free (void *arg)
52 : {
53 26866 : struct Dwarf_CU *p = (struct Dwarf_CU *) arg;
54 :
55 26866 : tdestroy (p->locs, noop_free);
56 :
57 : /* Only free the CU internals if its not a fake CU. */
58 26866 : if(p != p->dbg->fake_loc_cu && p != p->dbg->fake_loclists_cu
59 21565 : && p != p->dbg->fake_addr_cu)
60 : {
61 21526 : Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
62 :
63 : /* Free split dwarf one way (from skeleton to split). */
64 21526 : if (p->unit_type == DW_UT_skeleton
65 67 : && p->split != NULL && p->split != (void *)-1)
66 : {
67 : /* The fake_addr_cu might be shared, only release one. */
68 48 : if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu)
69 48 : p->split->dbg->fake_addr_cu = NULL;
70 48 : INTUSE(dwarf_end) (p->split->dbg);
71 : }
72 : }
73 26866 : }
74 :
75 :
76 : int
77 5590 : dwarf_end (Dwarf *dwarf)
78 : {
79 5590 : if (dwarf != NULL)
80 : {
81 5581 : if (dwarf->cfi != NULL)
82 : /* Clean up the CFI cache. */
83 18 : __libdw_destroy_frame_cache (dwarf->cfi);
84 :
85 5581 : Dwarf_Sig8_Hash_free (&dwarf->sig8_hash);
86 :
87 : /* The search tree for the CUs. NB: the CU data itself is
88 : allocated separately, but the abbreviation hash tables need
89 : to be handled. */
90 5581 : tdestroy (dwarf->cu_tree, cu_free);
91 5581 : tdestroy (dwarf->tu_tree, cu_free);
92 :
93 : /* Search tree for macro opcode tables. */
94 5581 : tdestroy (dwarf->macro_ops, noop_free);
95 :
96 : /* Search tree for decoded .debug_lines units. */
97 5581 : tdestroy (dwarf->files_lines, noop_free);
98 :
99 : /* And the split Dwarf. */
100 5581 : tdestroy (dwarf->split_tree, noop_free);
101 :
102 : /* Free the internally allocated memory. */
103 6137 : for (size_t i = 0; i < dwarf->mem_stacks; i++)
104 : {
105 556 : struct libdw_memblock *memp = dwarf->mem_tails[i];
106 19598 : while (memp != NULL)
107 : {
108 19042 : struct libdw_memblock *prevp = memp->prev;
109 19042 : free (memp);
110 19042 : memp = prevp;
111 : }
112 : }
113 5581 : if (dwarf->mem_tails != NULL)
114 545 : free (dwarf->mem_tails);
115 5581 : pthread_rwlock_destroy (&dwarf->mem_rwl);
116 :
117 : /* Free the pubnames helper structure. */
118 5581 : free (dwarf->pubnames_sets);
119 :
120 : /* Free the ELF descriptor if necessary. */
121 5581 : if (dwarf->free_elf)
122 204 : elf_end (dwarf->elf);
123 :
124 : /* Free the fake location list CU. */
125 5581 : if (dwarf->fake_loc_cu != NULL)
126 : {
127 5256 : cu_free (dwarf->fake_loc_cu);
128 5256 : free (dwarf->fake_loc_cu);
129 : }
130 5581 : if (dwarf->fake_loclists_cu != NULL)
131 : {
132 45 : cu_free (dwarf->fake_loclists_cu);
133 45 : free (dwarf->fake_loclists_cu);
134 : }
135 5581 : if (dwarf->fake_addr_cu != NULL)
136 : {
137 39 : cu_free (dwarf->fake_addr_cu);
138 39 : free (dwarf->fake_addr_cu);
139 : }
140 :
141 : /* Did we find and allocate the alt Dwarf ourselves? */
142 5581 : if (dwarf->alt_fd != -1)
143 : {
144 2 : INTUSE(dwarf_end) (dwarf->alt_dwarf);
145 2 : close (dwarf->alt_fd);
146 : }
147 :
148 : /* The cached dir we found the Dwarf ELF file in. */
149 5581 : free (dwarf->debugdir);
150 :
151 : /* Free the context descriptor. */
152 5581 : free (dwarf);
153 : }
154 :
155 5590 : return 0;
156 : }
157 : INTDEF(dwarf_end)
|