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