xref: /aosp_15_r20/external/elfutils/libdw/dwarf_end.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
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