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