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