Skip to content

Commit 5d8b70c

Browse files
committed
Made PageSize detection / Handling dynamic. nd fixed elfloading for pagesize not 4K. The define are still there but might be removed shortly (for #1231, #1226, #1189, #1175, #999, #384 and probably a few other)
1 parent d60ba04 commit 5d8b70c

File tree

3 files changed

+49
-65
lines changed

3 files changed

+49
-65
lines changed

src/elfs/elfloader.c

+46-51
Original file line numberDiff line numberDiff line change
@@ -196,19 +196,6 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
196196
}
197197
if(!offs && !head->vaddr)
198198
offs = (uintptr_t)find47bitBlockElf(head->memsz+head->align, mainbin, max_align); // limit to 47bits...
199-
#if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
200-
// Will not try anything smart on pagesize != 4k....
201-
size_t sz = head->memsz;
202-
void* raw = NULL;
203-
void* image = NULL;
204-
if(!head->vaddr) {
205-
sz += head->align;
206-
raw = mmap64((void*)offs, sz, 0, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
207-
image = mmap64((void*)(((uintptr_t)raw+max_align)&~max_align), head->memsz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
208-
} else {
209-
image = raw = mmap64((void*)head->vaddr, sz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
210-
}
211-
#else // PAGE4K
212199
// prereserve the whole elf image, without populating
213200
size_t sz = head->memsz;
214201
void* raw = NULL;
@@ -220,7 +207,6 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
220207
} else {
221208
image = raw = mmap64((void*)head->vaddr, sz, 0, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
222209
}
223-
#endif
224210
if(image!=MAP_FAILED && !head->vaddr && image!=(void*)offs) {
225211
printf_log(LOG_INFO, "%s: Mmap64 for (@%p 0x%zx) for elf \"%s\" returned %p(%p/0x%zx) instead\n", (((uintptr_t)image)&max_align)?"Error":"Warning", (void*)(head->vaddr?head->vaddr:offs), head->memsz, head->name, image, raw, head->align);
226212
offs = (uintptr_t)image;
@@ -240,17 +226,14 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
240226
return 1;
241227
offs = (uintptr_t)image-head->vaddr;
242228
}
243-
printf_log(log_level, "Pre-allocated 0x%zx byte at %p for %s\n", head->memsz, image, head->name);
229+
printf_dump(log_level, "Pre-allocated 0x%zx byte at %p for %s\n", head->memsz, image, head->name);
244230
head->delta = offs;
245-
printf_log(log_level, "Delta of %p (vaddr=%p) for Elf \"%s\"\n", (void*)offs, (void*)head->vaddr, head->name);
231+
printf_dump(log_level, "Delta of %p (vaddr=%p) for Elf \"%s\"\n", (void*)offs, (void*)head->vaddr, head->name);
246232

247233
head->image = image;
248234
head->raw = raw;
249235
head->raw_size = sz;
250236
setProtection_elf((uintptr_t)raw, sz, 0);
251-
#if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
252-
setProtection_elf((uintptr_t)image, head->memsz, PROT_READ|PROT_WRITE|PROT_EXEC);
253-
#endif
254237

255238
head->multiblocks = (multiblock_t*)box_calloc(head->multiblock_n, sizeof(multiblock_t));
256239
head->tlsbase = AddTLSPartition(context, head->tlssize);
@@ -267,20 +250,10 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
267250
head->multiblocks[n].size = e->p_filesz;
268251
head->multiblocks[n].align = e->p_align;
269252
uint8_t prot = ((e->p_flags & PF_R)?PROT_READ:0)|((e->p_flags & PF_W)?PROT_WRITE:0)|((e->p_flags & PF_X)?PROT_EXEC:0);
270-
#if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
271-
head->multiblocks[n].p = NULL;
272-
if(e->p_filesz) {
273-
fseeko64(head->file, head->multiblocks[n].offs, SEEK_SET);
274-
if(fread((void*)head->multiblocks[n].paddr, head->multiblocks[n].size, 1, head->file)!=1) {
275-
printf_log(LOG_NONE, "Cannot read elf block (@%p 0x%zx) for elf \"%s\"\n", (void*)head->multiblocks[n].offs, head->multiblocks[n].asize, head->name);
276-
return 1;
277-
}
278-
}
279-
#else //PAGE4K
280253
// check if alignment is correct
281254
uintptr_t balign = head->multiblocks[n].align-1;
282-
if(balign<(box64_pagesize-1)) balign = (box64_pagesize-1);
283-
head->multiblocks[n].asize = ALIGN(e->p_memsz+(e->p_paddr&balign));
255+
if(balign<4095) balign = 4095;
256+
head->multiblocks[n].asize = (e->p_memsz+(e->p_paddr&balign)+4095)&~4095;
284257
int try_mmap = 1;
285258
if(e->p_paddr&balign)
286259
try_mmap = 0;
@@ -290,8 +263,10 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
290263
try_mmap = 0;
291264
if(!e->p_filesz)
292265
try_mmap = 0;
266+
if(e->p_align<box64_pagesize)
267+
try_mmap = 0;
293268
if(try_mmap) {
294-
printf_log(log_level, "Mmaping 0x%lx(0x%lx) bytes @%p for Elf \"%s\"\n", head->multiblocks[n].size, head->multiblocks[n].asize, (void*)head->multiblocks[n].paddr, head->name);
269+
printf_dump(log_level, "Mmaping 0x%lx(0x%lx) bytes @%p for Elf \"%s\"\n", head->multiblocks[n].size, head->multiblocks[n].asize, (void*)head->multiblocks[n].paddr, head->name);
295270
void* p = mmap64(
296271
(void*)head->multiblocks[n].paddr,
297272
head->multiblocks[n].size,
@@ -302,7 +277,7 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
302277
);
303278
if(p==MAP_FAILED || p!=(void*)head->multiblocks[n].paddr) {
304279
try_mmap = 0;
305-
printf_log(log_level, "Mapping failed, using regular mmap+read");
280+
printf_dump(log_level, "Mapping failed, using regular mmap+read");
306281
} else {
307282
if(e->p_memsz>e->p_filesz)
308283
memset((void*)((uintptr_t)p + e->p_filesz), 0, e->p_memsz-e->p_filesz);
@@ -314,15 +289,43 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
314289
if(!try_mmap) {
315290
uintptr_t paddr = head->multiblocks[n].paddr&~balign;
316291
size_t asize = head->multiblocks[n].asize;
317-
printf_log(log_level, "Allocating 0x%zx (0x%zx) bytes @%p, will read 0x%zx @%p for Elf \"%s\"\n", asize, e->p_memsz, (void*)paddr, e->p_filesz, (void*)head->multiblocks[n].paddr, head->name);
318-
void* p = mmap64(
319-
(void*)paddr,
320-
asize,
321-
prot|PROT_WRITE,
322-
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
323-
-1,
324-
0
325-
);
292+
void* p = MAP_FAILED;
293+
if(paddr==(paddr&~(box64_pagesize-1)) && (asize==ALIGN(asize))) {
294+
printf_dump(log_level, "Allocating 0x%zx (0x%zx) bytes @%p, will read 0x%zx @%p for Elf \"%s\"\n", asize, e->p_memsz, (void*)paddr, e->p_filesz, (void*)head->multiblocks[n].paddr, head->name);
295+
p = mmap64(
296+
(void*)paddr,
297+
asize,
298+
prot|PROT_WRITE,
299+
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
300+
-1,
301+
0
302+
);
303+
} else {
304+
// difference in pagesize, so need to mmap only what needed to be...
305+
//check startint point
306+
uintptr_t new_addr = paddr;
307+
ssize_t new_size = asize;
308+
while(getProtection(new_addr) && (new_size>0)) {
309+
new_size -= ALIGN(new_addr) - new_addr;
310+
new_addr = ALIGN(new_addr);
311+
}
312+
if(new_size>0) {
313+
printf_dump(log_level, "Allocating 0x%zx (0x%zx) bytes @%p, will read 0x%zx @%p for Elf \"%s\"\n", ALIGN(new_size), e->p_memsz, (void*)new_addr, e->p_filesz, (void*)head->multiblocks[n].paddr, head->name);
314+
p = mmap64(
315+
(void*)new_addr,
316+
ALIGN(new_size),
317+
prot|PROT_WRITE,
318+
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
319+
-1,
320+
0
321+
);
322+
if(p==(void*)new_addr)
323+
p = (void*)paddr;
324+
} else {
325+
p = (void*)paddr;
326+
printf_dump(log_level, "Will read 0x%zx @%p for Elf \"%s\"\n", e->p_filesz, (void*)head->multiblocks[n].paddr, head->name);
327+
}
328+
}
326329
if(p==MAP_FAILED || p!=(void*)paddr) {
327330
printf_log(LOG_NONE, "Cannot create memory map (@%p 0x%zx/0x%zx) for elf \"%s\"", (void*)paddr, asize, balign, head->name);
328331
if(p==MAP_FAILED) {
@@ -341,10 +344,9 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
341344
return 1;
342345
}
343346
}
344-
if(!(prot&PROT_WRITE))
347+
if(!(prot&PROT_WRITE) && (paddr==(paddr&(box64_pagesize-1)) && (asize==ALIGN(asize))))
345348
mprotect((void*)paddr, asize, prot);
346349
}
347-
#endif //PAGE4K
348350
#ifdef DYNAREC
349351
if(box64_dynarec && (e->p_flags & PF_X)) {
350352
dynarec_log(LOG_DEBUG, "Add ELF eXecutable Memory %p:%p\n", head->multiblocks[n].p, (void*)head->multiblocks[n].asize);
@@ -1430,20 +1432,13 @@ int IsAddressInElfSpace(const elfheader_t* h, uintptr_t addr)
14301432
{
14311433
if(!h)
14321434
return 0;
1433-
#if defined(PAGE8K) || defined(PAGE16K) || defined(PAGE64K)
1434-
uintptr_t base = (uintptr_t)h->image;
1435-
uintptr_t end = base+h->memsz;
1436-
if(base && addr>=base && addr<=end)
1437-
return 1;
1438-
#else //PAGE4K
14391435
for(int i=0; i<h->multiblock_n; ++i) {
14401436
uintptr_t base = (uintptr_t)h->multiblocks[i].p;
14411437
uintptr_t end = (uintptr_t)h->multiblocks[i].p + h->multiblocks[i].asize - 1;
14421438
if(base && addr>=base && addr<=end)
14431439
return 1;
14441440

14451441
}
1446-
#endif //PAGE4K
14471442
return 0;
14481443
}
14491444
elfheader_t* FindElfAddress(box64context_t *context, uintptr_t addr)

src/main.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -439,10 +439,8 @@ HWCAP2_ECV
439439
printf_log(LOG_INFO, " FRINT");
440440
if(arm64_afp)
441441
printf_log(LOG_INFO, " AFP");
442-
printf_log(LOG_INFO, " PageSize:%zd ", box64_pagesize);
443442
#elif defined(LA464)
444443
printf_log(LOG_INFO, "Dynarec for LoongArch");
445-
printf_log(LOG_INFO, " PageSize:%zd ", box64_pagesize);
446444
#elif defined(RV64)
447445
void RV64_Detect_Function();
448446
if(!getenv("BOX64_DYNAREC_RV64NOEXT"))
@@ -462,8 +460,6 @@ HWCAP2_ECV
462460
if(rv64_xtheadfmemidx) printf_log(LOG_INFO, " XTheadFMemIdx");
463461
if(rv64_xtheadmac) printf_log(LOG_INFO, " XTheadMac");
464462
if(rv64_xtheadfmv) printf_log(LOG_INFO, " XTheadFmv");
465-
466-
printf_log(LOG_INFO, " PageSize:%zd ", box64_pagesize);
467463
#else
468464
#error Unsupported architecture
469465
#endif
@@ -998,7 +994,7 @@ void LoadLogEnv()
998994
#endif
999995
int ncpu = getNCpu();
1000996
const char* cpuname = getCpuName();
1001-
printf_log(LOG_INFO, "Running on %s with %d Cores\n", cpuname, ncpu);
997+
printf_log(LOG_INFO, " PageSize:%zd Running on %s with %d Cores\n", box64_pagesize, cpuname, ncpu);
1002998
}
1003999

10041000
EXPORTDYN

src/tools/bridge.c

+2-9
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,8 @@ typedef struct brick_s {
2828
int sz;
2929
brick_t *next;
3030
} brick_t;
31-
#ifdef PAGE8K
32-
#define NBRICK (8192/sizeof(onebridge_t))
33-
#elif defined(PAGE16K)
34-
#define NBRICK (16384/sizeof(onebridge_t))
35-
#elif defined(PAGE64K)
36-
#define NBRICK (65536/sizeof(onebridge_t))
37-
#else
38-
#define NBRICK (4096/sizeof(onebridge_t))
39-
#endif
31+
32+
#define NBRICK (box64_pagesize/sizeof(onebridge_t))
4033

4134
typedef struct bridge_s {
4235
brick_t *head;

0 commit comments

Comments
 (0)