From baf3145769356901218f033486daaba43900e3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 18 Jun 2004 15:20:47 +0000 Subject: [PATCH] Fixed a big bug in the ELF loader: it didn't clear out the loaded segment above p_filesz - that means it didn't clear BSS etc. - this was not noticeable from Bochs, though. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8045 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/boot/loader/elf.cpp | 41 +++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/kernel/boot/loader/elf.cpp b/src/kernel/boot/loader/elf.cpp index 33d1f297d3..eb79d0a910 100644 --- a/src/kernel/boot/loader/elf.cpp +++ b/src/kernel/boot/loader/elf.cpp @@ -175,26 +175,28 @@ elf_load_image(int fd, preloaded_image *image) image->text_region.size = 0; for (int32 i = 0; i < elfHeader.e_phnum; i++) { - switch (programHeaders[i].p_type) { + Elf32_Phdr &header = programHeaders[i]; + + switch (header.p_type) { case PT_LOAD: break; case PT_DYNAMIC: - image->dynamic_section.start = programHeaders[i].p_vaddr; - image->dynamic_section.size = programHeaders[i].p_memsz; + image->dynamic_section.start = header.p_vaddr; + image->dynamic_section.size = header.p_memsz; continue; default: - dprintf("unhandled pheader type 0x%lx\n", programHeaders[i].p_type); + dprintf("unhandled pheader type 0x%lx\n", header.p_type); continue; } elf_region *region; - if (programHeaders[i].IsReadWrite()) { + if (header.IsReadWrite()) { if (image->data_region.size != 0) { dprintf("elf: rw already handled!\n"); continue; } region = &image->data_region; - } else if (programHeaders[i].IsExecutable()) { + } else if (header.IsExecutable()) { if (image->text_region.size != 0) { dprintf("elf: ro already handled!\n"); continue; @@ -203,8 +205,8 @@ elf_load_image(int fd, preloaded_image *image) } else continue; - region->start = ROUNDOWN(programHeaders[i].p_vaddr, B_PAGE_SIZE); - region->size = ROUNDUP(programHeaders[i].p_memsz + (programHeaders[i].p_vaddr % B_PAGE_SIZE), PAGE_SIZE); + region->start = ROUNDOWN(header.p_vaddr, B_PAGE_SIZE); + region->size = ROUNDUP(header.p_memsz + (header.p_vaddr % B_PAGE_SIZE), PAGE_SIZE); region->delta = -region->start; TRACE(("segment %d: start = %p, size = %lu, delta = %lx\n", i, @@ -230,27 +232,34 @@ elf_load_image(int fd, preloaded_image *image) // load program data for (int i = 0; i < elfHeader.e_phnum; i++) { - if (programHeaders[i].p_type != PT_LOAD) + Elf32_Phdr &header = programHeaders[i]; + + if (header.p_type != PT_LOAD) continue; elf_region *region; - if (programHeaders[i].IsReadWrite()) + if (header.IsReadWrite()) region = &image->data_region; - else if (programHeaders[i].IsExecutable()) + else if (header.IsExecutable()) region = &image->text_region; else continue; - TRACE(("load segment %d (%ld bytes)...\n", i, programHeaders[i].p_filesz)); + TRACE(("load segment %d (%ld bytes)...\n", i, header.p_filesz)); - length = read_pos(fd, programHeaders[i].p_offset, - (void *)(region->start + (programHeaders[i].p_vaddr % B_PAGE_SIZE)), - programHeaders[i].p_filesz); - if (length < (ssize_t)programHeaders[i].p_filesz) { + length = read_pos(fd, header.p_offset, + (void *)(region->start + (header.p_vaddr % B_PAGE_SIZE)), header.p_filesz); + if (length < (ssize_t)header.p_filesz) { status = B_BAD_DATA; dprintf("error reading in seg %d\n", i); goto error2; } + + // clear anything above the file size (that may also contain the BSS area) + + uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz; + if (offset < region->size) + memset((void *)(region->start + offset), 0, region->size - offset); } // modify the dynamic section by the delta of the regions