diff --git a/Kernel/Prekernel/init.cpp b/Kernel/Prekernel/init.cpp index 65ef94ac2f..85bcaba5d1 100644 --- a/Kernel/Prekernel/init.cpp +++ b/Kernel/Prekernel/init.cpp @@ -75,18 +75,26 @@ extern "C" [[noreturn]] void init() halt(); __builtin_memcpy(kernel_program_headers, kernel_image + kernel_elf_header.e_phoff, sizeof(ElfW(Phdr)) * kernel_elf_header.e_phnum); - FlatPtr kernel_load_base = kernel_program_headers[0].p_vaddr; - FlatPtr kernel_load_end = kernel_program_headers[kernel_elf_header.e_phnum - 1].p_vaddr + kernel_program_headers[kernel_elf_header.e_phnum - 1].p_memsz; + FlatPtr kernel_load_base, kernel_load_end; + for (size_t i = 0; i < kernel_elf_header.e_phnum; i++) { + auto& kernel_program_header = kernel_program_headers[i]; + if (kernel_program_header.p_type != PT_LOAD) + continue; + auto start = kernel_program_header.p_vaddr; + auto end = start + kernel_program_header.p_memsz; + if (start < (FlatPtr)end_of_prekernel_image) + halt(); + if (kernel_program_header.p_paddr < (FlatPtr)end_of_prekernel_image) + halt(); + if (kernel_load_base == 0 || start < kernel_load_base) + kernel_load_base = start; + if (end > kernel_load_end) + kernel_load_end = end; + } // align to 1GB kernel_load_base &= ~(FlatPtr)0x3fffffff; - if (kernel_program_headers[0].p_vaddr < (FlatPtr)end_of_prekernel_image) - halt(); - - if (kernel_program_headers[0].p_paddr < (FlatPtr)end_of_prekernel_image) - halt(); - #if ARCH(I386) int pdpt_flags = 0x1; #else