blob: 7259984104a0b2e28f80ac314f5c2c65084c9975 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Find debugging and symbol information for a module in libdwfl.
Josh Stone65cefbd2014-03-11 10:19:28 -07002 Copyright (C) 2005-2012, 2014 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004
Mark Wielaardde2ed972012-06-05 17:15:16 +02005 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00007
Mark Wielaardde2ed972012-06-05 17:15:16 +02008 * 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
11
12 or
13
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
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
Ulrich Drepper361df7d2006-04-04 21:38:57 +000021 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.
24
Mark Wielaardde2ed972012-06-05 17:15:16 +020025 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/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000028
29#include "libdwflP.h"
Florian Weimer920f03d2014-04-15 17:11:17 +020030#include <inttypes.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000031#include <fcntl.h>
32#include <string.h>
Roland McGrathd17fac72005-08-23 08:20:21 +000033#include <unistd.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000034#include "../libdw/libdwP.h" /* DWARF_E_* values are here. */
Mark Wielaard5083a702013-01-16 15:19:32 +010035#include "../libelf/libelfP.h"
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000036
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000037static inline Dwfl_Error
Mark Wielaarddf85bf92014-05-01 14:48:27 +020038open_elf_file (Elf **elf, int *fd, char **name)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000039{
Mark Wielaarddf85bf92014-05-01 14:48:27 +020040 if (*elf == NULL)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000041 {
Roland McGrathe07da4f2011-03-08 16:26:02 -080042 /* CBFAIL uses errno if it's set, so clear it first in case we don't
43 set it with an open failure below. */
44 errno = 0;
45
Roland McGrath059c83e2008-02-21 06:19:39 +000046 /* If there was a pre-primed file name left that the callback left
47 behind, try to open that file name. */
Mark Wielaarddf85bf92014-05-01 14:48:27 +020048 if (*fd < 0 && *name != NULL)
49 *fd = TEMP_FAILURE_RETRY (open64 (*name, O_RDONLY));
Roland McGrath059c83e2008-02-21 06:19:39 +000050
Mark Wielaarddf85bf92014-05-01 14:48:27 +020051 if (*fd < 0)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000052 return CBFAIL;
53
Mark Wielaarddf85bf92014-05-01 14:48:27 +020054 return __libdw_open_file (fd, elf, true, false);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000055 }
Mark Wielaarddf85bf92014-05-01 14:48:27 +020056 else if (unlikely (elf_kind (*elf) != ELF_K_ELF))
Roland McGrath122f3882008-08-26 07:20:29 +000057 {
Mark Wielaarddf85bf92014-05-01 14:48:27 +020058 elf_end (*elf);
59 *elf = NULL;
60 close (*fd);
61 *fd = -1;
Roland McGrath122f3882008-08-26 07:20:29 +000062 return DWFL_E_BADELF;
63 }
64
Mark Wielaarddf85bf92014-05-01 14:48:27 +020065 /* Elf file already open and looks fine. */
66 return DWFL_E_NOERROR;
67}
68
69/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD.
70 When we return success, FILE->elf and FILE->vaddr are set up. */
71static inline Dwfl_Error
72open_elf (Dwfl_Module *mod, struct dwfl_file *file)
73{
74 Dwfl_Error error = open_elf_file (&file->elf, &file->fd, &file->name);
75 if (error != DWFL_E_NOERROR)
76 return error;
77
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000078 GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
79 if (ehdr == NULL)
Ulrich Drepper6258e742007-03-13 06:22:40 +000080 {
81 elf_error:
Roland McGrathed431dd2010-05-06 00:52:51 -070082 elf_end (file->elf);
83 file->elf = NULL;
Ulrich Drepper6258e742007-03-13 06:22:40 +000084 close (file->fd);
85 file->fd = -1;
Roland McGrath122f3882008-08-26 07:20:29 +000086 return DWFL_E (LIBELF, elf_errno ());
Ulrich Drepper6258e742007-03-13 06:22:40 +000087 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000088
Josh Stone65cefbd2014-03-11 10:19:28 -070089 if (ehdr->e_type != ET_REL)
Roland McGrathf95760a2010-01-07 20:24:34 -080090 {
Roland McGrath2c7d0dd2011-01-04 19:29:53 -080091 /* In any non-ET_REL file, we compute the "synchronization address".
92
93 We start with the address at the end of the first PT_LOAD
94 segment. When prelink converts REL to RELA in an ET_DYN
95 file, it expands the space between the beginning of the
96 segment and the actual code/data addresses. Since that
97 change wasn't made in the debug file, the distance from
98 p_vaddr to an address of interest (in an st_value or DWARF
99 data) now differs between the main and debug files. The
100 distance from address_sync to an address of interest remains
101 consistent.
102
103 If there are no section headers at all (full stripping), then
104 the end of the first segment is a valid synchronization address.
105 This cannot happen in a prelinked file, since prelink itself
106 relies on section headers for prelinking and for undoing it.
107 (If you do full stripping on a prelinked file, then you get what
108 you deserve--you can neither undo the prelinking, nor expect to
109 line it up with a debug file separated before prelinking.)
110
111 However, when prelink processes an ET_EXEC file, it can do
112 something different. There it juggles the "special" sections
113 (SHT_DYNSYM et al) to make space for the additional prelink
114 special sections. Sometimes it will do this by moving a special
Roland McGrath5ad466d2011-01-11 10:17:01 -0800115 section like .dynstr after the real program sections in the first
116 PT_LOAD segment--i.e. to the end. That changes the end address of
117 the segment, so it no longer lines up correctly and is not a valid
118 synchronization address to use. Because of this, we need to apply
119 a different prelink-savvy means to discover the synchronization
120 address when there is a separate debug file and a prelinked main
121 file. That is done in find_debuginfo, below. */
Roland McGrath2c7d0dd2011-01-04 19:29:53 -0800122
Roland McGrathf95760a2010-01-07 20:24:34 -0800123 size_t phnum;
124 if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0))
125 goto elf_error;
126
Roland McGrath1743d7f2010-11-12 16:46:47 -0800127 file->vaddr = file->address_sync = 0;
Roland McGrathf95760a2010-01-07 20:24:34 -0800128 for (size_t i = 0; i < phnum; ++i)
129 {
130 GElf_Phdr ph_mem;
131 GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
Roland McGrath1743d7f2010-11-12 16:46:47 -0800132 if (unlikely (ph == NULL))
Roland McGrathf95760a2010-01-07 20:24:34 -0800133 goto elf_error;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800134 if (ph->p_type == PT_LOAD)
Roland McGrathf95760a2010-01-07 20:24:34 -0800135 {
Roland McGrath5ad466d2011-01-11 10:17:01 -0800136 file->vaddr = ph->p_vaddr & -ph->p_align;
137 file->address_sync = ph->p_vaddr + ph->p_memsz;
Roland McGrathf95760a2010-01-07 20:24:34 -0800138 break;
139 }
140 }
141 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000142
Josh Stone65cefbd2014-03-11 10:19:28 -0700143 /* We only want to set the module e_type explictly once, derived from
144 the main ELF file. (It might be changed for the kernel, because
145 that is special - see below.) open_elf is always called first for
146 the main ELF file, because both find_dw and find_symtab call
147 __libdwfl_getelf first to open the main file. So don't let debug
148 or aux files override the module e_type. The kernel heuristic
149 below could otherwise trigger for non-kernel/non-main files, since
150 their phdrs might not match the actual load addresses. */
151 if (file == &mod->main)
152 {
153 mod->e_type = ehdr->e_type;
Ulrich Drepper6258e742007-03-13 06:22:40 +0000154
Josh Stone65cefbd2014-03-11 10:19:28 -0700155 /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN. */
156 if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr)
157 mod->e_type = ET_DYN;
158 }
159 else
160 assert (mod->main.elf != NULL);
Ulrich Drepper6258e742007-03-13 06:22:40 +0000161
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000162 return DWFL_E_NOERROR;
163}
164
Jan Kratochvil3fdcdcb2012-10-17 21:49:10 +0200165/* We have an authoritative build ID for this module MOD, so don't use
166 a file by name that doesn't match that ID. */
167static void
168mod_verify_build_id (Dwfl_Module *mod)
169{
170 assert (mod->build_id_len > 0);
171
172 switch (__builtin_expect (__libdwfl_find_build_id (mod, false,
173 mod->main.elf), 2))
174 {
175 case 2:
176 /* Build ID matches as it should. */
177 return;
178
179 case -1: /* ELF error. */
180 mod->elferr = INTUSE(dwfl_errno) ();
181 break;
182
183 case 0: /* File has no build ID note. */
184 case 1: /* FIle has a build ID that does not match. */
185 mod->elferr = DWFL_E_WRONG_ID_ELF;
186 break;
187
188 default:
189 abort ();
190 }
191
192 /* We get here when it was the right ELF file. Clear it out. */
193 elf_end (mod->main.elf);
194 mod->main.elf = NULL;
195 if (mod->main.fd >= 0)
196 {
197 close (mod->main.fd);
198 mod->main.fd = -1;
199 }
200}
201
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000202/* Find the main ELF file for this module and open libelf on it.
203 When we return success, MOD->main.elf and MOD->main.bias are set up. */
Roland McGratha605a3c2009-04-19 18:27:01 -0700204void
Roland McGrath10361572009-04-20 11:50:50 -0700205internal_function
Roland McGratha605a3c2009-04-19 18:27:01 -0700206__libdwfl_getelf (Dwfl_Module *mod)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000207{
208 if (mod->main.elf != NULL /* Already done. */
209 || mod->elferr != DWFL_E_NOERROR) /* Cached failure. */
210 return;
211
212 mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod),
213 &mod->main.name,
214 &mod->main.elf);
Roland McGrathed431dd2010-05-06 00:52:51 -0700215 const bool fallback = mod->main.elf == NULL && mod->main.fd < 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000216 mod->elferr = open_elf (mod, &mod->main);
Roland McGrathed431dd2010-05-06 00:52:51 -0700217 if (mod->elferr != DWFL_E_NOERROR)
218 return;
Roland McGrath59ea7f32007-10-04 08:50:09 +0000219
Roland McGrathed431dd2010-05-06 00:52:51 -0700220 if (!mod->main.valid)
Roland McGrath59ea7f32007-10-04 08:50:09 +0000221 {
222 /* Clear any explicitly reported build ID, just in case it was wrong.
223 We'll fetch it from the file when asked. */
Roland McGrathbfc01702008-04-06 01:57:32 +0000224 free (mod->build_id_bits);
225 mod->build_id_bits = NULL;
Roland McGrath59ea7f32007-10-04 08:50:09 +0000226 mod->build_id_len = 0;
227 }
Roland McGrathed431dd2010-05-06 00:52:51 -0700228 else if (fallback)
Jan Kratochvil3fdcdcb2012-10-17 21:49:10 +0200229 mod_verify_build_id (mod);
Roland McGrath1743d7f2010-11-12 16:46:47 -0800230
231 mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000232}
233
Roland McGrath5ad466d2011-01-11 10:17:01 -0800234/* If the main file might have been prelinked, then we need to
235 discover the correct synchronization address between the main and
236 debug files. Because of prelink's section juggling, we cannot rely
237 on the address_sync computed from PT_LOAD segments (see open_elf).
238
239 We will attempt to discover a synchronization address based on the
240 section headers instead. But finding a section address that is
241 safe to use requires identifying which sections are SHT_PROGBITS.
242 We can do that in the main file, but in the debug file all the
243 allocated sections have been transformed into SHT_NOBITS so we have
244 lost the means to match them up correctly.
245
246 The only method left to us is to decode the .gnu.prelink_undo
247 section in the prelinked main file. This shows what the sections
248 looked like before prelink juggled them--when they still had a
249 direct correspondence to the debug file. */
250static Dwfl_Error
Mark Wielaard5083a702013-01-16 15:19:32 +0100251find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
Roland McGrath5ad466d2011-01-11 10:17:01 -0800252{
253 /* The magic section is only identified by name. */
254 size_t shstrndx;
255 if (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0)
256 return DWFL_E_LIBELF;
257
258 Elf_Scn *scn = NULL;
259 while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
260 {
261 GElf_Shdr shdr_mem;
262 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
263 if (unlikely (shdr == NULL))
264 return DWFL_E_LIBELF;
265 if (shdr->sh_type == SHT_PROGBITS
266 && !(shdr->sh_flags & SHF_ALLOC)
267 && shdr->sh_name != 0)
268 {
269 const char *secname = elf_strptr (mod->main.elf, shstrndx,
270 shdr->sh_name);
271 if (unlikely (secname == NULL))
272 return DWFL_E_LIBELF;
273 if (!strcmp (secname, ".gnu.prelink_undo"))
274 break;
275 }
276 }
277
278 if (scn == NULL)
279 /* There was no .gnu.prelink_undo section. */
280 return DWFL_E_NOERROR;
281
282 Elf_Data *undodata = elf_rawdata (scn, NULL);
283 if (unlikely (undodata == NULL))
284 return DWFL_E_LIBELF;
285
286 /* Decode the section. It consists of the original ehdr, phdrs,
287 and shdrs (but omits section 0). */
288
289 union
290 {
291 Elf32_Ehdr e32;
292 Elf64_Ehdr e64;
293 } ehdr;
294 Elf_Data dst =
295 {
296 .d_buf = &ehdr,
297 .d_size = sizeof ehdr,
298 .d_type = ELF_T_EHDR,
299 .d_version = EV_CURRENT
300 };
301 Elf_Data src = *undodata;
302 src.d_size = gelf_fsize (mod->main.elf, ELF_T_EHDR, 1, EV_CURRENT);
303 src.d_type = ELF_T_EHDR;
304 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
305 elf_getident (mod->main.elf, NULL)[EI_DATA])
306 == NULL))
307 return DWFL_E_LIBELF;
308
309 size_t shentsize = gelf_fsize (mod->main.elf, ELF_T_SHDR, 1, EV_CURRENT);
310 size_t phentsize = gelf_fsize (mod->main.elf, ELF_T_PHDR, 1, EV_CURRENT);
311
312 uint_fast16_t phnum;
313 uint_fast16_t shnum;
314 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
315 {
316 if (ehdr.e32.e_shentsize != shentsize
317 || ehdr.e32.e_phentsize != phentsize)
318 return DWFL_E_BAD_PRELINK;
319 phnum = ehdr.e32.e_phnum;
320 shnum = ehdr.e32.e_shnum;
321 }
322 else
323 {
324 if (ehdr.e64.e_shentsize != shentsize
325 || ehdr.e64.e_phentsize != phentsize)
326 return DWFL_E_BAD_PRELINK;
327 phnum = ehdr.e64.e_phnum;
328 shnum = ehdr.e64.e_shnum;
329 }
330
331 /* Since prelink does not store the zeroth section header in the undo
332 section, it cannot support SHN_XINDEX encoding. */
333 if (unlikely (shnum >= SHN_LORESERVE)
334 || unlikely (undodata->d_size != (src.d_size
335 + phnum * phentsize
336 + (shnum - 1) * shentsize)))
337 return DWFL_E_BAD_PRELINK;
338
339 /* We look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections. (Most
340 every file will have some SHT_PROGBITS sections, but it's possible to
341 have one with nothing but .bss, i.e. SHT_NOBITS.) The special sections
342 that can be moved around have different sh_type values--except for
343 .interp, the section that became the PT_INTERP segment. So we exclude
344 the SHT_PROGBITS section whose address matches the PT_INTERP p_vaddr.
345 For this reason, we must examine the phdrs first to find PT_INTERP. */
346
Roland McGrath0ef40202011-02-01 16:58:32 -0800347 GElf_Addr main_interp = 0;
348 {
349 size_t main_phnum;
350 if (unlikely (elf_getphdrnum (mod->main.elf, &main_phnum)))
351 return DWFL_E_LIBELF;
352 for (size_t i = 0; i < main_phnum; ++i)
353 {
354 GElf_Phdr phdr;
355 if (unlikely (gelf_getphdr (mod->main.elf, i, &phdr) == NULL))
356 return DWFL_E_LIBELF;
357 if (phdr.p_type == PT_INTERP)
358 {
359 main_interp = phdr.p_vaddr;
360 break;
361 }
362 }
363 }
364
Roland McGrath5ad466d2011-01-11 10:17:01 -0800365 src.d_buf += src.d_size;
366 src.d_type = ELF_T_PHDR;
367 src.d_size = phnum * phentsize;
368
Roland McGrath0ef40202011-02-01 16:58:32 -0800369 GElf_Addr undo_interp = 0;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800370 {
371 union
372 {
373 Elf32_Phdr p32[phnum];
374 Elf64_Phdr p64[phnum];
375 } phdr;
376 dst.d_buf = &phdr;
377 dst.d_size = sizeof phdr;
378 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
379 ehdr.e32.e_ident[EI_DATA]) == NULL))
380 return DWFL_E_LIBELF;
381 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
382 {
383 for (uint_fast16_t i = 0; i < phnum; ++i)
384 if (phdr.p32[i].p_type == PT_INTERP)
385 {
Roland McGrath0ef40202011-02-01 16:58:32 -0800386 undo_interp = phdr.p32[i].p_vaddr;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800387 break;
388 }
389 }
390 else
391 {
392 for (uint_fast16_t i = 0; i < phnum; ++i)
Roland McGrath9fdd4612011-02-01 16:09:43 -0800393 if (phdr.p64[i].p_type == PT_INTERP)
Roland McGrath5ad466d2011-01-11 10:17:01 -0800394 {
Roland McGrath0ef40202011-02-01 16:58:32 -0800395 undo_interp = phdr.p64[i].p_vaddr;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800396 break;
397 }
398 }
399 }
400
Roland McGrath0ef40202011-02-01 16:58:32 -0800401 if (unlikely ((main_interp == 0) != (undo_interp == 0)))
402 return DWFL_E_BAD_PRELINK;
403
Roland McGrath5ad466d2011-01-11 10:17:01 -0800404 src.d_buf += src.d_size;
405 src.d_type = ELF_T_SHDR;
406 src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum - 1, EV_CURRENT);
407
408 union
409 {
410 Elf32_Shdr s32[shnum - 1];
411 Elf64_Shdr s64[shnum - 1];
412 } shdr;
413 dst.d_buf = &shdr;
414 dst.d_size = sizeof shdr;
415 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
416 ehdr.e32.e_ident[EI_DATA]) == NULL))
417 return DWFL_E_LIBELF;
418
419 /* Now we can look at the original section headers of the main file
420 before it was prelinked. First we'll apply our method to the main
421 file sections as they are after prelinking, to calculate the
422 synchronization address of the main file. Then we'll apply that
423 same method to the saved section headers, to calculate the matching
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800424 synchronization address of the debug file.
425
426 The method is to consider SHF_ALLOC sections that are either
427 SHT_PROGBITS or SHT_NOBITS, excluding the section whose sh_addr
428 matches the PT_INTERP p_vaddr. The special sections that can be
429 moved by prelink have other types, except for .interp (which
430 becomes PT_INTERP). The "real" sections cannot move as such, but
431 .bss can be split into .dynbss and .bss, with the total memory
432 image remaining the same but being spread across the two sections.
433 So we consider the highest section end, which still matches up. */
Roland McGrath5ad466d2011-01-11 10:17:01 -0800434
435 GElf_Addr highest;
436
Roland McGrath0ef40202011-02-01 16:58:32 -0800437 inline void consider_shdr (GElf_Addr interp,
438 GElf_Word sh_type,
Roland McGrath5ad466d2011-01-11 10:17:01 -0800439 GElf_Xword sh_flags,
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800440 GElf_Addr sh_addr,
441 GElf_Xword sh_size)
Roland McGrath5ad466d2011-01-11 10:17:01 -0800442 {
443 if ((sh_flags & SHF_ALLOC)
444 && ((sh_type == SHT_PROGBITS && sh_addr != interp)
445 || sh_type == SHT_NOBITS))
446 {
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800447 const GElf_Addr sh_end = sh_addr + sh_size;
448 if (sh_end > highest)
449 highest = sh_end;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800450 }
451 }
452
453 highest = 0;
454 scn = NULL;
455 while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
456 {
457 GElf_Shdr sh_mem;
458 GElf_Shdr *sh = gelf_getshdr (scn, &sh_mem);
459 if (unlikely (sh == NULL))
460 return DWFL_E_LIBELF;
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800461 consider_shdr (main_interp, sh->sh_type, sh->sh_flags,
462 sh->sh_addr, sh->sh_size);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800463 }
464 if (highest > mod->main.vaddr)
465 {
466 mod->main.address_sync = highest;
467
468 highest = 0;
469 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
470 for (size_t i = 0; i < shnum - 1; ++i)
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800471 consider_shdr (undo_interp, shdr.s32[i].sh_type, shdr.s32[i].sh_flags,
472 shdr.s32[i].sh_addr, shdr.s32[i].sh_size);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800473 else
474 for (size_t i = 0; i < shnum - 1; ++i)
Roland McGrath3a44c9a2011-02-01 19:06:21 -0800475 consider_shdr (undo_interp, shdr.s64[i].sh_type, shdr.s64[i].sh_flags,
476 shdr.s64[i].sh_addr, shdr.s64[i].sh_size);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800477
Mark Wielaard5083a702013-01-16 15:19:32 +0100478 if (highest > file->vaddr)
479 file->address_sync = highest;
Roland McGrath5ad466d2011-01-11 10:17:01 -0800480 else
481 return DWFL_E_BAD_PRELINK;
482 }
483
484 return DWFL_E_NOERROR;
485}
Ulrich Drepperc07fbb32007-03-30 19:14:59 +0000486
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000487/* Find the separate debuginfo file for this module and open libelf on it.
488 When we return success, MOD->debug is set up. */
489static Dwfl_Error
490find_debuginfo (Dwfl_Module *mod)
491{
Roland McGrathd17fac72005-08-23 08:20:21 +0000492 if (mod->debug.elf != NULL)
493 return DWFL_E_NOERROR;
494
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000495 GElf_Word debuglink_crc = 0;
Mark Wielaard93802972014-04-11 23:52:47 +0200496 const char *debuglink_file;
497 debuglink_file = INTUSE(dwelf_elf_gnu_debuglink) (mod->main.elf,
498 &debuglink_crc);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000499
500 mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
501 mod->main.name,
502 debuglink_file,
503 debuglink_crc,
504 &mod->debug.name);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800505 Dwfl_Error result = open_elf (mod, &mod->debug);
506 if (result == DWFL_E_NOERROR && mod->debug.address_sync != 0)
Mark Wielaard5083a702013-01-16 15:19:32 +0100507 result = find_prelink_address_sync (mod, &mod->debug);
Roland McGrath5ad466d2011-01-11 10:17:01 -0800508 return result;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000509}
510
Mark Wielaarddf85bf92014-05-01 14:48:27 +0200511/* Try to find the alternative debug link for the given DWARF and set
512 it if found. Only called when mod->dw is already setup but still
513 might need an alternative (dwz multi) debug file. filename is either
514 the main or debug name from which the Dwarf was created. */
515static void
516find_debug_altlink (Dwfl_Module *mod, const char *filename)
517{
518 assert (mod->dw != NULL);
519
520 const char *altname;
521 const void *build_id;
522 ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
523 &altname,
524 &build_id);
525
526 if (build_id_len > 0)
527 {
528 /* We could store altfile in the module, but don't really need it. */
529 char *altfile = NULL;
530 mod->alt_fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
531 filename,
532 altname,
533 0,
534 &altfile);
535
536 /* The (internal) callbacks might just set mod->alt_elf directly
537 because they open the Elf anyway for sanity checking.
538 Otherwise open either the given file name or use the fd
539 returned. */
540 Dwfl_Error error = open_elf_file (&mod->alt_elf, &mod->alt_fd,
541 &altfile);
542 if (error == DWFL_E_NOERROR)
543 {
544 mod->alt = INTUSE(dwarf_begin_elf) (mod->alt_elf,
545 DWARF_C_READ, NULL);
546 if (mod->alt == NULL)
547 {
548 elf_end (mod->alt_elf);
549 mod->alt_elf = NULL;
550 close (mod->alt_fd);
551 mod->alt_fd = -1;
552 }
553 else
554 dwarf_setalt (mod->dw, mod->alt);
555 }
556
557 free (altfile); /* See above, we don't really need it. */
558 }
559}
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000560
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000561/* Try to find a symbol table in FILE.
562 Returns DWFL_E_NOERROR if a proper one is found.
563 Returns DWFL_E_NO_SYMTAB if not, but still sets results for SHT_DYNSYM. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000564static Dwfl_Error
565load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
566 Elf_Scn **symscn, Elf_Scn **xndxscn,
Mark Wielaardef431cd2011-10-31 23:17:06 +0100567 size_t *syments, int *first_global, GElf_Word *strshndx)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000568{
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000569 bool symtab = false;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000570 Elf_Scn *scn = NULL;
571 while ((scn = elf_nextscn (file->elf, scn)) != NULL)
572 {
573 GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
574 if (shdr != NULL)
575 switch (shdr->sh_type)
576 {
577 case SHT_SYMTAB:
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000578 symtab = true;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000579 *symscn = scn;
580 *symfile = file;
581 *strshndx = shdr->sh_link;
582 *syments = shdr->sh_size / shdr->sh_entsize;
Mark Wielaardef431cd2011-10-31 23:17:06 +0100583 *first_global = shdr->sh_info;
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000584 if (*xndxscn != NULL)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000585 return DWFL_E_NOERROR;
586 break;
587
588 case SHT_DYNSYM:
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000589 if (symtab)
590 break;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000591 /* Use this if need be, but keep looking for SHT_SYMTAB. */
592 *symscn = scn;
593 *symfile = file;
594 *strshndx = shdr->sh_link;
595 *syments = shdr->sh_size / shdr->sh_entsize;
Mark Wielaard5083a702013-01-16 15:19:32 +0100596 *first_global = shdr->sh_info;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000597 break;
598
599 case SHT_SYMTAB_SHNDX:
600 *xndxscn = scn;
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000601 if (symtab)
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000602 return DWFL_E_NOERROR;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000603 break;
604
605 default:
606 break;
607 }
608 }
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000609
Roland McGrathd11f9cb2008-03-26 20:51:59 +0000610 if (symtab)
Ulrich Drepperb597dfa2007-10-16 05:21:27 +0000611 /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
612 return DWFL_E_NOERROR;
613
614 /* We found no SHT_SYMTAB, so any SHT_SYMTAB_SHNDX was bogus.
615 We might have found an SHT_DYNSYM and set *SYMSCN et al though. */
616 *xndxscn = NULL;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000617 return DWFL_E_NO_SYMTAB;
618}
619
Roland McGrath59ea7f32007-10-04 08:50:09 +0000620
621/* Translate addresses into file offsets.
622 OFFS[*] start out zero and remain zero if unresolved. */
623static void
Roland McGrathf95760a2010-01-07 20:24:34 -0800624find_offsets (Elf *elf, size_t phnum, size_t n,
Roland McGrath59ea7f32007-10-04 08:50:09 +0000625 GElf_Addr addrs[n], GElf_Off offs[n])
626{
627 size_t unsolved = n;
Roland McGrathf95760a2010-01-07 20:24:34 -0800628 for (size_t i = 0; i < phnum; ++i)
Roland McGrath59ea7f32007-10-04 08:50:09 +0000629 {
630 GElf_Phdr phdr_mem;
631 GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
632 if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
633 for (size_t j = 0; j < n; ++j)
634 if (offs[j] == 0
635 && addrs[j] >= phdr->p_vaddr
636 && addrs[j] - phdr->p_vaddr < phdr->p_filesz)
637 {
638 offs[j] = addrs[j] - phdr->p_vaddr + phdr->p_offset;
639 if (--unsolved == 0)
640 break;
641 }
642 }
643}
644
645/* Try to find a dynamic symbol table via phdrs. */
646static void
647find_dynsym (Dwfl_Module *mod)
648{
649 GElf_Ehdr ehdr_mem;
650 GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem);
651
Roland McGrathf95760a2010-01-07 20:24:34 -0800652 size_t phnum;
653 if (unlikely (elf_getphdrnum (mod->main.elf, &phnum) != 0))
654 return;
655
656 for (size_t i = 0; i < phnum; ++i)
Roland McGrath59ea7f32007-10-04 08:50:09 +0000657 {
658 GElf_Phdr phdr_mem;
659 GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
660 if (phdr == NULL)
661 break;
662
663 if (phdr->p_type == PT_DYNAMIC)
664 {
665 /* Examine the dynamic section for the pointers we need. */
666
667 Elf_Data *data = elf_getdata_rawchunk (mod->main.elf,
668 phdr->p_offset, phdr->p_filesz,
669 ELF_T_DYN);
670 if (data == NULL)
671 continue;
672
673 enum
674 {
675 i_symtab,
676 i_strtab,
677 i_hash,
678 i_gnu_hash,
679 i_max
680 };
681 GElf_Addr addrs[i_max] = { 0, };
682 GElf_Xword strsz = 0;
683 size_t n = data->d_size / gelf_fsize (mod->main.elf,
684 ELF_T_DYN, 1, EV_CURRENT);
685 for (size_t j = 0; j < n; ++j)
686 {
687 GElf_Dyn dyn_mem;
688 GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
689 if (dyn != NULL)
690 switch (dyn->d_tag)
691 {
692 case DT_SYMTAB:
693 addrs[i_symtab] = dyn->d_un.d_ptr;
694 continue;
695
696 case DT_HASH:
697 addrs[i_hash] = dyn->d_un.d_ptr;
698 continue;
699
700 case DT_GNU_HASH:
701 addrs[i_gnu_hash] = dyn->d_un.d_ptr;
702 continue;
703
704 case DT_STRTAB:
705 addrs[i_strtab] = dyn->d_un.d_ptr;
706 continue;
707
708 case DT_STRSZ:
709 strsz = dyn->d_un.d_val;
710 continue;
711
712 default:
713 continue;
714
715 case DT_NULL:
716 break;
717 }
718 break;
719 }
720
721 /* Translate pointers into file offsets. */
722 GElf_Off offs[i_max] = { 0, };
Roland McGrathf95760a2010-01-07 20:24:34 -0800723 find_offsets (mod->main.elf, phnum, i_max, addrs, offs);
Roland McGrath59ea7f32007-10-04 08:50:09 +0000724
725 /* Figure out the size of the symbol table. */
726 if (offs[i_hash] != 0)
727 {
728 /* In the original format, .hash says the size of .dynsym. */
729
730 size_t entsz = SH_ENTSIZE_HASH (ehdr);
731 data = elf_getdata_rawchunk (mod->main.elf,
732 offs[i_hash] + entsz, entsz,
733 entsz == 4 ? ELF_T_WORD
734 : ELF_T_XWORD);
735 if (data != NULL)
736 mod->syments = (entsz == 4
737 ? *(const GElf_Word *) data->d_buf
738 : *(const GElf_Xword *) data->d_buf);
739 }
740 if (offs[i_gnu_hash] != 0 && mod->syments == 0)
741 {
742 /* In the new format, we can derive it with some work. */
743
744 const struct
745 {
746 Elf32_Word nbuckets;
747 Elf32_Word symndx;
748 Elf32_Word maskwords;
749 Elf32_Word shift2;
750 } *header;
751
752 data = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash],
753 sizeof *header, ELF_T_WORD);
754 if (data != NULL)
755 {
756 header = data->d_buf;
757 Elf32_Word nbuckets = header->nbuckets;
758 Elf32_Word symndx = header->symndx;
759 GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header
760 + (gelf_getclass (mod->main.elf)
761 * sizeof (Elf32_Word)
762 * header->maskwords));
763
764 data = elf_getdata_rawchunk (mod->main.elf, buckets_at,
765 nbuckets * sizeof (Elf32_Word),
766 ELF_T_WORD);
767 if (data != NULL && symndx < nbuckets)
768 {
769 const Elf32_Word *const buckets = data->d_buf;
770 Elf32_Word maxndx = symndx;
771 for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
772 if (buckets[bucket] > maxndx)
773 maxndx = buckets[bucket];
774
775 GElf_Off hasharr_at = (buckets_at
776 + nbuckets * sizeof (Elf32_Word));
777 hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
778 do
779 {
780 data = elf_getdata_rawchunk (mod->main.elf,
781 hasharr_at,
782 sizeof (Elf32_Word),
783 ELF_T_WORD);
784 if (data != NULL
785 && (*(const Elf32_Word *) data->d_buf & 1u))
786 {
787 mod->syments = maxndx + 1;
788 break;
789 }
790 ++maxndx;
791 hasharr_at += sizeof (Elf32_Word);
792 } while (data != NULL);
793 }
794 }
795 }
796 if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0)
797 mod->syments = ((offs[i_strtab] - offs[i_symtab])
798 / gelf_fsize (mod->main.elf,
799 ELF_T_SYM, 1, EV_CURRENT));
800
801 if (mod->syments > 0)
802 {
803 mod->symdata = elf_getdata_rawchunk (mod->main.elf,
804 offs[i_symtab],
805 gelf_fsize (mod->main.elf,
806 ELF_T_SYM,
807 mod->syments,
808 EV_CURRENT),
809 ELF_T_SYM);
810 if (mod->symdata != NULL)
811 {
812 mod->symstrdata = elf_getdata_rawchunk (mod->main.elf,
813 offs[i_strtab],
814 strsz,
815 ELF_T_BYTE);
816 if (mod->symstrdata == NULL)
817 mod->symdata = NULL;
818 }
819 if (mod->symdata == NULL)
820 mod->symerr = DWFL_E (LIBELF, elf_errno ());
821 else
822 {
823 mod->symfile = &mod->main;
824 mod->symerr = DWFL_E_NOERROR;
825 }
826 return;
827 }
828 }
829 }
830}
831
Josh Stonedb35c872013-11-18 14:29:35 -0800832
833#if USE_LZMA
834/* Try to find the offset between the main file and .gnu_debugdata. */
835static bool
836find_aux_address_sync (Dwfl_Module *mod)
837{
838 /* Don't trust the phdrs in the minisymtab elf file to be setup correctly.
839 The address_sync is equal to the main file it is embedded in at first. */
840 mod->aux_sym.address_sync = mod->main.address_sync;
841
842 /* Adjust address_sync for the difference in entry addresses, attempting to
843 account for ELF relocation changes after aux was split. */
844 GElf_Ehdr ehdr_main, ehdr_aux;
845 if (unlikely (gelf_getehdr (mod->main.elf, &ehdr_main) == NULL)
846 || unlikely (gelf_getehdr (mod->aux_sym.elf, &ehdr_aux) == NULL))
847 return false;
848 mod->aux_sym.address_sync += ehdr_aux.e_entry - ehdr_main.e_entry;
849
850 /* The shdrs are setup OK to make find_prelink_address_sync () do the right
851 thing, which is possibly more reliable, but it needs .gnu.prelink_undo. */
852 if (mod->aux_sym.address_sync != 0)
853 return find_prelink_address_sync (mod, &mod->aux_sym) == DWFL_E_NOERROR;
854
855 return true;
856}
857#endif
858
Mark Wielaard5083a702013-01-16 15:19:32 +0100859/* Try to find the auxiliary symbol table embedded in the main elf file
860 section .gnu_debugdata. Only matters if the symbol information comes
861 from the main file dynsym. No harm done if not found. */
862static void
863find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)),
864 Elf_Scn **aux_symscn __attribute__ ((unused)),
865 Elf_Scn **aux_xndxscn __attribute__ ((unused)),
866 GElf_Word *aux_strshndx __attribute__ ((unused)))
867{
868 /* Since a .gnu_debugdata section is compressed using lzma don't do
869 anything unless we have support for that. */
870#if USE_LZMA
871 Elf *elf = mod->main.elf;
872
873 size_t shstrndx;
874 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
875 return;
876
877 Elf_Scn *scn = NULL;
878 while ((scn = elf_nextscn (elf, scn)) != NULL)
879 {
880 GElf_Shdr shdr_mem;
881 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
882 if (shdr == NULL)
883 return;
884
885 const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
886 if (name == NULL)
887 return;
888
889 if (!strcmp (name, ".gnu_debugdata"))
890 break;
891 }
892
893 if (scn == NULL)
894 return;
895
896 /* Found the .gnu_debugdata section. Uncompress the lzma image and
897 turn it into an ELF image. */
898 Elf_Data *rawdata = elf_rawdata (scn, NULL);
899 if (rawdata == NULL)
900 return;
901
902 Dwfl_Error error;
903 void *buffer = NULL;
904 size_t size = 0;
905 error = __libdw_unlzma (-1, 0, rawdata->d_buf, rawdata->d_size,
906 &buffer, &size);
907 if (error == DWFL_E_NOERROR)
908 {
909 if (unlikely (size == 0))
910 free (buffer);
911 else
912 {
913 mod->aux_sym.elf = elf_memory (buffer, size);
914 if (mod->aux_sym.elf == NULL)
915 free (buffer);
916 else
917 {
918 mod->aux_sym.fd = -1;
919 mod->aux_sym.elf->flags |= ELF_F_MALLOCED;
920 if (open_elf (mod, &mod->aux_sym) != DWFL_E_NOERROR)
921 return;
Josh Stonedb35c872013-11-18 14:29:35 -0800922 if (! find_aux_address_sync (mod))
Mark Wielaard5083a702013-01-16 15:19:32 +0100923 {
Josh Stonedb35c872013-11-18 14:29:35 -0800924 elf_end (mod->aux_sym.elf);
925 mod->aux_sym.elf = NULL;
926 return;
Mark Wielaard5083a702013-01-16 15:19:32 +0100927 }
928
929 /* So far, so good. Get minisymtab table data and cache it. */
930 bool minisymtab = false;
931 scn = NULL;
932 while ((scn = elf_nextscn (mod->aux_sym.elf, scn)) != NULL)
933 {
934 GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
935 if (shdr != NULL)
936 switch (shdr->sh_type)
937 {
938 case SHT_SYMTAB:
939 minisymtab = true;
940 *aux_symscn = scn;
941 *aux_strshndx = shdr->sh_link;
Mark Wielaard697bdca2013-01-23 17:39:19 +0100942 mod->aux_syments = shdr->sh_size / shdr->sh_entsize;
Mark Wielaard5083a702013-01-16 15:19:32 +0100943 mod->aux_first_global = shdr->sh_info;
944 if (*aux_xndxscn != NULL)
945 return;
946 break;
947
948 case SHT_SYMTAB_SHNDX:
949 *aux_xndxscn = scn;
950 if (minisymtab)
951 return;
952 break;
953
954 default:
955 break;
956 }
957 }
958
959 if (minisymtab)
960 /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
961 return;
962
963 /* We found no SHT_SYMTAB, so everything else is bogus. */
964 *aux_xndxscn = NULL;
965 *aux_strshndx = 0;
966 mod->aux_syments = 0;
967 elf_end (mod->aux_sym.elf);
968 mod->aux_sym.elf = NULL;
969 return;
970 }
971 }
972 }
973 else
974 free (buffer);
975#endif
976}
977
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000978/* Try to find a symbol table in either MOD->main.elf or MOD->debug.elf. */
979static void
980find_symtab (Dwfl_Module *mod)
981{
Mark Wielaard697bdca2013-01-23 17:39:19 +0100982 if (mod->symdata != NULL || mod->aux_symdata != NULL /* Already done. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000983 || mod->symerr != DWFL_E_NOERROR) /* Cached previous failure. */
984 return;
985
Roland McGratha605a3c2009-04-19 18:27:01 -0700986 __libdwfl_getelf (mod);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000987 mod->symerr = mod->elferr;
988 if (mod->symerr != DWFL_E_NOERROR)
989 return;
990
991 /* First see if the main ELF file has the debugging information. */
992 Elf_Scn *symscn = NULL, *xndxscn = NULL;
Mark Wielaard5083a702013-01-16 15:19:32 +0100993 Elf_Scn *aux_symscn = NULL, *aux_xndxscn = NULL;
994 GElf_Word strshndx, aux_strshndx = 0;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000995 mod->symerr = load_symtab (&mod->main, &mod->symfile, &symscn,
Mark Wielaardef431cd2011-10-31 23:17:06 +0100996 &xndxscn, &mod->syments, &mod->first_global,
997 &strshndx);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000998 switch (mod->symerr)
999 {
1000 default:
1001 return;
1002
1003 case DWFL_E_NOERROR:
1004 break;
1005
1006 case DWFL_E_NO_SYMTAB:
1007 /* Now we have to look for a separate debuginfo file. */
1008 mod->symerr = find_debuginfo (mod);
1009 switch (mod->symerr)
1010 {
1011 default:
1012 return;
1013
1014 case DWFL_E_NOERROR:
1015 mod->symerr = load_symtab (&mod->debug, &mod->symfile, &symscn,
Mark Wielaardef431cd2011-10-31 23:17:06 +01001016 &xndxscn, &mod->syments,
1017 &mod->first_global, &strshndx);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001018 break;
1019
1020 case DWFL_E_CB: /* The find_debuginfo hook failed. */
1021 mod->symerr = DWFL_E_NO_SYMTAB;
1022 break;
1023 }
1024
1025 switch (mod->symerr)
1026 {
1027 default:
1028 return;
1029
1030 case DWFL_E_NOERROR:
1031 break;
1032
1033 case DWFL_E_NO_SYMTAB:
Mark Wielaard697bdca2013-01-23 17:39:19 +01001034 /* There might be an auxiliary table. */
1035 find_aux_sym (mod, &aux_symscn, &aux_xndxscn, &aux_strshndx);
1036
Roland McGrath59ea7f32007-10-04 08:50:09 +00001037 if (symscn != NULL)
1038 {
1039 /* We still have the dynamic symbol table. */
1040 mod->symerr = DWFL_E_NOERROR;
1041 break;
1042 }
1043
Mark Wielaard697bdca2013-01-23 17:39:19 +01001044 if (aux_symscn != NULL)
1045 {
1046 /* We still have the auxiliary symbol table. */
1047 mod->symerr = DWFL_E_NOERROR;
1048 goto aux_cache;
1049 }
1050
Roland McGrath59ea7f32007-10-04 08:50:09 +00001051 /* Last ditch, look for dynamic symbols without section headers. */
1052 find_dynsym (mod);
1053 return;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001054 }
1055 break;
1056 }
1057
1058 /* This does some sanity checks on the string table section. */
1059 if (elf_strptr (mod->symfile->elf, strshndx, 0) == NULL)
1060 {
1061 elferr:
1062 mod->symerr = DWFL_E (LIBELF, elf_errno ());
Mark Wielaard5083a702013-01-16 15:19:32 +01001063 goto aux_cleanup;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001064 }
1065
Mark Wielaardef431cd2011-10-31 23:17:06 +01001066 /* Cache the data; MOD->syments and MOD->first_global were set above. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001067
Roland McGrath3712b282005-08-23 05:58:42 +00001068 mod->symstrdata = elf_getdata (elf_getscn (mod->symfile->elf, strshndx),
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001069 NULL);
1070 if (mod->symstrdata == NULL)
1071 goto elferr;
1072
1073 if (xndxscn == NULL)
1074 mod->symxndxdata = NULL;
1075 else
1076 {
Roland McGrath3712b282005-08-23 05:58:42 +00001077 mod->symxndxdata = elf_getdata (xndxscn, NULL);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001078 if (mod->symxndxdata == NULL)
1079 goto elferr;
1080 }
1081
Roland McGrath3712b282005-08-23 05:58:42 +00001082 mod->symdata = elf_getdata (symscn, NULL);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001083 if (mod->symdata == NULL)
1084 goto elferr;
Mark Wielaard5083a702013-01-16 15:19:32 +01001085
1086 /* Cache any auxiliary symbol info, when it fails, just ignore aux_sym. */
1087 if (aux_symscn != NULL)
1088 {
Mark Wielaard697bdca2013-01-23 17:39:19 +01001089 aux_cache:
Mark Wielaard5083a702013-01-16 15:19:32 +01001090 /* This does some sanity checks on the string table section. */
1091 if (elf_strptr (mod->aux_sym.elf, aux_strshndx, 0) == NULL)
1092 {
1093 aux_cleanup:
1094 mod->aux_syments = 0;
1095 elf_end (mod->aux_sym.elf);
1096 mod->aux_sym.elf = NULL;
1097 return;
1098 }
1099
1100 mod->aux_symstrdata = elf_getdata (elf_getscn (mod->aux_sym.elf,
1101 aux_strshndx),
1102 NULL);
1103 if (mod->aux_symstrdata == NULL)
1104 goto aux_cleanup;
1105
1106 if (aux_xndxscn == NULL)
1107 mod->aux_symxndxdata = NULL;
1108 else
1109 {
Mark Wielaard2e73a8a2013-09-12 11:27:56 +02001110 mod->aux_symxndxdata = elf_getdata (aux_xndxscn, NULL);
Mark Wielaard5083a702013-01-16 15:19:32 +01001111 if (mod->aux_symxndxdata == NULL)
1112 goto aux_cleanup;
1113 }
1114
1115 mod->aux_symdata = elf_getdata (aux_symscn, NULL);
1116 if (mod->aux_symdata == NULL)
1117 goto aux_cleanup;
1118 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001119}
1120
1121
Roland McGrath994b4892005-12-05 22:46:21 +00001122/* Try to open a libebl backend for MOD. */
1123Dwfl_Error
Ulrich Drepper077c65f2006-07-12 19:54:51 +00001124internal_function
Roland McGrath994b4892005-12-05 22:46:21 +00001125__libdwfl_module_getebl (Dwfl_Module *mod)
1126{
1127 if (mod->ebl == NULL)
1128 {
Roland McGratha605a3c2009-04-19 18:27:01 -07001129 __libdwfl_getelf (mod);
Roland McGrath994b4892005-12-05 22:46:21 +00001130 if (mod->elferr != DWFL_E_NOERROR)
1131 return mod->elferr;
1132
1133 mod->ebl = ebl_openbackend (mod->main.elf);
1134 if (mod->ebl == NULL)
1135 return DWFL_E_LIBEBL;
1136 }
1137 return DWFL_E_NOERROR;
1138}
1139
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001140/* Try to start up libdw on DEBUGFILE. */
1141static Dwfl_Error
Roland McGrathd17fac72005-08-23 08:20:21 +00001142load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001143{
Roland McGrath059c83e2008-02-21 06:19:39 +00001144 if (mod->e_type == ET_REL && !debugfile->relocated)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001145 {
1146 const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
1147
1148 /* The debugging sections have to be relocated. */
1149 if (cb->section_address == NULL)
1150 return DWFL_E_NOREL;
1151
Roland McGrath994b4892005-12-05 22:46:21 +00001152 Dwfl_Error error = __libdwfl_module_getebl (mod);
1153 if (error != DWFL_E_NOERROR)
1154 return error;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001155
1156 find_symtab (mod);
1157 Dwfl_Error result = mod->symerr;
1158 if (result == DWFL_E_NOERROR)
Roland McGrathe4c22ea2007-10-23 13:07:39 +00001159 result = __libdwfl_relocate (mod, debugfile->elf, true);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001160 if (result != DWFL_E_NOERROR)
1161 return result;
Roland McGrathd17fac72005-08-23 08:20:21 +00001162
1163 /* Don't keep the file descriptors around. */
1164 if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
1165 {
1166 close (mod->main.fd);
1167 mod->main.fd = -1;
1168 }
1169 if (debugfile->fd != -1 && elf_cntl (debugfile->elf, ELF_C_FDREAD) == 0)
1170 {
1171 close (debugfile->fd);
1172 debugfile->fd = -1;
1173 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001174 }
1175
Roland McGrathd17fac72005-08-23 08:20:21 +00001176 mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001177 if (mod->dw == NULL)
1178 {
Roland McGrath4959bf82005-08-09 10:31:08 +00001179 int err = INTUSE(dwarf_errno) ();
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001180 return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err);
1181 }
1182
1183 /* Until we have iterated through all CU's, we might do lazy lookups. */
1184 mod->lazycu = 1;
1185
1186 return DWFL_E_NOERROR;
1187}
1188
1189/* Try to start up libdw on either the main file or the debuginfo file. */
1190static void
1191find_dw (Dwfl_Module *mod)
1192{
1193 if (mod->dw != NULL /* Already done. */
1194 || mod->dwerr != DWFL_E_NOERROR) /* Cached previous failure. */
1195 return;
1196
Roland McGratha605a3c2009-04-19 18:27:01 -07001197 __libdwfl_getelf (mod);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001198 mod->dwerr = mod->elferr;
1199 if (mod->dwerr != DWFL_E_NOERROR)
1200 return;
1201
1202 /* First see if the main ELF file has the debugging information. */
Roland McGrathd17fac72005-08-23 08:20:21 +00001203 mod->dwerr = load_dw (mod, &mod->main);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001204 switch (mod->dwerr)
1205 {
1206 case DWFL_E_NOERROR:
1207 mod->debug.elf = mod->main.elf;
Roland McGrath1743d7f2010-11-12 16:46:47 -08001208 mod->debug.address_sync = mod->main.address_sync;
Mark Wielaarddf85bf92014-05-01 14:48:27 +02001209
Mark Wielaarddf85bf92014-05-01 14:48:27 +02001210 /* The Dwarf might need an alt debug file, find that now after
1211 everything about the debug file has been setup (the
1212 find_debuginfo callback might need it). */
1213 find_debug_altlink (mod, mod->main.name);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001214 return;
1215
1216 case DWFL_E_NO_DWARF:
1217 break;
1218
1219 default:
1220 goto canonicalize;
1221 }
1222
1223 /* Now we have to look for a separate debuginfo file. */
1224 mod->dwerr = find_debuginfo (mod);
1225 switch (mod->dwerr)
1226 {
1227 case DWFL_E_NOERROR:
Roland McGrathd17fac72005-08-23 08:20:21 +00001228 mod->dwerr = load_dw (mod, &mod->debug);
Mark Wielaarddf85bf92014-05-01 14:48:27 +02001229 if (mod->dwerr == DWFL_E_NOERROR)
1230 {
Mark Wielaarddf85bf92014-05-01 14:48:27 +02001231 /* The Dwarf might need an alt debug file, find that now after
1232 everything about the debug file has been setup (the
1233 find_debuginfo callback might need it). */
1234 find_debug_altlink (mod, mod->debug.name);
Mark Wielaarddf85bf92014-05-01 14:48:27 +02001235 return;
1236 }
1237
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001238 break;
1239
1240 case DWFL_E_CB: /* The find_debuginfo hook failed. */
1241 mod->dwerr = DWFL_E_NO_DWARF;
1242 return;
1243
1244 default:
1245 break;
1246 }
1247
1248 canonicalize:
1249 mod->dwerr = __libdwfl_canon_error (mod->dwerr);
1250}
1251
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001252Dwarf *
1253dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
1254{
1255 if (mod == NULL)
1256 return NULL;
1257
1258 find_dw (mod);
1259 if (mod->dwerr == DWFL_E_NOERROR)
1260 {
Roland McGrathe4c22ea2007-10-23 13:07:39 +00001261 /* If dwfl_module_getelf was used previously, then partial apply
1262 relocation to miscellaneous sections in the debug file too. */
1263 if (mod->e_type == ET_REL
1264 && mod->main.relocated && ! mod->debug.relocated)
1265 {
1266 mod->debug.relocated = true;
1267 if (mod->debug.elf != mod->main.elf)
1268 (void) __libdwfl_relocate (mod, mod->debug.elf, false);
1269 }
1270
Roland McGrath1743d7f2010-11-12 16:46:47 -08001271 *bias = dwfl_adjusted_dwarf_addr (mod, 0);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001272 return mod->dw;
1273 }
1274
1275 __libdwfl_seterrno (mod->dwerr);
1276 return NULL;
1277}
1278INTDEF (dwfl_module_getdwarf)
1279
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001280int
1281dwfl_module_getsymtab (Dwfl_Module *mod)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001282{
1283 if (mod == NULL)
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001284 return -1;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001285
1286 find_symtab (mod);
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001287 if (mod->symerr == DWFL_E_NOERROR)
Mark Wielaard697bdca2013-01-23 17:39:19 +01001288 /* We will skip the auxiliary zero entry if there is another one. */
1289 return (mod->syments + mod->aux_syments
1290 - (mod->syments > 0 && mod->aux_syments > 0 ? 1 : 0));
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001291
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001292 __libdwfl_seterrno (mod->symerr);
1293 return -1;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001294}
Ulrich Dreppere1812e12006-07-12 07:46:03 +00001295INTDEF (dwfl_module_getsymtab)
Mark Wielaard14c2d9e2013-12-16 13:28:59 +01001296
1297int
1298dwfl_module_getsymtab_first_global (Dwfl_Module *mod)
1299{
1300 if (mod == NULL)
1301 return -1;
1302
1303 find_symtab (mod);
1304 if (mod->symerr == DWFL_E_NOERROR)
1305 {
1306 /* All local symbols should come before all global symbols. If
1307 we have an auxiliary table make sure all the main locals come
1308 first, then all aux locals, then all main globals and finally all
1309 aux globals. And skip the auxiliary table zero undefined
1310 entry. */
1311 int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
1312 return mod->first_global + mod->aux_first_global - skip_aux_zero;
1313 }
1314
1315 __libdwfl_seterrno (mod->symerr);
1316 return -1;
1317}
1318INTDEF (dwfl_module_getsymtab_first_global)