[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:
Justin C. Miller
2022-02-13 00:05:35 -08:00
parent dc5efeecbb
commit 3be4b103a2

View File

@@ -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;