1 /* Find debugging and symbol information for a module in libdwfl.
2 Copyright (C) 2005-2012, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
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
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
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.
24
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/>. */
28
29 #include "libdwflP.h"
30 #include <inttypes.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include "../libdw/libdwP.h" /* DWARF_E_* values are here. */
35 #include "../libelf/libelfP.h"
36
37 static inline Dwfl_Error
open_elf_file(Elf ** elf,int * fd,char ** name)38 open_elf_file (Elf **elf, int *fd, char **name)
39 {
40 if (*elf == NULL)
41 {
42 /* 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
46 /* If there was a pre-primed file name left that the callback left
47 behind, try to open that file name. */
48 if (*fd < 0 && *name != NULL)
49 *fd = TEMP_FAILURE_RETRY (open (*name, O_RDONLY));
50
51 if (*fd < 0)
52 return CBFAIL;
53
54 return __libdw_open_file (fd, elf, true, false);
55 }
56 else if (unlikely (elf_kind (*elf) != ELF_K_ELF))
57 {
58 elf_end (*elf);
59 *elf = NULL;
60 close (*fd);
61 *fd = -1;
62 return DWFL_E_BADELF;
63 }
64
65 /* 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. */
71 static inline Dwfl_Error
open_elf(Dwfl_Module * mod,struct dwfl_file * file)72 open_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
78 GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
79 if (ehdr == NULL)
80 {
81 elf_error:
82 elf_end (file->elf);
83 file->elf = NULL;
84 close (file->fd);
85 file->fd = -1;
86 return DWFL_E (LIBELF, elf_errno ());
87 }
88
89 if (ehdr->e_type != ET_REL)
90 {
91 /* 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
115 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. */
122
123 size_t phnum;
124 if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0))
125 goto elf_error;
126
127 file->vaddr = file->address_sync = 0;
128 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);
132 if (unlikely (ph == NULL))
133 goto elf_error;
134 if (ph->p_type == PT_LOAD)
135 {
136 file->vaddr = ph->p_vaddr & -ph->p_align;
137 file->address_sync = ph->p_vaddr + ph->p_memsz;
138 break;
139 }
140 }
141 }
142
143 /* 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;
154
155 /* 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);
161
162 return DWFL_E_NOERROR;
163 }
164
165 /* 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. */
167 static void
mod_verify_build_id(Dwfl_Module * mod)168 mod_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
202 /* 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. */
204 void
205 internal_function
__libdwfl_getelf(Dwfl_Module * mod)206 __libdwfl_getelf (Dwfl_Module *mod)
207 {
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);
215 const bool fallback = mod->main.elf == NULL && mod->main.fd < 0;
216 mod->elferr = open_elf (mod, &mod->main);
217 if (mod->elferr != DWFL_E_NOERROR)
218 return;
219
220 if (!mod->main.valid)
221 {
222 /* Clear any explicitly reported build ID, just in case it was wrong.
223 We'll fetch it from the file when asked. */
224 free (mod->build_id_bits);
225 mod->build_id_bits = NULL;
226 mod->build_id_len = 0;
227 }
228 else if (fallback)
229 mod_verify_build_id (mod);
230
231 mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
232 }
233
234 static inline void
consider_shdr(GElf_Addr interp,GElf_Word sh_type,GElf_Xword sh_flags,GElf_Addr sh_addr,GElf_Xword sh_size,GElf_Addr * phighest)235 consider_shdr (GElf_Addr interp,
236 GElf_Word sh_type,
237 GElf_Xword sh_flags,
238 GElf_Addr sh_addr,
239 GElf_Xword sh_size,
240 GElf_Addr *phighest)
241 {
242 if ((sh_flags & SHF_ALLOC)
243 && ((sh_type == SHT_PROGBITS && sh_addr != interp)
244 || sh_type == SHT_NOBITS))
245 {
246 const GElf_Addr sh_end = sh_addr + sh_size;
247 if (sh_end > *phighest)
248 *phighest = sh_end;
249 }
250 }
251
252 /* If the main file might have been prelinked, then we need to
253 discover the correct synchronization address between the main and
254 debug files. Because of prelink's section juggling, we cannot rely
255 on the address_sync computed from PT_LOAD segments (see open_elf).
256
257 We will attempt to discover a synchronization address based on the
258 section headers instead. But finding a section address that is
259 safe to use requires identifying which sections are SHT_PROGBITS.
260 We can do that in the main file, but in the debug file all the
261 allocated sections have been transformed into SHT_NOBITS so we have
262 lost the means to match them up correctly.
263
264 The only method left to us is to decode the .gnu.prelink_undo
265 section in the prelinked main file. This shows what the sections
266 looked like before prelink juggled them--when they still had a
267 direct correspondence to the debug file. */
268 static Dwfl_Error
find_prelink_address_sync(Dwfl_Module * mod,struct dwfl_file * file)269 find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
270 {
271 /* The magic section is only identified by name. */
272 size_t shstrndx;
273 if (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0)
274 return DWFL_E_LIBELF;
275
276 Elf_Scn *scn = NULL;
277 while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
278 {
279 GElf_Shdr shdr_mem;
280 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
281 if (unlikely (shdr == NULL))
282 return DWFL_E_LIBELF;
283 if (shdr->sh_type == SHT_PROGBITS
284 && !(shdr->sh_flags & SHF_ALLOC)
285 && shdr->sh_name != 0)
286 {
287 const char *secname = elf_strptr (mod->main.elf, shstrndx,
288 shdr->sh_name);
289 if (unlikely (secname == NULL))
290 return DWFL_E_LIBELF;
291 if (!strcmp (secname, ".gnu.prelink_undo"))
292 break;
293 }
294 }
295
296 if (scn == NULL)
297 /* There was no .gnu.prelink_undo section. */
298 return DWFL_E_NOERROR;
299
300 Elf_Data *undodata = elf_rawdata (scn, NULL);
301 if (unlikely (undodata == NULL))
302 return DWFL_E_LIBELF;
303
304 /* Decode the section. It consists of the original ehdr, phdrs,
305 and shdrs (but omits section 0). */
306
307 union
308 {
309 Elf32_Ehdr e32;
310 Elf64_Ehdr e64;
311 } ehdr;
312 Elf_Data dst =
313 {
314 .d_buf = &ehdr,
315 .d_size = sizeof ehdr,
316 .d_type = ELF_T_EHDR,
317 .d_version = EV_CURRENT
318 };
319 Elf_Data src = *undodata;
320 src.d_size = gelf_fsize (mod->main.elf, ELF_T_EHDR, 1, EV_CURRENT);
321 src.d_type = ELF_T_EHDR;
322 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
323 elf_getident (mod->main.elf, NULL)[EI_DATA])
324 == NULL))
325 return DWFL_E_LIBELF;
326
327 size_t shentsize = gelf_fsize (mod->main.elf, ELF_T_SHDR, 1, EV_CURRENT);
328 size_t phentsize = gelf_fsize (mod->main.elf, ELF_T_PHDR, 1, EV_CURRENT);
329
330 uint_fast16_t phnum;
331 uint_fast16_t shnum;
332 if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
333 {
334 if (ehdr.e32.e_shentsize != shentsize
335 || ehdr.e32.e_phentsize != phentsize)
336 return DWFL_E_BAD_PRELINK;
337 phnum = ehdr.e32.e_phnum;
338 shnum = ehdr.e32.e_shnum;
339 }
340 else
341 {
342 if (ehdr.e64.e_shentsize != shentsize
343 || ehdr.e64.e_phentsize != phentsize)
344 return DWFL_E_BAD_PRELINK;
345 phnum = ehdr.e64.e_phnum;
346 shnum = ehdr.e64.e_shnum;
347 }
348
349 /* Since prelink does not store the zeroth section header in the undo
350 section, it cannot support SHN_XINDEX encoding. */
351 if (unlikely (shnum >= SHN_LORESERVE)
352 || unlikely (undodata->d_size != (src.d_size
353 + phnum * phentsize
354 + (shnum - 1) * shentsize)))
355 return DWFL_E_BAD_PRELINK;
356
357 /* We look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections. (Most
358 every file will have some SHT_PROGBITS sections, but it's possible to
359 have one with nothing but .bss, i.e. SHT_NOBITS.) The special sections
360 that can be moved around have different sh_type values--except for
361 .interp, the section that became the PT_INTERP segment. So we exclude
362 the SHT_PROGBITS section whose address matches the PT_INTERP p_vaddr.
363 For this reason, we must examine the phdrs first to find PT_INTERP. */
364
365 GElf_Addr main_interp = 0;
366 {
367 size_t main_phnum;
368 if (unlikely (elf_getphdrnum (mod->main.elf, &main_phnum)))
369 return DWFL_E_LIBELF;
370 for (size_t i = 0; i < main_phnum; ++i)
371 {
372 GElf_Phdr phdr;
373 if (unlikely (gelf_getphdr (mod->main.elf, i, &phdr) == NULL))
374 return DWFL_E_LIBELF;
375 if (phdr.p_type == PT_INTERP)
376 {
377 main_interp = phdr.p_vaddr;
378 break;
379 }
380 }
381 }
382
383 src.d_buf += src.d_size;
384 src.d_type = ELF_T_PHDR;
385 src.d_size = phnum * phentsize;
386
387 GElf_Addr undo_interp = 0;
388 bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
389 {
390 size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
391 if (unlikely (phnum > SIZE_MAX / phdr_size))
392 return DWFL_E_NOMEM;
393 const size_t phdrs_bytes = phnum * phdr_size;
394 void *phdrs = malloc (phdrs_bytes);
395 if (unlikely (phdrs == NULL))
396 return DWFL_E_NOMEM;
397 dst.d_buf = phdrs;
398 dst.d_size = phdrs_bytes;
399 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
400 ehdr.e32.e_ident[EI_DATA]) == NULL))
401 {
402 free (phdrs);
403 return DWFL_E_LIBELF;
404 }
405 if (class32)
406 {
407 Elf32_Phdr (*p32)[phnum] = phdrs;
408 for (uint_fast16_t i = 0; i < phnum; ++i)
409 if ((*p32)[i].p_type == PT_INTERP)
410 {
411 undo_interp = (*p32)[i].p_vaddr;
412 break;
413 }
414 }
415 else
416 {
417 Elf64_Phdr (*p64)[phnum] = phdrs;
418 for (uint_fast16_t i = 0; i < phnum; ++i)
419 if ((*p64)[i].p_type == PT_INTERP)
420 {
421 undo_interp = (*p64)[i].p_vaddr;
422 break;
423 }
424 }
425 free (phdrs);
426 }
427
428 if (unlikely ((main_interp == 0) != (undo_interp == 0)))
429 return DWFL_E_BAD_PRELINK;
430
431 src.d_buf += src.d_size;
432 src.d_type = ELF_T_SHDR;
433 src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum - 1, EV_CURRENT);
434
435 size_t shdr_size = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
436 if (unlikely (shnum - 1 > SIZE_MAX / shdr_size))
437 return DWFL_E_NOMEM;
438 const size_t shdrs_bytes = (shnum - 1) * shdr_size;
439 void *shdrs = malloc (shdrs_bytes);
440 if (unlikely (shdrs == NULL))
441 return DWFL_E_NOMEM;
442 dst.d_buf = shdrs;
443 dst.d_size = shdrs_bytes;
444 if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
445 ehdr.e32.e_ident[EI_DATA]) == NULL))
446 {
447 free (shdrs);
448 return DWFL_E_LIBELF;
449 }
450
451 /* Now we can look at the original section headers of the main file
452 before it was prelinked. First we'll apply our method to the main
453 file sections as they are after prelinking, to calculate the
454 synchronization address of the main file. Then we'll apply that
455 same method to the saved section headers, to calculate the matching
456 synchronization address of the debug file.
457
458 The method is to consider SHF_ALLOC sections that are either
459 SHT_PROGBITS or SHT_NOBITS, excluding the section whose sh_addr
460 matches the PT_INTERP p_vaddr. The special sections that can be
461 moved by prelink have other types, except for .interp (which
462 becomes PT_INTERP). The "real" sections cannot move as such, but
463 .bss can be split into .dynbss and .bss, with the total memory
464 image remaining the same but being spread across the two sections.
465 So we consider the highest section end, which still matches up. */
466
467 GElf_Addr highest;
468
469 highest = 0;
470 scn = NULL;
471 while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
472 {
473 GElf_Shdr sh_mem;
474 GElf_Shdr *sh = gelf_getshdr (scn, &sh_mem);
475 if (unlikely (sh == NULL))
476 {
477 free (shdrs);
478 return DWFL_E_LIBELF;
479 }
480 consider_shdr (main_interp, sh->sh_type, sh->sh_flags,
481 sh->sh_addr, sh->sh_size, &highest);
482 }
483 if (highest > mod->main.vaddr)
484 {
485 mod->main.address_sync = highest;
486
487 highest = 0;
488 if (class32)
489 {
490 Elf32_Shdr (*s32)[shnum - 1] = shdrs;
491 for (size_t i = 0; i < shnum - 1; ++i)
492 consider_shdr (undo_interp, (*s32)[i].sh_type,
493 (*s32)[i].sh_flags, (*s32)[i].sh_addr,
494 (*s32)[i].sh_size, &highest);
495 }
496 else
497 {
498 Elf64_Shdr (*s64)[shnum - 1] = shdrs;
499 for (size_t i = 0; i < shnum - 1; ++i)
500 consider_shdr (undo_interp, (*s64)[i].sh_type,
501 (*s64)[i].sh_flags, (*s64)[i].sh_addr,
502 (*s64)[i].sh_size, &highest);
503 }
504
505 if (highest > file->vaddr)
506 file->address_sync = highest;
507 else
508 {
509 free (shdrs);
510 return DWFL_E_BAD_PRELINK;
511 }
512 }
513
514 free (shdrs);
515
516 return DWFL_E_NOERROR;
517 }
518
519 /* Find the separate debuginfo file for this module and open libelf on it.
520 When we return success, MOD->debug is set up. */
521 static Dwfl_Error
find_debuginfo(Dwfl_Module * mod)522 find_debuginfo (Dwfl_Module *mod)
523 {
524 if (mod->debug.elf != NULL)
525 return DWFL_E_NOERROR;
526
527 GElf_Word debuglink_crc = 0;
528 const char *debuglink_file;
529 debuglink_file = INTUSE(dwelf_elf_gnu_debuglink) (mod->main.elf,
530 &debuglink_crc);
531
532 mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
533 mod->main.name,
534 debuglink_file,
535 debuglink_crc,
536 &mod->debug.name);
537 Dwfl_Error result = open_elf (mod, &mod->debug);
538 if (result == DWFL_E_NOERROR && mod->debug.address_sync != 0)
539 result = find_prelink_address_sync (mod, &mod->debug);
540 return result;
541 }
542
543 /* Try to find the alternative debug link for the given DWARF and set
544 it if found. Only called when mod->dw is already setup but still
545 might need an alternative (dwz multi) debug file. filename is either
546 the main or debug name from which the Dwarf was created. */
547 static void
find_debug_altlink(Dwfl_Module * mod,const char * filename)548 find_debug_altlink (Dwfl_Module *mod, const char *filename)
549 {
550 assert (mod->dw != NULL);
551
552 const char *altname;
553 const void *build_id;
554 ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
555 &altname,
556 &build_id);
557
558 if (build_id_len > 0)
559 {
560 /* We could store altfile in the module, but don't really need it. */
561 char *altfile = NULL;
562 mod->alt_fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
563 filename,
564 altname,
565 0,
566 &altfile);
567
568 /* The (internal) callbacks might just set mod->alt_elf directly
569 because they open the Elf anyway for sanity checking.
570 Otherwise open either the given file name or use the fd
571 returned. */
572 Dwfl_Error error = open_elf_file (&mod->alt_elf, &mod->alt_fd,
573 &altfile);
574 if (error == DWFL_E_NOERROR)
575 {
576 mod->alt = INTUSE(dwarf_begin_elf) (mod->alt_elf,
577 DWARF_C_READ, NULL);
578 if (mod->alt == NULL)
579 {
580 elf_end (mod->alt_elf);
581 mod->alt_elf = NULL;
582 close (mod->alt_fd);
583 mod->alt_fd = -1;
584 }
585 else
586 dwarf_setalt (mod->dw, mod->alt);
587 }
588
589 free (altfile); /* See above, we don't really need it. */
590 }
591 }
592
593 /* Try to find a symbol table in FILE.
594 Returns DWFL_E_NOERROR if a proper one is found.
595 Returns DWFL_E_NO_SYMTAB if not, but still sets results for SHT_DYNSYM. */
596 static Dwfl_Error
load_symtab(struct dwfl_file * file,struct dwfl_file ** symfile,Elf_Scn ** symscn,Elf_Scn ** xndxscn,size_t * syments,int * first_global,GElf_Word * strshndx)597 load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
598 Elf_Scn **symscn, Elf_Scn **xndxscn,
599 size_t *syments, int *first_global, GElf_Word *strshndx)
600 {
601 bool symtab = false;
602 Elf_Scn *scn = NULL;
603 while ((scn = elf_nextscn (file->elf, scn)) != NULL)
604 {
605 GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
606 if (shdr != NULL)
607 switch (shdr->sh_type)
608 {
609 case SHT_SYMTAB:
610 if (shdr->sh_entsize == 0)
611 break;
612 symtab = true;
613 *symscn = scn;
614 *symfile = file;
615 *strshndx = shdr->sh_link;
616 *syments = shdr->sh_size / shdr->sh_entsize;
617 *first_global = shdr->sh_info;
618 if (*xndxscn != NULL)
619 return DWFL_E_NOERROR;
620 break;
621
622 case SHT_DYNSYM:
623 if (symtab)
624 break;
625 /* Use this if need be, but keep looking for SHT_SYMTAB. */
626 if (shdr->sh_entsize == 0)
627 break;
628 *symscn = scn;
629 *symfile = file;
630 *strshndx = shdr->sh_link;
631 *syments = shdr->sh_size / shdr->sh_entsize;
632 *first_global = shdr->sh_info;
633 break;
634
635 case SHT_SYMTAB_SHNDX:
636 *xndxscn = scn;
637 if (symtab)
638 return DWFL_E_NOERROR;
639 break;
640
641 default:
642 break;
643 }
644 }
645
646 if (symtab)
647 /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
648 return DWFL_E_NOERROR;
649
650 /* We found no SHT_SYMTAB, so any SHT_SYMTAB_SHNDX was bogus.
651 We might have found an SHT_DYNSYM and set *SYMSCN et al though. */
652 *xndxscn = NULL;
653 return DWFL_E_NO_SYMTAB;
654 }
655
656
657 /* Translate addresses into file offsets.
658 OFFS[*] start out zero and remain zero if unresolved. */
659 static void
find_offsets(Elf * elf,GElf_Addr main_bias,size_t phnum,size_t n,GElf_Addr addrs[n],GElf_Off offs[n])660 find_offsets (Elf *elf, GElf_Addr main_bias, size_t phnum, size_t n,
661 GElf_Addr addrs[n], GElf_Off offs[n])
662 {
663 size_t unsolved = n;
664 for (size_t i = 0; i < phnum; ++i)
665 {
666 GElf_Phdr phdr_mem;
667 GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
668 if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
669 for (size_t j = 0; j < n; ++j)
670 if (offs[j] == 0
671 && addrs[j] >= phdr->p_vaddr + main_bias
672 && addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz)
673 {
674 offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset;
675 if (--unsolved == 0)
676 break;
677 }
678 }
679 }
680
681 /* Various addresses we might want to pull from the dynamic segment. */
682 enum
683 {
684 i_symtab,
685 i_strtab,
686 i_hash,
687 i_gnu_hash,
688 i_max
689 };
690
691 /* Translate pointers into file offsets. ADJUST is either zero
692 in case the dynamic segment wasn't adjusted or mod->main_bias.
693 Will set mod->symfile if the translated offsets can be used as
694 symbol table. */
695 static void
translate_offs(GElf_Addr adjust,Dwfl_Module * mod,size_t phnum,GElf_Addr addrs[i_max],GElf_Xword strsz,GElf_Ehdr * ehdr)696 translate_offs (GElf_Addr adjust,
697 Dwfl_Module *mod, size_t phnum,
698 GElf_Addr addrs[i_max], GElf_Xword strsz,
699 GElf_Ehdr *ehdr)
700 {
701 GElf_Off offs[i_max] = { 0, };
702 find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, offs);
703
704 /* Figure out the size of the symbol table. */
705 if (offs[i_hash] != 0)
706 {
707 /* In the original format, .hash says the size of .dynsym. */
708
709 size_t entsz = SH_ENTSIZE_HASH (ehdr);
710 Elf_Data *data = elf_getdata_rawchunk (mod->main.elf,
711 offs[i_hash] + entsz, entsz,
712 (entsz == 4
713 ? ELF_T_WORD : ELF_T_XWORD));
714 if (data != NULL)
715 mod->syments = (entsz == 4
716 ? *(const GElf_Word *) data->d_buf
717 : *(const GElf_Xword *) data->d_buf);
718 }
719 if (offs[i_gnu_hash] != 0 && mod->syments == 0)
720 {
721 /* In the new format, we can derive it with some work. */
722
723 const struct
724 {
725 Elf32_Word nbuckets;
726 Elf32_Word symndx;
727 Elf32_Word maskwords;
728 Elf32_Word shift2;
729 } *header;
730
731 Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash],
732 sizeof *header, ELF_T_WORD);
733 if (data != NULL)
734 {
735 header = data->d_buf;
736 Elf32_Word nbuckets = header->nbuckets;
737 Elf32_Word symndx = header->symndx;
738 GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header
739 + (gelf_getclass (mod->main.elf)
740 * sizeof (Elf32_Word)
741 * header->maskwords));
742
743 // elf_getdata_rawchunk takes a size_t, make sure it
744 // doesn't overflow.
745 #if SIZE_MAX <= UINT32_MAX
746 if (nbuckets > SIZE_MAX / sizeof (Elf32_Word))
747 data = NULL;
748 else
749 #endif
750 data = elf_getdata_rawchunk (mod->main.elf, buckets_at,
751 nbuckets * sizeof (Elf32_Word),
752 ELF_T_WORD);
753 if (data != NULL && symndx < nbuckets)
754 {
755 const Elf32_Word *const buckets = data->d_buf;
756 Elf32_Word maxndx = symndx;
757 for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
758 if (buckets[bucket] > maxndx)
759 maxndx = buckets[bucket];
760
761 GElf_Off hasharr_at = (buckets_at
762 + nbuckets * sizeof (Elf32_Word));
763 hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
764 do
765 {
766 data = elf_getdata_rawchunk (mod->main.elf,
767 hasharr_at,
768 sizeof (Elf32_Word),
769 ELF_T_WORD);
770 if (data != NULL
771 && (*(const Elf32_Word *) data->d_buf & 1u))
772 {
773 mod->syments = maxndx + 1;
774 break;
775 }
776 ++maxndx;
777 hasharr_at += sizeof (Elf32_Word);
778 }
779 while (data != NULL);
780 }
781 }
782 }
783 if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0)
784 mod->syments = ((offs[i_strtab] - offs[i_symtab])
785 / gelf_fsize (mod->main.elf,
786 ELF_T_SYM, 1, EV_CURRENT));
787
788 if (mod->syments > 0)
789 {
790 mod->symdata = elf_getdata_rawchunk (mod->main.elf,
791 offs[i_symtab],
792 gelf_fsize (mod->main.elf,
793 ELF_T_SYM,
794 mod->syments,
795 EV_CURRENT),
796 ELF_T_SYM);
797 if (mod->symdata != NULL)
798 {
799 mod->symstrdata = elf_getdata_rawchunk (mod->main.elf,
800 offs[i_strtab],
801 strsz,
802 ELF_T_BYTE);
803 if (mod->symstrdata == NULL)
804 mod->symdata = NULL;
805 }
806 if (mod->symdata == NULL)
807 mod->symerr = DWFL_E (LIBELF, elf_errno ());
808 else
809 {
810 mod->symfile = &mod->main;
811 mod->symerr = DWFL_E_NOERROR;
812 }
813 }
814 }
815
816 /* Try to find a dynamic symbol table via phdrs. */
817 static void
find_dynsym(Dwfl_Module * mod)818 find_dynsym (Dwfl_Module *mod)
819 {
820 GElf_Ehdr ehdr_mem;
821 GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem);
822
823 size_t phnum;
824 if (unlikely (elf_getphdrnum (mod->main.elf, &phnum) != 0))
825 return;
826
827 for (size_t i = 0; i < phnum; ++i)
828 {
829 GElf_Phdr phdr_mem;
830 GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
831 if (phdr == NULL)
832 break;
833
834 if (phdr->p_type == PT_DYNAMIC)
835 {
836 /* Examine the dynamic section for the pointers we need. */
837
838 Elf_Data *data = elf_getdata_rawchunk (mod->main.elf,
839 phdr->p_offset, phdr->p_filesz,
840 ELF_T_DYN);
841 if (data == NULL)
842 continue;
843
844 GElf_Addr addrs[i_max] = { 0, };
845 GElf_Xword strsz = 0;
846 size_t n = data->d_size / gelf_fsize (mod->main.elf,
847 ELF_T_DYN, 1, EV_CURRENT);
848 for (size_t j = 0; j < n; ++j)
849 {
850 GElf_Dyn dyn_mem;
851 GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
852 if (dyn != NULL)
853 switch (dyn->d_tag)
854 {
855 case DT_SYMTAB:
856 addrs[i_symtab] = dyn->d_un.d_ptr;
857 continue;
858
859 case DT_HASH:
860 addrs[i_hash] = dyn->d_un.d_ptr;
861 continue;
862
863 case DT_GNU_HASH:
864 addrs[i_gnu_hash] = dyn->d_un.d_ptr;
865 continue;
866
867 case DT_STRTAB:
868 addrs[i_strtab] = dyn->d_un.d_ptr;
869 continue;
870
871 case DT_STRSZ:
872 strsz = dyn->d_un.d_val;
873 continue;
874
875 default:
876 continue;
877
878 case DT_NULL:
879 break;
880 }
881 break;
882 }
883
884 /* First try unadjusted, like ELF files from disk, vdso.
885 Then try for already adjusted dynamic section, like ELF
886 from remote memory. */
887 translate_offs (0, mod, phnum, addrs, strsz, ehdr);
888 if (mod->symfile == NULL)
889 translate_offs (mod->main_bias, mod, phnum, addrs, strsz, ehdr);
890
891 return;
892 }
893 }
894 }
895
896
897 #if USE_LZMA
898 /* Try to find the offset between the main file and .gnu_debugdata. */
899 static bool
find_aux_address_sync(Dwfl_Module * mod)900 find_aux_address_sync (Dwfl_Module *mod)
901 {
902 /* Don't trust the phdrs in the minisymtab elf file to be setup correctly.
903 The address_sync is equal to the main file it is embedded in at first. */
904 mod->aux_sym.address_sync = mod->main.address_sync;
905
906 /* Adjust address_sync for the difference in entry addresses, attempting to
907 account for ELF relocation changes after aux was split. */
908 GElf_Ehdr ehdr_main, ehdr_aux;
909 if (unlikely (gelf_getehdr (mod->main.elf, &ehdr_main) == NULL)
910 || unlikely (gelf_getehdr (mod->aux_sym.elf, &ehdr_aux) == NULL))
911 return false;
912 mod->aux_sym.address_sync += ehdr_aux.e_entry - ehdr_main.e_entry;
913
914 /* The shdrs are setup OK to make find_prelink_address_sync () do the right
915 thing, which is possibly more reliable, but it needs .gnu.prelink_undo. */
916 if (mod->aux_sym.address_sync != 0)
917 return find_prelink_address_sync (mod, &mod->aux_sym) == DWFL_E_NOERROR;
918
919 return true;
920 }
921 #endif
922
923 /* Try to find the auxiliary symbol table embedded in the main elf file
924 section .gnu_debugdata. Only matters if the symbol information comes
925 from the main file dynsym. No harm done if not found. */
926 static void
find_aux_sym(Dwfl_Module * mod,Elf_Scn ** aux_symscn,Elf_Scn ** aux_xndxscn,GElf_Word * aux_strshndx)927 find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)),
928 Elf_Scn **aux_symscn __attribute__ ((unused)),
929 Elf_Scn **aux_xndxscn __attribute__ ((unused)),
930 GElf_Word *aux_strshndx __attribute__ ((unused)))
931 {
932 /* Since a .gnu_debugdata section is compressed using lzma don't do
933 anything unless we have support for that. */
934 #if USE_LZMA
935 Elf *elf = mod->main.elf;
936
937 size_t shstrndx;
938 if (elf_getshdrstrndx (elf, &shstrndx) < 0)
939 return;
940
941 Elf_Scn *scn = NULL;
942 while ((scn = elf_nextscn (elf, scn)) != NULL)
943 {
944 GElf_Shdr shdr_mem;
945 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
946 if (shdr == NULL)
947 return;
948
949 const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
950 if (name == NULL)
951 return;
952
953 if (!strcmp (name, ".gnu_debugdata"))
954 break;
955 }
956
957 if (scn == NULL)
958 return;
959
960 /* Found the .gnu_debugdata section. Uncompress the lzma image and
961 turn it into an ELF image. */
962 Elf_Data *rawdata = elf_rawdata (scn, NULL);
963 if (rawdata == NULL)
964 return;
965
966 Dwfl_Error error;
967 void *buffer = NULL;
968 size_t size = 0;
969 error = __libdw_unlzma (-1, 0, rawdata->d_buf, rawdata->d_size,
970 &buffer, &size);
971 if (error == DWFL_E_NOERROR)
972 {
973 if (unlikely (size == 0))
974 free (buffer);
975 else
976 {
977 mod->aux_sym.elf = elf_memory (buffer, size);
978 if (mod->aux_sym.elf == NULL)
979 free (buffer);
980 else
981 {
982 mod->aux_sym.fd = -1;
983 mod->aux_sym.elf->flags |= ELF_F_MALLOCED;
984 if (open_elf (mod, &mod->aux_sym) != DWFL_E_NOERROR)
985 return;
986 if (! find_aux_address_sync (mod))
987 {
988 elf_end (mod->aux_sym.elf);
989 mod->aux_sym.elf = NULL;
990 return;
991 }
992
993 /* So far, so good. Get minisymtab table data and cache it. */
994 bool minisymtab = false;
995 scn = NULL;
996 while ((scn = elf_nextscn (mod->aux_sym.elf, scn)) != NULL)
997 {
998 GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
999 if (shdr != NULL)
1000 switch (shdr->sh_type)
1001 {
1002 case SHT_SYMTAB:
1003 minisymtab = true;
1004 *aux_symscn = scn;
1005 *aux_strshndx = shdr->sh_link;
1006 mod->aux_syments = shdr->sh_size / shdr->sh_entsize;
1007 mod->aux_first_global = shdr->sh_info;
1008 if (*aux_xndxscn != NULL)
1009 return;
1010 break;
1011
1012 case SHT_SYMTAB_SHNDX:
1013 *aux_xndxscn = scn;
1014 if (minisymtab)
1015 return;
1016 break;
1017
1018 default:
1019 break;
1020 }
1021 }
1022
1023 if (minisymtab)
1024 /* We found one, though no SHT_SYMTAB_SHNDX to go with it. */
1025 return;
1026
1027 /* We found no SHT_SYMTAB, so everything else is bogus. */
1028 *aux_xndxscn = NULL;
1029 *aux_strshndx = 0;
1030 mod->aux_syments = 0;
1031 elf_end (mod->aux_sym.elf);
1032 mod->aux_sym.elf = NULL;
1033 return;
1034 }
1035 }
1036 }
1037 else
1038 free (buffer);
1039 #endif
1040 }
1041
1042 /* Try to find a symbol table in either MOD->main.elf or MOD->debug.elf. */
1043 static void
find_symtab(Dwfl_Module * mod)1044 find_symtab (Dwfl_Module *mod)
1045 {
1046 if (mod->symdata != NULL || mod->aux_symdata != NULL /* Already done. */
1047 || mod->symerr != DWFL_E_NOERROR) /* Cached previous failure. */
1048 return;
1049
1050 __libdwfl_getelf (mod);
1051 mod->symerr = mod->elferr;
1052 if (mod->symerr != DWFL_E_NOERROR)
1053 return;
1054
1055 /* First see if the main ELF file has the debugging information. */
1056 Elf_Scn *symscn = NULL, *xndxscn = NULL;
1057 Elf_Scn *aux_symscn = NULL, *aux_xndxscn = NULL;
1058 GElf_Word strshndx, aux_strshndx = 0;
1059 mod->symerr = load_symtab (&mod->main, &mod->symfile, &symscn,
1060 &xndxscn, &mod->syments, &mod->first_global,
1061 &strshndx);
1062 switch (mod->symerr)
1063 {
1064 default:
1065 return;
1066
1067 case DWFL_E_NOERROR:
1068 break;
1069
1070 case DWFL_E_NO_SYMTAB:
1071 /* Now we have to look for a separate debuginfo file. */
1072 mod->symerr = find_debuginfo (mod);
1073 switch (mod->symerr)
1074 {
1075 default:
1076 return;
1077
1078 case DWFL_E_NOERROR:
1079 mod->symerr = load_symtab (&mod->debug, &mod->symfile, &symscn,
1080 &xndxscn, &mod->syments,
1081 &mod->first_global, &strshndx);
1082 break;
1083
1084 case DWFL_E_CB: /* The find_debuginfo hook failed. */
1085 mod->symerr = DWFL_E_NO_SYMTAB;
1086 break;
1087 }
1088
1089 switch (mod->symerr)
1090 {
1091 default:
1092 return;
1093
1094 case DWFL_E_NOERROR:
1095 break;
1096
1097 case DWFL_E_NO_SYMTAB:
1098 /* There might be an auxiliary table. */
1099 find_aux_sym (mod, &aux_symscn, &aux_xndxscn, &aux_strshndx);
1100
1101 if (symscn != NULL)
1102 {
1103 /* We still have the dynamic symbol table. */
1104 mod->symerr = DWFL_E_NOERROR;
1105 break;
1106 }
1107
1108 if (aux_symscn != NULL)
1109 {
1110 /* We still have the auxiliary symbol table. */
1111 mod->symerr = DWFL_E_NOERROR;
1112 goto aux_cache;
1113 }
1114
1115 /* Last ditch, look for dynamic symbols without section headers. */
1116 find_dynsym (mod);
1117 return;
1118 }
1119 break;
1120 }
1121
1122 /* This does some sanity checks on the string table section. */
1123 if (elf_strptr (mod->symfile->elf, strshndx, 0) == NULL)
1124 {
1125 elferr:
1126 mod->symdata = NULL;
1127 mod->syments = 0;
1128 mod->first_global = 0;
1129 mod->symerr = DWFL_E (LIBELF, elf_errno ());
1130 goto aux_cleanup; /* This cleans up some more and tries find_dynsym. */
1131 }
1132
1133 /* Cache the data; MOD->syments and MOD->first_global were set
1134 above. If any of the sections is compressed, uncompress it
1135 first. Only the string data setion could theoretically be
1136 compressed GNU style (as .zdebug_str). Everything else only ELF
1137 gabi style (SHF_COMPRESSED). */
1138
1139 Elf_Scn *symstrscn = elf_getscn (mod->symfile->elf, strshndx);
1140 if (symstrscn == NULL)
1141 goto elferr;
1142
1143 GElf_Shdr shdr_mem;
1144 GElf_Shdr *shdr = gelf_getshdr (symstrscn, &shdr_mem);
1145 if (shdr == NULL)
1146 goto elferr;
1147
1148 size_t shstrndx;
1149 if (elf_getshdrstrndx (mod->symfile->elf, &shstrndx) < 0)
1150 goto elferr;
1151
1152 const char *sname = elf_strptr (mod->symfile->elf, shstrndx, shdr->sh_name);
1153 if (sname == NULL)
1154 goto elferr;
1155
1156 if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
1157 /* Try to uncompress, but it might already have been, an error
1158 might just indicate, already uncompressed. */
1159 elf_compress_gnu (symstrscn, 0, 0);
1160
1161 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1162 if (elf_compress (symstrscn, 0, 0) < 0)
1163 goto elferr;
1164
1165 mod->symstrdata = elf_getdata (symstrscn, NULL);
1166 if (mod->symstrdata == NULL || mod->symstrdata->d_buf == NULL)
1167 goto elferr;
1168
1169 if (xndxscn == NULL)
1170 mod->symxndxdata = NULL;
1171 else
1172 {
1173 shdr = gelf_getshdr (xndxscn, &shdr_mem);
1174 if (shdr == NULL)
1175 goto elferr;
1176
1177 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1178 if (elf_compress (xndxscn, 0, 0) < 0)
1179 goto elferr;
1180
1181 mod->symxndxdata = elf_getdata (xndxscn, NULL);
1182 if (mod->symxndxdata == NULL || mod->symxndxdata->d_buf == NULL)
1183 goto elferr;
1184 }
1185
1186 shdr = gelf_getshdr (symscn, &shdr_mem);
1187 if (shdr == NULL)
1188 goto elferr;
1189
1190 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1191 if (elf_compress (symscn, 0, 0) < 0)
1192 goto elferr;
1193
1194 mod->symdata = elf_getdata (symscn, NULL);
1195 if (mod->symdata == NULL || mod->symdata->d_buf == NULL)
1196 goto elferr;
1197
1198 // Sanity check number of symbols.
1199 shdr = gelf_getshdr (symscn, &shdr_mem);
1200 if (shdr == NULL || shdr->sh_entsize == 0
1201 || mod->syments > mod->symdata->d_size / shdr->sh_entsize
1202 || (size_t) mod->first_global > mod->syments)
1203 goto elferr;
1204
1205 /* Cache any auxiliary symbol info, when it fails, just ignore aux_sym. */
1206 if (aux_symscn != NULL)
1207 {
1208 aux_cache:
1209 /* This does some sanity checks on the string table section. */
1210 if (elf_strptr (mod->aux_sym.elf, aux_strshndx, 0) == NULL)
1211 {
1212 aux_cleanup:
1213 mod->aux_syments = 0;
1214 elf_end (mod->aux_sym.elf);
1215 mod->aux_sym.elf = NULL;
1216 /* We thought we had something through shdrs, but it failed...
1217 Last ditch, look for dynamic symbols without section headers. */
1218 find_dynsym (mod);
1219 return;
1220 }
1221
1222 Elf_Scn *aux_strscn = elf_getscn (mod->aux_sym.elf, aux_strshndx);
1223 if (aux_strscn == NULL)
1224 goto elferr;
1225
1226 shdr = gelf_getshdr (aux_strscn, &shdr_mem);
1227 if (shdr == NULL)
1228 goto elferr;
1229
1230 size_t aux_shstrndx;
1231 if (elf_getshdrstrndx (mod->aux_sym.elf, &aux_shstrndx) < 0)
1232 goto elferr;
1233
1234 sname = elf_strptr (mod->aux_sym.elf, aux_shstrndx,
1235 shdr->sh_name);
1236 if (sname == NULL)
1237 goto elferr;
1238
1239 if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
1240 /* Try to uncompress, but it might already have been, an error
1241 might just indicate, already uncompressed. */
1242 elf_compress_gnu (aux_strscn, 0, 0);
1243
1244 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1245 if (elf_compress (aux_strscn, 0, 0) < 0)
1246 goto elferr;
1247
1248 mod->aux_symstrdata = elf_getdata (aux_strscn, NULL);
1249 if (mod->aux_symstrdata == NULL || mod->aux_symstrdata->d_buf == NULL)
1250 goto aux_cleanup;
1251
1252 if (aux_xndxscn == NULL)
1253 mod->aux_symxndxdata = NULL;
1254 else
1255 {
1256 shdr = gelf_getshdr (aux_xndxscn, &shdr_mem);
1257 if (shdr == NULL)
1258 goto elferr;
1259
1260 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1261 if (elf_compress (aux_xndxscn, 0, 0) < 0)
1262 goto elferr;
1263
1264 mod->aux_symxndxdata = elf_getdata (aux_xndxscn, NULL);
1265 if (mod->aux_symxndxdata == NULL
1266 || mod->aux_symxndxdata->d_buf == NULL)
1267 goto aux_cleanup;
1268 }
1269
1270 shdr = gelf_getshdr (aux_symscn, &shdr_mem);
1271 if (shdr == NULL)
1272 goto elferr;
1273
1274 if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
1275 if (elf_compress (aux_symscn, 0, 0) < 0)
1276 goto elferr;
1277
1278 mod->aux_symdata = elf_getdata (aux_symscn, NULL);
1279 if (mod->aux_symdata == NULL || mod->aux_symdata->d_buf == NULL)
1280 goto aux_cleanup;
1281
1282 // Sanity check number of aux symbols.
1283 shdr = gelf_getshdr (aux_symscn, &shdr_mem);
1284 if (mod->aux_syments > mod->aux_symdata->d_size / shdr->sh_entsize
1285 || (size_t) mod->aux_first_global > mod->aux_syments)
1286 goto aux_cleanup;
1287 }
1288 }
1289
1290
1291 /* Try to open a libebl backend for MOD. */
1292 Dwfl_Error
1293 internal_function
__libdwfl_module_getebl(Dwfl_Module * mod)1294 __libdwfl_module_getebl (Dwfl_Module *mod)
1295 {
1296 if (mod->ebl == NULL)
1297 {
1298 __libdwfl_getelf (mod);
1299 if (mod->elferr != DWFL_E_NOERROR)
1300 return mod->elferr;
1301
1302 mod->ebl = ebl_openbackend (mod->main.elf);
1303 if (mod->ebl == NULL)
1304 return DWFL_E_LIBEBL;
1305 }
1306 return DWFL_E_NOERROR;
1307 }
1308
1309 /* Try to start up libdw on DEBUGFILE. */
1310 static Dwfl_Error
load_dw(Dwfl_Module * mod,struct dwfl_file * debugfile)1311 load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
1312 {
1313 if (mod->e_type == ET_REL && !debugfile->relocated)
1314 {
1315 const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
1316
1317 /* The debugging sections have to be relocated. */
1318 if (cb->section_address == NULL)
1319 return DWFL_E_NOREL;
1320
1321 Dwfl_Error error = __libdwfl_module_getebl (mod);
1322 if (error != DWFL_E_NOERROR)
1323 return error;
1324
1325 find_symtab (mod);
1326 Dwfl_Error result = mod->symerr;
1327 if (result == DWFL_E_NOERROR)
1328 result = __libdwfl_relocate (mod, debugfile->elf, true);
1329 if (result != DWFL_E_NOERROR)
1330 return result;
1331
1332 /* Don't keep the file descriptors around. */
1333 if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
1334 {
1335 close (mod->main.fd);
1336 mod->main.fd = -1;
1337 }
1338 if (debugfile->fd != -1 && elf_cntl (debugfile->elf, ELF_C_FDREAD) == 0)
1339 {
1340 close (debugfile->fd);
1341 debugfile->fd = -1;
1342 }
1343 }
1344
1345 mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL);
1346 if (mod->dw == NULL)
1347 {
1348 int err = INTUSE(dwarf_errno) ();
1349 return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err);
1350 }
1351
1352 /* Until we have iterated through all CU's, we might do lazy lookups. */
1353 mod->lazycu = 1;
1354
1355 return DWFL_E_NOERROR;
1356 }
1357
1358 /* Try to start up libdw on either the main file or the debuginfo file. */
1359 static void
find_dw(Dwfl_Module * mod)1360 find_dw (Dwfl_Module *mod)
1361 {
1362 if (mod->dw != NULL /* Already done. */
1363 || mod->dwerr != DWFL_E_NOERROR) /* Cached previous failure. */
1364 return;
1365
1366 __libdwfl_getelf (mod);
1367 mod->dwerr = mod->elferr;
1368 if (mod->dwerr != DWFL_E_NOERROR)
1369 return;
1370
1371 /* First see if the main ELF file has the debugging information. */
1372 mod->dwerr = load_dw (mod, &mod->main);
1373 switch (mod->dwerr)
1374 {
1375 case DWFL_E_NOERROR:
1376 mod->debug.elf = mod->main.elf;
1377 mod->debug.address_sync = mod->main.address_sync;
1378
1379 /* The Dwarf might need an alt debug file, find that now after
1380 everything about the debug file has been setup (the
1381 find_debuginfo callback might need it). */
1382 find_debug_altlink (mod, mod->main.name);
1383 return;
1384
1385 case DWFL_E_NO_DWARF:
1386 break;
1387
1388 default:
1389 goto canonicalize;
1390 }
1391
1392 /* Now we have to look for a separate debuginfo file. */
1393 mod->dwerr = find_debuginfo (mod);
1394 switch (mod->dwerr)
1395 {
1396 case DWFL_E_NOERROR:
1397 mod->dwerr = load_dw (mod, &mod->debug);
1398 if (mod->dwerr == DWFL_E_NOERROR)
1399 {
1400 /* The Dwarf might need an alt debug file, find that now after
1401 everything about the debug file has been setup (the
1402 find_debuginfo callback might need it). */
1403 find_debug_altlink (mod, mod->debug.name);
1404 return;
1405 }
1406
1407 break;
1408
1409 case DWFL_E_CB: /* The find_debuginfo hook failed. */
1410 mod->dwerr = DWFL_E_NO_DWARF;
1411 return;
1412
1413 default:
1414 break;
1415 }
1416
1417 canonicalize:
1418 mod->dwerr = __libdwfl_canon_error (mod->dwerr);
1419 }
1420
1421 Dwarf *
dwfl_module_getdwarf(Dwfl_Module * mod,Dwarf_Addr * bias)1422 dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
1423 {
1424 if (mod == NULL)
1425 return NULL;
1426
1427 find_dw (mod);
1428 if (mod->dwerr == DWFL_E_NOERROR)
1429 {
1430 /* If dwfl_module_getelf was used previously, then partial apply
1431 relocation to miscellaneous sections in the debug file too. */
1432 if (mod->e_type == ET_REL
1433 && mod->main.relocated && ! mod->debug.relocated)
1434 {
1435 mod->debug.relocated = true;
1436 if (mod->debug.elf != mod->main.elf)
1437 (void) __libdwfl_relocate (mod, mod->debug.elf, false);
1438 }
1439
1440 *bias = dwfl_adjusted_dwarf_addr (mod, 0);
1441 return mod->dw;
1442 }
1443
1444 __libdwfl_seterrno (mod->dwerr);
1445 return NULL;
1446 }
INTDEF(dwfl_module_getdwarf)1447 INTDEF (dwfl_module_getdwarf)
1448
1449 int
1450 dwfl_module_getsymtab (Dwfl_Module *mod)
1451 {
1452 if (mod == NULL)
1453 return -1;
1454
1455 find_symtab (mod);
1456 if (mod->symerr == DWFL_E_NOERROR)
1457 /* We will skip the auxiliary zero entry if there is another one. */
1458 return (mod->syments + mod->aux_syments
1459 - (mod->syments > 0 && mod->aux_syments > 0 ? 1 : 0));
1460
1461 __libdwfl_seterrno (mod->symerr);
1462 return -1;
1463 }
INTDEF(dwfl_module_getsymtab)1464 INTDEF (dwfl_module_getsymtab)
1465
1466 int
1467 dwfl_module_getsymtab_first_global (Dwfl_Module *mod)
1468 {
1469 if (mod == NULL)
1470 return -1;
1471
1472 find_symtab (mod);
1473 if (mod->symerr == DWFL_E_NOERROR)
1474 {
1475 /* All local symbols should come before all global symbols. If
1476 we have an auxiliary table make sure all the main locals come
1477 first, then all aux locals, then all main globals and finally all
1478 aux globals. And skip the auxiliary table zero undefined
1479 entry. */
1480 int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
1481 return mod->first_global + mod->aux_first_global - skip_aux_zero;
1482 }
1483
1484 __libdwfl_seterrno (mod->symerr);
1485 return -1;
1486 }
1487 INTDEF (dwfl_module_getsymtab_first_global)
1488