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