1 /* Sniff out modules from ELF headers visible in memory segments.
2 Copyright (C) 2008-2012, 2014, 2015 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
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
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
18 or both in parallel, as here.
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.
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/>. */
30 #include "../libelf/libelfP.h" /* For NOTE_ALIGN. */
38 #include <sys/param.h>
44 /* A good size for the initial read from memory, if it's not too costly.
45 This more than covers the phdrs and note segment in the average 64-bit
48 #define INITIAL_READ 1024
50 #if __BYTE_ORDER == __LITTLE_ENDIAN
51 # define MY_ELFDATA ELFDATA2LSB
53 # define MY_ELFDATA ELFDATA2MSB
57 # define MAX(a, b) ((a) > (b) ? (a) : (b))
61 /* Return user segment index closest to ADDR but not above it.
62 If NEXT, return the closest to ADDR but not below it. */
64 addr_segndx (Dwfl *dwfl, size_t segment, GElf_Addr addr, bool next)
69 if (dwfl->lookup_segndx[segment] >= 0)
70 ndx = dwfl->lookup_segndx[segment];
71 if (++segment >= dwfl->lookup_elts - 1)
72 return next ? ndx + 1 : ndx;
74 while (dwfl->lookup_addr[segment] < addr);
78 while (dwfl->lookup_segndx[segment] < 0)
79 if (++segment >= dwfl->lookup_elts - 1)
81 ndx = dwfl->lookup_segndx[segment];
87 /* Return whether there is SZ bytes available at PTR till END. */
90 buf_has_data (const void *ptr, const void *end, size_t sz)
92 return ptr < end && (size_t) (end - ptr) >= sz;
95 /* Read SZ bytes into *RETP from *PTRP (limited by END) in format EI_DATA.
96 Function comes from src/readelf.c . */
99 buf_read_ulong (unsigned char ei_data, size_t sz,
100 const void **ptrp, const void *end, uint64_t *retp)
102 if (! buf_has_data (*ptrp, end, sz))
111 memcpy (&u, *ptrp, sz);
117 if (MY_ELFDATA != ei_data)
131 /* Try to find matching entry for module from address MODULE_START to
132 MODULE_END in NT_FILE note located at NOTE_FILE of NOTE_FILE_SIZE
133 bytes in format EI_CLASS and EI_DATA. */
136 handle_file_note (GElf_Addr module_start, GElf_Addr module_end,
137 unsigned char ei_class, unsigned char ei_data,
138 const void *note_file, size_t note_file_size)
140 if (note_file == NULL)
156 const void *ptr = note_file;
157 const void *end = note_file + note_file_size;
159 if (! buf_read_ulong (ei_data, sz, &ptr, end, &count))
161 if (! buf_read_ulong (ei_data, sz, &ptr, end, NULL)) // page_size
164 uint64_t maxcount = (size_t) (end - ptr) / (3 * sz);
165 if (count > maxcount)
168 /* Where file names are stored. */
169 const char *fptr = ptr + 3 * count * sz;
171 ssize_t firstix = -1;
173 for (size_t mix = 0; mix < count; mix++)
175 uint64_t mstart, mend, moffset;
176 if (! buf_read_ulong (ei_data, sz, &ptr, fptr, &mstart)
177 || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &mend)
178 || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &moffset))
180 if (mstart == module_start && moffset == 0)
181 firstix = lastix = mix;
182 if (firstix != -1 && mstart < module_end)
184 if (mend >= module_end)
190 const char *retval = NULL;
191 for (ssize_t mix = 0; mix <= lastix; mix++)
193 const char *fnext = memchr (fptr, 0, (const char *) end - fptr);
198 if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0)
205 /* Return true iff we are certain ELF cannot match BUILD_ID of
206 BUILD_ID_LEN bytes. Pass DISK_FILE_HAS_BUILD_ID as false if it is
207 certain ELF does not contain build-id (it is only a performance hit
208 to pass it always as true). */
211 invalid_elf (Elf *elf, bool disk_file_has_build_id,
212 const void *build_id, size_t build_id_len)
214 if (! disk_file_has_build_id && build_id_len > 0)
216 /* Module found in segments with build-id is more reliable
217 than a module found via DT_DEBUG on disk without any
221 if (disk_file_has_build_id && build_id_len > 0)
223 const void *elf_build_id;
224 ssize_t elf_build_id_len;
226 /* If there is a build id in the elf file, check it. */
227 elf_build_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id);
228 if (elf_build_id_len > 0)
230 if (build_id_len != (size_t) elf_build_id_len
231 || memcmp (build_id, elf_build_id, build_id_len) != 0)
239 dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
240 Dwfl_Memory_Callback *memory_callback,
241 void *memory_callback_arg,
242 Dwfl_Module_Callback *read_eagerly,
243 void *read_eagerly_arg,
244 const void *note_file, size_t note_file_size,
245 const struct r_debug_info *r_debug_info)
247 size_t segment = ndx;
249 if (segment >= dwfl->lookup_elts)
250 segment = dwfl->lookup_elts - 1;
253 && (dwfl->lookup_segndx[segment] > ndx
254 || dwfl->lookup_segndx[segment] == -1))
257 while (dwfl->lookup_segndx[segment] < ndx)
258 if (++segment == dwfl->lookup_elts)
261 GElf_Addr start = dwfl->lookup_addr[segment];
263 inline bool segment_read (int segndx,
264 void **buffer, size_t *buffer_available,
265 GElf_Addr addr, size_t minread)
267 return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available,
268 addr, minread, memory_callback_arg);
271 inline void release_buffer (void **buffer, size_t *buffer_available)
274 (void) segment_read (-1, buffer, buffer_available, 0, 0);
277 /* First read in the file header and check its sanity. */
280 size_t buffer_available = INITIAL_READ;
284 /* We might have to reserve some memory for the phdrs. Set to NULL
285 here so we can always safely free it. */
288 inline int finish (void)
291 release_buffer (&buffer, &buffer_available);
299 if (segment_read (ndx, &buffer, &buffer_available,
300 start, sizeof (Elf64_Ehdr))
301 || memcmp (buffer, ELFMAG, SELFMAG) != 0)
304 inline bool read_portion (void **data, size_t *data_size,
305 GElf_Addr vaddr, size_t filesz)
307 if (vaddr - start + filesz > buffer_available
308 /* If we're in string mode, then don't consider the buffer we have
309 sufficient unless it contains the terminator of the string. */
310 || (filesz == 0 && memchr (vaddr - start + buffer, '\0',
311 buffer_available - (vaddr - start)) == NULL))
315 return segment_read (addr_segndx (dwfl, segment, vaddr, false),
316 data, data_size, vaddr, filesz);
319 /* We already have this whole note segment from our initial read. */
320 *data = vaddr - start + buffer;
325 inline void finish_portion (void **data, size_t *data_size)
328 release_buffer (data, data_size);
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;
343 uint_fast16_t phentsize;
347 .d_type = ELF_T_EHDR,
348 .d_buf = (void *) buffer,
349 .d_version = EV_CURRENT,
353 .d_type = ELF_T_EHDR,
355 .d_size = sizeof ehdr,
356 .d_version = EV_CURRENT,
358 e_ident = ((const unsigned char *) buffer);
359 ei_class = e_ident[EI_CLASS];
360 ei_data = e_ident[EI_DATA];
364 xlatefrom.d_size = sizeof (Elf32_Ehdr);
365 if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
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))
373 shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
377 xlatefrom.d_size = sizeof (Elf64_Ehdr);
378 if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
380 e_type = ehdr.e64.e_type;
381 phoff = ehdr.e64.e_phoff;
382 phnum = ehdr.e64.e_phnum;
383 phentsize = ehdr.e64.e_phentsize;
384 if (phentsize != sizeof (Elf64_Phdr))
386 shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
393 /* The file header tells where to find the program headers.
394 These are what we need to find the boundaries of the module.
395 Without them, we don't have a module to report. */
400 xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
401 xlatefrom.d_size = phnum * phentsize;
403 void *ph_buffer = NULL;
404 size_t ph_buffer_size = 0;
405 if (read_portion (&ph_buffer, &ph_buffer_size,
406 start + phoff, xlatefrom.d_size))
409 xlatefrom.d_buf = ph_buffer;
411 bool class32 = ei_class == ELFCLASS32;
412 size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
413 if (unlikely (phnum > SIZE_MAX / phdr_size))
415 const size_t phdrsp_bytes = phnum * phdr_size;
416 phdrsp = malloc (phdrsp_bytes);
417 if (unlikely (phdrsp == NULL))
420 xlateto.d_buf = phdrsp;
421 xlateto.d_size = phdrsp_bytes;
423 /* Track the bounds of the file visible in memory. */
424 GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end. */
425 GElf_Off file_end = 0; /* Rounded up to effective page size. */
426 GElf_Off contiguous = 0; /* Visible as contiguous file from START. */
427 GElf_Off total_filesz = 0; /* Total size of data to read. */
429 /* Collect the bias between START and the containing PT_LOAD's p_vaddr. */
431 bool found_bias = false;
433 /* Collect the unbiased bounds of the module here. */
434 GElf_Addr module_start = -1l;
435 GElf_Addr module_end = 0;
436 GElf_Addr module_address_sync = 0;
438 /* If we see PT_DYNAMIC, record it here. */
439 GElf_Addr dyn_vaddr = 0;
440 GElf_Xword dyn_filesz = 0;
442 /* Collect the build ID bits here. */
443 void *build_id = NULL;
444 size_t build_id_len = 0;
445 GElf_Addr build_id_vaddr = 0;
447 /* Consider a PT_NOTE we've found in the image. */
448 inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz)
450 /* If we have already seen a build ID, we don't care any more. */
451 if (build_id != NULL || filesz == 0)
456 if (read_portion (&data, &data_size, vaddr, filesz))
459 assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
462 if (ei_data == MY_ELFDATA)
466 notes = malloc (filesz);
467 if (unlikely (notes == NULL))
469 xlatefrom.d_type = xlateto.d_type = ELF_T_NHDR;
470 xlatefrom.d_buf = (void *) data;
471 xlatefrom.d_size = filesz;
472 xlateto.d_buf = notes;
473 xlateto.d_size = filesz;
474 if (elf32_xlatetom (&xlateto, &xlatefrom,
475 ehdr.e32.e_ident[EI_DATA]) == NULL)
479 const GElf_Nhdr *nh = notes;
480 while ((const void *) nh < (const void *) notes + filesz)
482 const void *note_name = nh + 1;
483 const void *note_desc = note_name + NOTE_ALIGN (nh->n_namesz);
484 if (unlikely ((size_t) ((const void *) notes + filesz
485 - note_desc) < nh->n_descsz))
488 if (nh->n_type == NT_GNU_BUILD_ID
490 && nh->n_namesz == sizeof "GNU"
491 && !memcmp (note_name, "GNU", sizeof "GNU"))
493 build_id_vaddr = note_desc - (const void *) notes + vaddr;
494 build_id_len = nh->n_descsz;
495 build_id = malloc (nh->n_descsz);
496 if (likely (build_id != NULL))
497 memcpy (build_id, note_desc, build_id_len);
501 nh = note_desc + NOTE_ALIGN (nh->n_descsz);
507 finish_portion (&data, &data_size);
510 /* Consider each of the program headers we've read from the image. */
511 inline void consider_phdr (GElf_Word type,
512 GElf_Addr vaddr, GElf_Xword memsz,
513 GElf_Off offset, GElf_Xword filesz,
524 /* We calculate from the p_offset of the note segment,
525 because we don't yet know the bias for its p_vaddr. */
526 consider_notes (start + offset, filesz);
530 align = dwfl->segment_align > 1 ? dwfl->segment_align : align ?: 1;
532 GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align;
533 GElf_Addr filesz_vaddr = filesz < memsz ? vaddr + filesz : vaddr_end;
534 GElf_Off filesz_offset = filesz_vaddr - vaddr + offset;
536 if (file_trimmed_end < offset + filesz)
538 file_trimmed_end = offset + filesz;
540 /* Trim the last segment so we don't bother with zeros
541 in the last page that are off the end of the file.
542 However, if the extra bit in that page includes the
543 section headers, keep them. */
544 if (shdrs_end <= filesz_offset && shdrs_end > file_trimmed_end)
546 filesz += shdrs_end - file_trimmed_end;
547 file_trimmed_end = shdrs_end;
551 total_filesz += filesz;
553 if (file_end < filesz_offset)
555 file_end = filesz_offset;
556 if (filesz_vaddr - start == filesz_offset)
557 contiguous = file_end;
560 if (!found_bias && (offset & -align) == 0
561 && likely (filesz_offset >= phoff + phnum * phentsize))
563 bias = start - vaddr;
567 if ((vaddr & -align) < module_start)
569 module_start = vaddr & -align;
570 module_address_sync = vaddr + memsz;
573 if (module_end < vaddr_end)
574 module_end = vaddr_end;
579 Elf32_Phdr (*p32)[phnum] = phdrsp;
580 Elf64_Phdr (*p64)[phnum] = phdrsp;
581 if (ei_class == ELFCLASS32)
583 if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
584 found_bias = false; /* Trigger error check. */
586 for (uint_fast16_t i = 0; i < phnum; ++i)
587 consider_phdr ((*p32)[i].p_type,
588 (*p32)[i].p_vaddr, (*p32)[i].p_memsz,
589 (*p32)[i].p_offset, (*p32)[i].p_filesz,
594 if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
595 found_bias = false; /* Trigger error check. */
597 for (uint_fast16_t i = 0; i < phnum; ++i)
598 consider_phdr ((*p64)[i].p_type,
599 (*p64)[i].p_vaddr, (*p64)[i].p_memsz,
600 (*p64)[i].p_offset, (*p64)[i].p_filesz,
604 finish_portion (&ph_buffer, &ph_buffer_size);
606 /* We must have seen the segment covering offset 0, or else the ELF
607 header we read at START was not produced by these program headers. */
608 if (unlikely (!found_bias))
614 /* Now we know enough to report a module for sure: its bounds. */
615 module_start += bias;
620 /* NAME found from link map has precedence over DT_SONAME possibly read
622 bool name_is_final = false;
624 /* Try to match up DYN_VADDR against L_LD as found in link map.
625 Segments sniffing may guess invalid address as the first read-only memory
626 mapping may not be dumped to the core file (if ELF headers are not dumped)
627 and the ELF header is dumped first with the read/write mapping of the same
628 file at higher addresses. */
629 if (r_debug_info != NULL)
630 for (const struct r_debug_info_module *module = r_debug_info->module;
631 module != NULL; module = module->next)
632 if (module_start <= module->l_ld && module->l_ld < module_end)
634 /* L_LD read from link map must be right while DYN_VADDR is unsafe.
635 Therefore subtract DYN_VADDR and add L_LD to get a possibly
636 corrective displacement for all addresses computed so far. */
637 GElf_Addr fixup = module->l_ld - dyn_vaddr;
638 if ((fixup & (dwfl->segment_align - 1)) == 0
639 && module_start + fixup <= module->l_ld
640 && module->l_ld < module_end + fixup)
642 module_start += fixup;
646 if (module->name[0] != '\0')
648 name = basename (module->name);
649 name_is_final = true;
655 if (r_debug_info != NULL)
657 bool skip_this_module = false;
658 for (struct r_debug_info_module *module = r_debug_info->module;
659 module != NULL; module = module->next)
660 if ((module_end > module->start && module_start < module->end)
661 || dyn_vaddr == module->l_ld)
663 if (module->elf != NULL
664 && invalid_elf (module->elf, module->disk_file_has_build_id,
665 build_id, build_id_len))
667 elf_end (module->elf);
672 if (module->elf != NULL)
674 /* Ignore this found module if it would conflict in address
675 space with any already existing module of DWFL. */
676 skip_this_module = true;
679 if (skip_this_module)
686 const char *file_note_name = handle_file_note (module_start, module_end,
688 note_file, note_file_size);
691 name = file_note_name;
692 name_is_final = true;
693 bool invalid = false;
694 fd = open (name, O_RDONLY);
697 Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
698 if (error == DWFL_E_NOERROR)
699 invalid = invalid_elf (elf, true /* disk_file_has_build_id */,
700 build_id, build_id_len);
704 /* The file was there, but the build_id didn't match. We
705 still want to report the module, but need to get the ELF
706 some other way if possible. */
714 /* Our return value now says to skip the segments contained
715 within the module. */
716 ndx = addr_segndx (dwfl, segment, module_end, true);
718 /* Examine its .dynamic section to get more interesting details.
719 If it has DT_SONAME, we'll use that as the module name.
720 If it has a DT_DEBUG, then it's actually a PIE rather than a DSO.
721 We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME,
722 and they also tell us the essential portion of the file
723 for fetching symbols. */
724 GElf_Addr soname_stroff = 0;
725 GElf_Addr dynstr_vaddr = 0;
726 GElf_Xword dynstrsz = 0;
727 bool execlike = false;
728 inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val)
752 return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0;
755 const size_t dyn_entsize = (ei_class == ELFCLASS32
756 ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
757 void *dyn_data = NULL;
758 size_t dyn_data_size = 0;
759 if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
760 && ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
762 void *dyns = malloc (dyn_filesz);
763 Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = dyns;
764 Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = dyns;
765 if (unlikely (dyns == NULL))
768 xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
769 xlatefrom.d_buf = (void *) dyn_data;
770 xlatefrom.d_size = dyn_filesz;
771 xlateto.d_buf = dyns;
772 xlateto.d_size = dyn_filesz;
774 if (ei_class == ELFCLASS32)
776 if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
777 for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i)
778 if (consider_dyn ((*d32)[i].d_tag, (*d32)[i].d_un.d_val))
783 if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
784 for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i)
785 if (consider_dyn ((*d64)[i].d_tag, (*d64)[i].d_un.d_val))
790 finish_portion (&dyn_data, &dyn_data_size);
792 /* We'll use the name passed in or a stupid default if not DT_SONAME. */
794 name = e_type == ET_EXEC ? "[exe]" : execlike ? "[pie]" : "[dso]";
797 size_t soname_size = 0;
798 if (! name_is_final && dynstrsz != 0 && dynstr_vaddr != 0)
800 /* We know the bounds of the .dynstr section.
802 The DYNSTR_VADDR pointer comes from the .dynamic section
803 (DT_STRTAB, detected above). Ordinarily the dynamic linker
804 will have adjusted this pointer in place so it's now an
805 absolute address. But sometimes .dynamic is read-only (in
806 vDSOs and odd architectures), and sometimes the adjustment
807 just hasn't happened yet in the memory image we looked at.
808 So treat DYNSTR_VADDR as an absolute address if it falls
809 within the module bounds, or try applying the phdr bias
810 when that adjusts it to fall within the module bounds. */
812 if ((dynstr_vaddr < module_start || dynstr_vaddr >= module_end)
813 && dynstr_vaddr + bias >= module_start
814 && dynstr_vaddr + bias < module_end)
815 dynstr_vaddr += bias;
817 if (unlikely (dynstr_vaddr + dynstrsz > module_end))
820 /* Try to get the DT_SONAME string. */
821 if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz
822 && ! read_portion (&soname, &soname_size,
823 dynstr_vaddr + soname_stroff, 0))
827 /* Now that we have chosen the module's name and bounds, report it.
828 If we found a build ID, report that too. */
830 Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, name,
831 module_start, module_end);
833 // !execlike && ET_EXEC is PIE.
834 // execlike && !ET_EXEC is a static executable.
835 if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC))
836 mod->is_executable = true;
838 if (likely (mod != NULL) && build_id != NULL
839 && unlikely (INTUSE(dwfl_module_report_build_id) (mod,
848 /* At this point we do not need BUILD_ID or NAME any more.
849 They have been copied. */
851 finish_portion (&soname, &soname_size);
853 if (unlikely (mod == NULL))
859 /* We have reported the module. Now let the caller decide whether we
860 should read the whole thing in right now. */
862 const GElf_Off cost = (contiguous < file_trimmed_end ? total_filesz
863 : buffer_available >= contiguous ? 0
864 : contiguous - buffer_available);
865 const GElf_Off worthwhile = ((dynstr_vaddr == 0 || dynstrsz == 0) ? 0
866 : dynstr_vaddr + dynstrsz - start);
867 const GElf_Off whole = MAX (file_trimmed_end, shdrs_end);
870 && (*read_eagerly) (MODCB_ARGS (mod), &buffer, &buffer_available,
871 cost, worthwhile, whole, contiguous,
872 read_eagerly_arg, &elf)
875 /* The caller wants to read the whole file in right now, but hasn't
876 done it for us. Fill in a local image of the virtual file. */
878 void *contents = calloc (1, file_trimmed_end);
879 if (unlikely (contents == NULL))
882 inline void final_read (size_t offset, GElf_Addr vaddr, size_t size)
884 void *into = contents + offset;
885 size_t read_size = size;
886 (void) segment_read (addr_segndx (dwfl, segment, vaddr, false),
887 &into, &read_size, vaddr, size);
890 if (contiguous < file_trimmed_end)
892 /* We can't use the memory image verbatim as the file image.
893 So we'll be reading into a local image of the virtual file. */
895 inline void read_phdr (GElf_Word type, GElf_Addr vaddr,
896 GElf_Off offset, GElf_Xword filesz)
899 final_read (offset, vaddr + bias, filesz);
902 if (ei_class == ELFCLASS32)
903 for (uint_fast16_t i = 0; i < phnum; ++i)
904 read_phdr ((*p32)[i].p_type, (*p32)[i].p_vaddr,
905 (*p32)[i].p_offset, (*p32)[i].p_filesz);
907 for (uint_fast16_t i = 0; i < phnum; ++i)
908 read_phdr ((*p64)[i].p_type, (*p64)[i].p_vaddr,
909 (*p64)[i].p_offset, (*p64)[i].p_filesz);
913 /* The whole file sits contiguous in memory,
914 but the caller didn't want to just do it. */
916 const size_t have = MIN (buffer_available, file_trimmed_end);
917 memcpy (contents, buffer, have);
919 if (have < file_trimmed_end)
920 final_read (have, start + have, file_trimmed_end - have);
923 elf = elf_memory (contents, file_trimmed_end);
924 if (unlikely (elf == NULL))
927 elf->flags |= ELF_F_MALLOCED;
932 /* Install the file in the module. */
936 mod->main.vaddr = module_start - bias;
937 mod->main.address_sync = module_address_sync;
938 mod->main_bias = bias;