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