w6l+selfhost: dynamic-link + .data — shared R+W segment
.data now lives at the end of the dyn-path R+W PT_LOAD, just after .dynamic. The single segment covers .got.plt + .dynamic + .data; its filesz drops trailing zeros (BSS) while memsz spans the full extent. Relocation moves from main.c into each emit function so the static and dynamic paths use their own data_va — text→data refs land on the right VA regardless of path. Removes the early-error in dynout.c that previously refused any .data with -l/-L. Tests: 810_dyn gains two new dyn+.data fixtures (mutable read+write of an i32, plus a zero-init i64 verifying the BSS scan still produces a valid p_filesz<p_memsz under the shared segment).
This commit is contained in:
@@ -63,6 +63,16 @@ l_emit_elf(Lnk *l, FILE *f, u64 base, u64 entry)
|
||||
const u64 rx_end = text_off + l->textlen;
|
||||
const int has_data = (l->datalen > 0);
|
||||
|
||||
/* data goes at the next page boundary so the loader can grant a
|
||||
* fresh page of R+W permissions without overlapping the R+X mapping. */
|
||||
const u64 data_off = has_data ? ((rx_end + page - 1) & ~(page - 1)) : 0;
|
||||
const u64 data_va = has_data ? (base + data_off) : 0;
|
||||
|
||||
/* Apply relocations now that the layout's text_va/data_va are
|
||||
* known. Deferred from main.c so the dynamic-link path can use
|
||||
* its own data_va. */
|
||||
if (l_relocate(l, base + text_off, data_va) != 0) return 1;
|
||||
|
||||
/* BSS optimisation: trailing zero bytes in .data can be left out
|
||||
* of the file. The loader zero-fills the gap between p_filesz and
|
||||
* p_memsz, so this shrinks the binary without changing semantics.
|
||||
@@ -75,11 +85,6 @@ l_emit_elf(Lnk *l, FILE *f, u64 base, u64 entry)
|
||||
bsslen++;
|
||||
}
|
||||
const u64 data_file_len = l->datalen - bsslen;
|
||||
|
||||
/* data goes at the next page boundary so the loader can grant a
|
||||
* fresh page of R+W permissions without overlapping the R+X mapping. */
|
||||
const u64 data_off = has_data ? ((rx_end + page - 1) & ~(page - 1)) : 0;
|
||||
const u64 data_va = has_data ? (base + data_off) : 0;
|
||||
const u64 file_end = has_data ? (data_off + data_file_len) : rx_end;
|
||||
(void)data_va;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user