From 3be4b103a22afbc4cd0e8c485d3de81f70db51b2 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sun, 13 Feb 2022 00:05:35 -0800 Subject: [PATCH] [srv.init] Improve loader for non-aligned segments The drv.uart ELF currently ends up with a segment vaddr starting at 0x215010, which includes .data and .bss. The old loader was mishandling this in a few ways: - Not zeroing out the leading 16 bytes, or the trailing .bss section - Copying the segment data to the start of the page, so it was offset by -16 bytes. - Mapping the VMA into the child program at the non-page-aligned address, which causes all sorts of trouble. --- src/user/srv.init/loader.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/user/srv.init/loader.cpp b/src/user/srv.init/loader.cpp index 472b5b7..8b009f7 100644 --- a/src/user/srv.init/loader.cpp +++ b/src/user/srv.init/loader.cpp @@ -78,11 +78,17 @@ load_program(const module_program &prog, j6_handle_t sys, char *err_msg) return false; } - void *src = reinterpret_cast(prog.base_address + seg.offset); - void *dest = reinterpret_cast(load_addr); - memcpy(dest, src, seg.file_size); + uintptr_t start = prog.base_address + seg.offset; + size_t prelude = start & 0xfff; + size_t prologue = seg.mem_size - (prelude+seg.file_size); - res = j6_vma_map(sub_vma, proc, seg.vaddr); + uint8_t *src = reinterpret_cast(start); + uint8_t *dest = reinterpret_cast(load_addr); + memset(dest, 0, prelude); + memcpy(dest+prelude, src, seg.file_size); + memset(dest+prelude+seg.file_size, 0, prologue); + + res = j6_vma_map(sub_vma, proc, seg.vaddr & ~0xfffull); if (res != j6_status_ok) { sprintf(err_msg, " ** error loading program '%s': mapping sub vma to child: %lx", prog.filename, res); return false;