w6l: dynamic e_entry rebases with the actual text offset, both stages

When the dynamic section pushed the header past the first page, the
entry point kept its first-page address — every sufficiently large
dynamic binary SIGSEGV'd into the headers. Recompute e_entry as
entry - 0x1000 + text_off in both stages (ELF: the entry must point
into .text wherever it lands). Both stages move in one commit: one
ELF contract; the 989_dynentry gate pins the field and the run.
This commit is contained in:
2026-06-13 10:17:51 +09:00
parent 95da870734
commit 675a0368cd
5 changed files with 222 additions and 3 deletions

View File

@@ -661,7 +661,13 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
dwr16(filebuf.ptr, 16u64, ET_EXEC_D);
dwr16(filebuf.ptr, 18u64, EM_X86_64_D);
dwr32(filebuf.ptr, 20u64, EV_CURRENT_D);
dwr64(filebuf.ptr, 24u64, entry);
// #63: main computed `entry` as BASE + CODE_VA_OFF (== PAGE) + val
// assuming .text sits at file offset 0x1000, but textoff above is
// recomputed and overflows 0x1000 once the dynamic headers exceed the
// first page (e.g. ~100 dyn syms). Rebase e_entry onto the actual textoff
// so it points at the real _start instead of into the headers. Both
// stages (#263). PAGE is dynout-local; equals main.ww's CODE_VA_OFF.
dwr64(filebuf.ptr, 24u64, entry - PAGE + textoff);
dwr64(filebuf.ptr, 32u64, ehdrsz);
dwr64(filebuf.ptr, 40u64, 0u64);
dwr32(filebuf.ptr, 48u64, 0u32);

View File

@@ -4754,7 +4754,13 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
dwr16(filebuf.ptr, 16u64, ET_EXEC_D);
dwr16(filebuf.ptr, 18u64, EM_X86_64_D);
dwr32(filebuf.ptr, 20u64, EV_CURRENT_D);
dwr64(filebuf.ptr, 24u64, entry);
// #63: main computed `entry` as BASE + CODE_VA_OFF (== PAGE) + val
// assuming .text sits at file offset 0x1000, but textoff above is
// recomputed and overflows 0x1000 once the dynamic headers exceed the
// first page (e.g. ~100 dyn syms). Rebase e_entry onto the actual textoff
// so it points at the real _start instead of into the headers. Both
// stages (#263). PAGE is dynout-local; equals main.ww's CODE_VA_OFF.
dwr64(filebuf.ptr, 24u64, entry - PAGE + textoff);
dwr64(filebuf.ptr, 32u64, ehdrsz);
dwr64(filebuf.ptr, 40u64, 0u64);
dwr32(filebuf.ptr, 48u64, 0u32);