[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.
This commit is contained in:
@@ -78,11 +78,17 @@ load_program(const module_program &prog, j6_handle_t sys, char *err_msg)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *src = reinterpret_cast<void *>(prog.base_address + seg.offset);
|
uintptr_t start = prog.base_address + seg.offset;
|
||||||
void *dest = reinterpret_cast<void *>(load_addr);
|
size_t prelude = start & 0xfff;
|
||||||
memcpy(dest, src, seg.file_size);
|
size_t prologue = seg.mem_size - (prelude+seg.file_size);
|
||||||
|
|
||||||
res = j6_vma_map(sub_vma, proc, seg.vaddr);
|
uint8_t *src = reinterpret_cast<uint8_t *>(start);
|
||||||
|
uint8_t *dest = reinterpret_cast<uint8_t *>(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) {
|
if (res != j6_status_ok) {
|
||||||
sprintf(err_msg, " ** error loading program '%s': mapping sub vma to child: %lx", prog.filename, res);
|
sprintf(err_msg, " ** error loading program '%s': mapping sub vma to child: %lx", prog.filename, res);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user