selfhost/cmd/w6l/dynout+obj: amalloc → alloc([], N)! (α/γ-11)

Phase 0 eleventh α/γ-batch. ~23 amalloc sites:
 - w6l/dynout.ww: 22 (~18 α u8 ELF section buffers + 3 γ pointer
   arrays — dynsyms []*lsym, sosused []*lso, vernameptrarr []*u8)
 - w6l/obj.ww:346 standalone α hdrsize u8

All single-shot fixed-count (NOT β grow as originally classified
in the phase0-mapper audit). α: `[]u8 = alloc([], N)!` + .ptr at
the dwr*/drd*/dbcopy callees. γ: element-count was bytes/8.

obj.ww:346 keeps the `*u8` legacy alias via `let mb: *u8 = mbs.ptr;`
since `armember.data` is `*u8` and gets stored across the function;
heap memory survives the local slice header (no GC, process-exit
reclaim).

Verified 132/132 incl. 992_w6l_ww + 995_self_rebuild + 996_dyn_ww
byte-identity.
This commit is contained in:
2026-05-21 08:37:12 +09:00
parent c91d684708
commit f2ea7fccec
3 changed files with 214 additions and 212 deletions

View File

@@ -175,7 +175,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nu: u64 = n: u64; let nu: u64 = n: u64;
// ---- collect dyn syms into a plt_idx-indexed array ---- // ---- collect dyn syms into a plt_idx-indexed array ----
let dynsyms: **lsym = amalloc(a, nu * 8u64): **lsym; let dynsyms: []*lsym = alloc([], nu)!;
let s: *lsym = l.syms; let s: *lsym = l.syms;
for (s != nil) { for (s != nil) {
if (s.isdyn != 0) { if (s.isdyn != 0) {
@@ -200,7 +200,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let maxsos: i32 = 0; let maxsos: i32 = 0;
let so: *lso = l.sos; let so: *lso = l.sos;
for (so != nil) { maxsos += 1; so = so.sonext; }; for (so != nil) { maxsos += 1; so = so.sonext; };
let sosused: **lso = amalloc(a, (maxsos: u64) * 8u64): **lso; let sosused: []*lso = alloc([], maxsos: u64)!;
let nsos: i32 = 0; let nsos: i32 = 0;
so = l.sos; so = l.sos;
for (so != nil) { for (so != nil) {
@@ -229,16 +229,16 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
// ver_dynstr_off[v] = offset within .dynstr (assigned after layout). // ver_dynstr_off[v] = offset within .dynstr (assigned after layout).
// ver_vna_other[v] = versym index (starting at 2). // ver_vna_other[v] = versym index (starting at 2).
let vlibsosidxbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8; let vlibsosidxbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
let vlibfirstbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8; let vlibfirstbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
let vlibcountbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8; let vlibcountbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
let nvlibs: i32 = 0; let nvlibs: i32 = 0;
let verlibidxbuf: *u8 = amalloc(a, nu * 4u64): *u8; let verlibidxbuf: []u8 = alloc([], nu * 4u64)!;
let vernameptrarr: **u8 = amalloc(a, nu * 8u64): **u8; let vernameptrarr: []*u8 = alloc([], nu)!;
let vernamelenbuf: *u8 = amalloc(a, nu * 4u64): *u8; let vernamelenbuf: []u8 = alloc([], nu * 4u64)!;
let verdynstroff: *u8 = amalloc(a, nu * 4u64): *u8; let verdynstroff: []u8 = alloc([], nu * 4u64)!;
let vervnaother: *u8 = amalloc(a, nu * 2u64): *u8; let vervnaother: []u8 = alloc([], nu * 2u64)!;
let nvers: i32 = 0; let nvers: i32 = 0;
let si: i32 = 0; let si: i32 = 0;
@@ -258,8 +258,8 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
} else { j += 1; }; } else { j += 1; };
}; };
if (has != 0) { if (has != 0) {
dwr32(vlibsosidxbuf, (nvlibs: u64) * 4u64, si: u32); dwr32(vlibsosidxbuf.ptr, (nvlibs: u64) * 4u64, si: u32);
dwr32(vlibfirstbuf, (nvlibs: u64) * 4u64, nvers: u32); dwr32(vlibfirstbuf.ptr, (nvlibs: u64) * 4u64, nvers: u32);
let added: i32 = 0; let added: i32 = 0;
let jj: i32 = 0; let jj: i32 = 0;
for (jj < n) { for (jj < n) {
@@ -275,15 +275,15 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let kk: i32 = nvers - added + k; let kk: i32 = nvers - added + k;
let existing: str; let existing: str;
existing.ptr = vernameptrarr[kk]; existing.ptr = vernameptrarr[kk];
existing.len = drdi32(vernamelenbuf, (kk: u64) * 4u64); existing.len = drdi32(vernamelenbuf.ptr, (kk: u64) * 4u64);
if (streqd(existing, vname)) { if (streqd(existing, vname)) {
seen = 1; k = added; seen = 1; k = added;
} else { k += 1; }; } else { k += 1; };
}; };
if (seen == 0) { if (seen == 0) {
dwr32(verlibidxbuf, (nvers: u64) * 4u64, nvlibs: u32); dwr32(verlibidxbuf.ptr, (nvers: u64) * 4u64, nvlibs: u32);
vernameptrarr[nvers] = vname.ptr; vernameptrarr[nvers] = vname.ptr;
dwri32(vernamelenbuf, (nvers: u64) * 4u64, vname.len); dwri32(vernamelenbuf.ptr, (nvers: u64) * 4u64, vname.len);
nvers += 1; nvers += 1;
added += 1; added += 1;
}; };
@@ -291,7 +291,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
jj += 1; jj += 1;
}; };
dwr32(vlibcountbuf, (nvlibs: u64) * 4u64, added: u32); dwr32(vlibcountbuf.ptr, (nvlibs: u64) * 4u64, added: u32);
nvlibs += 1; nvlibs += 1;
}; };
si += 1; si += 1;
@@ -301,11 +301,11 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nextvna: u16 = 2u16; let nextvna: u16 = 2u16;
let vi: i32 = 0; let vi: i32 = 0;
for (vi < nvlibs) { for (vi < nvlibs) {
let first: i32 = drdi32(vlibfirstbuf, (vi: u64) * 4u64); let first: i32 = drdi32(vlibfirstbuf.ptr, (vi: u64) * 4u64);
let cnt: i32 = drdi32(vlibcountbuf, (vi: u64) * 4u64); let cnt: i32 = drdi32(vlibcountbuf.ptr, (vi: u64) * 4u64);
let k: i32 = 0; let k: i32 = 0;
for (k < cnt) { for (k < cnt) {
dwr16(vervnaother, ((first + k): u64) * 2u64, nextvna); dwr16(vervnaother.ptr, ((first + k): u64) * 2u64, nextvna);
nextvna += 1u16; nextvna += 1u16;
k += 1; k += 1;
}; };
@@ -330,35 +330,35 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
pi = 0; pi = 0;
for (pi < nvers) { for (pi < nvers) {
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64); let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
dynstrsz += nmlen: u64; dynstrsz += nmlen: u64;
dynstrsz += 1u64; dynstrsz += 1u64;
pi += 1; pi += 1;
}; };
// ---- fill dynstr ---- // ---- fill dynstr ----
let dynstr: *u8 = amalloc(a, dynstrsz): *u8; let dynstr: []u8 = alloc([], dynstrsz)!;
let dynstrpos: u64 = 1u64; // past leading NUL let dynstrpos: u64 = 1u64; // past leading NUL
let sonamestr: *u8 = amalloc(a, (nsos: u64) * 4u64): *u8; let sonamestr: []u8 = alloc([], (nsos: u64) * 4u64)!;
pi = 0; pi = 0;
for (pi < nsos) { for (pi < nsos) {
dwr32(sonamestr, (pi: u64) * 4u64, dynstrpos: u32); dwr32(sonamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
let so2: *lso = sosused[pi]; let so2: *lso = sosused[pi];
let snm: str = so2.soname; let snm: str = so2.soname;
dbcopy(dynstr, dynstrpos, snm.ptr, snm.len: u64); dbcopy(dynstr.ptr, dynstrpos, snm.ptr, snm.len: u64);
dynstrpos += snm.len: u64; dynstrpos += snm.len: u64;
dynstr[dynstrpos] = 0u8; dynstr[dynstrpos] = 0u8;
dynstrpos += 1u64; dynstrpos += 1u64;
pi += 1; pi += 1;
}; };
let symnamestr: *u8 = amalloc(a, nu * 4u64): *u8; let symnamestr: []u8 = alloc([], nu * 4u64)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
dwr32(symnamestr, (pi: u64) * 4u64, dynstrpos: u32); dwr32(symnamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
let dsm: *lsym = dynsyms[pi]; let dsm: *lsym = dynsyms[pi];
let snm: str = dsm.name; let snm: str = dsm.name;
dbcopy(dynstr, dynstrpos, snm.ptr, snm.len: u64); dbcopy(dynstr.ptr, dynstrpos, snm.ptr, snm.len: u64);
dynstrpos += snm.len: u64; dynstrpos += snm.len: u64;
dynstr[dynstrpos] = 0u8; dynstr[dynstrpos] = 0u8;
dynstrpos += 1u64; dynstrpos += 1u64;
@@ -366,10 +366,10 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
pi = 0; pi = 0;
for (pi < nvers) { for (pi < nvers) {
dwr32(verdynstroff, (pi: u64) * 4u64, dynstrpos: u32); dwr32(verdynstroff.ptr, (pi: u64) * 4u64, dynstrpos: u32);
let nmp: *u8 = vernameptrarr[pi]; let nmp: *u8 = vernameptrarr[pi];
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64); let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
dbcopy(dynstr, dynstrpos, nmp, nmlen: u64); dbcopy(dynstr.ptr, dynstrpos, nmp, nmlen: u64);
dynstrpos += nmlen: u64; dynstrpos += nmlen: u64;
dynstr[dynstrpos] = 0u8; dynstr[dynstrpos] = 0u8;
dynstrpos += 1u64; dynstrpos += 1u64;
@@ -377,7 +377,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
// ---- per-dyn-sym versym index ---- // ---- per-dyn-sym versym index ----
let versymfor: *u8 = amalloc(a, nu * 2u64): *u8; let versymfor: []u8 = alloc([], nu * 2u64)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let dsm3: *lsym = dynsyms[pi]; let dsm3: *lsym = dynsyms[pi];
@@ -385,27 +385,27 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nm3: str = dsm3.name; let nm3: str = dsm3.name;
let vname: str = soversion(dl3, nm3); let vname: str = soversion(dl3, nm3);
if (vname.len == 0) { if (vname.len == 0) {
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D); dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
} else { } else {
let matched: i32 = 0; let matched: i32 = 0;
let vk: i32 = 0; let vk: i32 = 0;
for (vk < nvers) { for (vk < nvers) {
let vlx: i32 = drdi32(verlibidxbuf, (vk: u64) * 4u64); let vlx: i32 = drdi32(verlibidxbuf.ptr, (vk: u64) * 4u64);
let sosx: i32 = drdi32(vlibsosidxbuf, (vlx: u64) * 4u64); let sosx: i32 = drdi32(vlibsosidxbuf.ptr, (vlx: u64) * 4u64);
if (sosused[sosx] == dl3) { if (sosused[sosx] == dl3) {
let exi: str; let exi: str;
exi.ptr = vernameptrarr[vk]; exi.ptr = vernameptrarr[vk];
exi.len = drdi32(vernamelenbuf, (vk: u64) * 4u64); exi.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
if (streqd(exi, vname)) { if (streqd(exi, vname)) {
let other: u16 = drdu16(vervnaother, (vk: u64) * 2u64); let other: u16 = drdu16(vervnaother.ptr, (vk: u64) * 2u64);
dwr16(versymfor, (pi: u64) * 2u64, other); dwr16(versymfor.ptr, (pi: u64) * 2u64, other);
matched = 1; matched = 1;
vk = nvers; vk = nvers;
} else { vk += 1; }; } else { vk += 1; };
} else { vk += 1; }; } else { vk += 1; };
}; };
if (matched == 0) { if (matched == 0) {
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D); dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
}; };
}; };
pi += 1; pi += 1;
@@ -432,7 +432,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let verneedsz: u64 = 0u64; let verneedsz: u64 = 0u64;
let vli: i32 = 0; let vli: i32 = 0;
for (vli < nvlibs) { for (vli < nvlibs) {
let cnt: i32 = drdi32(vlibcountbuf, (vli: u64) * 4u64); let cnt: i32 = drdi32(vlibcountbuf.ptr, (vli: u64) * 4u64);
verneedsz += 16u64 + 16u64 * (cnt: u64); verneedsz += 16u64 + 16u64 * (cnt: u64);
vli += 1; vli += 1;
}; };
@@ -498,96 +498,96 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let filedataend: u64 = dataoff + datafilelen; let filedataend: u64 = dataoff + datafilelen;
// ---- build .dynsym ---- // ---- build .dynsym ----
let dynsymbuf: *u8 = amalloc(a, dynsymsz): *u8; let dynsymbuf: []u8 = alloc([], dynsymsz)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let eoff: u64 = (1u64 + (pi: u64)) * 24u64; let eoff: u64 = (1u64 + (pi: u64)) * 24u64;
dwr32(dynsymbuf, eoff + 0u64, drdu32(symnamestr, (pi: u64) * 4u64)); dwr32(dynsymbuf.ptr, eoff + 0u64, drdu32(symnamestr.ptr, (pi: u64) * 4u64));
dwr8(dynsymbuf, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8)); dwr8(dynsymbuf.ptr, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8));
dwr8(dynsymbuf, eoff + 5u64, 0u8); dwr8(dynsymbuf.ptr, eoff + 5u64, 0u8);
dwr16(dynsymbuf, eoff + 6u64, 0u16); dwr16(dynsymbuf.ptr, eoff + 6u64, 0u16);
dwr64(dynsymbuf, eoff + 8u64, 0u64); dwr64(dynsymbuf.ptr, eoff + 8u64, 0u64);
dwr64(dynsymbuf, eoff + 16u64, 0u64); dwr64(dynsymbuf.ptr, eoff + 16u64, 0u64);
pi += 1; pi += 1;
}; };
// ---- build .hash (SysV, 1 bucket) ---- // ---- build .hash (SysV, 1 bucket) ----
let hashbuf: *u8 = amalloc(a, hashsz): *u8; let hashbuf: []u8 = alloc([], hashsz)!;
dwr32(hashbuf, 0u64, nbuckets); dwr32(hashbuf.ptr, 0u64, nbuckets);
dwr32(hashbuf, 4u64, nchain); dwr32(hashbuf.ptr, 4u64, nchain);
let bucket0: u32 = 0u32; let bucket0: u32 = 0u32;
if (nsymstotal > 1u64) { bucket0 = 1u32; }; if (nsymstotal > 1u64) { bucket0 = 1u32; };
dwr32(hashbuf, 8u64, bucket0); dwr32(hashbuf.ptr, 8u64, bucket0);
let ci: u64 = 1u64; let ci: u64 = 1u64;
for (ci < nsymstotal) { for (ci < nsymstotal) {
let nxt: u32 = 0u32; let nxt: u32 = 0u32;
if (ci + 1u64 < nsymstotal) { nxt = (ci + 1u64): u32; }; if (ci + 1u64 < nsymstotal) { nxt = (ci + 1u64): u32; };
dwr32(hashbuf, 8u64 + (nbuckets: u64) * 4u64 + ci * 4u64, nxt); dwr32(hashbuf.ptr, 8u64 + (nbuckets: u64) * 4u64 + ci * 4u64, nxt);
ci += 1u64; ci += 1u64;
}; };
// ---- build .rela.plt ---- // ---- build .rela.plt ----
let relapltbuf: *u8 = amalloc(a, relapltsz): *u8; let relapltbuf: []u8 = alloc([], relapltsz)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let roff: u64 = (pi: u64) * 24u64; let roff: u64 = (pi: u64) * 24u64;
dwr64(relapltbuf, roff + 0u64, gotpltva + (3u64 + (pi: u64)) * 8u64); dwr64(relapltbuf.ptr, roff + 0u64, gotpltva + (3u64 + (pi: u64)) * 8u64);
let info: u64 = ((1u64 + (pi: u64)) << 32u64) | (R_X86_64_JUMP_SLOT_D: u64); let info: u64 = ((1u64 + (pi: u64)) << 32u64) | (R_X86_64_JUMP_SLOT_D: u64);
dwr64(relapltbuf, roff + 8u64, info); dwr64(relapltbuf.ptr, roff + 8u64, info);
dwri64(relapltbuf, roff + 16u64, 0i64); dwri64(relapltbuf.ptr, roff + 16u64, 0i64);
pi += 1; pi += 1;
}; };
// ---- build .gnu.version (u16 per dynsym entry) ---- // ---- build .gnu.version (u16 per dynsym entry) ----
let versymbuf: *u8 = amalloc(a, versymsz): *u8; let versymbuf: []u8 = alloc([], versymsz)!;
dwr16(versymbuf, 0u64, VER_NDX_LOCAL_D); dwr16(versymbuf.ptr, 0u64, VER_NDX_LOCAL_D);
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
dwr16(versymbuf, 2u64 + (pi: u64) * 2u64, drdu16(versymfor, (pi: u64) * 2u64)); dwr16(versymbuf.ptr, 2u64 + (pi: u64) * 2u64, drdu16(versymfor.ptr, (pi: u64) * 2u64));
pi += 1; pi += 1;
}; };
// ---- build .gnu.version_r ---- // ---- build .gnu.version_r ----
let verneedbuf: *u8 = amalloc(a, verneedsz): *u8; let verneedbuf: []u8 = alloc([], verneedsz)!;
if (verneedsz > 0u64) { if (verneedsz > 0u64) {
let vnoff: u64 = 0u64; let vnoff: u64 = 0u64;
vli = 0; vli = 0;
for (vli < nvlibs) { for (vli < nvlibs) {
let sosidx: i32 = drdi32(vlibsosidxbuf, (vli: u64) * 4u64); let sosidx: i32 = drdi32(vlibsosidxbuf.ptr, (vli: u64) * 4u64);
let first: i32 = drdi32(vlibfirstbuf, (vli: u64) * 4u64); let first: i32 = drdi32(vlibfirstbuf.ptr, (vli: u64) * 4u64);
let cnt: i32 = drdi32(vlibcountbuf, (vli: u64) * 4u64); let cnt: i32 = drdi32(vlibcountbuf.ptr, (vli: u64) * 4u64);
let vnstart: u64 = vnoff; let vnstart: u64 = vnoff;
dwr16(verneedbuf, vnoff + 0u64, 1u16); dwr16(verneedbuf.ptr, vnoff + 0u64, 1u16);
dwr16(verneedbuf, vnoff + 2u64, cnt: u16); dwr16(verneedbuf.ptr, vnoff + 2u64, cnt: u16);
dwr32(verneedbuf, vnoff + 4u64, drdu32(sonamestr, (sosidx: u64) * 4u64)); dwr32(verneedbuf.ptr, vnoff + 4u64, drdu32(sonamestr.ptr, (sosidx: u64) * 4u64));
dwr32(verneedbuf, vnoff + 8u64, 16u32); dwr32(verneedbuf.ptr, vnoff + 8u64, 16u32);
vnoff += 16u64; vnoff += 16u64;
let k: i32 = 0; let k: i32 = 0;
for (k < cnt) { for (k < cnt) {
let vk: i32 = first + k; let vk: i32 = first + k;
let nm: str; let nm: str;
nm.ptr = vernameptrarr[vk]; nm.ptr = vernameptrarr[vk];
nm.len = drdi32(vernamelenbuf, (vk: u64) * 4u64); nm.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
let h: u32 = elfhash(nm); let h: u32 = elfhash(nm);
dwr32(verneedbuf, vnoff + 0u64, h); dwr32(verneedbuf.ptr, vnoff + 0u64, h);
dwr16(verneedbuf, vnoff + 4u64, 0u16); dwr16(verneedbuf.ptr, vnoff + 4u64, 0u16);
dwr16(verneedbuf, vnoff + 6u64, drdu16(vervnaother, (vk: u64) * 2u64)); dwr16(verneedbuf.ptr, vnoff + 6u64, drdu16(vervnaother.ptr, (vk: u64) * 2u64));
dwr32(verneedbuf, vnoff + 8u64, drdu32(verdynstroff, (vk: u64) * 4u64)); dwr32(verneedbuf.ptr, vnoff + 8u64, drdu32(verdynstroff.ptr, (vk: u64) * 4u64));
let nxt: u32 = 0u32; let nxt: u32 = 0u32;
if (k + 1 < cnt) { nxt = 16u32; }; if (k + 1 < cnt) { nxt = 16u32; };
dwr32(verneedbuf, vnoff + 12u64, nxt); dwr32(verneedbuf.ptr, vnoff + 12u64, nxt);
vnoff += 16u64; vnoff += 16u64;
k += 1; k += 1;
}; };
let vnnxt: u32 = 0u32; let vnnxt: u32 = 0u32;
if (vli + 1 < nvlibs) { vnnxt = (vnoff - vnstart): u32; }; if (vli + 1 < nvlibs) { vnnxt = (vnoff - vnstart): u32; };
dwr32(verneedbuf, vnstart + 12u64, vnnxt); dwr32(verneedbuf.ptr, vnstart + 12u64, vnnxt);
vli += 1; vli += 1;
}; };
}; };
// ---- build .plt ---- // ---- build .plt ----
let pltbuf: *u8 = amalloc(a, pltsz): *u8; let pltbuf: []u8 = alloc([], pltsz)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let poff: u64 = (pi: u64) * PLT_STUB_BYTES_D; let poff: u64 = (pi: u64) * PLT_STUB_BYTES_D;
@@ -595,42 +595,42 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nextip: u64 = stubva + 6u64; let nextip: u64 = stubva + 6u64;
let slotva: u64 = gotpltva + (3u64 + (pi: u64)) * 8u64; let slotva: u64 = gotpltva + (3u64 + (pi: u64)) * 8u64;
let disp: i64 = (slotva: i64) - (nextip: i64); let disp: i64 = (slotva: i64) - (nextip: i64);
dwr8(pltbuf, poff + 0u64, 255u8); dwr8(pltbuf.ptr, poff + 0u64, 255u8);
dwr8(pltbuf, poff + 1u64, 37u8); dwr8(pltbuf.ptr, poff + 1u64, 37u8);
dwr32(pltbuf, poff + 2u64, (disp: i32): u32); dwr32(pltbuf.ptr, poff + 2u64, (disp: i32): u32);
pi += 1; pi += 1;
}; };
// ---- build .got.plt ---- // ---- build .got.plt ----
let gotpltbuf: *u8 = amalloc(a, gotpltsz): *u8; let gotpltbuf: []u8 = alloc([], gotpltsz)!;
dwr64(gotpltbuf, 0u64, dynamicva); dwr64(gotpltbuf.ptr, 0u64, dynamicva);
// ---- build .dynamic ---- // ---- build .dynamic ----
let dynamicbuf: *u8 = amalloc(a, dynamicsz): *u8; let dynamicbuf: []u8 = alloc([], dynamicsz)!;
let dk: u64 = 0u64; let dk: u64 = 0u64;
pi = 0; pi = 0;
for (pi < nsos) { for (pi < nsos) {
dwri64(dynamicbuf, dk * 16u64 + 0u64, DT_NEEDED); dwri64(dynamicbuf.ptr, dk * 16u64 + 0u64, DT_NEEDED);
dwr64(dynamicbuf, dk * 16u64 + 8u64, drdu32(sonamestr, (pi: u64) * 4u64): u64); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, drdu32(sonamestr.ptr, (pi: u64) * 4u64): u64);
dk += 1u64; dk += 1u64;
pi += 1; pi += 1;
}; };
dwri64(dynamicbuf, dk * 16u64, DT_HASH); dwr64(dynamicbuf, dk * 16u64 + 8u64, hashva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_HASH); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, hashva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynsymva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynsymva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrsz); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrsz); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf, dk * 16u64 + 8u64, 24u64); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 24u64); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf, dk * 16u64 + 8u64, gotpltva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, gotpltva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, relapltsz); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltsz); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf, dk * 16u64 + 8u64, relapltva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_BIND_NOW); dwr64(dynamicbuf, dk * 16u64 + 8u64, 0u64); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_BIND_NOW); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 0u64); dk += 1u64;
if (withver != 0) { if (withver != 0) {
dwri64(dynamicbuf, dk * 16u64, DT_VERSYM); dwr64(dynamicbuf, dk * 16u64 + 8u64, versymva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERSYM); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, versymva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf, dk * 16u64 + 8u64, verneedva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, verneedva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_VERNEEDNUM); dwr64(dynamicbuf, dk * 16u64 + 8u64, nvlibs: u64);dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERNEEDNUM); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, nvlibs: u64);dk += 1u64;
}; };
dwri64(dynamicbuf, dk * 16u64, DT_NULL); dwr64(dynamicbuf, dk * 16u64 + 8u64, 0u64); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_NULL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 0u64); dk += 1u64;
if (dk != ndyn) { if (dk != ndyn) {
os.write(2, "w6l: dynamic entry count mismatch\n".ptr, 33u64); os.write(2, "w6l: dynamic entry count mismatch\n".ptr, 33u64);
return 1; return 1;
@@ -729,20 +729,20 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
// Sections. // Sections.
dbcopy(filebuf.ptr, interpoff, INTERP.ptr, INTERP.len: u64); dbcopy(filebuf.ptr, interpoff, INTERP.ptr, INTERP.len: u64);
dwr8(filebuf.ptr, interpoff + (INTERP.len: u64), 0u8); dwr8(filebuf.ptr, interpoff + (INTERP.len: u64), 0u8);
dbcopy(filebuf.ptr, dynstroff, dynstr, dynstrsz); dbcopy(filebuf.ptr, dynstroff, dynstr.ptr, dynstrsz);
dbcopy(filebuf.ptr, dynsymoff, dynsymbuf, dynsymsz); dbcopy(filebuf.ptr, dynsymoff, dynsymbuf.ptr, dynsymsz);
dbcopy(filebuf.ptr, hashoff, hashbuf, hashsz); dbcopy(filebuf.ptr, hashoff, hashbuf.ptr, hashsz);
dbcopy(filebuf.ptr, versymoff, versymbuf, versymsz); dbcopy(filebuf.ptr, versymoff, versymbuf.ptr, versymsz);
if (verneedsz > 0u64) { if (verneedsz > 0u64) {
dbcopy(filebuf.ptr, verneedoff, verneedbuf, verneedsz); dbcopy(filebuf.ptr, verneedoff, verneedbuf.ptr, verneedsz);
}; };
dbcopy(filebuf.ptr, relapltoff, relapltbuf, relapltsz); dbcopy(filebuf.ptr, relapltoff, relapltbuf.ptr, relapltsz);
if (l.textlen > 0u64) { if (l.textlen > 0u64) {
dbcopy(filebuf.ptr, textoff, l.text, l.textlen); dbcopy(filebuf.ptr, textoff, l.text, l.textlen);
}; };
dbcopy(filebuf.ptr, pltoff, pltbuf, pltsz); dbcopy(filebuf.ptr, pltoff, pltbuf.ptr, pltsz);
dbcopy(filebuf.ptr, gotpltoff, gotpltbuf, gotpltsz); dbcopy(filebuf.ptr, gotpltoff, gotpltbuf.ptr, gotpltsz);
dbcopy(filebuf.ptr, dynamicoff, dynamicbuf, dynamicsz); dbcopy(filebuf.ptr, dynamicoff, dynamicbuf.ptr, dynamicsz);
if (datafilelen > 0u64) { if (datafilelen > 0u64) {
dbcopy(filebuf.ptr, dataoff, l.data, datafilelen); dbcopy(filebuf.ptr, dataoff, l.data, datafilelen);
}; };

View File

@@ -1317,7 +1317,8 @@ fn loadarchive(l: *lnk, path: *u8, buf: *u8, len: u64) i32 = {
// any padding entries (NUL or space leading byte). // any padding entries (NUL or space leading byte).
if (first != 47u8) { if (first != 0u8) { if (first != 32u8) { if (first != 47u8) { if (first != 0u8) { if (first != 32u8) {
let m: *armember = alloc(armember { size = hdrsize })!; let m: *armember = alloc(armember { size = hdrsize })!;
let mb: *u8 = amalloc(l.a, hdrsize): *u8; let mbs: []u8 = alloc([], hdrsize)!;
let mb: *u8 = mbs.ptr;
let i: u64 = 0u64; let i: u64 = 0u64;
for (i < hdrsize) { for (i < hdrsize) {
mb[i] = buf[hdrend + i]; mb[i] = buf[hdrend + i];
@@ -2301,7 +2302,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nu: u64 = n: u64; let nu: u64 = n: u64;
// ---- collect dyn syms into a plt_idx-indexed array ---- // ---- collect dyn syms into a plt_idx-indexed array ----
let dynsyms: **lsym = amalloc(a, nu * 8u64): **lsym; let dynsyms: []*lsym = alloc([], nu)!;
let s: *lsym = l.syms; let s: *lsym = l.syms;
for (s != nil) { for (s != nil) {
if (s.isdyn != 0) { if (s.isdyn != 0) {
@@ -2326,7 +2327,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let maxsos: i32 = 0; let maxsos: i32 = 0;
let so: *lso = l.sos; let so: *lso = l.sos;
for (so != nil) { maxsos += 1; so = so.sonext; }; for (so != nil) { maxsos += 1; so = so.sonext; };
let sosused: **lso = amalloc(a, (maxsos: u64) * 8u64): **lso; let sosused: []*lso = alloc([], maxsos: u64)!;
let nsos: i32 = 0; let nsos: i32 = 0;
so = l.sos; so = l.sos;
for (so != nil) { for (so != nil) {
@@ -2355,16 +2356,16 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
// ver_dynstr_off[v] = offset within .dynstr (assigned after layout). // ver_dynstr_off[v] = offset within .dynstr (assigned after layout).
// ver_vna_other[v] = versym index (starting at 2). // ver_vna_other[v] = versym index (starting at 2).
let vlibsosidxbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8; let vlibsosidxbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
let vlibfirstbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8; let vlibfirstbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
let vlibcountbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8; let vlibcountbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
let nvlibs: i32 = 0; let nvlibs: i32 = 0;
let verlibidxbuf: *u8 = amalloc(a, nu * 4u64): *u8; let verlibidxbuf: []u8 = alloc([], nu * 4u64)!;
let vernameptrarr: **u8 = amalloc(a, nu * 8u64): **u8; let vernameptrarr: []*u8 = alloc([], nu)!;
let vernamelenbuf: *u8 = amalloc(a, nu * 4u64): *u8; let vernamelenbuf: []u8 = alloc([], nu * 4u64)!;
let verdynstroff: *u8 = amalloc(a, nu * 4u64): *u8; let verdynstroff: []u8 = alloc([], nu * 4u64)!;
let vervnaother: *u8 = amalloc(a, nu * 2u64): *u8; let vervnaother: []u8 = alloc([], nu * 2u64)!;
let nvers: i32 = 0; let nvers: i32 = 0;
let si: i32 = 0; let si: i32 = 0;
@@ -2384,8 +2385,8 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
} else { j += 1; }; } else { j += 1; };
}; };
if (has != 0) { if (has != 0) {
dwr32(vlibsosidxbuf, (nvlibs: u64) * 4u64, si: u32); dwr32(vlibsosidxbuf.ptr, (nvlibs: u64) * 4u64, si: u32);
dwr32(vlibfirstbuf, (nvlibs: u64) * 4u64, nvers: u32); dwr32(vlibfirstbuf.ptr, (nvlibs: u64) * 4u64, nvers: u32);
let added: i32 = 0; let added: i32 = 0;
let jj: i32 = 0; let jj: i32 = 0;
for (jj < n) { for (jj < n) {
@@ -2401,15 +2402,15 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let kk: i32 = nvers - added + k; let kk: i32 = nvers - added + k;
let existing: str; let existing: str;
existing.ptr = vernameptrarr[kk]; existing.ptr = vernameptrarr[kk];
existing.len = drdi32(vernamelenbuf, (kk: u64) * 4u64); existing.len = drdi32(vernamelenbuf.ptr, (kk: u64) * 4u64);
if (streqd(existing, vname)) { if (streqd(existing, vname)) {
seen = 1; k = added; seen = 1; k = added;
} else { k += 1; }; } else { k += 1; };
}; };
if (seen == 0) { if (seen == 0) {
dwr32(verlibidxbuf, (nvers: u64) * 4u64, nvlibs: u32); dwr32(verlibidxbuf.ptr, (nvers: u64) * 4u64, nvlibs: u32);
vernameptrarr[nvers] = vname.ptr; vernameptrarr[nvers] = vname.ptr;
dwri32(vernamelenbuf, (nvers: u64) * 4u64, vname.len); dwri32(vernamelenbuf.ptr, (nvers: u64) * 4u64, vname.len);
nvers += 1; nvers += 1;
added += 1; added += 1;
}; };
@@ -2417,7 +2418,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
jj += 1; jj += 1;
}; };
dwr32(vlibcountbuf, (nvlibs: u64) * 4u64, added: u32); dwr32(vlibcountbuf.ptr, (nvlibs: u64) * 4u64, added: u32);
nvlibs += 1; nvlibs += 1;
}; };
si += 1; si += 1;
@@ -2427,11 +2428,11 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nextvna: u16 = 2u16; let nextvna: u16 = 2u16;
let vi: i32 = 0; let vi: i32 = 0;
for (vi < nvlibs) { for (vi < nvlibs) {
let first: i32 = drdi32(vlibfirstbuf, (vi: u64) * 4u64); let first: i32 = drdi32(vlibfirstbuf.ptr, (vi: u64) * 4u64);
let cnt: i32 = drdi32(vlibcountbuf, (vi: u64) * 4u64); let cnt: i32 = drdi32(vlibcountbuf.ptr, (vi: u64) * 4u64);
let k: i32 = 0; let k: i32 = 0;
for (k < cnt) { for (k < cnt) {
dwr16(vervnaother, ((first + k): u64) * 2u64, nextvna); dwr16(vervnaother.ptr, ((first + k): u64) * 2u64, nextvna);
nextvna += 1u16; nextvna += 1u16;
k += 1; k += 1;
}; };
@@ -2456,35 +2457,35 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
pi = 0; pi = 0;
for (pi < nvers) { for (pi < nvers) {
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64); let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
dynstrsz += nmlen: u64; dynstrsz += nmlen: u64;
dynstrsz += 1u64; dynstrsz += 1u64;
pi += 1; pi += 1;
}; };
// ---- fill dynstr ---- // ---- fill dynstr ----
let dynstr: *u8 = amalloc(a, dynstrsz): *u8; let dynstr: []u8 = alloc([], dynstrsz)!;
let dynstrpos: u64 = 1u64; // past leading NUL let dynstrpos: u64 = 1u64; // past leading NUL
let sonamestr: *u8 = amalloc(a, (nsos: u64) * 4u64): *u8; let sonamestr: []u8 = alloc([], (nsos: u64) * 4u64)!;
pi = 0; pi = 0;
for (pi < nsos) { for (pi < nsos) {
dwr32(sonamestr, (pi: u64) * 4u64, dynstrpos: u32); dwr32(sonamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
let so2: *lso = sosused[pi]; let so2: *lso = sosused[pi];
let snm: str = so2.soname; let snm: str = so2.soname;
dbcopy(dynstr, dynstrpos, snm.ptr, snm.len: u64); dbcopy(dynstr.ptr, dynstrpos, snm.ptr, snm.len: u64);
dynstrpos += snm.len: u64; dynstrpos += snm.len: u64;
dynstr[dynstrpos] = 0u8; dynstr[dynstrpos] = 0u8;
dynstrpos += 1u64; dynstrpos += 1u64;
pi += 1; pi += 1;
}; };
let symnamestr: *u8 = amalloc(a, nu * 4u64): *u8; let symnamestr: []u8 = alloc([], nu * 4u64)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
dwr32(symnamestr, (pi: u64) * 4u64, dynstrpos: u32); dwr32(symnamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
let dsm: *lsym = dynsyms[pi]; let dsm: *lsym = dynsyms[pi];
let snm: str = dsm.name; let snm: str = dsm.name;
dbcopy(dynstr, dynstrpos, snm.ptr, snm.len: u64); dbcopy(dynstr.ptr, dynstrpos, snm.ptr, snm.len: u64);
dynstrpos += snm.len: u64; dynstrpos += snm.len: u64;
dynstr[dynstrpos] = 0u8; dynstr[dynstrpos] = 0u8;
dynstrpos += 1u64; dynstrpos += 1u64;
@@ -2492,10 +2493,10 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
pi = 0; pi = 0;
for (pi < nvers) { for (pi < nvers) {
dwr32(verdynstroff, (pi: u64) * 4u64, dynstrpos: u32); dwr32(verdynstroff.ptr, (pi: u64) * 4u64, dynstrpos: u32);
let nmp: *u8 = vernameptrarr[pi]; let nmp: *u8 = vernameptrarr[pi];
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64); let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
dbcopy(dynstr, dynstrpos, nmp, nmlen: u64); dbcopy(dynstr.ptr, dynstrpos, nmp, nmlen: u64);
dynstrpos += nmlen: u64; dynstrpos += nmlen: u64;
dynstr[dynstrpos] = 0u8; dynstr[dynstrpos] = 0u8;
dynstrpos += 1u64; dynstrpos += 1u64;
@@ -2503,7 +2504,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
}; };
// ---- per-dyn-sym versym index ---- // ---- per-dyn-sym versym index ----
let versymfor: *u8 = amalloc(a, nu * 2u64): *u8; let versymfor: []u8 = alloc([], nu * 2u64)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let dsm3: *lsym = dynsyms[pi]; let dsm3: *lsym = dynsyms[pi];
@@ -2511,27 +2512,27 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nm3: str = dsm3.name; let nm3: str = dsm3.name;
let vname: str = soversion(dl3, nm3); let vname: str = soversion(dl3, nm3);
if (vname.len == 0) { if (vname.len == 0) {
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D); dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
} else { } else {
let matched: i32 = 0; let matched: i32 = 0;
let vk: i32 = 0; let vk: i32 = 0;
for (vk < nvers) { for (vk < nvers) {
let vlx: i32 = drdi32(verlibidxbuf, (vk: u64) * 4u64); let vlx: i32 = drdi32(verlibidxbuf.ptr, (vk: u64) * 4u64);
let sosx: i32 = drdi32(vlibsosidxbuf, (vlx: u64) * 4u64); let sosx: i32 = drdi32(vlibsosidxbuf.ptr, (vlx: u64) * 4u64);
if (sosused[sosx] == dl3) { if (sosused[sosx] == dl3) {
let exi: str; let exi: str;
exi.ptr = vernameptrarr[vk]; exi.ptr = vernameptrarr[vk];
exi.len = drdi32(vernamelenbuf, (vk: u64) * 4u64); exi.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
if (streqd(exi, vname)) { if (streqd(exi, vname)) {
let other: u16 = drdu16(vervnaother, (vk: u64) * 2u64); let other: u16 = drdu16(vervnaother.ptr, (vk: u64) * 2u64);
dwr16(versymfor, (pi: u64) * 2u64, other); dwr16(versymfor.ptr, (pi: u64) * 2u64, other);
matched = 1; matched = 1;
vk = nvers; vk = nvers;
} else { vk += 1; }; } else { vk += 1; };
} else { vk += 1; }; } else { vk += 1; };
}; };
if (matched == 0) { if (matched == 0) {
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D); dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
}; };
}; };
pi += 1; pi += 1;
@@ -2558,7 +2559,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let verneedsz: u64 = 0u64; let verneedsz: u64 = 0u64;
let vli: i32 = 0; let vli: i32 = 0;
for (vli < nvlibs) { for (vli < nvlibs) {
let cnt: i32 = drdi32(vlibcountbuf, (vli: u64) * 4u64); let cnt: i32 = drdi32(vlibcountbuf.ptr, (vli: u64) * 4u64);
verneedsz += 16u64 + 16u64 * (cnt: u64); verneedsz += 16u64 + 16u64 * (cnt: u64);
vli += 1; vli += 1;
}; };
@@ -2624,96 +2625,96 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let filedataend: u64 = dataoff + datafilelen; let filedataend: u64 = dataoff + datafilelen;
// ---- build .dynsym ---- // ---- build .dynsym ----
let dynsymbuf: *u8 = amalloc(a, dynsymsz): *u8; let dynsymbuf: []u8 = alloc([], dynsymsz)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let eoff: u64 = (1u64 + (pi: u64)) * 24u64; let eoff: u64 = (1u64 + (pi: u64)) * 24u64;
dwr32(dynsymbuf, eoff + 0u64, drdu32(symnamestr, (pi: u64) * 4u64)); dwr32(dynsymbuf.ptr, eoff + 0u64, drdu32(symnamestr.ptr, (pi: u64) * 4u64));
dwr8(dynsymbuf, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8)); dwr8(dynsymbuf.ptr, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8));
dwr8(dynsymbuf, eoff + 5u64, 0u8); dwr8(dynsymbuf.ptr, eoff + 5u64, 0u8);
dwr16(dynsymbuf, eoff + 6u64, 0u16); dwr16(dynsymbuf.ptr, eoff + 6u64, 0u16);
dwr64(dynsymbuf, eoff + 8u64, 0u64); dwr64(dynsymbuf.ptr, eoff + 8u64, 0u64);
dwr64(dynsymbuf, eoff + 16u64, 0u64); dwr64(dynsymbuf.ptr, eoff + 16u64, 0u64);
pi += 1; pi += 1;
}; };
// ---- build .hash (SysV, 1 bucket) ---- // ---- build .hash (SysV, 1 bucket) ----
let hashbuf: *u8 = amalloc(a, hashsz): *u8; let hashbuf: []u8 = alloc([], hashsz)!;
dwr32(hashbuf, 0u64, nbuckets); dwr32(hashbuf.ptr, 0u64, nbuckets);
dwr32(hashbuf, 4u64, nchain); dwr32(hashbuf.ptr, 4u64, nchain);
let bucket0: u32 = 0u32; let bucket0: u32 = 0u32;
if (nsymstotal > 1u64) { bucket0 = 1u32; }; if (nsymstotal > 1u64) { bucket0 = 1u32; };
dwr32(hashbuf, 8u64, bucket0); dwr32(hashbuf.ptr, 8u64, bucket0);
let ci: u64 = 1u64; let ci: u64 = 1u64;
for (ci < nsymstotal) { for (ci < nsymstotal) {
let nxt: u32 = 0u32; let nxt: u32 = 0u32;
if (ci + 1u64 < nsymstotal) { nxt = (ci + 1u64): u32; }; if (ci + 1u64 < nsymstotal) { nxt = (ci + 1u64): u32; };
dwr32(hashbuf, 8u64 + (nbuckets: u64) * 4u64 + ci * 4u64, nxt); dwr32(hashbuf.ptr, 8u64 + (nbuckets: u64) * 4u64 + ci * 4u64, nxt);
ci += 1u64; ci += 1u64;
}; };
// ---- build .rela.plt ---- // ---- build .rela.plt ----
let relapltbuf: *u8 = amalloc(a, relapltsz): *u8; let relapltbuf: []u8 = alloc([], relapltsz)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let roff: u64 = (pi: u64) * 24u64; let roff: u64 = (pi: u64) * 24u64;
dwr64(relapltbuf, roff + 0u64, gotpltva + (3u64 + (pi: u64)) * 8u64); dwr64(relapltbuf.ptr, roff + 0u64, gotpltva + (3u64 + (pi: u64)) * 8u64);
let info: u64 = ((1u64 + (pi: u64)) << 32u64) | (R_X86_64_JUMP_SLOT_D: u64); let info: u64 = ((1u64 + (pi: u64)) << 32u64) | (R_X86_64_JUMP_SLOT_D: u64);
dwr64(relapltbuf, roff + 8u64, info); dwr64(relapltbuf.ptr, roff + 8u64, info);
dwri64(relapltbuf, roff + 16u64, 0i64); dwri64(relapltbuf.ptr, roff + 16u64, 0i64);
pi += 1; pi += 1;
}; };
// ---- build .gnu.version (u16 per dynsym entry) ---- // ---- build .gnu.version (u16 per dynsym entry) ----
let versymbuf: *u8 = amalloc(a, versymsz): *u8; let versymbuf: []u8 = alloc([], versymsz)!;
dwr16(versymbuf, 0u64, VER_NDX_LOCAL_D); dwr16(versymbuf.ptr, 0u64, VER_NDX_LOCAL_D);
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
dwr16(versymbuf, 2u64 + (pi: u64) * 2u64, drdu16(versymfor, (pi: u64) * 2u64)); dwr16(versymbuf.ptr, 2u64 + (pi: u64) * 2u64, drdu16(versymfor.ptr, (pi: u64) * 2u64));
pi += 1; pi += 1;
}; };
// ---- build .gnu.version_r ---- // ---- build .gnu.version_r ----
let verneedbuf: *u8 = amalloc(a, verneedsz): *u8; let verneedbuf: []u8 = alloc([], verneedsz)!;
if (verneedsz > 0u64) { if (verneedsz > 0u64) {
let vnoff: u64 = 0u64; let vnoff: u64 = 0u64;
vli = 0; vli = 0;
for (vli < nvlibs) { for (vli < nvlibs) {
let sosidx: i32 = drdi32(vlibsosidxbuf, (vli: u64) * 4u64); let sosidx: i32 = drdi32(vlibsosidxbuf.ptr, (vli: u64) * 4u64);
let first: i32 = drdi32(vlibfirstbuf, (vli: u64) * 4u64); let first: i32 = drdi32(vlibfirstbuf.ptr, (vli: u64) * 4u64);
let cnt: i32 = drdi32(vlibcountbuf, (vli: u64) * 4u64); let cnt: i32 = drdi32(vlibcountbuf.ptr, (vli: u64) * 4u64);
let vnstart: u64 = vnoff; let vnstart: u64 = vnoff;
dwr16(verneedbuf, vnoff + 0u64, 1u16); dwr16(verneedbuf.ptr, vnoff + 0u64, 1u16);
dwr16(verneedbuf, vnoff + 2u64, cnt: u16); dwr16(verneedbuf.ptr, vnoff + 2u64, cnt: u16);
dwr32(verneedbuf, vnoff + 4u64, drdu32(sonamestr, (sosidx: u64) * 4u64)); dwr32(verneedbuf.ptr, vnoff + 4u64, drdu32(sonamestr.ptr, (sosidx: u64) * 4u64));
dwr32(verneedbuf, vnoff + 8u64, 16u32); dwr32(verneedbuf.ptr, vnoff + 8u64, 16u32);
vnoff += 16u64; vnoff += 16u64;
let k: i32 = 0; let k: i32 = 0;
for (k < cnt) { for (k < cnt) {
let vk: i32 = first + k; let vk: i32 = first + k;
let nm: str; let nm: str;
nm.ptr = vernameptrarr[vk]; nm.ptr = vernameptrarr[vk];
nm.len = drdi32(vernamelenbuf, (vk: u64) * 4u64); nm.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
let h: u32 = elfhash(nm); let h: u32 = elfhash(nm);
dwr32(verneedbuf, vnoff + 0u64, h); dwr32(verneedbuf.ptr, vnoff + 0u64, h);
dwr16(verneedbuf, vnoff + 4u64, 0u16); dwr16(verneedbuf.ptr, vnoff + 4u64, 0u16);
dwr16(verneedbuf, vnoff + 6u64, drdu16(vervnaother, (vk: u64) * 2u64)); dwr16(verneedbuf.ptr, vnoff + 6u64, drdu16(vervnaother.ptr, (vk: u64) * 2u64));
dwr32(verneedbuf, vnoff + 8u64, drdu32(verdynstroff, (vk: u64) * 4u64)); dwr32(verneedbuf.ptr, vnoff + 8u64, drdu32(verdynstroff.ptr, (vk: u64) * 4u64));
let nxt: u32 = 0u32; let nxt: u32 = 0u32;
if (k + 1 < cnt) { nxt = 16u32; }; if (k + 1 < cnt) { nxt = 16u32; };
dwr32(verneedbuf, vnoff + 12u64, nxt); dwr32(verneedbuf.ptr, vnoff + 12u64, nxt);
vnoff += 16u64; vnoff += 16u64;
k += 1; k += 1;
}; };
let vnnxt: u32 = 0u32; let vnnxt: u32 = 0u32;
if (vli + 1 < nvlibs) { vnnxt = (vnoff - vnstart): u32; }; if (vli + 1 < nvlibs) { vnnxt = (vnoff - vnstart): u32; };
dwr32(verneedbuf, vnstart + 12u64, vnnxt); dwr32(verneedbuf.ptr, vnstart + 12u64, vnnxt);
vli += 1; vli += 1;
}; };
}; };
// ---- build .plt ---- // ---- build .plt ----
let pltbuf: *u8 = amalloc(a, pltsz): *u8; let pltbuf: []u8 = alloc([], pltsz)!;
pi = 0; pi = 0;
for (pi < n) { for (pi < n) {
let poff: u64 = (pi: u64) * PLT_STUB_BYTES_D; let poff: u64 = (pi: u64) * PLT_STUB_BYTES_D;
@@ -2721,42 +2722,42 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
let nextip: u64 = stubva + 6u64; let nextip: u64 = stubva + 6u64;
let slotva: u64 = gotpltva + (3u64 + (pi: u64)) * 8u64; let slotva: u64 = gotpltva + (3u64 + (pi: u64)) * 8u64;
let disp: i64 = (slotva: i64) - (nextip: i64); let disp: i64 = (slotva: i64) - (nextip: i64);
dwr8(pltbuf, poff + 0u64, 255u8); dwr8(pltbuf.ptr, poff + 0u64, 255u8);
dwr8(pltbuf, poff + 1u64, 37u8); dwr8(pltbuf.ptr, poff + 1u64, 37u8);
dwr32(pltbuf, poff + 2u64, (disp: i32): u32); dwr32(pltbuf.ptr, poff + 2u64, (disp: i32): u32);
pi += 1; pi += 1;
}; };
// ---- build .got.plt ---- // ---- build .got.plt ----
let gotpltbuf: *u8 = amalloc(a, gotpltsz): *u8; let gotpltbuf: []u8 = alloc([], gotpltsz)!;
dwr64(gotpltbuf, 0u64, dynamicva); dwr64(gotpltbuf.ptr, 0u64, dynamicva);
// ---- build .dynamic ---- // ---- build .dynamic ----
let dynamicbuf: *u8 = amalloc(a, dynamicsz): *u8; let dynamicbuf: []u8 = alloc([], dynamicsz)!;
let dk: u64 = 0u64; let dk: u64 = 0u64;
pi = 0; pi = 0;
for (pi < nsos) { for (pi < nsos) {
dwri64(dynamicbuf, dk * 16u64 + 0u64, DT_NEEDED); dwri64(dynamicbuf.ptr, dk * 16u64 + 0u64, DT_NEEDED);
dwr64(dynamicbuf, dk * 16u64 + 8u64, drdu32(sonamestr, (pi: u64) * 4u64): u64); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, drdu32(sonamestr.ptr, (pi: u64) * 4u64): u64);
dk += 1u64; dk += 1u64;
pi += 1; pi += 1;
}; };
dwri64(dynamicbuf, dk * 16u64, DT_HASH); dwr64(dynamicbuf, dk * 16u64 + 8u64, hashva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_HASH); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, hashva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynsymva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynsymva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrsz); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrsz); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf, dk * 16u64 + 8u64, 24u64); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 24u64); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf, dk * 16u64 + 8u64, gotpltva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, gotpltva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, relapltsz); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltsz); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf, dk * 16u64 + 8u64, relapltva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_BIND_NOW); dwr64(dynamicbuf, dk * 16u64 + 8u64, 0u64); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_BIND_NOW); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 0u64); dk += 1u64;
if (withver != 0) { if (withver != 0) {
dwri64(dynamicbuf, dk * 16u64, DT_VERSYM); dwr64(dynamicbuf, dk * 16u64 + 8u64, versymva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERSYM); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, versymva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf, dk * 16u64 + 8u64, verneedva); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, verneedva); dk += 1u64;
dwri64(dynamicbuf, dk * 16u64, DT_VERNEEDNUM); dwr64(dynamicbuf, dk * 16u64 + 8u64, nvlibs: u64);dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERNEEDNUM); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, nvlibs: u64);dk += 1u64;
}; };
dwri64(dynamicbuf, dk * 16u64, DT_NULL); dwr64(dynamicbuf, dk * 16u64 + 8u64, 0u64); dk += 1u64; dwri64(dynamicbuf.ptr, dk * 16u64, DT_NULL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 0u64); dk += 1u64;
if (dk != ndyn) { if (dk != ndyn) {
os.write(2, "w6l: dynamic entry count mismatch\n".ptr, 33u64); os.write(2, "w6l: dynamic entry count mismatch\n".ptr, 33u64);
return 1; return 1;
@@ -2855,20 +2856,20 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
// Sections. // Sections.
dbcopy(filebuf.ptr, interpoff, INTERP.ptr, INTERP.len: u64); dbcopy(filebuf.ptr, interpoff, INTERP.ptr, INTERP.len: u64);
dwr8(filebuf.ptr, interpoff + (INTERP.len: u64), 0u8); dwr8(filebuf.ptr, interpoff + (INTERP.len: u64), 0u8);
dbcopy(filebuf.ptr, dynstroff, dynstr, dynstrsz); dbcopy(filebuf.ptr, dynstroff, dynstr.ptr, dynstrsz);
dbcopy(filebuf.ptr, dynsymoff, dynsymbuf, dynsymsz); dbcopy(filebuf.ptr, dynsymoff, dynsymbuf.ptr, dynsymsz);
dbcopy(filebuf.ptr, hashoff, hashbuf, hashsz); dbcopy(filebuf.ptr, hashoff, hashbuf.ptr, hashsz);
dbcopy(filebuf.ptr, versymoff, versymbuf, versymsz); dbcopy(filebuf.ptr, versymoff, versymbuf.ptr, versymsz);
if (verneedsz > 0u64) { if (verneedsz > 0u64) {
dbcopy(filebuf.ptr, verneedoff, verneedbuf, verneedsz); dbcopy(filebuf.ptr, verneedoff, verneedbuf.ptr, verneedsz);
}; };
dbcopy(filebuf.ptr, relapltoff, relapltbuf, relapltsz); dbcopy(filebuf.ptr, relapltoff, relapltbuf.ptr, relapltsz);
if (l.textlen > 0u64) { if (l.textlen > 0u64) {
dbcopy(filebuf.ptr, textoff, l.text, l.textlen); dbcopy(filebuf.ptr, textoff, l.text, l.textlen);
}; };
dbcopy(filebuf.ptr, pltoff, pltbuf, pltsz); dbcopy(filebuf.ptr, pltoff, pltbuf.ptr, pltsz);
dbcopy(filebuf.ptr, gotpltoff, gotpltbuf, gotpltsz); dbcopy(filebuf.ptr, gotpltoff, gotpltbuf.ptr, gotpltsz);
dbcopy(filebuf.ptr, dynamicoff, dynamicbuf, dynamicsz); dbcopy(filebuf.ptr, dynamicoff, dynamicbuf.ptr, dynamicsz);
if (datafilelen > 0u64) { if (datafilelen > 0u64) {
dbcopy(filebuf.ptr, dataoff, l.data, datafilelen); dbcopy(filebuf.ptr, dataoff, l.data, datafilelen);
}; };

View File

@@ -343,7 +343,8 @@ fn loadarchive(l: *lnk, path: *u8, buf: *u8, len: u64) i32 = {
// any padding entries (NUL or space leading byte). // any padding entries (NUL or space leading byte).
if (first != 47u8) { if (first != 0u8) { if (first != 32u8) { if (first != 47u8) { if (first != 0u8) { if (first != 32u8) {
let m: *armember = alloc(armember { size = hdrsize })!; let m: *armember = alloc(armember { size = hdrsize })!;
let mb: *u8 = amalloc(l.a, hdrsize): *u8; let mbs: []u8 = alloc([], hdrsize)!;
let mb: *u8 = mbs.ptr;
let i: u64 = 0u64; let i: u64 = 0u64;
for (i < hdrsize) { for (i < hdrsize) {
mb[i] = buf[hdrend + i]; mb[i] = buf[hdrend + i];