Fix bug that caused a crash if an interrupt was triggered while loading a binary.
This commit is contained in:
parent
9a4ad50d34
commit
907baa75a7
@ -160,6 +160,65 @@ Loader_EnterUserLevel(void *arg)
|
||||
Trap_Pop(&tf);
|
||||
}
|
||||
|
||||
void
|
||||
LoaderFileHelper(AS *as, VNode *vn, uintptr_t vaddr,
|
||||
uintptr_t offset, uintptr_t len)
|
||||
{
|
||||
void *raddr;
|
||||
|
||||
if ((vaddr % PGSIZE) != 0) {
|
||||
uintptr_t maxlen = PGSIZE - (vaddr % PGSIZE);
|
||||
uintptr_t rlen = maxlen < len ? maxlen : len;
|
||||
|
||||
raddr = (void *)DMPA2VA(PMap_Translate(as, vaddr));
|
||||
VFS_Read(vn, raddr, offset, rlen);
|
||||
vaddr += rlen;
|
||||
offset += rlen;
|
||||
len -= rlen;
|
||||
}
|
||||
|
||||
while (len > PGSIZE) {
|
||||
raddr = (void *)DMPA2VA(PMap_Translate(as, vaddr));
|
||||
VFS_Read(vn, raddr, offset, PGSIZE);
|
||||
vaddr += PGSIZE;
|
||||
offset += PGSIZE;
|
||||
len -= PGSIZE;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
raddr = (void *)DMPA2VA(PMap_Translate(as, vaddr));
|
||||
VFS_Read(vn, raddr, offset, len);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LoaderZeroHelper(AS *as, uintptr_t vaddr, uintptr_t len)
|
||||
{
|
||||
void *raddr;
|
||||
|
||||
if ((vaddr % PGSIZE) != 0) {
|
||||
uintptr_t maxlen = PGSIZE - (vaddr % PGSIZE);
|
||||
uintptr_t rlen = maxlen < len ? maxlen : len;
|
||||
|
||||
raddr = (void *)DMPA2VA(PMap_Translate(as, vaddr));
|
||||
memset(raddr, 0, rlen);
|
||||
vaddr += rlen;
|
||||
len -= rlen;
|
||||
}
|
||||
|
||||
while (len > PGSIZE) {
|
||||
raddr = (void *)DMPA2VA(PMap_Translate(as, vaddr));
|
||||
memset(raddr, 0, PGSIZE);
|
||||
vaddr += PGSIZE;
|
||||
len -= PGSIZE;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
raddr = (void *)DMPA2VA(PMap_Translate(as, vaddr));
|
||||
memset(raddr, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len)
|
||||
{
|
||||
@ -201,27 +260,23 @@ Loader_Load(Thread *thr, VNode *vn, void *buf, uint64_t len)
|
||||
|
||||
void *stack = PAlloc_AllocPage();
|
||||
PMap_Map(as, (uint64_t)DMVA2PA(stack), 0x70000000, 1, 0);
|
||||
PMap_LoadAS(as); // Reload CR3
|
||||
|
||||
for (i = 0; i < ehdr->e_phnum; i++)
|
||||
{
|
||||
ASSERT(phdr[i].p_type != PT_DYNAMIC);
|
||||
if (phdr[i].p_type == PT_LOAD) {
|
||||
if (phdr[i].p_filesz != 0) {
|
||||
VFS_Read(vn, (void *)phdr[i].p_vaddr,
|
||||
phdr[i].p_offset, phdr[i].p_filesz);
|
||||
LoaderFileHelper(as, vn, phdr[i].p_vaddr,
|
||||
phdr[i].p_offset, phdr[i].p_filesz);
|
||||
}
|
||||
memset((void *)(phdr[i].p_vaddr + phdr[i].p_filesz),
|
||||
0,
|
||||
(uintptr_t)(phdr[i].p_memsz - phdr[i].p_filesz));
|
||||
LoaderZeroHelper(as,
|
||||
phdr[i].p_vaddr + phdr[i].p_filesz,
|
||||
phdr[i].p_memsz - phdr[i].p_filesz);
|
||||
}
|
||||
}
|
||||
|
||||
Thread_SetupKThread(thr, Loader_EnterUserLevel, (void *)ehdr->e_entry);
|
||||
|
||||
// Restore AS
|
||||
PMap_LoadAS(Thread_Current()->space);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user