1*7304104dSAndroid Build Coastguard Worker /* Report a module to libdwfl based on ELF program headers.
2*7304104dSAndroid Build Coastguard Worker Copyright (C) 2005-2010 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker
5*7304104dSAndroid Build Coastguard Worker This file is free software; you can redistribute it and/or modify
6*7304104dSAndroid Build Coastguard Worker it under the terms of either
7*7304104dSAndroid Build Coastguard Worker
8*7304104dSAndroid Build Coastguard Worker * the GNU Lesser General Public License as published by the Free
9*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 3 of the License, or (at
10*7304104dSAndroid Build Coastguard Worker your option) any later version
11*7304104dSAndroid Build Coastguard Worker
12*7304104dSAndroid Build Coastguard Worker or
13*7304104dSAndroid Build Coastguard Worker
14*7304104dSAndroid Build Coastguard Worker * the GNU General Public License as published by the Free
15*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 2 of the License, or (at
16*7304104dSAndroid Build Coastguard Worker your option) any later version
17*7304104dSAndroid Build Coastguard Worker
18*7304104dSAndroid Build Coastguard Worker or both in parallel, as here.
19*7304104dSAndroid Build Coastguard Worker
20*7304104dSAndroid Build Coastguard Worker elfutils is distributed in the hope that it will be useful, but
21*7304104dSAndroid Build Coastguard Worker WITHOUT ANY WARRANTY; without even the implied warranty of
22*7304104dSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23*7304104dSAndroid Build Coastguard Worker General Public License for more details.
24*7304104dSAndroid Build Coastguard Worker
25*7304104dSAndroid Build Coastguard Worker You should have received copies of the GNU General Public License and
26*7304104dSAndroid Build Coastguard Worker the GNU Lesser General Public License along with this program. If
27*7304104dSAndroid Build Coastguard Worker not, see <http://www.gnu.org/licenses/>. */
28*7304104dSAndroid Build Coastguard Worker
29*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
30*7304104dSAndroid Build Coastguard Worker # include <config.h>
31*7304104dSAndroid Build Coastguard Worker #endif
32*7304104dSAndroid Build Coastguard Worker
33*7304104dSAndroid Build Coastguard Worker #include "libdwflP.h"
34*7304104dSAndroid Build Coastguard Worker #include <fcntl.h>
35*7304104dSAndroid Build Coastguard Worker
36*7304104dSAndroid Build Coastguard Worker /* We start every ET_REL module at a moderately aligned boundary.
37*7304104dSAndroid Build Coastguard Worker This keeps the low addresses easy to read compared to a layout
38*7304104dSAndroid Build Coastguard Worker starting at 0 (as when using -e). It also makes it unlikely
39*7304104dSAndroid Build Coastguard Worker that a middle section will have a larger alignment and require
40*7304104dSAndroid Build Coastguard Worker rejiggering (see below). */
41*7304104dSAndroid Build Coastguard Worker #define REL_MIN_ALIGN ((GElf_Xword) 0x100)
42*7304104dSAndroid Build Coastguard Worker
43*7304104dSAndroid Build Coastguard Worker bool
44*7304104dSAndroid Build Coastguard Worker internal_function
__libdwfl_elf_address_range(Elf * elf,GElf_Addr base,bool add_p_vaddr,bool sanity,GElf_Addr * vaddrp,GElf_Addr * address_syncp,GElf_Addr * startp,GElf_Addr * endp,GElf_Addr * biasp,GElf_Half * e_typep)45*7304104dSAndroid Build Coastguard Worker __libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
46*7304104dSAndroid Build Coastguard Worker bool sanity, GElf_Addr *vaddrp,
47*7304104dSAndroid Build Coastguard Worker GElf_Addr *address_syncp, GElf_Addr *startp,
48*7304104dSAndroid Build Coastguard Worker GElf_Addr *endp, GElf_Addr *biasp,
49*7304104dSAndroid Build Coastguard Worker GElf_Half *e_typep)
50*7304104dSAndroid Build Coastguard Worker {
51*7304104dSAndroid Build Coastguard Worker GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
52*7304104dSAndroid Build Coastguard Worker if (ehdr == NULL)
53*7304104dSAndroid Build Coastguard Worker {
54*7304104dSAndroid Build Coastguard Worker elf_error:
55*7304104dSAndroid Build Coastguard Worker __libdwfl_seterrno (DWFL_E_LIBELF);
56*7304104dSAndroid Build Coastguard Worker return false;
57*7304104dSAndroid Build Coastguard Worker }
58*7304104dSAndroid Build Coastguard Worker
59*7304104dSAndroid Build Coastguard Worker GElf_Addr vaddr = 0;
60*7304104dSAndroid Build Coastguard Worker GElf_Addr address_sync = 0;
61*7304104dSAndroid Build Coastguard Worker GElf_Addr start = 0, end = 0, bias = 0;
62*7304104dSAndroid Build Coastguard Worker switch (ehdr->e_type)
63*7304104dSAndroid Build Coastguard Worker {
64*7304104dSAndroid Build Coastguard Worker case ET_REL:
65*7304104dSAndroid Build Coastguard Worker /* For a relocatable object, we do an arbitrary section layout.
66*7304104dSAndroid Build Coastguard Worker By updating the section header in place, we leave the layout
67*7304104dSAndroid Build Coastguard Worker information to be found by relocation. */
68*7304104dSAndroid Build Coastguard Worker
69*7304104dSAndroid Build Coastguard Worker start = end = base = (base + REL_MIN_ALIGN - 1) & -REL_MIN_ALIGN;
70*7304104dSAndroid Build Coastguard Worker
71*7304104dSAndroid Build Coastguard Worker bool first = true;
72*7304104dSAndroid Build Coastguard Worker Elf_Scn *scn = NULL;
73*7304104dSAndroid Build Coastguard Worker while ((scn = elf_nextscn (elf, scn)) != NULL)
74*7304104dSAndroid Build Coastguard Worker {
75*7304104dSAndroid Build Coastguard Worker GElf_Shdr shdr_mem;
76*7304104dSAndroid Build Coastguard Worker GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
77*7304104dSAndroid Build Coastguard Worker if (unlikely (shdr == NULL))
78*7304104dSAndroid Build Coastguard Worker goto elf_error;
79*7304104dSAndroid Build Coastguard Worker
80*7304104dSAndroid Build Coastguard Worker if (shdr->sh_flags & SHF_ALLOC)
81*7304104dSAndroid Build Coastguard Worker {
82*7304104dSAndroid Build Coastguard Worker const GElf_Xword align = shdr->sh_addralign ?: 1;
83*7304104dSAndroid Build Coastguard Worker const GElf_Addr next = (end + align - 1) & -align;
84*7304104dSAndroid Build Coastguard Worker if (shdr->sh_addr == 0
85*7304104dSAndroid Build Coastguard Worker /* Once we've started doing layout we have to do it all,
86*7304104dSAndroid Build Coastguard Worker unless we just laid out the first section at 0 when
87*7304104dSAndroid Build Coastguard Worker it already was at 0. */
88*7304104dSAndroid Build Coastguard Worker || (bias == 0 && end > start && end != next))
89*7304104dSAndroid Build Coastguard Worker {
90*7304104dSAndroid Build Coastguard Worker shdr->sh_addr = next;
91*7304104dSAndroid Build Coastguard Worker if (end == base)
92*7304104dSAndroid Build Coastguard Worker /* This is the first section assigned a location.
93*7304104dSAndroid Build Coastguard Worker Use its aligned address as the module's base. */
94*7304104dSAndroid Build Coastguard Worker start = base = shdr->sh_addr;
95*7304104dSAndroid Build Coastguard Worker else if (unlikely (base & (align - 1)))
96*7304104dSAndroid Build Coastguard Worker {
97*7304104dSAndroid Build Coastguard Worker /* If BASE has less than the maximum alignment of
98*7304104dSAndroid Build Coastguard Worker any section, we eat more than the optimal amount
99*7304104dSAndroid Build Coastguard Worker of padding and so make the module's apparent
100*7304104dSAndroid Build Coastguard Worker size come out larger than it would when placed
101*7304104dSAndroid Build Coastguard Worker at zero. So reset the layout with a better base. */
102*7304104dSAndroid Build Coastguard Worker
103*7304104dSAndroid Build Coastguard Worker start = end = base = (base + align - 1) & -align;
104*7304104dSAndroid Build Coastguard Worker Elf_Scn *prev_scn = NULL;
105*7304104dSAndroid Build Coastguard Worker do
106*7304104dSAndroid Build Coastguard Worker {
107*7304104dSAndroid Build Coastguard Worker prev_scn = elf_nextscn (elf, prev_scn);
108*7304104dSAndroid Build Coastguard Worker GElf_Shdr prev_shdr_mem;
109*7304104dSAndroid Build Coastguard Worker GElf_Shdr *prev_shdr = gelf_getshdr (prev_scn,
110*7304104dSAndroid Build Coastguard Worker &prev_shdr_mem);
111*7304104dSAndroid Build Coastguard Worker if (unlikely (prev_shdr == NULL))
112*7304104dSAndroid Build Coastguard Worker goto elf_error;
113*7304104dSAndroid Build Coastguard Worker if (prev_shdr->sh_flags & SHF_ALLOC)
114*7304104dSAndroid Build Coastguard Worker {
115*7304104dSAndroid Build Coastguard Worker const GElf_Xword prev_align
116*7304104dSAndroid Build Coastguard Worker = prev_shdr->sh_addralign ?: 1;
117*7304104dSAndroid Build Coastguard Worker
118*7304104dSAndroid Build Coastguard Worker prev_shdr->sh_addr
119*7304104dSAndroid Build Coastguard Worker = (end + prev_align - 1) & -prev_align;
120*7304104dSAndroid Build Coastguard Worker end = prev_shdr->sh_addr + prev_shdr->sh_size;
121*7304104dSAndroid Build Coastguard Worker
122*7304104dSAndroid Build Coastguard Worker if (unlikely (! gelf_update_shdr (prev_scn,
123*7304104dSAndroid Build Coastguard Worker prev_shdr)))
124*7304104dSAndroid Build Coastguard Worker goto elf_error;
125*7304104dSAndroid Build Coastguard Worker }
126*7304104dSAndroid Build Coastguard Worker }
127*7304104dSAndroid Build Coastguard Worker while (prev_scn != scn);
128*7304104dSAndroid Build Coastguard Worker continue;
129*7304104dSAndroid Build Coastguard Worker }
130*7304104dSAndroid Build Coastguard Worker
131*7304104dSAndroid Build Coastguard Worker end = shdr->sh_addr + shdr->sh_size;
132*7304104dSAndroid Build Coastguard Worker if (likely (shdr->sh_addr != 0)
133*7304104dSAndroid Build Coastguard Worker && unlikely (! gelf_update_shdr (scn, shdr)))
134*7304104dSAndroid Build Coastguard Worker goto elf_error;
135*7304104dSAndroid Build Coastguard Worker }
136*7304104dSAndroid Build Coastguard Worker else
137*7304104dSAndroid Build Coastguard Worker {
138*7304104dSAndroid Build Coastguard Worker /* The address is already assigned. Just track it. */
139*7304104dSAndroid Build Coastguard Worker if (first || end < shdr->sh_addr + shdr->sh_size)
140*7304104dSAndroid Build Coastguard Worker end = shdr->sh_addr + shdr->sh_size;
141*7304104dSAndroid Build Coastguard Worker if (first || bias > shdr->sh_addr)
142*7304104dSAndroid Build Coastguard Worker /* This is the lowest address in the module. */
143*7304104dSAndroid Build Coastguard Worker bias = shdr->sh_addr;
144*7304104dSAndroid Build Coastguard Worker
145*7304104dSAndroid Build Coastguard Worker if ((shdr->sh_addr - bias + base) & (align - 1))
146*7304104dSAndroid Build Coastguard Worker /* This section winds up misaligned using BASE.
147*7304104dSAndroid Build Coastguard Worker Adjust BASE upwards to make it congruent to
148*7304104dSAndroid Build Coastguard Worker the lowest section address in the file modulo ALIGN. */
149*7304104dSAndroid Build Coastguard Worker base = (((base + align - 1) & -align)
150*7304104dSAndroid Build Coastguard Worker + (bias & (align - 1)));
151*7304104dSAndroid Build Coastguard Worker }
152*7304104dSAndroid Build Coastguard Worker
153*7304104dSAndroid Build Coastguard Worker first = false;
154*7304104dSAndroid Build Coastguard Worker }
155*7304104dSAndroid Build Coastguard Worker }
156*7304104dSAndroid Build Coastguard Worker
157*7304104dSAndroid Build Coastguard Worker if (bias != 0)
158*7304104dSAndroid Build Coastguard Worker {
159*7304104dSAndroid Build Coastguard Worker /* The section headers had nonzero sh_addr values. The layout
160*7304104dSAndroid Build Coastguard Worker was already done. We've just collected the total span.
161*7304104dSAndroid Build Coastguard Worker Now just compute the bias from the requested base. */
162*7304104dSAndroid Build Coastguard Worker start = base;
163*7304104dSAndroid Build Coastguard Worker end = end - bias + start;
164*7304104dSAndroid Build Coastguard Worker bias = start - bias;
165*7304104dSAndroid Build Coastguard Worker }
166*7304104dSAndroid Build Coastguard Worker break;
167*7304104dSAndroid Build Coastguard Worker
168*7304104dSAndroid Build Coastguard Worker /* Everything else has to have program headers. */
169*7304104dSAndroid Build Coastguard Worker
170*7304104dSAndroid Build Coastguard Worker case ET_EXEC:
171*7304104dSAndroid Build Coastguard Worker case ET_CORE:
172*7304104dSAndroid Build Coastguard Worker /* An assigned base address is meaningless for these. */
173*7304104dSAndroid Build Coastguard Worker base = 0;
174*7304104dSAndroid Build Coastguard Worker add_p_vaddr = true;
175*7304104dSAndroid Build Coastguard Worker FALLTHROUGH;
176*7304104dSAndroid Build Coastguard Worker case ET_DYN:
177*7304104dSAndroid Build Coastguard Worker default:;
178*7304104dSAndroid Build Coastguard Worker size_t phnum;
179*7304104dSAndroid Build Coastguard Worker if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
180*7304104dSAndroid Build Coastguard Worker goto elf_error;
181*7304104dSAndroid Build Coastguard Worker for (size_t i = 0; i < phnum; ++i)
182*7304104dSAndroid Build Coastguard Worker {
183*7304104dSAndroid Build Coastguard Worker GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
184*7304104dSAndroid Build Coastguard Worker if (unlikely (ph == NULL))
185*7304104dSAndroid Build Coastguard Worker goto elf_error;
186*7304104dSAndroid Build Coastguard Worker if (ph->p_type == PT_LOAD)
187*7304104dSAndroid Build Coastguard Worker {
188*7304104dSAndroid Build Coastguard Worker vaddr = ph->p_vaddr & -ph->p_align;
189*7304104dSAndroid Build Coastguard Worker address_sync = ph->p_vaddr + ph->p_memsz;
190*7304104dSAndroid Build Coastguard Worker break;
191*7304104dSAndroid Build Coastguard Worker }
192*7304104dSAndroid Build Coastguard Worker }
193*7304104dSAndroid Build Coastguard Worker if (add_p_vaddr)
194*7304104dSAndroid Build Coastguard Worker {
195*7304104dSAndroid Build Coastguard Worker start = base + vaddr;
196*7304104dSAndroid Build Coastguard Worker bias = base;
197*7304104dSAndroid Build Coastguard Worker }
198*7304104dSAndroid Build Coastguard Worker else
199*7304104dSAndroid Build Coastguard Worker {
200*7304104dSAndroid Build Coastguard Worker start = base;
201*7304104dSAndroid Build Coastguard Worker bias = base - vaddr;
202*7304104dSAndroid Build Coastguard Worker }
203*7304104dSAndroid Build Coastguard Worker
204*7304104dSAndroid Build Coastguard Worker for (size_t i = phnum; i-- > 0;)
205*7304104dSAndroid Build Coastguard Worker {
206*7304104dSAndroid Build Coastguard Worker GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
207*7304104dSAndroid Build Coastguard Worker if (unlikely (ph == NULL))
208*7304104dSAndroid Build Coastguard Worker goto elf_error;
209*7304104dSAndroid Build Coastguard Worker if (ph->p_type == PT_LOAD
210*7304104dSAndroid Build Coastguard Worker && ph->p_vaddr + ph->p_memsz > 0)
211*7304104dSAndroid Build Coastguard Worker {
212*7304104dSAndroid Build Coastguard Worker end = bias + (ph->p_vaddr + ph->p_memsz);
213*7304104dSAndroid Build Coastguard Worker break;
214*7304104dSAndroid Build Coastguard Worker }
215*7304104dSAndroid Build Coastguard Worker }
216*7304104dSAndroid Build Coastguard Worker
217*7304104dSAndroid Build Coastguard Worker if (end == 0 && sanity)
218*7304104dSAndroid Build Coastguard Worker {
219*7304104dSAndroid Build Coastguard Worker __libdwfl_seterrno (DWFL_E_NO_PHDR);
220*7304104dSAndroid Build Coastguard Worker return false;
221*7304104dSAndroid Build Coastguard Worker }
222*7304104dSAndroid Build Coastguard Worker break;
223*7304104dSAndroid Build Coastguard Worker }
224*7304104dSAndroid Build Coastguard Worker if (vaddrp)
225*7304104dSAndroid Build Coastguard Worker *vaddrp = vaddr;
226*7304104dSAndroid Build Coastguard Worker if (address_syncp)
227*7304104dSAndroid Build Coastguard Worker *address_syncp = address_sync;
228*7304104dSAndroid Build Coastguard Worker if (startp)
229*7304104dSAndroid Build Coastguard Worker *startp = start;
230*7304104dSAndroid Build Coastguard Worker if (endp)
231*7304104dSAndroid Build Coastguard Worker *endp = end;
232*7304104dSAndroid Build Coastguard Worker if (biasp)
233*7304104dSAndroid Build Coastguard Worker *biasp = bias;
234*7304104dSAndroid Build Coastguard Worker if (e_typep)
235*7304104dSAndroid Build Coastguard Worker *e_typep = ehdr->e_type;
236*7304104dSAndroid Build Coastguard Worker return true;
237*7304104dSAndroid Build Coastguard Worker }
238*7304104dSAndroid Build Coastguard Worker
239*7304104dSAndroid Build Coastguard Worker Dwfl_Module *
240*7304104dSAndroid Build Coastguard Worker internal_function
__libdwfl_report_elf(Dwfl * dwfl,const char * name,const char * file_name,int fd,Elf * elf,GElf_Addr base,bool add_p_vaddr,bool sanity)241*7304104dSAndroid Build Coastguard Worker __libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
242*7304104dSAndroid Build Coastguard Worker int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr,
243*7304104dSAndroid Build Coastguard Worker bool sanity)
244*7304104dSAndroid Build Coastguard Worker {
245*7304104dSAndroid Build Coastguard Worker GElf_Addr vaddr, address_sync, start, end, bias;
246*7304104dSAndroid Build Coastguard Worker GElf_Half e_type;
247*7304104dSAndroid Build Coastguard Worker if (! __libdwfl_elf_address_range (elf, base, add_p_vaddr, sanity, &vaddr,
248*7304104dSAndroid Build Coastguard Worker &address_sync, &start, &end, &bias,
249*7304104dSAndroid Build Coastguard Worker &e_type))
250*7304104dSAndroid Build Coastguard Worker return NULL;
251*7304104dSAndroid Build Coastguard Worker Dwfl_Module *m = INTUSE(dwfl_report_module) (dwfl, name, start, end);
252*7304104dSAndroid Build Coastguard Worker if (m != NULL)
253*7304104dSAndroid Build Coastguard Worker {
254*7304104dSAndroid Build Coastguard Worker if (m->main.name == NULL)
255*7304104dSAndroid Build Coastguard Worker {
256*7304104dSAndroid Build Coastguard Worker m->main.name = strdup (file_name);
257*7304104dSAndroid Build Coastguard Worker m->main.fd = fd;
258*7304104dSAndroid Build Coastguard Worker }
259*7304104dSAndroid Build Coastguard Worker else if ((fd >= 0 && m->main.fd != fd)
260*7304104dSAndroid Build Coastguard Worker || strcmp (m->main.name, file_name))
261*7304104dSAndroid Build Coastguard Worker {
262*7304104dSAndroid Build Coastguard Worker overlap:
263*7304104dSAndroid Build Coastguard Worker m->gc = true;
264*7304104dSAndroid Build Coastguard Worker __libdwfl_seterrno (DWFL_E_OVERLAP);
265*7304104dSAndroid Build Coastguard Worker return NULL;
266*7304104dSAndroid Build Coastguard Worker }
267*7304104dSAndroid Build Coastguard Worker
268*7304104dSAndroid Build Coastguard Worker /* Preinstall the open ELF handle for the module. */
269*7304104dSAndroid Build Coastguard Worker if (m->main.elf == NULL)
270*7304104dSAndroid Build Coastguard Worker {
271*7304104dSAndroid Build Coastguard Worker m->main.elf = elf;
272*7304104dSAndroid Build Coastguard Worker m->main.vaddr = vaddr;
273*7304104dSAndroid Build Coastguard Worker m->main.address_sync = address_sync;
274*7304104dSAndroid Build Coastguard Worker m->main_bias = bias;
275*7304104dSAndroid Build Coastguard Worker m->e_type = e_type;
276*7304104dSAndroid Build Coastguard Worker }
277*7304104dSAndroid Build Coastguard Worker else
278*7304104dSAndroid Build Coastguard Worker {
279*7304104dSAndroid Build Coastguard Worker if (m->main_bias != bias
280*7304104dSAndroid Build Coastguard Worker || m->main.vaddr != vaddr || m->main.address_sync != address_sync)
281*7304104dSAndroid Build Coastguard Worker goto overlap;
282*7304104dSAndroid Build Coastguard Worker elf_end (m->main.elf);
283*7304104dSAndroid Build Coastguard Worker m->main.elf = elf;
284*7304104dSAndroid Build Coastguard Worker }
285*7304104dSAndroid Build Coastguard Worker }
286*7304104dSAndroid Build Coastguard Worker return m;
287*7304104dSAndroid Build Coastguard Worker }
288*7304104dSAndroid Build Coastguard Worker
289*7304104dSAndroid Build Coastguard Worker NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
290*7304104dSAndroid Build Coastguard Worker Dwfl_Module *
dwfl_report_elf(Dwfl * dwfl,const char * name,const char * file_name,int fd,GElf_Addr base,bool add_p_vaddr)291*7304104dSAndroid Build Coastguard Worker dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
292*7304104dSAndroid Build Coastguard Worker GElf_Addr base, bool add_p_vaddr)
293*7304104dSAndroid Build Coastguard Worker {
294*7304104dSAndroid Build Coastguard Worker bool closefd = false;
295*7304104dSAndroid Build Coastguard Worker if (fd < 0)
296*7304104dSAndroid Build Coastguard Worker {
297*7304104dSAndroid Build Coastguard Worker closefd = true;
298*7304104dSAndroid Build Coastguard Worker fd = open (file_name, O_RDONLY);
299*7304104dSAndroid Build Coastguard Worker if (fd < 0)
300*7304104dSAndroid Build Coastguard Worker {
301*7304104dSAndroid Build Coastguard Worker __libdwfl_seterrno (DWFL_E_ERRNO);
302*7304104dSAndroid Build Coastguard Worker return NULL;
303*7304104dSAndroid Build Coastguard Worker }
304*7304104dSAndroid Build Coastguard Worker }
305*7304104dSAndroid Build Coastguard Worker
306*7304104dSAndroid Build Coastguard Worker Elf *elf;
307*7304104dSAndroid Build Coastguard Worker Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, false);
308*7304104dSAndroid Build Coastguard Worker if (error != DWFL_E_NOERROR)
309*7304104dSAndroid Build Coastguard Worker {
310*7304104dSAndroid Build Coastguard Worker __libdwfl_seterrno (error);
311*7304104dSAndroid Build Coastguard Worker return NULL;
312*7304104dSAndroid Build Coastguard Worker }
313*7304104dSAndroid Build Coastguard Worker
314*7304104dSAndroid Build Coastguard Worker Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name,
315*7304104dSAndroid Build Coastguard Worker fd, elf, base, add_p_vaddr, true);
316*7304104dSAndroid Build Coastguard Worker if (mod == NULL)
317*7304104dSAndroid Build Coastguard Worker {
318*7304104dSAndroid Build Coastguard Worker elf_end (elf);
319*7304104dSAndroid Build Coastguard Worker if (closefd)
320*7304104dSAndroid Build Coastguard Worker close (fd);
321*7304104dSAndroid Build Coastguard Worker }
322*7304104dSAndroid Build Coastguard Worker
323*7304104dSAndroid Build Coastguard Worker return mod;
324*7304104dSAndroid Build Coastguard Worker }
325*7304104dSAndroid Build Coastguard Worker NEW_INTDEF (dwfl_report_elf)
326*7304104dSAndroid Build Coastguard Worker
327*7304104dSAndroid Build Coastguard Worker #ifdef SYMBOL_VERSIONING
328*7304104dSAndroid Build Coastguard Worker Dwfl_Module *
329*7304104dSAndroid Build Coastguard Worker _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
330*7304104dSAndroid Build Coastguard Worker const char *file_name, int fd,
331*7304104dSAndroid Build Coastguard Worker GElf_Addr base);
332*7304104dSAndroid Build Coastguard Worker COMPAT_VERSION_NEWPROTO (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr)
333*7304104dSAndroid Build Coastguard Worker
334*7304104dSAndroid Build Coastguard Worker Dwfl_Module *
_compat_without_add_p_vaddr_dwfl_report_elf(Dwfl * dwfl,const char * name,const char * file_name,int fd,GElf_Addr base)335*7304104dSAndroid Build Coastguard Worker _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
336*7304104dSAndroid Build Coastguard Worker const char *file_name, int fd,
337*7304104dSAndroid Build Coastguard Worker GElf_Addr base)
338*7304104dSAndroid Build Coastguard Worker {
339*7304104dSAndroid Build Coastguard Worker return dwfl_report_elf (dwfl, name, file_name, fd, base, true);
340*7304104dSAndroid Build Coastguard Worker }
341*7304104dSAndroid Build Coastguard Worker #endif
342