* @brief Load the segments of an ELF file into memory. * * This function is responsible for loading the segments of an ELF file into memory, * including handling dynamic libraries and setting up the entry point for execution. * * @param load_info Pointer to the structure containing ELF loading information. * @return RT_EOK if the segments are successfully loaded and prepared for execution.
| 810 | * - Interpreter loading errors |
| 811 | */ |
| 812 | static int elf_load_segment(elf_load_info_t *load_info) |
| 813 | { |
| 814 | int ret; |
| 815 | rt_ubase_t app_load_base = 0; /* Base address for loading the application. */ |
| 816 | load_info->load_addr = 0; /* Load address for the ELF file. */ |
| 817 | load_info->interp_base = 0; /* Base address for loading the interpreter. */ |
| 818 | load_info->exec_info.map_size = 0; /* Total size of the mapped segments. */ |
| 819 | |
| 820 | if (load_info->exec_info.ehdr.e_type == ET_DYN) |
| 821 | { |
| 822 | ret = total_mapping_size(&load_info->exec_info); |
| 823 | if (ret) |
| 824 | { |
| 825 | LOG_E("%s : total_mapping_size failed", __func__); |
| 826 | return -RT_ERROR; |
| 827 | } |
| 828 | LOG_D("%s : map_size : 0x%x", __func__, load_info->exec_info.map_size); |
| 829 | |
| 830 | /* Calculate the base address for loading the ELF file by adding a random offset to the default load address. |
| 831 | This randomization enhances security by making it harder for attackers to predict the memory layout. */ |
| 832 | app_load_base = ELF_EXEC_LOAD_ADDR + elf_random_offset(); |
| 833 | } |
| 834 | |
| 835 | /* Map the segments of the ELF file into memory */ |
| 836 | ret = elf_file_mmap(load_info, &load_info->exec_info, &load_info->load_addr, |
| 837 | load_info->exec_info.map_size, &app_load_base); |
| 838 | elf_file_close(load_info->exec_info.fd); |
| 839 | if (ret != RT_EOK) |
| 840 | { |
| 841 | LOG_W("%s : elf_file_close exec failed", __func__); |
| 842 | } |
| 843 | load_info->exec_info.fd = ELF_INVALID_FD; |
| 844 | |
| 845 | if (load_info->interp_info.fd != ELF_INVALID_FD) |
| 846 | { |
| 847 | ret = load_elf_interp(load_info, &load_info->interp_base); /* load the interpreter */ |
| 848 | if (ret) |
| 849 | { |
| 850 | LOG_E("%s : load_elf_interp failed, ret = %d", __func__, ret); |
| 851 | return ret; |
| 852 | } |
| 853 | elf_file_close(load_info->interp_info.fd); |
| 854 | if (ret != RT_EOK) |
| 855 | { |
| 856 | LOG_W("%s : elf_file_close interp failed, ret = %d", __func__, ret); |
| 857 | } |
| 858 | load_info->interp_info.fd = ELF_INVALID_FD; |
| 859 | |
| 860 | /* if a interpreter exist, first jump to the interpreter's entry to handle dynamic libs' loading. */ |
| 861 | load_info->e_entry = load_info->interp_info.ehdr.e_entry + load_info->interp_base; |
| 862 | load_info->exec_info.ehdr.e_entry = load_info->exec_info.ehdr.e_entry + app_load_base; /* Update the ELF file's entry address by adding the base address. */ |
| 863 | } |
| 864 | else |
| 865 | { |
| 866 | /* If there is no interpreter, use the ELF file's entry address directly. */ |
| 867 | load_info->e_entry = load_info->exec_info.ehdr.e_entry; |
| 868 | } |
| 869 |
no test coverage detected