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