MCPcopy Create free account
hub / github.com/RT-Thread/rt-thread / elf_file_mmap

Function elf_file_mmap

components/lwp/lwp_elf.c:619–701  ·  view source on GitHub ↗

* @brief Map ELF segments into memory. * * This function maps the loadable segments of an ELF file into the process's address space. * It handles both executable and shared library files, manages BSS sections, and sets up * the load address and base address for dynamic libraries. * * @param load_info Pointer to the structure containing ELF loading context. * @param elf_info Pointer to the s

Source from the content-addressed store, hash-verified

617 * @return -ENOMEM if memory allocation fails.
618 */
619static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ubase_t *elfload_addr,
620 rt_uint32_t map_size, rt_ubase_t *load_base)
621{
622 int ret, i;
623 rt_ubase_t map_va, bss_start, bss_end;
624 Elf_Ehdr *ehdr = &elf_info->ehdr; /* ELF header */
625 Elf_Phdr *phdr = elf_info->phdr; /* Program header array */
626 const Elf_Phdr *tmp_phdr = phdr; /* Current program header */
627 int fd = elf_info->fd; /* File descriptor for ELF file */
628 rt_ubase_t load_addr; /* Calculated load address */
629 size_t prot = PROT_READ | PROT_WRITE; /* Memory protection flags */
630 size_t flags = MAP_FIXED | MAP_PRIVATE; /* Memory mapping flags */
631
632 /* Iterate through all program headers */
633 for (i = 0; i < ehdr->e_phnum; ++i, ++tmp_phdr)
634 {
635 /* Only process PT_LOAD segments (loadable segments) */
636 if (tmp_phdr->p_type != PT_LOAD)
637 {
638 continue;
639 }
640
641 /* For executable files, validate the program header */
642 if (ehdr->e_type == ET_EXEC)
643 {
644 if (elf_check_phdr(tmp_phdr) != RT_EOK)
645 {
646 LOG_E("%s : elf_check_phdr failed", __func__);
647 return -RT_ERROR;
648 }
649 }
650
651 load_addr = tmp_phdr->p_vaddr + *load_base;
652 LOG_D("%s : p_vaddr : 0x%x, load_addr : 0x%x", __func__, tmp_phdr->p_vaddr, load_addr);
653
654 /* When both the segment's virtual address and the load base are 0, the segment is loaded at any available
655 address rather than a fixed one. This behavior is particularly useful for Position-Independent Code (PIC)
656 or shared libraries. */
657 if ((tmp_phdr->p_vaddr == 0) && (*load_base == 0))
658 {
659 flags &= ~MAP_FIXED;
660 }
661
662 /* Map the segment into memory */
663 map_va = elf_map(load_info->lwp, tmp_phdr, fd, load_addr, prot, flags, map_size);
664 if (!map_va)
665 {
666 LOG_E("%s : elf_map failed", __func__);
667 return -ENOMEM;
668 }
669
670 map_size = 0;
671
672 elf_user_dump(load_info->lwp, (void *)load_addr, 64);
673
674 /* Handle BSS section (zero-initialized data) */
675 if ((tmp_phdr->p_memsz > tmp_phdr->p_filesz) && (tmp_phdr->p_flags & PF_W))
676 {

Callers 2

load_elf_interpFunction · 0.85
elf_load_segmentFunction · 0.85

Calls 4

elf_check_phdrFunction · 0.85
elf_mapFunction · 0.85
elf_user_dumpFunction · 0.85
elf_zero_bssFunction · 0.85

Tested by

no test coverage detected