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