Home | History | Annotate | Download | only in libdwfl
      1 /* Sniff out modules from ELF headers visible in memory segments.
      2    Copyright (C) 2008-2012, 2014, 2015 Red Hat, Inc.
      3    This file is part of elfutils.
      4 
      5    This file is free software; you can redistribute it and/or modify
      6    it under the terms of either
      7 
      8      * the GNU Lesser General Public License as published by the Free
      9        Software Foundation; either version 3 of the License, or (at
     10        your option) any later version
     11 
     12    or
     13 
     14      * the GNU General Public License as published by the Free
     15        Software Foundation; either version 2 of the License, or (at
     16        your option) any later version
     17 
     18    or both in parallel, as here.
     19 
     20    elfutils is distributed in the hope that it will be useful, but
     21    WITHOUT ANY WARRANTY; without even the implied warranty of
     22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23    General Public License for more details.
     24 
     25    You should have received copies of the GNU General Public License and
     26    the GNU Lesser General Public License along with this program.  If
     27    not, see <http://www.gnu.org/licenses/>.  */
     28 
     29 #include <config.h>
     30 #include "../libelf/libelfP.h"	/* For NOTE_ALIGN.  */
     31 #undef	_
     32 #include "libdwflP.h"
     33 #include "common.h"
     34 
     35 #include <elf.h>
     36 #include <gelf.h>
     37 #include <inttypes.h>
     38 #include <sys/param.h>
     39 #include <endian.h>
     40 #include <unistd.h>
     41 #include <fcntl.h>
     42 
     43 
     44 /* A good size for the initial read from memory, if it's not too costly.
     45    This more than covers the phdrs and note segment in the average 64-bit
     46    binary.  */
     47 
     48 #define INITIAL_READ	1024
     49 
     50 #if __BYTE_ORDER == __LITTLE_ENDIAN
     51 # define MY_ELFDATA	ELFDATA2LSB
     52 #else
     53 # define MY_ELFDATA	ELFDATA2MSB
     54 #endif
     55 
     56 #ifndef MAX
     57 # define MAX(a, b) ((a) > (b) ? (a) : (b))
     58 #endif
     59 
     60 
     61 /* Return user segment index closest to ADDR but not above it.
     62    If NEXT, return the closest to ADDR but not below it.  */
     63 static int
     64 addr_segndx (Dwfl *dwfl, size_t segment, GElf_Addr addr, bool next)
     65 {
     66   int ndx = -1;
     67   do
     68     {
     69       if (dwfl->lookup_segndx[segment] >= 0)
     70 	ndx = dwfl->lookup_segndx[segment];
     71       if (++segment >= dwfl->lookup_elts - 1)
     72 	return next ? ndx + 1 : ndx;
     73     }
     74   while (dwfl->lookup_addr[segment] < addr);
     75 
     76   if (next)
     77     {
     78       while (dwfl->lookup_segndx[segment] < 0)
     79 	if (++segment >= dwfl->lookup_elts - 1)
     80 	  return ndx + 1;
     81       ndx = dwfl->lookup_segndx[segment];
     82     }
     83 
     84   return ndx;
     85 }
     86 
     87 /* Return whether there is SZ bytes available at PTR till END.  */
     88 
     89 static bool
     90 buf_has_data (const void *ptr, const void *end, size_t sz)
     91 {
     92   return ptr < end && (size_t) (end - ptr) >= sz;
     93 }
     94 
     95 /* Read SZ bytes into *RETP from *PTRP (limited by END) in format EI_DATA.
     96    Function comes from src/readelf.c .  */
     97 
     98 static bool
     99 buf_read_ulong (unsigned char ei_data, size_t sz,
    100 		const void **ptrp, const void *end, uint64_t *retp)
    101 {
    102   if (! buf_has_data (*ptrp, end, sz))
    103     return false;
    104 
    105   union
    106   {
    107     uint64_t u64;
    108     uint32_t u32;
    109   } u;
    110 
    111   memcpy (&u, *ptrp, sz);
    112   (*ptrp) += sz;
    113 
    114   if (retp == NULL)
    115     return true;
    116 
    117   if (MY_ELFDATA != ei_data)
    118     {
    119       if (sz == 4)
    120 	CONVERT (u.u32);
    121       else
    122 	CONVERT (u.u64);
    123     }
    124   if (sz == 4)
    125     *retp = u.u32;
    126   else
    127     *retp = u.u64;
    128   return true;
    129 }
    130 
    131 /* Try to find matching entry for module from address MODULE_START to
    132    MODULE_END in NT_FILE note located at NOTE_FILE of NOTE_FILE_SIZE
    133    bytes in format EI_CLASS and EI_DATA.  */
    134 
    135 static const char *
    136 handle_file_note (GElf_Addr module_start, GElf_Addr module_end,
    137 		  unsigned char ei_class, unsigned char ei_data,
    138 		  const void *note_file, size_t note_file_size)
    139 {
    140   if (note_file == NULL)
    141     return NULL;
    142 
    143   size_t sz;
    144   switch (ei_class)
    145     {
    146     case ELFCLASS32:
    147       sz = 4;
    148       break;
    149     case ELFCLASS64:
    150       sz = 8;
    151       break;
    152     default:
    153       return NULL;
    154     }
    155 
    156   const void *ptr = note_file;
    157   const void *end = note_file + note_file_size;
    158   uint64_t count;
    159   if (! buf_read_ulong (ei_data, sz, &ptr, end, &count))
    160     return NULL;
    161   if (! buf_read_ulong (ei_data, sz, &ptr, end, NULL)) // page_size
    162     return NULL;
    163 
    164   uint64_t maxcount = (size_t) (end - ptr) / (3 * sz);
    165   if (count > maxcount)
    166     return NULL;
    167 
    168   /* Where file names are stored.  */
    169   const char *fptr = ptr + 3 * count * sz;
    170 
    171   ssize_t firstix = -1;
    172   ssize_t lastix = -1;
    173   for (size_t mix = 0; mix < count; mix++)
    174     {
    175       uint64_t mstart, mend, moffset;
    176       if (! buf_read_ulong (ei_data, sz, &ptr, fptr, &mstart)
    177 	  || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &mend)
    178 	  || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &moffset))
    179 	return NULL;
    180       if (mstart == module_start && moffset == 0)
    181 	firstix = lastix = mix;
    182       if (firstix != -1 && mstart < module_end)
    183 	lastix = mix;
    184       if (mend >= module_end)
    185 	break;
    186     }
    187   if (firstix == -1)
    188     return NULL;
    189 
    190   const char *retval = NULL;
    191   for (ssize_t mix = 0; mix <= lastix; mix++)
    192     {
    193       const char *fnext = memchr (fptr, 0, (const char *) end - fptr);
    194       if (fnext == NULL)
    195 	return NULL;
    196       if (mix == firstix)
    197 	retval = fptr;
    198       if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0)
    199 	return NULL;
    200       fptr = fnext + 1;
    201     }
    202   return retval;
    203 }
    204 
    205 /* Return true iff we are certain ELF cannot match BUILD_ID of
    206    BUILD_ID_LEN bytes.  Pass DISK_FILE_HAS_BUILD_ID as false if it is
    207    certain ELF does not contain build-id (it is only a performance hit
    208    to pass it always as true).  */
    209 
    210 static bool
    211 invalid_elf (Elf *elf, bool disk_file_has_build_id,
    212 	     const void *build_id, size_t build_id_len)
    213 {
    214   if (! disk_file_has_build_id && build_id_len > 0)
    215     {
    216       /* Module found in segments with build-id is more reliable
    217 	 than a module found via DT_DEBUG on disk without any
    218 	 build-id.   */
    219       return true;
    220     }
    221   if (disk_file_has_build_id && build_id_len > 0)
    222     {
    223       const void *elf_build_id;
    224       ssize_t elf_build_id_len;
    225 
    226       /* If there is a build id in the elf file, check it.  */
    227       elf_build_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id);
    228       if (elf_build_id_len > 0)
    229 	{
    230 	  if (build_id_len != (size_t) elf_build_id_len
    231 	      || memcmp (build_id, elf_build_id, build_id_len) != 0)
    232 	    return true;
    233 	}
    234     }
    235   return false;
    236 }
    237 
    238 int
    239 dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
    240 			    Dwfl_Memory_Callback *memory_callback,
    241 			    void *memory_callback_arg,
    242 			    Dwfl_Module_Callback *read_eagerly,
    243 			    void *read_eagerly_arg,
    244 			    const void *note_file, size_t note_file_size,
    245 			    const struct r_debug_info *r_debug_info)
    246 {
    247   size_t segment = ndx;
    248 
    249   if (segment >= dwfl->lookup_elts)
    250     segment = dwfl->lookup_elts - 1;
    251 
    252   while (segment > 0
    253 	 && (dwfl->lookup_segndx[segment] > ndx
    254 	     || dwfl->lookup_segndx[segment] == -1))
    255     --segment;
    256 
    257   while (dwfl->lookup_segndx[segment] < ndx)
    258     if (++segment == dwfl->lookup_elts)
    259       return 0;
    260 
    261   GElf_Addr start = dwfl->lookup_addr[segment];
    262 
    263   inline bool segment_read (int segndx,
    264 			    void **buffer, size_t *buffer_available,
    265 			    GElf_Addr addr, size_t minread)
    266   {
    267     return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available,
    268 				 addr, minread, memory_callback_arg);
    269   }
    270 
    271   inline void release_buffer (void **buffer, size_t *buffer_available)
    272   {
    273     if (*buffer != NULL)
    274       (void) segment_read (-1, buffer, buffer_available, 0, 0);
    275   }
    276 
    277   /* First read in the file header and check its sanity.  */
    278 
    279   void *buffer = NULL;
    280   size_t buffer_available = INITIAL_READ;
    281   Elf *elf = NULL;
    282   int fd = -1;
    283 
    284   /* We might have to reserve some memory for the phdrs.  Set to NULL
    285      here so we can always safely free it.  */
    286   void *phdrsp = NULL;
    287 
    288   inline int finish (void)
    289   {
    290     free (phdrsp);
    291     release_buffer (&buffer, &buffer_available);
    292     if (elf != NULL)
    293       elf_end (elf);
    294     if (fd != -1)
    295       close (fd);
    296     return ndx;
    297   }
    298 
    299   if (segment_read (ndx, &buffer, &buffer_available,
    300 		    start, sizeof (Elf64_Ehdr))
    301       || memcmp (buffer, ELFMAG, SELFMAG) != 0)
    302     return finish ();
    303 
    304   inline bool read_portion (void **data, size_t *data_size,
    305 			    GElf_Addr vaddr, size_t filesz)
    306   {
    307     if (vaddr - start + filesz > buffer_available
    308 	/* If we're in string mode, then don't consider the buffer we have
    309 	   sufficient unless it contains the terminator of the string.  */
    310 	|| (filesz == 0 && memchr (vaddr - start + buffer, '\0',
    311 				   buffer_available - (vaddr - start)) == NULL))
    312       {
    313 	*data = NULL;
    314 	*data_size = filesz;
    315 	return segment_read (addr_segndx (dwfl, segment, vaddr, false),
    316 			     data, data_size, vaddr, filesz);
    317       }
    318 
    319     /* We already have this whole note segment from our initial read.  */
    320     *data = vaddr - start + buffer;
    321     *data_size = 0;
    322     return false;
    323   }
    324 
    325   inline void finish_portion (void **data, size_t *data_size)
    326   {
    327     if (*data_size != 0)
    328       release_buffer (data, data_size);
    329   }
    330 
    331   /* Extract the information we need from the file header.  */
    332   const unsigned char *e_ident;
    333   unsigned char ei_class;
    334   unsigned char ei_data;
    335   uint16_t e_type;
    336   union
    337   {
    338     Elf32_Ehdr e32;
    339     Elf64_Ehdr e64;
    340   } ehdr;
    341   GElf_Off phoff;
    342   uint_fast16_t phnum;
    343   uint_fast16_t phentsize;
    344   GElf_Off shdrs_end;
    345   Elf_Data xlatefrom =
    346     {
    347       .d_type = ELF_T_EHDR,
    348       .d_buf = (void *) buffer,
    349       .d_version = EV_CURRENT,
    350     };
    351   Elf_Data xlateto =
    352     {
    353       .d_type = ELF_T_EHDR,
    354       .d_buf = &ehdr,
    355       .d_size = sizeof ehdr,
    356       .d_version = EV_CURRENT,
    357     };
    358   e_ident = ((const unsigned char *) buffer);
    359   ei_class = e_ident[EI_CLASS];
    360   ei_data = e_ident[EI_DATA];
    361   switch (ei_class)
    362     {
    363     case ELFCLASS32:
    364       xlatefrom.d_size = sizeof (Elf32_Ehdr);
    365       if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
    366 	return finish ();
    367       e_type = ehdr.e32.e_type;
    368       phoff = ehdr.e32.e_phoff;
    369       phnum = ehdr.e32.e_phnum;
    370       phentsize = ehdr.e32.e_phentsize;
    371       if (phentsize != sizeof (Elf32_Phdr))
    372 	return finish ();
    373       shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
    374       break;
    375 
    376     case ELFCLASS64:
    377       xlatefrom.d_size = sizeof (Elf64_Ehdr);
    378       if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
    379 	return finish ();
    380       e_type = ehdr.e64.e_type;
    381       phoff = ehdr.e64.e_phoff;
    382       phnum = ehdr.e64.e_phnum;
    383       phentsize = ehdr.e64.e_phentsize;
    384       if (phentsize != sizeof (Elf64_Phdr))
    385 	return finish ();
    386       shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
    387       break;
    388 
    389     default:
    390       return finish ();
    391     }
    392 
    393   /* The file header tells where to find the program headers.
    394      These are what we need to find the boundaries of the module.
    395      Without them, we don't have a module to report.  */
    396 
    397   if (phnum == 0)
    398     return finish ();
    399 
    400   xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
    401   xlatefrom.d_size = phnum * phentsize;
    402 
    403   void *ph_buffer = NULL;
    404   size_t ph_buffer_size = 0;
    405   if (read_portion (&ph_buffer, &ph_buffer_size,
    406 		    start + phoff, xlatefrom.d_size))
    407     return finish ();
    408 
    409   xlatefrom.d_buf = ph_buffer;
    410 
    411   bool class32 = ei_class == ELFCLASS32;
    412   size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
    413   if (unlikely (phnum > SIZE_MAX / phdr_size))
    414     return finish ();
    415   const size_t phdrsp_bytes = phnum * phdr_size;
    416   phdrsp = malloc (phdrsp_bytes);
    417   if (unlikely (phdrsp == NULL))
    418     return finish ();
    419 
    420   xlateto.d_buf = phdrsp;
    421   xlateto.d_size = phdrsp_bytes;
    422 
    423   /* Track the bounds of the file visible in memory.  */
    424   GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end.  */
    425   GElf_Off file_end = 0;	 /* Rounded up to effective page size.  */
    426   GElf_Off contiguous = 0;	 /* Visible as contiguous file from START.  */
    427   GElf_Off total_filesz = 0;	 /* Total size of data to read.  */
    428 
    429   /* Collect the bias between START and the containing PT_LOAD's p_vaddr.  */
    430   GElf_Addr bias = 0;
    431   bool found_bias = false;
    432 
    433   /* Collect the unbiased bounds of the module here.  */
    434   GElf_Addr module_start = -1l;
    435   GElf_Addr module_end = 0;
    436   GElf_Addr module_address_sync = 0;
    437 
    438   /* If we see PT_DYNAMIC, record it here.  */
    439   GElf_Addr dyn_vaddr = 0;
    440   GElf_Xword dyn_filesz = 0;
    441 
    442   /* Collect the build ID bits here.  */
    443   void *build_id = NULL;
    444   size_t build_id_len = 0;
    445   GElf_Addr build_id_vaddr = 0;
    446 
    447   /* Consider a PT_NOTE we've found in the image.  */
    448   inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz)
    449   {
    450     /* If we have already seen a build ID, we don't care any more.  */
    451     if (build_id != NULL || filesz == 0)
    452       return;
    453 
    454     void *data;
    455     size_t data_size;
    456     if (read_portion (&data, &data_size, vaddr, filesz))
    457       return;
    458 
    459     assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
    460 
    461     void *notes;
    462     if (ei_data == MY_ELFDATA)
    463       notes = data;
    464     else
    465       {
    466 	notes = malloc (filesz);
    467 	if (unlikely (notes == NULL))
    468 	  return;
    469 	xlatefrom.d_type = xlateto.d_type = ELF_T_NHDR;
    470 	xlatefrom.d_buf = (void *) data;
    471 	xlatefrom.d_size = filesz;
    472 	xlateto.d_buf = notes;
    473 	xlateto.d_size = filesz;
    474 	if (elf32_xlatetom (&xlateto, &xlatefrom,
    475 			    ehdr.e32.e_ident[EI_DATA]) == NULL)
    476 	  goto done;
    477       }
    478 
    479     const GElf_Nhdr *nh = notes;
    480     while ((const void *) nh < (const void *) notes + filesz)
    481      {
    482 	const void *note_name = nh + 1;
    483 	const void *note_desc = note_name + NOTE_ALIGN (nh->n_namesz);
    484 	if (unlikely ((size_t) ((const void *) notes + filesz
    485 				- note_desc) < nh->n_descsz))
    486 	  break;
    487 
    488 	if (nh->n_type == NT_GNU_BUILD_ID
    489 	    && nh->n_descsz > 0
    490 	    && nh->n_namesz == sizeof "GNU"
    491 	    && !memcmp (note_name, "GNU", sizeof "GNU"))
    492 	  {
    493 	    build_id_vaddr = note_desc - (const void *) notes + vaddr;
    494 	    build_id_len = nh->n_descsz;
    495 	    build_id = malloc (nh->n_descsz);
    496 	    if (likely (build_id != NULL))
    497 	      memcpy (build_id, note_desc, build_id_len);
    498 	    break;
    499 	  }
    500 
    501 	nh = note_desc + NOTE_ALIGN (nh->n_descsz);
    502       }
    503 
    504   done:
    505     if (notes != data)
    506       free (notes);
    507     finish_portion (&data, &data_size);
    508   }
    509 
    510   /* Consider each of the program headers we've read from the image.  */
    511   inline void consider_phdr (GElf_Word type,
    512 			     GElf_Addr vaddr, GElf_Xword memsz,
    513 			     GElf_Off offset, GElf_Xword filesz,
    514 			     GElf_Xword align)
    515   {
    516     switch (type)
    517       {
    518       case PT_DYNAMIC:
    519 	dyn_vaddr = vaddr;
    520 	dyn_filesz = filesz;
    521 	break;
    522 
    523       case PT_NOTE:
    524 	/* We calculate from the p_offset of the note segment,
    525 	   because we don't yet know the bias for its p_vaddr.  */
    526 	consider_notes (start + offset, filesz);
    527 	break;
    528 
    529       case PT_LOAD:
    530 	align = dwfl->segment_align > 1 ? dwfl->segment_align : align ?: 1;
    531 
    532 	GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align;
    533 	GElf_Addr filesz_vaddr = filesz < memsz ? vaddr + filesz : vaddr_end;
    534 	GElf_Off filesz_offset = filesz_vaddr - vaddr + offset;
    535 
    536 	if (file_trimmed_end < offset + filesz)
    537 	  {
    538 	    file_trimmed_end = offset + filesz;
    539 
    540 	    /* Trim the last segment so we don't bother with zeros
    541 	       in the last page that are off the end of the file.
    542 	       However, if the extra bit in that page includes the
    543 	       section headers, keep them.  */
    544 	    if (shdrs_end <= filesz_offset && shdrs_end > file_trimmed_end)
    545 	      {
    546 		filesz += shdrs_end - file_trimmed_end;
    547 		file_trimmed_end = shdrs_end;
    548 	      }
    549 	  }
    550 
    551 	total_filesz += filesz;
    552 
    553 	if (file_end < filesz_offset)
    554 	  {
    555 	    file_end = filesz_offset;
    556 	    if (filesz_vaddr - start == filesz_offset)
    557 	      contiguous = file_end;
    558 	  }
    559 
    560 	if (!found_bias && (offset & -align) == 0
    561 	    && likely (filesz_offset >= phoff + phnum * phentsize))
    562 	  {
    563 	    bias = start - vaddr;
    564 	    found_bias = true;
    565 	  }
    566 
    567 	if ((vaddr & -align) < module_start)
    568 	  {
    569 	    module_start = vaddr & -align;
    570 	    module_address_sync = vaddr + memsz;
    571 	  }
    572 
    573 	if (module_end < vaddr_end)
    574 	  module_end = vaddr_end;
    575 	break;
    576       }
    577   }
    578 
    579   Elf32_Phdr (*p32)[phnum] = phdrsp;
    580   Elf64_Phdr (*p64)[phnum] = phdrsp;
    581   if (ei_class == ELFCLASS32)
    582     {
    583       if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
    584 	found_bias = false;	/* Trigger error check.  */
    585       else
    586 	for (uint_fast16_t i = 0; i < phnum; ++i)
    587 	  consider_phdr ((*p32)[i].p_type,
    588 			 (*p32)[i].p_vaddr, (*p32)[i].p_memsz,
    589 			 (*p32)[i].p_offset, (*p32)[i].p_filesz,
    590 			 (*p32)[i].p_align);
    591     }
    592   else
    593     {
    594       if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
    595 	found_bias = false;	/* Trigger error check.  */
    596       else
    597 	for (uint_fast16_t i = 0; i < phnum; ++i)
    598 	  consider_phdr ((*p64)[i].p_type,
    599 			 (*p64)[i].p_vaddr, (*p64)[i].p_memsz,
    600 			 (*p64)[i].p_offset, (*p64)[i].p_filesz,
    601 			 (*p64)[i].p_align);
    602     }
    603 
    604   finish_portion (&ph_buffer, &ph_buffer_size);
    605 
    606   /* We must have seen the segment covering offset 0, or else the ELF
    607      header we read at START was not produced by these program headers.  */
    608   if (unlikely (!found_bias))
    609     {
    610       free (build_id);
    611       return finish ();
    612     }
    613 
    614   /* Now we know enough to report a module for sure: its bounds.  */
    615   module_start += bias;
    616   module_end += bias;
    617 
    618   dyn_vaddr += bias;
    619 
    620   /* NAME found from link map has precedence over DT_SONAME possibly read
    621      below.  */
    622   bool name_is_final = false;
    623 
    624   /* Try to match up DYN_VADDR against L_LD as found in link map.
    625      Segments sniffing may guess invalid address as the first read-only memory
    626      mapping may not be dumped to the core file (if ELF headers are not dumped)
    627      and the ELF header is dumped first with the read/write mapping of the same
    628      file at higher addresses.  */
    629   if (r_debug_info != NULL)
    630     for (const struct r_debug_info_module *module = r_debug_info->module;
    631 	 module != NULL; module = module->next)
    632       if (module_start <= module->l_ld && module->l_ld < module_end)
    633 	{
    634 	  /* L_LD read from link map must be right while DYN_VADDR is unsafe.
    635 	     Therefore subtract DYN_VADDR and add L_LD to get a possibly
    636 	     corrective displacement for all addresses computed so far.  */
    637 	  GElf_Addr fixup = module->l_ld - dyn_vaddr;
    638 	  if ((fixup & (dwfl->segment_align - 1)) == 0
    639 	      && module_start + fixup <= module->l_ld
    640 	      && module->l_ld < module_end + fixup)
    641 	    {
    642 	      module_start += fixup;
    643 	      module_end += fixup;
    644 	      dyn_vaddr += fixup;
    645 	      bias += fixup;
    646 	      if (module->name[0] != '\0')
    647 		{
    648 		  name = basename (module->name);
    649 		  name_is_final = true;
    650 		}
    651 	      break;
    652 	    }
    653 	}
    654 
    655   if (r_debug_info != NULL)
    656     {
    657       bool skip_this_module = false;
    658       for (struct r_debug_info_module *module = r_debug_info->module;
    659 	   module != NULL; module = module->next)
    660 	if ((module_end > module->start && module_start < module->end)
    661 	    || dyn_vaddr == module->l_ld)
    662 	  {
    663 	    if (module->elf != NULL
    664 	        && invalid_elf (module->elf, module->disk_file_has_build_id,
    665 				build_id, build_id_len))
    666 	      {
    667 		elf_end (module->elf);
    668 		close (module->fd);
    669 		module->elf = NULL;
    670 		module->fd = -1;
    671 	      }
    672 	    if (module->elf != NULL)
    673 	      {
    674 		/* Ignore this found module if it would conflict in address
    675 		   space with any already existing module of DWFL.  */
    676 		skip_this_module = true;
    677 	      }
    678 	  }
    679       if (skip_this_module)
    680 	{
    681 	  free (build_id);
    682 	  return finish ();
    683 	}
    684     }
    685 
    686   const char *file_note_name = handle_file_note (module_start, module_end,
    687 						 ei_class, ei_data,
    688 						 note_file, note_file_size);
    689   if (file_note_name)
    690     {
    691       name = file_note_name;
    692       name_is_final = true;
    693       bool invalid = false;
    694       fd = open (name, O_RDONLY);
    695       if (fd >= 0)
    696 	{
    697 	  Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
    698 	  if (error == DWFL_E_NOERROR)
    699 	    invalid = invalid_elf (elf, true /* disk_file_has_build_id */,
    700 				   build_id, build_id_len);
    701 	}
    702       if (invalid)
    703 	{
    704 	  /* The file was there, but the build_id didn't match.  We
    705 	     still want to report the module, but need to get the ELF
    706 	     some other way if possible.  */
    707 	  close (fd);
    708 	  fd = -1;
    709 	  elf_end (elf);
    710 	  elf = NULL;
    711 	}
    712     }
    713 
    714   /* Our return value now says to skip the segments contained
    715      within the module.  */
    716   ndx = addr_segndx (dwfl, segment, module_end, true);
    717 
    718   /* Examine its .dynamic section to get more interesting details.
    719      If it has DT_SONAME, we'll use that as the module name.
    720      If it has a DT_DEBUG, then it's actually a PIE rather than a DSO.
    721      We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME,
    722      and they also tell us the essential portion of the file
    723      for fetching symbols.  */
    724   GElf_Addr soname_stroff = 0;
    725   GElf_Addr dynstr_vaddr = 0;
    726   GElf_Xword dynstrsz = 0;
    727   bool execlike = false;
    728   inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val)
    729   {
    730     switch (tag)
    731       {
    732       default:
    733 	return false;
    734 
    735       case DT_DEBUG:
    736 	execlike = true;
    737 	break;
    738 
    739       case DT_SONAME:
    740 	soname_stroff = val;
    741 	break;
    742 
    743       case DT_STRTAB:
    744 	dynstr_vaddr = val;
    745 	break;
    746 
    747       case DT_STRSZ:
    748 	dynstrsz = val;
    749 	break;
    750       }
    751 
    752     return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0;
    753   }
    754 
    755   const size_t dyn_entsize = (ei_class == ELFCLASS32
    756 			      ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
    757   void *dyn_data = NULL;
    758   size_t dyn_data_size = 0;
    759   if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
    760       && ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
    761     {
    762       void *dyns = malloc (dyn_filesz);
    763       Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = dyns;
    764       Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = dyns;
    765       if (unlikely (dyns == NULL))
    766 	return finish ();
    767 
    768       xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
    769       xlatefrom.d_buf = (void *) dyn_data;
    770       xlatefrom.d_size = dyn_filesz;
    771       xlateto.d_buf = dyns;
    772       xlateto.d_size = dyn_filesz;
    773 
    774       if (ei_class == ELFCLASS32)
    775 	{
    776 	  if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
    777 	    for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i)
    778 	      if (consider_dyn ((*d32)[i].d_tag, (*d32)[i].d_un.d_val))
    779 		break;
    780 	}
    781       else
    782 	{
    783 	  if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
    784 	    for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i)
    785 	      if (consider_dyn ((*d64)[i].d_tag, (*d64)[i].d_un.d_val))
    786 		break;
    787 	}
    788       free (dyns);
    789     }
    790   finish_portion (&dyn_data, &dyn_data_size);
    791 
    792   /* We'll use the name passed in or a stupid default if not DT_SONAME.  */
    793   if (name == NULL)
    794     name = e_type == ET_EXEC ? "[exe]" : execlike ? "[pie]" : "[dso]";
    795 
    796   void *soname = NULL;
    797   size_t soname_size = 0;
    798   if (! name_is_final && dynstrsz != 0 && dynstr_vaddr != 0)
    799     {
    800       /* We know the bounds of the .dynstr section.
    801 
    802 	 The DYNSTR_VADDR pointer comes from the .dynamic section
    803 	 (DT_STRTAB, detected above).  Ordinarily the dynamic linker
    804 	 will have adjusted this pointer in place so it's now an
    805 	 absolute address.  But sometimes .dynamic is read-only (in
    806 	 vDSOs and odd architectures), and sometimes the adjustment
    807 	 just hasn't happened yet in the memory image we looked at.
    808 	 So treat DYNSTR_VADDR as an absolute address if it falls
    809 	 within the module bounds, or try applying the phdr bias
    810 	 when that adjusts it to fall within the module bounds.  */
    811 
    812       if ((dynstr_vaddr < module_start || dynstr_vaddr >= module_end)
    813 	  && dynstr_vaddr + bias >= module_start
    814 	  && dynstr_vaddr + bias < module_end)
    815 	dynstr_vaddr += bias;
    816 
    817       if (unlikely (dynstr_vaddr + dynstrsz > module_end))
    818 	dynstrsz = 0;
    819 
    820       /* Try to get the DT_SONAME string.  */
    821       if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz
    822 	  && ! read_portion (&soname, &soname_size,
    823 			     dynstr_vaddr + soname_stroff, 0))
    824 	name = soname;
    825     }
    826 
    827   /* Now that we have chosen the module's name and bounds, report it.
    828      If we found a build ID, report that too.  */
    829 
    830   Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, name,
    831 						 module_start, module_end);
    832 
    833   // !execlike && ET_EXEC is PIE.
    834   // execlike && !ET_EXEC is a static executable.
    835   if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC))
    836     mod->is_executable = true;
    837 
    838   if (likely (mod != NULL) && build_id != NULL
    839       && unlikely (INTUSE(dwfl_module_report_build_id) (mod,
    840 							build_id,
    841 							build_id_len,
    842 							build_id_vaddr)))
    843     {
    844       mod->gc = true;
    845       mod = NULL;
    846     }
    847 
    848   /* At this point we do not need BUILD_ID or NAME any more.
    849      They have been copied.  */
    850   free (build_id);
    851   finish_portion (&soname, &soname_size);
    852 
    853   if (unlikely (mod == NULL))
    854     {
    855       ndx = -1;
    856       return finish ();
    857     }
    858 
    859   /* We have reported the module.  Now let the caller decide whether we
    860      should read the whole thing in right now.  */
    861 
    862   const GElf_Off cost = (contiguous < file_trimmed_end ? total_filesz
    863 			 : buffer_available >= contiguous ? 0
    864 			 : contiguous - buffer_available);
    865   const GElf_Off worthwhile = ((dynstr_vaddr == 0 || dynstrsz == 0) ? 0
    866 			       : dynstr_vaddr + dynstrsz - start);
    867   const GElf_Off whole = MAX (file_trimmed_end, shdrs_end);
    868 
    869   if (elf == NULL
    870       && (*read_eagerly) (MODCB_ARGS (mod), &buffer, &buffer_available,
    871 			  cost, worthwhile, whole, contiguous,
    872 			  read_eagerly_arg, &elf)
    873       && elf == NULL)
    874     {
    875       /* The caller wants to read the whole file in right now, but hasn't
    876 	 done it for us.  Fill in a local image of the virtual file.  */
    877 
    878       void *contents = calloc (1, file_trimmed_end);
    879       if (unlikely (contents == NULL))
    880 	return finish ();
    881 
    882       inline void final_read (size_t offset, GElf_Addr vaddr, size_t size)
    883       {
    884 	void *into = contents + offset;
    885 	size_t read_size = size;
    886 	(void) segment_read (addr_segndx (dwfl, segment, vaddr, false),
    887 			     &into, &read_size, vaddr, size);
    888       }
    889 
    890       if (contiguous < file_trimmed_end)
    891 	{
    892 	  /* We can't use the memory image verbatim as the file image.
    893 	     So we'll be reading into a local image of the virtual file.  */
    894 
    895 	  inline void read_phdr (GElf_Word type, GElf_Addr vaddr,
    896 				 GElf_Off offset, GElf_Xword filesz)
    897 	  {
    898 	    if (type == PT_LOAD)
    899 	      final_read (offset, vaddr + bias, filesz);
    900 	  }
    901 
    902 	  if (ei_class == ELFCLASS32)
    903 	    for (uint_fast16_t i = 0; i < phnum; ++i)
    904 	      read_phdr ((*p32)[i].p_type, (*p32)[i].p_vaddr,
    905 			 (*p32)[i].p_offset, (*p32)[i].p_filesz);
    906 	  else
    907 	    for (uint_fast16_t i = 0; i < phnum; ++i)
    908 	      read_phdr ((*p64)[i].p_type, (*p64)[i].p_vaddr,
    909 			 (*p64)[i].p_offset, (*p64)[i].p_filesz);
    910 	}
    911       else
    912 	{
    913 	  /* The whole file sits contiguous in memory,
    914 	     but the caller didn't want to just do it.  */
    915 
    916 	  const size_t have = MIN (buffer_available, file_trimmed_end);
    917 	  memcpy (contents, buffer, have);
    918 
    919 	  if (have < file_trimmed_end)
    920 	    final_read (have, start + have, file_trimmed_end - have);
    921 	}
    922 
    923       elf = elf_memory (contents, file_trimmed_end);
    924       if (unlikely (elf == NULL))
    925 	free (contents);
    926       else
    927 	elf->flags |= ELF_F_MALLOCED;
    928     }
    929 
    930   if (elf != NULL)
    931     {
    932       /* Install the file in the module.  */
    933       mod->main.elf = elf;
    934       elf = NULL;
    935       fd = -1;
    936       mod->main.vaddr = module_start - bias;
    937       mod->main.address_sync = module_address_sync;
    938       mod->main_bias = bias;
    939     }
    940 
    941   return finish ();
    942 }
    943