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
This commit is contained in:
Axel Dörfler
2004-06-18 15:20:47 +00:00
parent 4c179368aa
commit baf3145769
+25 -16
View File
@@ -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