6l: port ET_DYN dynamic linking to the ww side
Ports cmd/6l/{dyn,dynout}.c into selfhost/cmd/6l/{dyn,dynout}.ww:
ET_DYN .so loading + PT_INTERP/PT_DYNAMIC ELF emission with .rela.plt,
.gnu.version_r, BIND_NOW. lsym grows dyn fields; pass.ww promotes
undefs to dyn; out.ww dispatches; main.ww takes -L/-l. The ww driver
forwards -L/-l to 6l_ww so 'ww_ww build snake.ww -L /usr/lib -l ncurses
-l c' runs without cc.
Test 996 pins byte-identical output to C-6l on snake.
'make bootstrap' gains a fourth stage with cmp ww3 == ww4, proving
ww3 is byte-stable when used as a compiler — not just a coincidental
two-stage equilibrium.
Four wwstage 6c cgen quirks surfaced and are documented in dynout.ww's
header (two-level field-write through a pointer field, (scalar, str)
tuple returns, def : str, ≤6 arg calling convention).
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
use os;
|
||||
use sym;
|
||||
use dynout;
|
||||
|
||||
def ET_EXEC: u16 = 2u16;
|
||||
def EM_X86_64_W: u16 = 62u16;
|
||||
@@ -43,6 +44,14 @@ fn wr_u64(buf: *u8, off: u64, v: u64) void = {
|
||||
// ---- emit ---------------------------------------------------------------
|
||||
|
||||
export fn l_emit_elf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
// Dispatch: any loaded shared object plus any dynamic ref means
|
||||
// we owe the loader a real PT_INTERP/PT_DYNAMIC binary.
|
||||
if (l.sos != nil) {
|
||||
if (l.dyn_n > 0) {
|
||||
return l_emit_dyn_elf(l, fd, base, entry);
|
||||
};
|
||||
};
|
||||
|
||||
let filesz: u64 = TEXT_OFF + l.textlen;
|
||||
|
||||
// One contiguous header buffer covering [0..0x1000), then .text.
|
||||
|
||||
Reference in New Issue
Block a user