1 /* Maintenance of module list in libdwfl.
2 Copyright (C) 2005, 2006, 2007, 2008, 2014 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
18 or both in parallel, as here.
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
34 free_cu (struct dwfl_cu *cu)
36 if (cu->lines != NULL)
42 nofree (void *arg __attribute__ ((unused)))
47 free_file (struct dwfl_file *file)
51 /* Close the fd only on the last reference. */
52 if (file->elf != NULL && elf_end (file->elf) == 0 && file->fd != -1)
58 __libdwfl_module_free (Dwfl_Module *mod)
60 if (mod->lazy_cu_root != NULL)
61 tdestroy (mod->lazy_cu_root, nofree);
63 if (mod->aranges != NULL)
68 for (size_t i = 0; i < mod->ncu; ++i)
75 INTUSE(dwarf_end) (mod->dw);
78 INTUSE(dwarf_end) (mod->alt);
79 if (mod->alt_elf != NULL)
80 elf_end (mod->alt_elf);
81 if (mod->alt_fd != -1)
87 ebl_closebackend (mod->ebl);
89 if (mod->debug.elf != mod->main.elf)
90 free_file (&mod->debug);
91 free_file (&mod->main);
92 free_file (&mod->aux_sym);
94 if (mod->build_id_bits != NULL)
95 free (mod->build_id_bits);
97 if (mod->reloc_info != NULL)
98 free (mod->reloc_info);
100 if (mod->eh_cfi != NULL)
101 dwarf_cfi_end (mod->eh_cfi);
108 dwfl_report_begin_add (Dwfl *dwfl __attribute__ ((unused)))
110 /* The lookup table will be cleared on demand, there is nothing we need
113 INTDEF (dwfl_report_begin_add)
116 dwfl_report_begin (Dwfl *dwfl)
118 /* Clear the segment lookup table. */
119 dwfl->lookup_elts = 0;
121 for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
124 dwfl->offline_next_address = OFFLINE_REDZONE;
126 INTDEF (dwfl_report_begin)
128 /* Report that a module called NAME spans addresses [START, END).
129 Returns the module handle, either existing or newly allocated,
130 or returns a null pointer for an allocation error. */
132 dwfl_report_module (Dwfl *dwfl, const char *name,
133 GElf_Addr start, GElf_Addr end)
135 Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
137 inline Dwfl_Module *use (Dwfl_Module *mod)
142 if (unlikely (dwfl->lookup_module != NULL))
144 free (dwfl->lookup_module);
145 dwfl->lookup_module = NULL;
151 for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
153 if (m->low_addr == start && m->high_addr == end
154 && !strcmp (m->name, name))
156 /* This module is still here. Move it to the place in the list
157 after the last module already reported. */
167 Dwfl_Module *mod = calloc (1, sizeof *mod);
171 mod->name = strdup (name);
172 if (mod->name == NULL)
176 __libdwfl_seterrno (DWFL_E_NOMEM);
180 mod->low_addr = start;
181 mod->high_addr = end;
186 INTDEF (dwfl_report_module)
189 /* Finish reporting the current set of modules to the library.
190 If REMOVED is not null, it's called for each module that
191 existed before but was not included in the current report.
192 Returns a nonzero return value from the callback.
193 DWFL cannot be used until this function has returned zero. */
195 dwfl_report_end (Dwfl *dwfl,
196 int (*removed) (Dwfl_Module *, void *,
197 const char *, Dwarf_Addr,
201 Dwfl_Module **tailp = &dwfl->modulelist;
202 while (*tailp != NULL)
204 Dwfl_Module *m = *tailp;
205 if (m->gc && removed != NULL)
207 int result = (*removed) (MODCB_ARGS (m), arg);
214 __libdwfl_module_free (m);
222 INTDEF (dwfl_report_end)