cmd: α/γ-4 rt.malloc → alloc([], N)! (w6a/w6c/w6l file slurps + sized bufs)

Phase 0 #8 fourth α-batch. 10 α/γ conversions across 6 files:
 - w6a/main.ww slurp (1)
 - w6c/main.ww slurp (1)
 - w6l/dyn.ww slurpso (1)
 - w6l/obj.ww slurp (1)
 - w6l/dynout.ww filebuf at :661 (1; threads .ptr through ~50
   dwr*/dbcopy callees — that's the 139-line w6l/dynout diff)
 - w6l/out.ww hdr at :92 (1)
 - w6l/main.ww 4 sites: bufp + γ {inputs, libdirs, lflags} (4)

Deferred:
 - w6l/main.ww 3× 16/8/20-byte δ fixed-bufs at :67/:106/:176 →
   stack-promote in a separate sub-task.
 - w6l/obj.ww :113/:135 β text-buffer growth → memio.dynamic refactor.

Pattern unchanged from 47918d3/00d88ff/e9eb67d: `alloc([], N: u64)!` +
`buf.len = N: i32;` + `buf.ptr` for callees taking `*u8`. γ uses
element-count (was bytes): `maxinputs: u64` not `maxinputs*8u64`.

Verified 132/132 + 995_self_rebuild byte-identity. Advances #45.
This commit is contained in:
2026-05-21 01:59:58 +09:00
parent e9eb67de04
commit 368b85ea33
10 changed files with 270 additions and 258 deletions

View File

@@ -3058,8 +3058,9 @@ fn slurp(path: *u8) (*u8, u64) = {
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let nz: u64 = n: u64; let nz: u64 = n: u64;
let buf: *u8 = rt.malloc(nz + 1u64): *u8; let buf: []u8 = alloc([], nz + 1u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, nz); buf.len = (nz + 1u64): i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, nz);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -3068,7 +3069,7 @@ fn slurp(path: *u8) (*u8, u64) = {
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
buf[nz] = 0u8; buf[nz] = 0u8;
return buf, nz; return buf.ptr, nz;
}; };
export fn main(argc: i32, argv: **u8) i32 = { export fn main(argc: i32, argv: **u8) i32 = {

View File

@@ -53,8 +53,9 @@ fn slurp(path: *u8) (*u8, u64) = {
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let nz: u64 = n: u64; let nz: u64 = n: u64;
let buf: *u8 = rt.malloc(nz + 1u64): *u8; let buf: []u8 = alloc([], nz + 1u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, nz); buf.len = (nz + 1u64): i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, nz);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -63,7 +64,7 @@ fn slurp(path: *u8) (*u8, u64) = {
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
buf[nz] = 0u8; buf[nz] = 0u8;
return buf, nz; return buf.ptr, nz;
}; };
export fn main(argc: i32, argv: **u8) i32 = { export fn main(argc: i32, argv: **u8) i32 = {

View File

@@ -23181,8 +23181,9 @@ fn slurp(path: *u8) (*u8, u64) = {
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let nz: u64 = n: u64; let nz: u64 = n: u64;
let buf: *u8 = rt.malloc(nz + 1u64): *u8; let buf: []u8 = alloc([], nz + 1u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, nz); buf.len = (nz + 1u64): i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, nz);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -23191,7 +23192,7 @@ fn slurp(path: *u8) (*u8, u64) = {
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
buf[nz] = 0u8; buf[nz] = 0u8;
return buf, nz; return buf.ptr, nz;
}; };
export fn main(argc: i32, argv: **u8) i32 = { export fn main(argc: i32, argv: **u8) i32 = {

View File

@@ -62,8 +62,9 @@ fn slurp(path: *u8) (*u8, u64) = {
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let nz: u64 = n: u64; let nz: u64 = n: u64;
let buf: *u8 = rt.malloc(nz + 1u64): *u8; let buf: []u8 = alloc([], nz + 1u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, nz); buf.len = (nz + 1u64): i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, nz);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -72,7 +73,7 @@ fn slurp(path: *u8) (*u8, u64) = {
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
buf[nz] = 0u8; buf[nz] = 0u8;
return buf, nz; return buf.ptr, nz;
}; };
export fn main(argc: i32, argv: **u8) i32 = { export fn main(argc: i32, argv: **u8) i32 = {

View File

@@ -135,8 +135,9 @@ fn slurpso(path: *u8) (*u8, u64) = {
case let v: i64 => n = v; case let v: i64 => n = v;
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let buf: *u8 = rt.malloc(n: u64): *u8; let buf: []u8 = alloc([], n: u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, n: u64); buf.len = n: i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, n: u64);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -144,7 +145,7 @@ fn slurpso(path: *u8) (*u8, u64) = {
case let e: os.oserror => return nil, 0u64; case let e: os.oserror => return nil, 0u64;
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
return buf, n: u64; return buf.ptr, n: u64;
}; };
// ---- verdef helpers ---------------------------------------------------- // ---- verdef helpers ----------------------------------------------------

View File

@@ -658,99 +658,96 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
// ---- assemble file buffer ---- // ---- assemble file buffer ----
let filebuf: *u8 = rt.malloc(fileend): *u8; let filebuf: []u8 = alloc([], fileend)!;
if (filebuf == nil) { filebuf.len = fileend: i32;
os.write(2, "w6l: out of memory\n".ptr, 18u64);
return 1;
};
// Ehdr // Ehdr
dwr8(filebuf, 0u64, 127u8); dwr8(filebuf.ptr, 0u64, 127u8);
dwr8(filebuf, 1u64, 69u8); dwr8(filebuf.ptr, 1u64, 69u8);
dwr8(filebuf, 2u64, 76u8); dwr8(filebuf.ptr, 2u64, 76u8);
dwr8(filebuf, 3u64, 70u8); dwr8(filebuf.ptr, 3u64, 70u8);
dwr8(filebuf, 4u64, ELFCLASS64_D); dwr8(filebuf.ptr, 4u64, ELFCLASS64_D);
dwr8(filebuf, 5u64, ELFDATA2LSB_D); dwr8(filebuf.ptr, 5u64, ELFDATA2LSB_D);
dwr8(filebuf, 6u64, EV_CURRENT_D: u8); dwr8(filebuf.ptr, 6u64, EV_CURRENT_D: u8);
dwr16(filebuf, 16u64, ET_EXEC_D); dwr16(filebuf.ptr, 16u64, ET_EXEC_D);
dwr16(filebuf, 18u64, EM_X86_64_D); dwr16(filebuf.ptr, 18u64, EM_X86_64_D);
dwr32(filebuf, 20u64, EV_CURRENT_D); dwr32(filebuf.ptr, 20u64, EV_CURRENT_D);
dwr64(filebuf, 24u64, entry); dwr64(filebuf.ptr, 24u64, entry);
dwr64(filebuf, 32u64, ehdrsz); dwr64(filebuf.ptr, 32u64, ehdrsz);
dwr64(filebuf, 40u64, 0u64); dwr64(filebuf.ptr, 40u64, 0u64);
dwr32(filebuf, 48u64, 0u32); dwr32(filebuf.ptr, 48u64, 0u32);
dwr16(filebuf, 52u64, ehdrsz: u16); dwr16(filebuf.ptr, 52u64, ehdrsz: u16);
dwr16(filebuf, 54u64, 56u16); dwr16(filebuf.ptr, 54u64, 56u16);
dwr16(filebuf, 56u64, nphdrs: u16); dwr16(filebuf.ptr, 56u64, nphdrs: u16);
dwr16(filebuf, 58u64, 0u16); dwr16(filebuf.ptr, 58u64, 0u16);
dwr16(filebuf, 60u64, 0u16); dwr16(filebuf.ptr, 60u64, 0u16);
dwr16(filebuf, 62u64, 0u16); dwr16(filebuf.ptr, 62u64, 0u16);
// Phdrs at offset 64. // Phdrs at offset 64.
let p0: u64 = 64u64; let p0: u64 = 64u64;
dwr32(filebuf, p0 + 0u64, PT_LOAD_D); dwr32(filebuf.ptr, p0 + 0u64, PT_LOAD_D);
dwr32(filebuf, p0 + 4u64, PF_R_D | PF_X_D); dwr32(filebuf.ptr, p0 + 4u64, PF_R_D | PF_X_D);
dwr64(filebuf, p0 + 8u64, 0u64); dwr64(filebuf.ptr, p0 + 8u64, 0u64);
dwr64(filebuf, p0 + 16u64, base); dwr64(filebuf.ptr, p0 + 16u64, base);
dwr64(filebuf, p0 + 24u64, base); dwr64(filebuf.ptr, p0 + 24u64, base);
dwr64(filebuf, p0 + 32u64, rxend); dwr64(filebuf.ptr, p0 + 32u64, rxend);
dwr64(filebuf, p0 + 40u64, rxend); dwr64(filebuf.ptr, p0 + 40u64, rxend);
dwr64(filebuf, p0 + 48u64, PAGE); dwr64(filebuf.ptr, p0 + 48u64, PAGE);
let p1: u64 = 64u64 + 56u64; let p1: u64 = 64u64 + 56u64;
dwr32(filebuf, p1 + 0u64, PT_LOAD_D); dwr32(filebuf.ptr, p1 + 0u64, PT_LOAD_D);
dwr32(filebuf, p1 + 4u64, PF_R_D | PF_W_D); dwr32(filebuf.ptr, p1 + 4u64, PF_R_D | PF_W_D);
dwr64(filebuf, p1 + 8u64, gotpltoff); dwr64(filebuf.ptr, p1 + 8u64, gotpltoff);
dwr64(filebuf, p1 + 16u64, gotpltva); dwr64(filebuf.ptr, p1 + 16u64, gotpltva);
dwr64(filebuf, p1 + 24u64, gotpltva); dwr64(filebuf.ptr, p1 + 24u64, gotpltva);
// filesz trims the .data trailing zeros (BSS); memsz covers // filesz trims the .data trailing zeros (BSS); memsz covers
// .got.plt + .dynamic + the full .data so the loader zero-fills. // .got.plt + .dynamic + the full .data so the loader zero-fills.
dwr64(filebuf, p1 + 32u64, filedataend - gotpltoff); dwr64(filebuf.ptr, p1 + 32u64, filedataend - gotpltoff);
dwr64(filebuf, p1 + 40u64, fileend - gotpltoff); dwr64(filebuf.ptr, p1 + 40u64, fileend - gotpltoff);
dwr64(filebuf, p1 + 48u64, PAGE); dwr64(filebuf.ptr, p1 + 48u64, PAGE);
let p2: u64 = 64u64 + 112u64; let p2: u64 = 64u64 + 112u64;
dwr32(filebuf, p2 + 0u64, PT_INTERP_D); dwr32(filebuf.ptr, p2 + 0u64, PT_INTERP_D);
dwr32(filebuf, p2 + 4u64, PF_R_D); dwr32(filebuf.ptr, p2 + 4u64, PF_R_D);
dwr64(filebuf, p2 + 8u64, interpoff); dwr64(filebuf.ptr, p2 + 8u64, interpoff);
dwr64(filebuf, p2 + 16u64, interpva); dwr64(filebuf.ptr, p2 + 16u64, interpva);
dwr64(filebuf, p2 + 24u64, interpva); dwr64(filebuf.ptr, p2 + 24u64, interpva);
dwr64(filebuf, p2 + 32u64, interpsz); dwr64(filebuf.ptr, p2 + 32u64, interpsz);
dwr64(filebuf, p2 + 40u64, interpsz); dwr64(filebuf.ptr, p2 + 40u64, interpsz);
dwr64(filebuf, p2 + 48u64, 1u64); dwr64(filebuf.ptr, p2 + 48u64, 1u64);
let p3: u64 = 64u64 + 168u64; let p3: u64 = 64u64 + 168u64;
dwr32(filebuf, p3 + 0u64, PT_DYNAMIC_D); dwr32(filebuf.ptr, p3 + 0u64, PT_DYNAMIC_D);
dwr32(filebuf, p3 + 4u64, PF_R_D | PF_W_D); dwr32(filebuf.ptr, p3 + 4u64, PF_R_D | PF_W_D);
dwr64(filebuf, p3 + 8u64, dynamicoff); dwr64(filebuf.ptr, p3 + 8u64, dynamicoff);
dwr64(filebuf, p3 + 16u64, dynamicva); dwr64(filebuf.ptr, p3 + 16u64, dynamicva);
dwr64(filebuf, p3 + 24u64, dynamicva); dwr64(filebuf.ptr, p3 + 24u64, dynamicva);
dwr64(filebuf, p3 + 32u64, dynamicsz); dwr64(filebuf.ptr, p3 + 32u64, dynamicsz);
dwr64(filebuf, p3 + 40u64, dynamicsz); dwr64(filebuf.ptr, p3 + 40u64, dynamicsz);
dwr64(filebuf, p3 + 48u64, 8u64); dwr64(filebuf.ptr, p3 + 48u64, 8u64);
// Sections. // Sections.
dbcopy(filebuf, interpoff, INTERP.ptr, INTERP.len: u64); dbcopy(filebuf.ptr, interpoff, INTERP.ptr, INTERP.len: u64);
dwr8(filebuf, interpoff + (INTERP.len: u64), 0u8); dwr8(filebuf.ptr, interpoff + (INTERP.len: u64), 0u8);
dbcopy(filebuf, dynstroff, dynstr, dynstrsz); dbcopy(filebuf.ptr, dynstroff, dynstr, dynstrsz);
dbcopy(filebuf, dynsymoff, dynsymbuf, dynsymsz); dbcopy(filebuf.ptr, dynsymoff, dynsymbuf, dynsymsz);
dbcopy(filebuf, hashoff, hashbuf, hashsz); dbcopy(filebuf.ptr, hashoff, hashbuf, hashsz);
dbcopy(filebuf, versymoff, versymbuf, versymsz); dbcopy(filebuf.ptr, versymoff, versymbuf, versymsz);
if (verneedsz > 0u64) { if (verneedsz > 0u64) {
dbcopy(filebuf, verneedoff, verneedbuf, verneedsz); dbcopy(filebuf.ptr, verneedoff, verneedbuf, verneedsz);
}; };
dbcopy(filebuf, relapltoff, relapltbuf, relapltsz); dbcopy(filebuf.ptr, relapltoff, relapltbuf, relapltsz);
if (l.textlen > 0u64) { if (l.textlen > 0u64) {
dbcopy(filebuf, textoff, l.text, l.textlen); dbcopy(filebuf.ptr, textoff, l.text, l.textlen);
}; };
dbcopy(filebuf, pltoff, pltbuf, pltsz); dbcopy(filebuf.ptr, pltoff, pltbuf, pltsz);
dbcopy(filebuf, gotpltoff, gotpltbuf, gotpltsz); dbcopy(filebuf.ptr, gotpltoff, gotpltbuf, gotpltsz);
dbcopy(filebuf, dynamicoff, dynamicbuf, dynamicsz); dbcopy(filebuf.ptr, dynamicoff, dynamicbuf, dynamicsz);
if (datafilelen > 0u64) { if (datafilelen > 0u64) {
dbcopy(filebuf, dataoff, l.data, datafilelen); dbcopy(filebuf.ptr, dataoff, l.data, datafilelen);
}; };
let wr: (i64 | os.oserror) = os.writeall(fd, filebuf, filedataend); let wr: (i64 | os.oserror) = os.writeall(fd, filebuf.ptr, filedataend);
match (wr) { match (wr) {
case let v: i64 => { if (v != filedataend: i64) { return 1; }; }; case let v: i64 => { if (v != filedataend: i64) { return 1; }; };
case let e: os.oserror => return 1; case let e: os.oserror => return 1;

View File

@@ -1061,8 +1061,9 @@ fn slurp(path: *u8) (*u8, u64) = {
case let v: i64 => n = v; case let v: i64 => n = v;
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let buf: *u8 = rt.malloc(n: u64): *u8; let buf: []u8 = alloc([], n: u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, n: u64); buf.len = n: i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, n: u64);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -1070,7 +1071,7 @@ fn slurp(path: *u8) (*u8, u64) = {
case let e: os.oserror => return nil, 0u64; case let e: os.oserror => return nil, 0u64;
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
return buf, n: u64; return buf.ptr, n: u64;
}; };
// ---- text buffer growth ------------------------------------------------ // ---- text buffer growth ------------------------------------------------
@@ -1721,8 +1722,9 @@ fn slurpso(path: *u8) (*u8, u64) = {
case let v: i64 => n = v; case let v: i64 => n = v;
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let buf: *u8 = rt.malloc(n: u64): *u8; let buf: []u8 = alloc([], n: u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, n: u64); buf.len = n: i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, n: u64);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -1730,7 +1732,7 @@ fn slurpso(path: *u8) (*u8, u64) = {
case let e: os.oserror => return nil, 0u64; case let e: os.oserror => return nil, 0u64;
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
return buf, n: u64; return buf.ptr, n: u64;
}; };
// ---- verdef helpers ---------------------------------------------------- // ---- verdef helpers ----------------------------------------------------
@@ -2782,99 +2784,96 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
// ---- assemble file buffer ---- // ---- assemble file buffer ----
let filebuf: *u8 = rt.malloc(fileend): *u8; let filebuf: []u8 = alloc([], fileend)!;
if (filebuf == nil) { filebuf.len = fileend: i32;
os.write(2, "w6l: out of memory\n".ptr, 18u64);
return 1;
};
// Ehdr // Ehdr
dwr8(filebuf, 0u64, 127u8); dwr8(filebuf.ptr, 0u64, 127u8);
dwr8(filebuf, 1u64, 69u8); dwr8(filebuf.ptr, 1u64, 69u8);
dwr8(filebuf, 2u64, 76u8); dwr8(filebuf.ptr, 2u64, 76u8);
dwr8(filebuf, 3u64, 70u8); dwr8(filebuf.ptr, 3u64, 70u8);
dwr8(filebuf, 4u64, ELFCLASS64_D); dwr8(filebuf.ptr, 4u64, ELFCLASS64_D);
dwr8(filebuf, 5u64, ELFDATA2LSB_D); dwr8(filebuf.ptr, 5u64, ELFDATA2LSB_D);
dwr8(filebuf, 6u64, EV_CURRENT_D: u8); dwr8(filebuf.ptr, 6u64, EV_CURRENT_D: u8);
dwr16(filebuf, 16u64, ET_EXEC_D); dwr16(filebuf.ptr, 16u64, ET_EXEC_D);
dwr16(filebuf, 18u64, EM_X86_64_D); dwr16(filebuf.ptr, 18u64, EM_X86_64_D);
dwr32(filebuf, 20u64, EV_CURRENT_D); dwr32(filebuf.ptr, 20u64, EV_CURRENT_D);
dwr64(filebuf, 24u64, entry); dwr64(filebuf.ptr, 24u64, entry);
dwr64(filebuf, 32u64, ehdrsz); dwr64(filebuf.ptr, 32u64, ehdrsz);
dwr64(filebuf, 40u64, 0u64); dwr64(filebuf.ptr, 40u64, 0u64);
dwr32(filebuf, 48u64, 0u32); dwr32(filebuf.ptr, 48u64, 0u32);
dwr16(filebuf, 52u64, ehdrsz: u16); dwr16(filebuf.ptr, 52u64, ehdrsz: u16);
dwr16(filebuf, 54u64, 56u16); dwr16(filebuf.ptr, 54u64, 56u16);
dwr16(filebuf, 56u64, nphdrs: u16); dwr16(filebuf.ptr, 56u64, nphdrs: u16);
dwr16(filebuf, 58u64, 0u16); dwr16(filebuf.ptr, 58u64, 0u16);
dwr16(filebuf, 60u64, 0u16); dwr16(filebuf.ptr, 60u64, 0u16);
dwr16(filebuf, 62u64, 0u16); dwr16(filebuf.ptr, 62u64, 0u16);
// Phdrs at offset 64. // Phdrs at offset 64.
let p0: u64 = 64u64; let p0: u64 = 64u64;
dwr32(filebuf, p0 + 0u64, PT_LOAD_D); dwr32(filebuf.ptr, p0 + 0u64, PT_LOAD_D);
dwr32(filebuf, p0 + 4u64, PF_R_D | PF_X_D); dwr32(filebuf.ptr, p0 + 4u64, PF_R_D | PF_X_D);
dwr64(filebuf, p0 + 8u64, 0u64); dwr64(filebuf.ptr, p0 + 8u64, 0u64);
dwr64(filebuf, p0 + 16u64, base); dwr64(filebuf.ptr, p0 + 16u64, base);
dwr64(filebuf, p0 + 24u64, base); dwr64(filebuf.ptr, p0 + 24u64, base);
dwr64(filebuf, p0 + 32u64, rxend); dwr64(filebuf.ptr, p0 + 32u64, rxend);
dwr64(filebuf, p0 + 40u64, rxend); dwr64(filebuf.ptr, p0 + 40u64, rxend);
dwr64(filebuf, p0 + 48u64, PAGE); dwr64(filebuf.ptr, p0 + 48u64, PAGE);
let p1: u64 = 64u64 + 56u64; let p1: u64 = 64u64 + 56u64;
dwr32(filebuf, p1 + 0u64, PT_LOAD_D); dwr32(filebuf.ptr, p1 + 0u64, PT_LOAD_D);
dwr32(filebuf, p1 + 4u64, PF_R_D | PF_W_D); dwr32(filebuf.ptr, p1 + 4u64, PF_R_D | PF_W_D);
dwr64(filebuf, p1 + 8u64, gotpltoff); dwr64(filebuf.ptr, p1 + 8u64, gotpltoff);
dwr64(filebuf, p1 + 16u64, gotpltva); dwr64(filebuf.ptr, p1 + 16u64, gotpltva);
dwr64(filebuf, p1 + 24u64, gotpltva); dwr64(filebuf.ptr, p1 + 24u64, gotpltva);
// filesz trims the .data trailing zeros (BSS); memsz covers // filesz trims the .data trailing zeros (BSS); memsz covers
// .got.plt + .dynamic + the full .data so the loader zero-fills. // .got.plt + .dynamic + the full .data so the loader zero-fills.
dwr64(filebuf, p1 + 32u64, filedataend - gotpltoff); dwr64(filebuf.ptr, p1 + 32u64, filedataend - gotpltoff);
dwr64(filebuf, p1 + 40u64, fileend - gotpltoff); dwr64(filebuf.ptr, p1 + 40u64, fileend - gotpltoff);
dwr64(filebuf, p1 + 48u64, PAGE); dwr64(filebuf.ptr, p1 + 48u64, PAGE);
let p2: u64 = 64u64 + 112u64; let p2: u64 = 64u64 + 112u64;
dwr32(filebuf, p2 + 0u64, PT_INTERP_D); dwr32(filebuf.ptr, p2 + 0u64, PT_INTERP_D);
dwr32(filebuf, p2 + 4u64, PF_R_D); dwr32(filebuf.ptr, p2 + 4u64, PF_R_D);
dwr64(filebuf, p2 + 8u64, interpoff); dwr64(filebuf.ptr, p2 + 8u64, interpoff);
dwr64(filebuf, p2 + 16u64, interpva); dwr64(filebuf.ptr, p2 + 16u64, interpva);
dwr64(filebuf, p2 + 24u64, interpva); dwr64(filebuf.ptr, p2 + 24u64, interpva);
dwr64(filebuf, p2 + 32u64, interpsz); dwr64(filebuf.ptr, p2 + 32u64, interpsz);
dwr64(filebuf, p2 + 40u64, interpsz); dwr64(filebuf.ptr, p2 + 40u64, interpsz);
dwr64(filebuf, p2 + 48u64, 1u64); dwr64(filebuf.ptr, p2 + 48u64, 1u64);
let p3: u64 = 64u64 + 168u64; let p3: u64 = 64u64 + 168u64;
dwr32(filebuf, p3 + 0u64, PT_DYNAMIC_D); dwr32(filebuf.ptr, p3 + 0u64, PT_DYNAMIC_D);
dwr32(filebuf, p3 + 4u64, PF_R_D | PF_W_D); dwr32(filebuf.ptr, p3 + 4u64, PF_R_D | PF_W_D);
dwr64(filebuf, p3 + 8u64, dynamicoff); dwr64(filebuf.ptr, p3 + 8u64, dynamicoff);
dwr64(filebuf, p3 + 16u64, dynamicva); dwr64(filebuf.ptr, p3 + 16u64, dynamicva);
dwr64(filebuf, p3 + 24u64, dynamicva); dwr64(filebuf.ptr, p3 + 24u64, dynamicva);
dwr64(filebuf, p3 + 32u64, dynamicsz); dwr64(filebuf.ptr, p3 + 32u64, dynamicsz);
dwr64(filebuf, p3 + 40u64, dynamicsz); dwr64(filebuf.ptr, p3 + 40u64, dynamicsz);
dwr64(filebuf, p3 + 48u64, 8u64); dwr64(filebuf.ptr, p3 + 48u64, 8u64);
// Sections. // Sections.
dbcopy(filebuf, interpoff, INTERP.ptr, INTERP.len: u64); dbcopy(filebuf.ptr, interpoff, INTERP.ptr, INTERP.len: u64);
dwr8(filebuf, interpoff + (INTERP.len: u64), 0u8); dwr8(filebuf.ptr, interpoff + (INTERP.len: u64), 0u8);
dbcopy(filebuf, dynstroff, dynstr, dynstrsz); dbcopy(filebuf.ptr, dynstroff, dynstr, dynstrsz);
dbcopy(filebuf, dynsymoff, dynsymbuf, dynsymsz); dbcopy(filebuf.ptr, dynsymoff, dynsymbuf, dynsymsz);
dbcopy(filebuf, hashoff, hashbuf, hashsz); dbcopy(filebuf.ptr, hashoff, hashbuf, hashsz);
dbcopy(filebuf, versymoff, versymbuf, versymsz); dbcopy(filebuf.ptr, versymoff, versymbuf, versymsz);
if (verneedsz > 0u64) { if (verneedsz > 0u64) {
dbcopy(filebuf, verneedoff, verneedbuf, verneedsz); dbcopy(filebuf.ptr, verneedoff, verneedbuf, verneedsz);
}; };
dbcopy(filebuf, relapltoff, relapltbuf, relapltsz); dbcopy(filebuf.ptr, relapltoff, relapltbuf, relapltsz);
if (l.textlen > 0u64) { if (l.textlen > 0u64) {
dbcopy(filebuf, textoff, l.text, l.textlen); dbcopy(filebuf.ptr, textoff, l.text, l.textlen);
}; };
dbcopy(filebuf, pltoff, pltbuf, pltsz); dbcopy(filebuf.ptr, pltoff, pltbuf, pltsz);
dbcopy(filebuf, gotpltoff, gotpltbuf, gotpltsz); dbcopy(filebuf.ptr, gotpltoff, gotpltbuf, gotpltsz);
dbcopy(filebuf, dynamicoff, dynamicbuf, dynamicsz); dbcopy(filebuf.ptr, dynamicoff, dynamicbuf, dynamicsz);
if (datafilelen > 0u64) { if (datafilelen > 0u64) {
dbcopy(filebuf, dataoff, l.data, datafilelen); dbcopy(filebuf.ptr, dataoff, l.data, datafilelen);
}; };
let wr: (i64 | os.oserror) = os.writeall(fd, filebuf, filedataend); let wr: (i64 | os.oserror) = os.writeall(fd, filebuf.ptr, filedataend);
match (wr) { match (wr) {
case let v: i64 => { if (v != filedataend: i64) { return 1; }; }; case let v: i64 => { if (v != filedataend: i64) { return 1; }; };
case let e: os.oserror => return 1; case let e: os.oserror => return 1;
@@ -2973,7 +2972,8 @@ export fn emitelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let datafilelen: u64 = l.datalen - bsslen; let datafilelen: u64 = l.datalen - bsslen;
// One contiguous header buffer covering [0..0x1000), then .text. // One contiguous header buffer covering [0..0x1000), then .text.
let hdr: *u8 = rt.malloc(TEXT_OFF): *u8; // zero-initialised by mmap let hdr: []u8 = alloc([], TEXT_OFF)!;
hdr.len = TEXT_OFF: i32;
// --- Ehdr (64 bytes) --- // --- Ehdr (64 bytes) ---
hdr[0u64] = 127u8; // 0x7f hdr[0u64] = 127u8; // 0x7f
@@ -2983,45 +2983,45 @@ export fn emitelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
hdr[4u64] = ELFCLASS64; hdr[4u64] = ELFCLASS64;
hdr[5u64] = ELFDATA2LSB; hdr[5u64] = ELFDATA2LSB;
hdr[6u64] = EV_CURRENT: u8; hdr[6u64] = EV_CURRENT: u8;
wru16(hdr, 16u64, ET_EXEC); // e_type wru16(hdr.ptr, 16u64, ET_EXEC); // e_type
wru16(hdr, 18u64, EM_X86_64_W); // e_machine wru16(hdr.ptr, 18u64, EM_X86_64_W); // e_machine
wru32(hdr, 20u64, EV_CURRENT); // e_version wru32(hdr.ptr, 20u64, EV_CURRENT); // e_version
wru64(hdr, 24u64, entry); // e_entry wru64(hdr.ptr, 24u64, entry); // e_entry
wru64(hdr, 32u64, 64u64); // e_phoff = sizeof(Ehdr) wru64(hdr.ptr, 32u64, 64u64); // e_phoff = sizeof(Ehdr)
wru64(hdr, 40u64, 0u64); // e_shoff wru64(hdr.ptr, 40u64, 0u64); // e_shoff
wru32(hdr, 48u64, 0u32); // e_flags wru32(hdr.ptr, 48u64, 0u32); // e_flags
wru16(hdr, 52u64, 64u16); // e_ehsize wru16(hdr.ptr, 52u64, 64u16); // e_ehsize
wru16(hdr, 54u64, 56u16); // e_phentsize wru16(hdr.ptr, 54u64, 56u16); // e_phentsize
if (hasdata) { wru16(hdr, 56u64, 2u16); } if (hasdata) { wru16(hdr.ptr, 56u64, 2u16); }
else { wru16(hdr, 56u64, 1u16); }; else { wru16(hdr.ptr, 56u64, 1u16); };
wru16(hdr, 58u64, 0u16); // e_shentsize wru16(hdr.ptr, 58u64, 0u16); // e_shentsize
wru16(hdr, 60u64, 0u16); // e_shnum wru16(hdr.ptr, 60u64, 0u16); // e_shnum
wru16(hdr, 62u64, 0u16); // e_shstrndx wru16(hdr.ptr, 62u64, 0u16); // e_shstrndx
// --- Phdr #1 (R+X) at offset 64 --- // --- Phdr #1 (R+X) at offset 64 ---
wru32(hdr, 64u64, PT_LOAD); wru32(hdr.ptr, 64u64, PT_LOAD);
wru32(hdr, 68u64, PF_R | PF_X); wru32(hdr.ptr, 68u64, PF_R | PF_X);
wru64(hdr, 72u64, 0u64); // p_offset wru64(hdr.ptr, 72u64, 0u64); // p_offset
wru64(hdr, 80u64, base); // p_vaddr wru64(hdr.ptr, 80u64, base); // p_vaddr
wru64(hdr, 88u64, base); // p_paddr wru64(hdr.ptr, 88u64, base); // p_paddr
wru64(hdr, 96u64, rxend); // p_filesz wru64(hdr.ptr, 96u64, rxend); // p_filesz
wru64(hdr, 104u64, rxend); // p_memsz wru64(hdr.ptr, 104u64, rxend); // p_memsz
wru64(hdr, 112u64, TEXT_OFF); // p_align wru64(hdr.ptr, 112u64, TEXT_OFF); // p_align
if (hasdata) { if (hasdata) {
// --- Phdr #2 (R+W) at offset 64+56=120 --- // --- Phdr #2 (R+W) at offset 64+56=120 ---
wru32(hdr, 120u64, PT_LOAD); wru32(hdr.ptr, 120u64, PT_LOAD);
wru32(hdr, 124u64, PF_R | PF_W); wru32(hdr.ptr, 124u64, PF_R | PF_W);
wru64(hdr, 128u64, dataoff); // p_offset wru64(hdr.ptr, 128u64, dataoff); // p_offset
wru64(hdr, 136u64, base + dataoff); // p_vaddr wru64(hdr.ptr, 136u64, base + dataoff); // p_vaddr
wru64(hdr, 144u64, base + dataoff); // p_paddr wru64(hdr.ptr, 144u64, base + dataoff); // p_paddr
wru64(hdr, 152u64, datafilelen); // p_filesz wru64(hdr.ptr, 152u64, datafilelen); // p_filesz
wru64(hdr, 160u64, l.datalen); // p_memsz wru64(hdr.ptr, 160u64, l.datalen); // p_memsz
wru64(hdr, 168u64, PAGE_SZ); // p_align wru64(hdr.ptr, 168u64, PAGE_SZ); // p_align
}; };
// Write [0..0x1000) then .text. // Write [0..0x1000) then .text.
let r1: (i64 | os.oserror) = os.writeall(fd, hdr, TEXT_OFF); let r1: (i64 | os.oserror) = os.writeall(fd, hdr.ptr, TEXT_OFF);
let n1: i64 = 0i64; let n1: i64 = 0i64;
match (r1) { match (r1) {
case let v: i64 => n1 = v; case let v: i64 => n1 = v;
@@ -3195,13 +3195,14 @@ fn islinkable(path: *u8) bool = {
// then lib<name>.a. Return arena-owned NUL-terminated path on success, // then lib<name>.a. Return arena-owned NUL-terminated path on success,
// nil on miss. // nil on miss.
fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = { fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = {
let bufp: *u8 = rt.malloc(1024u64): *u8; let bufp: []u8 = alloc([], 1024u64)!;
bufp.len = 1024;
let i: i32 = 0; let i: i32 = 0;
for (i < nlibdirs) { for (i < nlibdirs) {
let dir: *u8 = libdirs[i]; let dir: *u8 = libdirs[i];
let _l1: u64 = buildpath(bufp, dir, name, ".so"); let _l1: u64 = buildpath(bufp.ptr, dir, name, ".so");
if (islinkable(bufp)) { if (islinkable(bufp.ptr)) {
let pl: u64 = cstrlen(bufp); let pl: u64 = cstrlen(bufp.ptr);
let p: *u8 = amalloc(a, pl + 1u64): *u8; let p: *u8 = amalloc(a, pl + 1u64): *u8;
let k: u64 = 0u64; let k: u64 = 0u64;
for (k <= pl) { p[k] = bufp[k]; k += 1u64; }; for (k <= pl) { p[k] = bufp[k]; k += 1u64; };
@@ -3209,9 +3210,9 @@ fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = {
}; };
let v: u64 = 0u64; let v: u64 = 0u64;
for (v <= 8u64) { for (v <= 8u64) {
let _l2: u64 = buildpathv(bufp, dir, name, v); let _l2: u64 = buildpathv(bufp.ptr, dir, name, v);
if (islinkable(bufp)) { if (islinkable(bufp.ptr)) {
let pl2: u64 = cstrlen(bufp); let pl2: u64 = cstrlen(bufp.ptr);
let p2: *u8 = amalloc(a, pl2 + 1u64): *u8; let p2: *u8 = amalloc(a, pl2 + 1u64): *u8;
let k2: u64 = 0u64; let k2: u64 = 0u64;
for (k2 <= pl2) { p2[k2] = bufp[k2]; k2 += 1u64; }; for (k2 <= pl2) { p2[k2] = bufp[k2]; k2 += 1u64; };
@@ -3219,9 +3220,9 @@ fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = {
}; };
v += 1u64; v += 1u64;
}; };
let _l3: u64 = buildpath(bufp, dir, name, ".a"); let _l3: u64 = buildpath(bufp.ptr, dir, name, ".a");
if (islinkable(bufp)) { if (islinkable(bufp.ptr)) {
let pl3: u64 = cstrlen(bufp); let pl3: u64 = cstrlen(bufp.ptr);
let p3: *u8 = amalloc(a, pl3 + 1u64): *u8; let p3: *u8 = amalloc(a, pl3 + 1u64): *u8;
let k3: u64 = 0u64; let k3: u64 = 0u64;
for (k3 <= pl3) { p3[k3] = bufp[k3]; k3 += 1u64; }; for (k3 <= pl3) { p3[k3] = bufp[k3]; k3 += 1u64; };
@@ -3253,11 +3254,14 @@ fn isso(path: *u8) i32 = {
export fn main(argc: i32, argv: **u8) i32 = { export fn main(argc: i32, argv: **u8) i32 = {
let outpath: *u8 = nil; let outpath: *u8 = nil;
let maxinputs: i32 = 64; let maxinputs: i32 = 64;
let inputs: **u8 = rt.malloc((maxinputs: u64) * 8u64): **u8; let inputs: []*u8 = alloc([], maxinputs: u64)!;
inputs.len = maxinputs;
let ninputs: i32 = 0; let ninputs: i32 = 0;
let libdirs: **u8 = rt.malloc((maxinputs: u64) * 8u64): **u8; let libdirs: []*u8 = alloc([], maxinputs: u64)!;
libdirs.len = maxinputs;
let nlibdirs: i32 = 0; let nlibdirs: i32 = 0;
let lflags: **u8 = rt.malloc((maxinputs: u64) * 8u64): **u8; let lflags: []*u8 = alloc([], maxinputs: u64)!;
lflags.len = maxinputs;
let nlflags: i32 = 0; let nlflags: i32 = 0;
let i: i32 = 1; let i: i32 = 1;
@@ -3347,7 +3351,7 @@ export fn main(argc: i32, argv: **u8) i32 = {
// objects register their exports. // objects register their exports.
let lf: i32 = 0; let lf: i32 = 0;
for (lf < nlflags) { for (lf < nlflags) {
let p: *u8 = resolvelib(a, lflags[lf], libdirs, nlibdirs); let p: *u8 = resolvelib(a, lflags[lf], libdirs.ptr, nlibdirs);
if (p == nil) { if (p == nil) {
os.write(2, "w6l: cannot find -l".ptr, 18u64); os.write(2, "w6l: cannot find -l".ptr, 18u64);
let nm: *u8 = lflags[lf]; let nm: *u8 = lflags[lf];

View File

@@ -131,13 +131,14 @@ fn islinkable(path: *u8) bool = {
// then lib<name>.a. Return arena-owned NUL-terminated path on success, // then lib<name>.a. Return arena-owned NUL-terminated path on success,
// nil on miss. // nil on miss.
fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = { fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = {
let bufp: *u8 = rt.malloc(1024u64): *u8; let bufp: []u8 = alloc([], 1024u64)!;
bufp.len = 1024;
let i: i32 = 0; let i: i32 = 0;
for (i < nlibdirs) { for (i < nlibdirs) {
let dir: *u8 = libdirs[i]; let dir: *u8 = libdirs[i];
let _l1: u64 = buildpath(bufp, dir, name, ".so"); let _l1: u64 = buildpath(bufp.ptr, dir, name, ".so");
if (islinkable(bufp)) { if (islinkable(bufp.ptr)) {
let pl: u64 = cstrlen(bufp); let pl: u64 = cstrlen(bufp.ptr);
let p: *u8 = amalloc(a, pl + 1u64): *u8; let p: *u8 = amalloc(a, pl + 1u64): *u8;
let k: u64 = 0u64; let k: u64 = 0u64;
for (k <= pl) { p[k] = bufp[k]; k += 1u64; }; for (k <= pl) { p[k] = bufp[k]; k += 1u64; };
@@ -145,9 +146,9 @@ fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = {
}; };
let v: u64 = 0u64; let v: u64 = 0u64;
for (v <= 8u64) { for (v <= 8u64) {
let _l2: u64 = buildpathv(bufp, dir, name, v); let _l2: u64 = buildpathv(bufp.ptr, dir, name, v);
if (islinkable(bufp)) { if (islinkable(bufp.ptr)) {
let pl2: u64 = cstrlen(bufp); let pl2: u64 = cstrlen(bufp.ptr);
let p2: *u8 = amalloc(a, pl2 + 1u64): *u8; let p2: *u8 = amalloc(a, pl2 + 1u64): *u8;
let k2: u64 = 0u64; let k2: u64 = 0u64;
for (k2 <= pl2) { p2[k2] = bufp[k2]; k2 += 1u64; }; for (k2 <= pl2) { p2[k2] = bufp[k2]; k2 += 1u64; };
@@ -155,9 +156,9 @@ fn resolvelib(a: *arena, name: *u8, libdirs: **u8, nlibdirs: i32) *u8 = {
}; };
v += 1u64; v += 1u64;
}; };
let _l3: u64 = buildpath(bufp, dir, name, ".a"); let _l3: u64 = buildpath(bufp.ptr, dir, name, ".a");
if (islinkable(bufp)) { if (islinkable(bufp.ptr)) {
let pl3: u64 = cstrlen(bufp); let pl3: u64 = cstrlen(bufp.ptr);
let p3: *u8 = amalloc(a, pl3 + 1u64): *u8; let p3: *u8 = amalloc(a, pl3 + 1u64): *u8;
let k3: u64 = 0u64; let k3: u64 = 0u64;
for (k3 <= pl3) { p3[k3] = bufp[k3]; k3 += 1u64; }; for (k3 <= pl3) { p3[k3] = bufp[k3]; k3 += 1u64; };
@@ -189,11 +190,14 @@ fn isso(path: *u8) i32 = {
export fn main(argc: i32, argv: **u8) i32 = { export fn main(argc: i32, argv: **u8) i32 = {
let outpath: *u8 = nil; let outpath: *u8 = nil;
let maxinputs: i32 = 64; let maxinputs: i32 = 64;
let inputs: **u8 = rt.malloc((maxinputs: u64) * 8u64): **u8; let inputs: []*u8 = alloc([], maxinputs: u64)!;
inputs.len = maxinputs;
let ninputs: i32 = 0; let ninputs: i32 = 0;
let libdirs: **u8 = rt.malloc((maxinputs: u64) * 8u64): **u8; let libdirs: []*u8 = alloc([], maxinputs: u64)!;
libdirs.len = maxinputs;
let nlibdirs: i32 = 0; let nlibdirs: i32 = 0;
let lflags: **u8 = rt.malloc((maxinputs: u64) * 8u64): **u8; let lflags: []*u8 = alloc([], maxinputs: u64)!;
lflags.len = maxinputs;
let nlflags: i32 = 0; let nlflags: i32 = 0;
let i: i32 = 1; let i: i32 = 1;
@@ -283,7 +287,7 @@ export fn main(argc: i32, argv: **u8) i32 = {
// objects register their exports. // objects register their exports.
let lf: i32 = 0; let lf: i32 = 0;
for (lf < nlflags) { for (lf < nlflags) {
let p: *u8 = resolvelib(a, lflags[lf], libdirs, nlibdirs); let p: *u8 = resolvelib(a, lflags[lf], libdirs.ptr, nlibdirs);
if (p == nil) { if (p == nil) {
os.write(2, "w6l: cannot find -l".ptr, 18u64); os.write(2, "w6l: cannot find -l".ptr, 18u64);
let nm: *u8 = lflags[lf]; let nm: *u8 = lflags[lf];

View File

@@ -87,8 +87,9 @@ fn slurp(path: *u8) (*u8, u64) = {
case let v: i64 => n = v; case let v: i64 => n = v;
case let e: os.oserror => { os.close(fd); return nil, 0u64; }; case let e: os.oserror => { os.close(fd); return nil, 0u64; };
}; };
let buf: *u8 = rt.malloc(n: u64): *u8; let buf: []u8 = alloc([], n: u64)!;
let rr: (i64 | os.oserror) = os.readall(fd, buf, n: u64); buf.len = n: i32;
let rr: (i64 | os.oserror) = os.readall(fd, buf.ptr, n: u64);
os.close(fd); os.close(fd);
let got: i64 = 0i64; let got: i64 = 0i64;
match (rr) { match (rr) {
@@ -96,7 +97,7 @@ fn slurp(path: *u8) (*u8, u64) = {
case let e: os.oserror => return nil, 0u64; case let e: os.oserror => return nil, 0u64;
}; };
if (got != n) { return nil, 0u64; }; if (got != n) { return nil, 0u64; };
return buf, n: u64; return buf.ptr, n: u64;
}; };
// ---- text buffer growth ------------------------------------------------ // ---- text buffer growth ------------------------------------------------

View File

@@ -89,7 +89,8 @@ export fn emitelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let datafilelen: u64 = l.datalen - bsslen; let datafilelen: u64 = l.datalen - bsslen;
// One contiguous header buffer covering [0..0x1000), then .text. // One contiguous header buffer covering [0..0x1000), then .text.
let hdr: *u8 = rt.malloc(TEXT_OFF): *u8; // zero-initialised by mmap let hdr: []u8 = alloc([], TEXT_OFF)!;
hdr.len = TEXT_OFF: i32;
// --- Ehdr (64 bytes) --- // --- Ehdr (64 bytes) ---
hdr[0u64] = 127u8; // 0x7f hdr[0u64] = 127u8; // 0x7f
@@ -99,45 +100,45 @@ export fn emitelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
hdr[4u64] = ELFCLASS64; hdr[4u64] = ELFCLASS64;
hdr[5u64] = ELFDATA2LSB; hdr[5u64] = ELFDATA2LSB;
hdr[6u64] = EV_CURRENT: u8; hdr[6u64] = EV_CURRENT: u8;
wru16(hdr, 16u64, ET_EXEC); // e_type wru16(hdr.ptr, 16u64, ET_EXEC); // e_type
wru16(hdr, 18u64, EM_X86_64_W); // e_machine wru16(hdr.ptr, 18u64, EM_X86_64_W); // e_machine
wru32(hdr, 20u64, EV_CURRENT); // e_version wru32(hdr.ptr, 20u64, EV_CURRENT); // e_version
wru64(hdr, 24u64, entry); // e_entry wru64(hdr.ptr, 24u64, entry); // e_entry
wru64(hdr, 32u64, 64u64); // e_phoff = sizeof(Ehdr) wru64(hdr.ptr, 32u64, 64u64); // e_phoff = sizeof(Ehdr)
wru64(hdr, 40u64, 0u64); // e_shoff wru64(hdr.ptr, 40u64, 0u64); // e_shoff
wru32(hdr, 48u64, 0u32); // e_flags wru32(hdr.ptr, 48u64, 0u32); // e_flags
wru16(hdr, 52u64, 64u16); // e_ehsize wru16(hdr.ptr, 52u64, 64u16); // e_ehsize
wru16(hdr, 54u64, 56u16); // e_phentsize wru16(hdr.ptr, 54u64, 56u16); // e_phentsize
if (hasdata) { wru16(hdr, 56u64, 2u16); } if (hasdata) { wru16(hdr.ptr, 56u64, 2u16); }
else { wru16(hdr, 56u64, 1u16); }; else { wru16(hdr.ptr, 56u64, 1u16); };
wru16(hdr, 58u64, 0u16); // e_shentsize wru16(hdr.ptr, 58u64, 0u16); // e_shentsize
wru16(hdr, 60u64, 0u16); // e_shnum wru16(hdr.ptr, 60u64, 0u16); // e_shnum
wru16(hdr, 62u64, 0u16); // e_shstrndx wru16(hdr.ptr, 62u64, 0u16); // e_shstrndx
// --- Phdr #1 (R+X) at offset 64 --- // --- Phdr #1 (R+X) at offset 64 ---
wru32(hdr, 64u64, PT_LOAD); wru32(hdr.ptr, 64u64, PT_LOAD);
wru32(hdr, 68u64, PF_R | PF_X); wru32(hdr.ptr, 68u64, PF_R | PF_X);
wru64(hdr, 72u64, 0u64); // p_offset wru64(hdr.ptr, 72u64, 0u64); // p_offset
wru64(hdr, 80u64, base); // p_vaddr wru64(hdr.ptr, 80u64, base); // p_vaddr
wru64(hdr, 88u64, base); // p_paddr wru64(hdr.ptr, 88u64, base); // p_paddr
wru64(hdr, 96u64, rxend); // p_filesz wru64(hdr.ptr, 96u64, rxend); // p_filesz
wru64(hdr, 104u64, rxend); // p_memsz wru64(hdr.ptr, 104u64, rxend); // p_memsz
wru64(hdr, 112u64, TEXT_OFF); // p_align wru64(hdr.ptr, 112u64, TEXT_OFF); // p_align
if (hasdata) { if (hasdata) {
// --- Phdr #2 (R+W) at offset 64+56=120 --- // --- Phdr #2 (R+W) at offset 64+56=120 ---
wru32(hdr, 120u64, PT_LOAD); wru32(hdr.ptr, 120u64, PT_LOAD);
wru32(hdr, 124u64, PF_R | PF_W); wru32(hdr.ptr, 124u64, PF_R | PF_W);
wru64(hdr, 128u64, dataoff); // p_offset wru64(hdr.ptr, 128u64, dataoff); // p_offset
wru64(hdr, 136u64, base + dataoff); // p_vaddr wru64(hdr.ptr, 136u64, base + dataoff); // p_vaddr
wru64(hdr, 144u64, base + dataoff); // p_paddr wru64(hdr.ptr, 144u64, base + dataoff); // p_paddr
wru64(hdr, 152u64, datafilelen); // p_filesz wru64(hdr.ptr, 152u64, datafilelen); // p_filesz
wru64(hdr, 160u64, l.datalen); // p_memsz wru64(hdr.ptr, 160u64, l.datalen); // p_memsz
wru64(hdr, 168u64, PAGE_SZ); // p_align wru64(hdr.ptr, 168u64, PAGE_SZ); // p_align
}; };
// Write [0..0x1000) then .text. // Write [0..0x1000) then .text.
let r1: (i64 | os.oserror) = os.writeall(fd, hdr, TEXT_OFF); let r1: (i64 | os.oserror) = os.writeall(fd, hdr.ptr, TEXT_OFF);
let n1: i64 = 0i64; let n1: i64 = 0i64;
match (r1) { match (r1) {
case let v: i64 => n1 = v; case let v: i64 => n1 = v;