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