selfhost: mirror writable .data + R_X86_64_64 across the wwstage
Bring the wwstage toolchain to parity with C-side DATAW / DATAR /
.data / .rela.data support. With this, w6c_ww + w6a_ww + w6l_ww can
compile, assemble and link `let g: str = "lit";` (and the scalar /
str / slice / struct globals that landed earlier) end-to-end, with
output that's byte-identical to the C-side pipeline.
w6a (types.ww / parse.ww / asm.ww / obj.ww):
- A_DATAW + A_DATAR opcodes; parser learns `name+disp(SB)`;
A_DATAR records an R_X86_64_64 reloc in .data via the new
addrelocdata helper; areloc gains a `section` flag and asym
an `isdata` flag; obj.ww splits relocs into .rela.text /
.rela.data, emits .data PROGBITS + .rela.data conditionally,
and shuffles section indices the same way cmd/w6a/obj.c does
so byte output stays identical when no DATAW/DATAR are used.
w6l (sym.ww / obj.ww / pass.ww / out.ww / dynout.ww / main.ww):
- lrel grows `section`; lsym grows `indata`; lobj tracks
dataoff / datasize; lnk grows combined .data buffer;
- obj.ww loads .data and .rela.data, registers data symbols
with indata=1 and val shifted by the input's data_off, and
the archive scanner includes both .text and .data globals;
- pass.ww adds R_X86_64_64 (patch 8 bytes in .text or .data
with sym_va + addend); relocate's signature becomes
(textva, datava);
- out.ww emits a second PT_LOAD (R+W) when datalen > 0, with
.data at the page-aligned offset after .text;
- dynout.ww refuses .data + -l/-L cleanly (matches the C-side
error message);
- main.ww computes text_va / data_va and passes both to
relocate.
wcc cgen (cgen.ww / cgendecl.ww):
- letpreintern walks top-level str-lets and interns the strlit
BEFORE emitdatasection emits its DATA row, so emitletdataw
can later look up the same label;
- emitletdataw's 16B branch detects non-empty strlit init and
emits the 8-zero + 8-LE-len DATAW plus a DATAR slot+0,strlit
reloc, mirroring cmd/w6c/cgen.c.
Verified: `wwdump_ww -c` byte-matches `w6c` on a `let g: str =
"hello world\n";` fixture; `w6a_ww` and `w6l_ww` produce a
binary byte-identical to the C-side pipeline that runs and
prints "hello world". Bootstrap fixed-point holds (ww2 == ww3 ==
ww4), 26/26 tests green.
This commit is contained in:
@@ -7,8 +7,10 @@ use mem;
|
||||
|
||||
type lsym = struct {
|
||||
name: str,
|
||||
val: u64, // offset within combined .text once linked
|
||||
val: u64, // offset within combined .text (or .data when
|
||||
// indata=1) once linked
|
||||
defined: i32, // 1 if some lobj defines this symbol
|
||||
indata: i32, // 1 if defined in .data (writable globals)
|
||||
owner: *lobj,
|
||||
idxinowner: i32,
|
||||
// Dynamic-linking fields. Set by resolve when an undefined sym
|
||||
@@ -23,7 +25,8 @@ type lsym = struct {
|
||||
};
|
||||
|
||||
type lrel = struct {
|
||||
off: u64, // offset within combined .text
|
||||
off: u64, // offset within the relocation's section
|
||||
section: i32, // 0 = .text, 1 = .data
|
||||
kind: i32, // R_X86_64_*
|
||||
sym: *lsym,
|
||||
addend: i64,
|
||||
@@ -36,6 +39,8 @@ type lobj = struct {
|
||||
len: u64,
|
||||
textoff: u64, // offset of .text in combined output
|
||||
textsize: u64,
|
||||
dataoff: u64, // offset of .data in combined output
|
||||
datasize: u64, // bytes contributed to combined .data (0 if none)
|
||||
onext: *lobj,
|
||||
};
|
||||
|
||||
@@ -64,6 +69,11 @@ type lnk = struct {
|
||||
text: *u8, // combined .text
|
||||
textcap: u64,
|
||||
textlen: u64,
|
||||
// Combined .data (writable). Empty unless any input .o has a
|
||||
// .data PROGBITS section.
|
||||
data: *u8,
|
||||
datacap: u64,
|
||||
datalen: u64,
|
||||
errs: i32,
|
||||
dynn: i32, // number of syms routed through PLT
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user