Home | History | Annotate | Download | only in libdwfl
      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
     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
     72 open_elf (Dwfl_Module *mod, struct dwfl_file *file)
     73 {
     74   Dwfl_Error error = open_elf_file (&file->elf, &file->fd, &file->name);
     75   if (error != DWFL_E_NOERROR)
     76     return error;
     77 
     78   GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
     79   if (ehdr == NULL)
     80     {
     81     elf_error:
     82       elf_end (file->elf);
     83       file->elf = NULL;
     84       close (file->fd);
     85       file->fd = -1;
     86       return DWFL_E (LIBELF, elf_errno ());
     87     }
     88 
     89   if (ehdr->e_type != ET_REL)
     90     {
     91       /* In any non-ET_REL file, we compute the "synchronization address".
     92 
     93 	 We start with the address at the end of the first PT_LOAD
     94 	 segment.  When prelink converts REL to RELA in an ET_DYN
     95 	 file, it expands the space between the beginning of the
     96 	 segment and the actual code/data addresses.  Since that
     97 	 change wasn't made in the debug file, the distance from
     98 	 p_vaddr to an address of interest (in an st_value or DWARF
     99 	 data) now differs between the main and debug files.  The
    100 	 distance from address_sync to an address of interest remains
    101 	 consistent.
    102 
    103 	 If there are no section headers at all (full stripping), then
    104 	 the end of the first segment is a valid synchronization address.
    105 	 This cannot happen in a prelinked file, since prelink itself
    106 	 relies on section headers for prelinking and for undoing it.
    107 	 (If you do full stripping on a prelinked file, then you get what
    108 	 you deserve--you can neither undo the prelinking, nor expect to
    109 	 line it up with a debug file separated before prelinking.)
    110 
    111 	 However, when prelink processes an ET_EXEC file, it can do
    112 	 something different.  There it juggles the "special" sections
    113 	 (SHT_DYNSYM et al) to make space for the additional prelink
    114 	 special sections.  Sometimes it will do this by moving a special
    115 	 section like .dynstr after the real program sections in the first
    116 	 PT_LOAD segment--i.e. to the end.  That changes the end address of
    117 	 the segment, so it no longer lines up correctly and is not a valid
    118 	 synchronization address to use.  Because of this, we need to apply
    119 	 a different prelink-savvy means to discover the synchronization
    120 	 address when there is a separate debug file and a prelinked main
    121 	 file.  That is done in find_debuginfo, below.  */
    122 
    123       size_t phnum;
    124       if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0))
    125 	goto elf_error;
    126 
    127       file->vaddr = file->address_sync = 0;
    128       for (size_t i = 0; i < phnum; ++i)
    129 	{
    130 	  GElf_Phdr ph_mem;
    131 	  GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
    132 	  if (unlikely (ph == NULL))
    133 	    goto elf_error;
    134 	  if (ph->p_type == PT_LOAD)
    135 	    {
    136 	      file->vaddr = ph->p_vaddr & -ph->p_align;
    137 	      file->address_sync = ph->p_vaddr + ph->p_memsz;
    138 	      break;
    139 	    }
    140 	}
    141     }
    142 
    143   /* We only want to set the module e_type explictly once, derived from
    144      the main ELF file.  (It might be changed for the kernel, because
    145      that is special - see below.)  open_elf is always called first for
    146      the main ELF file, because both find_dw and find_symtab call
    147      __libdwfl_getelf first to open the main file.  So don't let debug
    148      or aux files override the module e_type.  The kernel heuristic
    149      below could otherwise trigger for non-kernel/non-main files, since
    150      their phdrs might not match the actual load addresses.  */
    151   if (file == &mod->main)
    152     {
    153       mod->e_type = ehdr->e_type;
    154 
    155       /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN.  */
    156       if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr)
    157 	mod->e_type = ET_DYN;
    158     }
    159   else
    160     assert (mod->main.elf != NULL);
    161 
    162   return DWFL_E_NOERROR;
    163 }
    164 
    165 /* We have an authoritative build ID for this module MOD, so don't use
    166    a file by name that doesn't match that ID.  */
    167 static void
    168 mod_verify_build_id (Dwfl_Module *mod)
    169 {
    170   assert (mod->build_id_len > 0);
    171 
    172   switch (__builtin_expect (__libdwfl_find_build_id (mod, false,
    173 						     mod->main.elf), 2))
    174     {
    175     case 2:
    176       /* Build ID matches as it should. */
    177       return;
    178 
    179     case -1:			/* ELF error.  */
    180       mod->elferr = INTUSE(dwfl_errno) ();
    181       break;
    182 
    183     case 0:			/* File has no build ID note.  */
    184     case 1:			/* FIle has a build ID that does not match.  */
    185       mod->elferr = DWFL_E_WRONG_ID_ELF;
    186       break;
    187 
    188     default:
    189       abort ();
    190     }
    191 
    192   /* We get here when it was the right ELF file.  Clear it out.  */
    193   elf_end (mod->main.elf);
    194   mod->main.elf = NULL;
    195   if (mod->main.fd >= 0)
    196     {
    197       close (mod->main.fd);
    198       mod->main.fd = -1;
    199     }
    200 }
    201 
    202 /* Find the main ELF file for this module and open libelf on it.
    203    When we return success, MOD->main.elf and MOD->main.bias are set up.  */
    204 void
    205 internal_function
    206 __libdwfl_getelf (Dwfl_Module *mod)
    207 {
    208   if (mod->main.elf != NULL	/* Already done.  */
    209       || mod->elferr != DWFL_E_NOERROR)	/* Cached failure.  */
    210     return;
    211 
    212   mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod),
    213 						    &mod->main.name,
    214 						    &mod->main.elf);
    215   const bool fallback = mod->main.elf == NULL && mod->main.fd < 0;
    216   mod->elferr = open_elf (mod, &mod->main);
    217   if (mod->elferr != DWFL_E_NOERROR)
    218     return;
    219 
    220   if (!mod->main.valid)
    221     {
    222       /* Clear any explicitly reported build ID, just in case it was wrong.
    223 	 We'll fetch it from the file when asked.  */
    224       free (mod->build_id_bits);
    225       mod->build_id_bits = NULL;
    226       mod->build_id_len = 0;
    227     }
    228   else if (fallback)
    229     mod_verify_build_id (mod);
    230 
    231   mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
    232 }
    233 
    234 /* 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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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
   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 *
   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 }
   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 }
   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