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