diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-04 09:09:55 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-04 09:09:55 +0100 |
| commit | f0d5e9d01ef74346da13f88f7d1b6678980e622b (patch) | |
| tree | 0636c68df9bb7a5ba2c8d82a7e5158764f04c76c /src | |
| parent | be05309e51e1df36dd1aec67e6421eb7dcf0e9c9 (diff) | |
| download | box64-f0d5e9d01ef74346da13f88f7d1b6678980e622b.tar.gz box64-f0d5e9d01ef74346da13f88f7d1b6678980e622b.zip | |
[ELFLOADER] More changes to elf memory managment
Diffstat (limited to 'src')
| -rw-r--r-- | src/elfs/elfloader.c | 37 | ||||
| -rw-r--r-- | src/elfs/elfloader_private.h | 1 |
2 files changed, 30 insertions, 8 deletions
diff --git a/src/elfs/elfloader.c b/src/elfs/elfloader.c index 4917c628..7cc4ec12 100644 --- a/src/elfs/elfloader.c +++ b/src/elfs/elfloader.c @@ -197,16 +197,34 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin) if(!offs && !head->vaddr) offs = (uintptr_t)find47bitBlockElf(head->memsz, mainbin, max_align); // limit to 47bits... + // prereserve the whole elf image, without populating + void* image = mmap64((void*)(head->vaddr?head->vaddr:offs), head->memsz, 0, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); + if(image!=MAP_FAILED && !head->vaddr && image!=(void*)offs) { + offs = (uintptr_t)image; + printf_log(LOG_INFO, "Mamp64 for (@%p 0x%zx) for elf \"%s\" returned %p instead", (void*)(head->vaddr?head->vaddr:offs), head->memsz, head->name, image); + } + if(image==MAP_FAILED || image!=(void*)(head->vaddr?head->vaddr:offs)) { + printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%zx) for elf \"%s\"", (void*)(head->vaddr?head->vaddr:offs), head->memsz, head->name); + if(image==MAP_FAILED) { + printf_log(LOG_NONE, " error=%d/%s\n", errno, strerror(errno)); + } else { + printf_log(LOG_NONE, " got %p\n", image); + } + return 1; + } head->delta = offs; printf_log(log_level, "Delta of %p (vaddr=%p) for Elf \"%s\"\n", (void*)offs, (void*)head->vaddr, head->name); + head->image = image; + setProtection_mmap((uintptr_t)image, head->memsz, 0); + head->multiblocks = (multiblock_t*)box_calloc(head->multiblock_n, sizeof(multiblock_t)); head->tlsbase = AddTLSPartition(context, head->tlssize); // and now, create all individual blocks head->memory = (char*)0xffffffffffffffff; int n = 0; for (size_t i=0; i<head->numPHEntries; ++i) { - if(head->PHEntries[i].p_type == PT_LOAD) { + if(head->PHEntries[i].p_type == PT_LOAD && head->PHEntries[i].p_flags) { Elf64_Phdr * e = &head->PHEntries[i]; head->multiblocks[n].flags = e->p_flags; @@ -225,16 +243,16 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin) try_mmap = 0; if(head->multiblocks[n].asize != head->multiblocks[n].size) try_mmap = 0; - if(!e->p_flags || !e->p_filesz) + if(!e->p_filesz) try_mmap = 0; - uint8_t prot = e->p_flags?(PROT_READ|PROT_WRITE|((e->p_flags & PF_X)?PROT_EXEC:0)):0; + uint8_t prot = PROT_READ|PROT_WRITE|((e->p_flags & PF_X)?PROT_EXEC:0); if(try_mmap) { printf_log(log_level, "Mmaping 0x%lx memory @%p for Elf \"%s\"\n", head->multiblocks[n].size, (void*)head->multiblocks[n].paddr, head->name); void* p = mmap64( (void*)head->multiblocks[n].paddr, head->multiblocks[n].asize, prot, - MAP_PRIVATE, + MAP_PRIVATE|MAP_FIXED, head->fileno, e->p_offset ); @@ -254,7 +272,7 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin) (void*)paddr, head->multiblocks[n].asize, prot, - MAP_PRIVATE|MAP_ANONYMOUS|(e->p_flags?MAP_NORESERVE:0), + MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0 ); @@ -315,17 +333,20 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin) void FreeElfMemory(elfheader_t* head) { if(head->multiblock_n) { - for(int i=0; i<head->multiblock_n; ++i) { #ifdef DYNAREC + for(int i=0; i<head->multiblock_n; ++i) { dynarec_log(LOG_INFO, "Free DynaBlocks for %s\n", head->path); if(box64_dynarec) cleanDBFromAddressRange((uintptr_t)head->multiblocks[i].p, head->multiblocks[i].size, 1); -#endif - munmap(head->multiblocks[i].p, head->multiblocks[i].asize); freeProtection((uintptr_t)head->multiblocks[i].p, head->multiblocks[i].asize); } +#endif box_free(head->multiblocks); } + // we only need to free the overall mmap, no need to free individual part as they are inside the big one + if(head->image && head->memsz) + munmap(head->image, head->memsz); + freeProtection((uintptr_t)head->image, head->memsz); } int isElfHasNeededVer(elfheader_t* head, const char* libname, elfheader_t* verneeded) diff --git a/src/elfs/elfloader_private.h b/src/elfs/elfloader_private.h index b80c87db..ed151b39 100644 --- a/src/elfs/elfloader_private.h +++ b/src/elfs/elfloader_private.h @@ -49,6 +49,7 @@ typedef struct elfheader_s { uint32_t flags; intptr_t delta; // should be 0 + void* image; uintptr_t entrypoint; uintptr_t initentry; |