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 /* ph_buffer_size will be zero if we got everything from the initial
416 buffer, otherwise it will be the size of the new buffer that
417 could be read. */
418 if (ph_buffer_size != 0)
419 xlatefrom.d_size = ph_buffer_size;
420
421 xlatefrom.d_buf = ph_buffer;
422
423 bool class32 = ei_class == ELFCLASS32;
424 size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
425 if (unlikely (phnum > SIZE_MAX / phdr_size))
426 return finish ();
427 const size_t phdrsp_bytes = phnum * phdr_size;
428 phdrsp = malloc (phdrsp_bytes);
429 if (unlikely (phdrsp == NULL))
430 return finish ();
431
432 xlateto.d_buf = phdrsp;
433 xlateto.d_size = phdrsp_bytes;
434
435 /* Track the bounds of the file visible in memory. */
436 GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
437 GElf_Off file_end = 0; /* Rounded up to effective page size. */
438 GElf_Off contiguous = 0; /* Visible as contiguous file from START. */
439 GElf_Off total_filesz = 0; /* Total size of data to read. */
440
441 /* Collect the bias between START and the containing PT_LOAD's p_vaddr. */
442 GElf_Addr bias = 0;
443 bool found_bias = false;
444
445 /* Collect the unbiased bounds of the module here. */
446 GElf_Addr module_start = -1l;
447 GElf_Addr module_end = 0;
448 GElf_Addr module_address_sync = 0;
449
450 /* If we see PT_DYNAMIC, record it here. */
451 GElf_Addr dyn_vaddr = 0;
452 GElf_Xword dyn_filesz = 0;
453
454 /* Collect the build ID bits here. */
455 void *build_id = NULL;
456 size_t build_id_len = 0;
457 GElf_Addr build_id_vaddr = 0;
458
459 /* Consider a PT_NOTE we've found in the image. */
460 inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz,
461 GElf_Xword align)
462 {
463 /* If we have already seen a build ID, we don't care any more. */
464 if (build_id != NULL || filesz == 0)
465 return;
466
467 void *data;
468 size_t data_size;
469 if (read_portion (&data, &data_size, vaddr, filesz))
470 return;
471
472 /* data_size will be zero if we got everything from the initial
473 buffer, otherwise it will be the size of the new buffer that
474 could be read. */
475 if (data_size != 0)
476 filesz = data_size;
477
478 assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
479
480 void *notes;
481 if (ei_data == MY_ELFDATA)
482 notes = data;
483 else
484 {
485 notes = malloc (filesz);
486 if (unlikely (notes == NULL))
487 return;
488 xlatefrom.d_type = xlateto.d_type = (align == 8
489 ? ELF_T_NHDR8 : ELF_T_NHDR);
490 xlatefrom.d_buf = (void *) data;
491 xlatefrom.d_size = filesz;
492 xlateto.d_buf = notes;
493 xlateto.d_size = filesz;
494 if (elf32_xlatetom (&xlateto, &xlatefrom,
495 ehdr.e32.e_ident[EI_DATA]) == NULL)
496 goto done;
497 }
498
499 const GElf_Nhdr *nh = notes;
500 size_t len = 0;
501 while (filesz > len + sizeof (*nh))
502 {
503 const void *note_name;
504 const void *note_desc;
505
506 len += sizeof (*nh);
507 note_name = notes + len;
508
509 len += nh->n_namesz;
510 len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len);
511 note_desc = notes + len;
512
513 if (unlikely (filesz < len + nh->n_descsz))
514 break;
515
516 if (nh->n_type == NT_GNU_BUILD_ID
517 && nh->n_descsz > 0
518 && nh->n_namesz == sizeof "GNU"
519 && !memcmp (note_name, "GNU", sizeof "GNU"))
520 {
521 build_id_vaddr = note_desc - (const void *) notes + vaddr;
522 build_id_len = nh->n_descsz;
523 build_id = malloc (nh->n_descsz);
524 if (likely (build_id != NULL))
525 memcpy (build_id, note_desc, build_id_len);
526 break;
527 }
528
529 len += nh->n_descsz;
530 len = align == 8 ? NOTE_ALIGN8 (len) : NOTE_ALIGN4 (len);
531 nh = (void *) notes + len;
532 }
533
534 done:
535 if (notes != data)
536 free (notes);
537 finish_portion (&data, &data_size);
538 }
539
540 /* Consider each of the program headers we've read from the image. */
541 inline void consider_phdr (GElf_Word type,
542 GElf_Addr vaddr, GElf_Xword memsz,
543 GElf_Off offset, GElf_Xword filesz,
544 GElf_Xword align)
545 {
546 switch (type)
547 {
548 case PT_DYNAMIC:
549 dyn_vaddr = vaddr;
550 dyn_filesz = filesz;
551 break;
552
553 case PT_NOTE:
554 /* We calculate from the p_offset of the note segment,
555 because we don't yet know the bias for its p_vaddr. */
556 consider_notes (start + offset, filesz, align);
557 break;
558
559 case PT_LOAD:
560 align = dwfl->segment_align > 1 ? dwfl->segment_align : align ?: 1;
561
562 GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align;
563 GElf_Addr filesz_vaddr = filesz < memsz ? vaddr + filesz : vaddr_end;
564 GElf_Off filesz_offset = filesz_vaddr - vaddr + offset;
565
566 if (file_trimmed_end < offset + filesz)
567 {
568 file_trimmed_end = offset + filesz;
569
570 /* Trim the last segment so we don't bother with zeros
571 in the last page that are off the end of the file.
572 However, if the extra bit in that page includes the
573 section headers, keep them. */
574 if (shdrs_end <= filesz_offset && shdrs_end > file_trimmed_end)
575 {
576 filesz += shdrs_end - file_trimmed_end;
577 file_trimmed_end = shdrs_end;
578 }
579 }
580
581 total_filesz += filesz;
582
583 if (file_end < filesz_offset)
584 {
585 file_end = filesz_offset;
586 if (filesz_vaddr - start == filesz_offset)
587 contiguous = file_end;
588 }
589
590 if (!found_bias && (offset & -align) == 0
591 && likely (filesz_offset >= phoff + phnum * phentsize))
592 {
593 bias = start - vaddr;
594 found_bias = true;
595 }
596
597 if ((vaddr & -align) < module_start)
598 {
599 module_start = vaddr & -align;
600 module_address_sync = vaddr + memsz;
601 }
602
603 if (module_end < vaddr_end)
604 module_end = vaddr_end;
605 break;
606 }
607 }
608
609 Elf32_Phdr (*p32)[phnum] = phdrsp;
610 Elf64_Phdr (*p64)[phnum] = phdrsp;
611 if (ei_class == ELFCLASS32)
612 {
613 if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
614 found_bias = false; /* Trigger error check. */
615 else
616 for (uint_fast16_t i = 0; i < phnum; ++i)
617 consider_phdr ((*p32)[i].p_type,
618 (*p32)[i].p_vaddr, (*p32)[i].p_memsz,
619 (*p32)[i].p_offset, (*p32)[i].p_filesz,
620 (*p32)[i].p_align);
621 }
622 else
623 {
624 if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
625 found_bias = false; /* Trigger error check. */
626 else
627 for (uint_fast16_t i = 0; i < phnum; ++i)
628 consider_phdr ((*p64)[i].p_type,
629 (*p64)[i].p_vaddr, (*p64)[i].p_memsz,
630 (*p64)[i].p_offset, (*p64)[i].p_filesz,
631 (*p64)[i].p_align);
632 }
633
634 finish_portion (&ph_buffer, &ph_buffer_size);
635
636 /* We must have seen the segment covering offset 0, or else the ELF
637 header we read at START was not produced by these program headers. */
638 if (unlikely (!found_bias))
639 {
640 free (build_id);
641 return finish ();
642 }
643
644 /* Now we know enough to report a module for sure: its bounds. */
645 module_start += bias;
646 module_end += bias;
647
648 dyn_vaddr += bias;
649
650 /* NAME found from link map has precedence over DT_SONAME possibly read
651 below. */
652 bool name_is_final = false;
653
654 /* Try to match up DYN_VADDR against L_LD as found in link map.
655 Segments sniffing may guess invalid address as the first read-only memory
656 mapping may not be dumped to the core file (if ELF headers are not dumped)
657 and the ELF header is dumped first with the read/write mapping of the same
658 file at higher addresses. */
659 if (r_debug_info != NULL)
660 for (const struct r_debug_info_module *module = r_debug_info->module;
661 module != NULL; module = module->next)
662 if (module_start <= module->l_ld && module->l_ld < module_end)
663 {
664 /* L_LD read from link map must be right while DYN_VADDR is unsafe.
665 Therefore subtract DYN_VADDR and add L_LD to get a possibly
666 corrective displacement for all addresses computed so far. */
667 GElf_Addr fixup = module->l_ld - dyn_vaddr;
668 if ((fixup & (dwfl->segment_align - 1)) == 0
669 && module_start + fixup <= module->l_ld
670 && module->l_ld < module_end + fixup)
671 {
672 module_start += fixup;
673 module_end += fixup;
674 dyn_vaddr += fixup;
675 bias += fixup;
676 if (module->name[0] != '\0')
677 {
678 name = basename (module->name);
679 name_is_final = true;
680 }
681 break;
682 }
683 }
684
685 if (r_debug_info != NULL)
686 {
687 bool skip_this_module = false;
688 for (struct r_debug_info_module *module = r_debug_info->module;
689 module != NULL; module = module->next)
690 if ((module_end > module->start && module_start < module->end)
691 || dyn_vaddr == module->l_ld)
692 {
693 if (module->elf != NULL
694 && invalid_elf (module->elf, module->disk_file_has_build_id,
695 build_id, build_id_len))
696 {
697 elf_end (module->elf);
698 close (module->fd);
699 module->elf = NULL;
700 module->fd = -1;
701 }
702 if (module->elf != NULL)
703 {
704 /* Ignore this found module if it would conflict in address
705 space with any already existing module of DWFL. */
706 skip_this_module = true;
707 }
708 }
709 if (skip_this_module)
710 {
711 free (build_id);
712 return finish ();
713 }
714 }
715
716 const char *file_note_name = handle_file_note (module_start, module_end,
717 ei_class, ei_data,
718 note_file, note_file_size);
719 if (file_note_name)
720 {
721 name = file_note_name;
722 name_is_final = true;
723 bool invalid = false;
724 fd = open (name, O_RDONLY);
725 if (fd >= 0)
726 {
727 Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
728 if (error == DWFL_E_NOERROR)
729 invalid = invalid_elf (elf, true /* disk_file_has_build_id */,
730 build_id, build_id_len);
731 }
732 if (invalid)
733 {
734 /* The file was there, but the build_id didn't match. We
735 still want to report the module, but need to get the ELF
736 some other way if possible. */
737 close (fd);
738 fd = -1;
739 elf_end (elf);
740 elf = NULL;
741 }
742 }
743
744 /* Our return value now says to skip the segments contained
745 within the module. */
746 ndx = addr_segndx (dwfl, segment, module_end, true);
747
748 /* Examine its .dynamic section to get more interesting details.
749 If it has DT_SONAME, we'll use that as the module name.
750 If it has a DT_DEBUG, then it's actually a PIE rather than a DSO.
751 We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME,
752 and they also tell us the essential portion of the file
753 for fetching symbols. */
754 GElf_Addr soname_stroff = 0;
755 GElf_Addr dynstr_vaddr = 0;
756 GElf_Xword dynstrsz = 0;
757 bool execlike = false;
758 inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val)
759 {
760 switch (tag)
761 {
762 default:
763 return false;
764
765 case DT_DEBUG:
766 execlike = true;
767 break;
768
769 case DT_SONAME:
770 soname_stroff = val;
771 break;
772
773 case DT_STRTAB:
774 dynstr_vaddr = val;
775 break;
776
777 case DT_STRSZ:
778 dynstrsz = val;
779 break;
780 }
781
782 return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0;
783 }
784
785 const size_t dyn_entsize = (ei_class == ELFCLASS32
786 ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
787 void *dyn_data = NULL;
788 size_t dyn_data_size = 0;
789 if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
790 && ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
791 {
792 /* dyn_data_size will be zero if we got everything from the initial
793 buffer, otherwise it will be the size of the new buffer that
794 could be read. */
795 if (dyn_data_size != 0)
796 dyn_filesz = dyn_data_size;
797
798 void *dyns = malloc (dyn_filesz);
799 Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = dyns;
800 Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = dyns;
801 if (unlikely (dyns == NULL))
802 return finish ();
803
804 xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
805 xlatefrom.d_buf = (void *) dyn_data;
806 xlatefrom.d_size = dyn_filesz;
807 xlateto.d_buf = dyns;
808 xlateto.d_size = dyn_filesz;
809
810 if (ei_class == ELFCLASS32)
811 {
812 if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
813 for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i)
814 if (consider_dyn ((*d32)[i].d_tag, (*d32)[i].d_un.d_val))
815 break;
816 }
817 else
818 {
819 if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
820 for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i)
821 if (consider_dyn ((*d64)[i].d_tag, (*d64)[i].d_un.d_val))
822 break;
823 }
824 free (dyns);
825 }
826 finish_portion (&dyn_data, &dyn_data_size);
827
828 /* We'll use the name passed in or a stupid default if not DT_SONAME. */
829 if (name == NULL)
830 name = e_type == ET_EXEC ? "[exe]" : execlike ? "[pie]" : "[dso]";
831
832 void *soname = NULL;
833 size_t soname_size = 0;
834 if (! name_is_final && dynstrsz != 0 && dynstr_vaddr != 0)
835 {
836 /* We know the bounds of the .dynstr section.
837
838 The DYNSTR_VADDR pointer comes from the .dynamic section
839 (DT_STRTAB, detected above). Ordinarily the dynamic linker
840 will have adjusted this pointer in place so it's now an
841 absolute address. But sometimes .dynamic is read-only (in
842 vDSOs and odd architectures), and sometimes the adjustment
843 just hasn't happened yet in the memory image we looked at.
844 So treat DYNSTR_VADDR as an absolute address if it falls
845 within the module bounds, or try applying the phdr bias
846 when that adjusts it to fall within the module bounds. */
847
848 if ((dynstr_vaddr < module_start || dynstr_vaddr >= module_end)
849 && dynstr_vaddr + bias >= module_start
850 && dynstr_vaddr + bias < module_end)
851 dynstr_vaddr += bias;
852
853 if (unlikely (dynstr_vaddr + dynstrsz > module_end))
854 dynstrsz = 0;
855
856 /* Try to get the DT_SONAME string. */
857 if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz
858 && ! read_portion (&soname, &soname_size,
859 dynstr_vaddr + soname_stroff, 0))
860 name = soname;
861 }
862
863 /* Now that we have chosen the module's name and bounds, report it.
864 If we found a build ID, report that too. */
865
866 Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, name,
867 module_start, module_end);
868
869 // !execlike && ET_EXEC is PIE.
870 // execlike && !ET_EXEC is a static executable.
871 if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC))
872 mod->is_executable = true;
873
874 if (likely (mod != NULL) && build_id != NULL
875 && unlikely (INTUSE(dwfl_module_report_build_id) (mod,
876 build_id,
877 build_id_len,
878 build_id_vaddr)))
879 {
880 mod->gc = true;
881 mod = NULL;
882 }
883
884 /* At this point we do not need BUILD_ID or NAME any more.
885 They have been copied. */
886 free (build_id);
887 finish_portion (&soname, &soname_size);
888
889 if (unlikely (mod == NULL))
890 {
891 ndx = -1;
892 return finish ();
893 }
894
895 /* We have reported the module. Now let the caller decide whether we
896 should read the whole thing in right now. */
897
898 const GElf_Off cost = (contiguous < file_trimmed_end ? total_filesz
899 : buffer_available >= contiguous ? 0
900 : contiguous - buffer_available);
901 const GElf_Off worthwhile = ((dynstr_vaddr == 0 || dynstrsz == 0) ? 0
902 : dynstr_vaddr + dynstrsz - start);
903 const GElf_Off whole = MAX (file_trimmed_end, shdrs_end);
904
905 if (elf == NULL
906 && (*read_eagerly) (MODCB_ARGS (mod), &buffer, &buffer_available,
907 cost, worthwhile, whole, contiguous,
908 read_eagerly_arg, &elf)
909 && elf == NULL)
910 {
911 /* The caller wants to read the whole file in right now, but hasn't
912 done it for us. Fill in a local image of the virtual file. */
913
914 void *contents = calloc (1, file_trimmed_end);
915 if (unlikely (contents == NULL))
916 return finish ();
917
918 inline void final_read (size_t offset, GElf_Addr vaddr, size_t size)
919 {
920 void *into = contents + offset;
921 size_t read_size = size;
922 (void) segment_read (addr_segndx (dwfl, segment, vaddr, false),
923 &into, &read_size, vaddr, size);
924 }
925
926 if (contiguous < file_trimmed_end)
927 {
928 /* We can't use the memory image verbatim as the file image.
929 So we'll be reading into a local image of the virtual file. */
930
931 inline void read_phdr (GElf_Word type, GElf_Addr vaddr,
932 GElf_Off offset, GElf_Xword filesz)
933 {
934 if (type == PT_LOAD)
935 final_read (offset, vaddr + bias, filesz);
936 }
937
938 if (ei_class == ELFCLASS32)
939 for (uint_fast16_t i = 0; i < phnum; ++i)
940 read_phdr ((*p32)[i].p_type, (*p32)[i].p_vaddr,
941 (*p32)[i].p_offset, (*p32)[i].p_filesz);
942 else
943 for (uint_fast16_t i = 0; i < phnum; ++i)
944 read_phdr ((*p64)[i].p_type, (*p64)[i].p_vaddr,
945 (*p64)[i].p_offset, (*p64)[i].p_filesz);
946 }
947 else
948 {
949 /* The whole file sits contiguous in memory,
950 but the caller didn't want to just do it. */
951
952 const size_t have = MIN (buffer_available, file_trimmed_end);
953 memcpy (contents, buffer, have);
954
955 if (have < file_trimmed_end)
956 final_read (have, start + have, file_trimmed_end - have);
957 }
958
959 elf = elf_memory (contents, file_trimmed_end);
960 if (unlikely (elf == NULL))
961 free (contents);
962 else
963 elf->flags |= ELF_F_MALLOCED;
964 }
965
966 if (elf != NULL)
967 {
968 /* Install the file in the module. */
969 mod->main.elf = elf;
970 mod->main.fd = fd;
971 elf = NULL;
972 fd = -1;
973 mod->main.vaddr = module_start - bias;
974 mod->main.address_sync = module_address_sync;
975 mod->main_bias = bias;
976 }
977
978 return finish ();
979 }
980