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 479757 : noop_free (void *arg __attribute__ ((unused)))
46 : {
47 479757 : }
48 :
49 :
50 : static void
51 21695 : cu_free (void *arg)
52 : {
53 21695 : struct Dwarf_CU *p = (struct Dwarf_CU *) arg;
54 :
55 21695 : Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
56 :
57 21695 : tdestroy (p->locs, noop_free);
58 :
59 : /* Free split dwarf one way (from skeleton to split). */
60 21695 : if (p->unit_type == DW_UT_skeleton
61 67 : && p->split != NULL && p->split != (void *)-1)
62 : {
63 : /* The fake_addr_cu might be shared, only release one. */
64 48 : if (p->dbg->fake_addr_cu == p->split->dbg->fake_addr_cu)
65 48 : p->split->dbg->fake_addr_cu = NULL;
66 48 : INTUSE(dwarf_end) (p->split->dbg);
67 : }
68 21695 : }
69 :
70 :
71 : int
72 5544 : dwarf_end (Dwarf *dwarf)
73 : {
74 5544 : if (dwarf != NULL)
75 : {
76 5538 : if (dwarf->cfi != NULL)
77 : /* Clean up the CFI cache. */
78 17 : __libdw_destroy_frame_cache (dwarf->cfi);
79 :
80 5538 : Dwarf_Sig8_Hash_free (&dwarf->sig8_hash);
81 :
82 : /* The search tree for the CUs. NB: the CU data itself is
83 : allocated separately, but the abbreviation hash tables need
84 : to be handled. */
85 5538 : tdestroy (dwarf->cu_tree, cu_free);
86 5538 : tdestroy (dwarf->tu_tree, cu_free);
87 :
88 : /* Search tree for macro opcode tables. */
89 5538 : tdestroy (dwarf->macro_ops, noop_free);
90 :
91 : /* Search tree for decoded .debug_lines units. */
92 5538 : tdestroy (dwarf->files_lines, noop_free);
93 :
94 : /* And the split Dwarf. */
95 5538 : tdestroy (dwarf->split_tree, noop_free);
96 :
97 5538 : struct libdw_memblock *memp = dwarf->mem_tail;
98 : /* The first block is allocated together with the Dwarf object. */
99 25026 : while (memp->prev != NULL)
100 : {
101 13950 : struct libdw_memblock *prevp = memp->prev;
102 13950 : free (memp);
103 13950 : memp = prevp;
104 : }
105 :
106 : /* Free the pubnames helper structure. */
107 5538 : free (dwarf->pubnames_sets);
108 :
109 : /* Free the ELF descriptor if necessary. */
110 5538 : if (dwarf->free_elf)
111 209 : elf_end (dwarf->elf);
112 :
113 : /* Free the fake location list CU. */
114 5538 : if (dwarf->fake_loc_cu != NULL)
115 : {
116 5258 : cu_free (dwarf->fake_loc_cu);
117 5258 : free (dwarf->fake_loc_cu);
118 : }
119 5538 : if (dwarf->fake_loclists_cu != NULL)
120 : {
121 45 : cu_free (dwarf->fake_loclists_cu);
122 45 : free (dwarf->fake_loclists_cu);
123 : }
124 5538 : if (dwarf->fake_addr_cu != NULL)
125 : {
126 39 : cu_free (dwarf->fake_addr_cu);
127 39 : free (dwarf->fake_addr_cu);
128 : }
129 :
130 : /* Did we find and allocate the alt Dwarf ourselves? */
131 5538 : if (dwarf->alt_fd != -1)
132 : {
133 2 : INTUSE(dwarf_end) (dwarf->alt_dwarf);
134 2 : close (dwarf->alt_fd);
135 : }
136 :
137 : /* The cached dir we found the Dwarf ELF file in. */
138 5538 : free (dwarf->debugdir);
139 :
140 : /* Free the context descriptor. */
141 5538 : free (dwarf);
142 : }
143 :
144 5544 : return 0;
145 : }
146 : INTDEF(dwarf_end)
|