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:
@@ -175,7 +175,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
let nu: u64 = n: u64;
|
||||
|
||||
// ---- 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;
|
||||
for (s != nil) {
|
||||
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 so: *lso = l.sos;
|
||||
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;
|
||||
so = l.sos;
|
||||
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_vna_other[v] = versym index (starting at 2).
|
||||
|
||||
let vlibsosidxbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8;
|
||||
let vlibfirstbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8;
|
||||
let vlibcountbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8;
|
||||
let vlibsosidxbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
|
||||
let vlibfirstbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
|
||||
let vlibcountbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
|
||||
let nvlibs: i32 = 0;
|
||||
|
||||
let verlibidxbuf: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let vernameptrarr: **u8 = amalloc(a, nu * 8u64): **u8;
|
||||
let vernamelenbuf: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let verdynstroff: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let vervnaother: *u8 = amalloc(a, nu * 2u64): *u8;
|
||||
let verlibidxbuf: []u8 = alloc([], nu * 4u64)!;
|
||||
let vernameptrarr: []*u8 = alloc([], nu)!;
|
||||
let vernamelenbuf: []u8 = alloc([], nu * 4u64)!;
|
||||
let verdynstroff: []u8 = alloc([], nu * 4u64)!;
|
||||
let vervnaother: []u8 = alloc([], nu * 2u64)!;
|
||||
let nvers: 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; };
|
||||
};
|
||||
if (has != 0) {
|
||||
dwr32(vlibsosidxbuf, (nvlibs: u64) * 4u64, si: u32);
|
||||
dwr32(vlibfirstbuf, (nvlibs: u64) * 4u64, nvers: u32);
|
||||
dwr32(vlibsosidxbuf.ptr, (nvlibs: u64) * 4u64, si: u32);
|
||||
dwr32(vlibfirstbuf.ptr, (nvlibs: u64) * 4u64, nvers: u32);
|
||||
let added: i32 = 0;
|
||||
let jj: i32 = 0;
|
||||
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 existing: str;
|
||||
existing.ptr = vernameptrarr[kk];
|
||||
existing.len = drdi32(vernamelenbuf, (kk: u64) * 4u64);
|
||||
existing.len = drdi32(vernamelenbuf.ptr, (kk: u64) * 4u64);
|
||||
if (streqd(existing, vname)) {
|
||||
seen = 1; k = added;
|
||||
} else { k += 1; };
|
||||
};
|
||||
if (seen == 0) {
|
||||
dwr32(verlibidxbuf, (nvers: u64) * 4u64, nvlibs: u32);
|
||||
dwr32(verlibidxbuf.ptr, (nvers: u64) * 4u64, nvlibs: u32);
|
||||
vernameptrarr[nvers] = vname.ptr;
|
||||
dwri32(vernamelenbuf, (nvers: u64) * 4u64, vname.len);
|
||||
dwri32(vernamelenbuf.ptr, (nvers: u64) * 4u64, vname.len);
|
||||
nvers += 1;
|
||||
added += 1;
|
||||
};
|
||||
@@ -291,7 +291,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
jj += 1;
|
||||
};
|
||||
dwr32(vlibcountbuf, (nvlibs: u64) * 4u64, added: u32);
|
||||
dwr32(vlibcountbuf.ptr, (nvlibs: u64) * 4u64, added: u32);
|
||||
nvlibs += 1;
|
||||
};
|
||||
si += 1;
|
||||
@@ -301,11 +301,11 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
let nextvna: u16 = 2u16;
|
||||
let vi: i32 = 0;
|
||||
for (vi < nvlibs) {
|
||||
let first: i32 = drdi32(vlibfirstbuf, (vi: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf, (vi: u64) * 4u64);
|
||||
let first: i32 = drdi32(vlibfirstbuf.ptr, (vi: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf.ptr, (vi: u64) * 4u64);
|
||||
let k: i32 = 0;
|
||||
for (k < cnt) {
|
||||
dwr16(vervnaother, ((first + k): u64) * 2u64, nextvna);
|
||||
dwr16(vervnaother.ptr, ((first + k): u64) * 2u64, nextvna);
|
||||
nextvna += 1u16;
|
||||
k += 1;
|
||||
};
|
||||
@@ -330,35 +330,35 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
pi = 0;
|
||||
for (pi < nvers) {
|
||||
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64);
|
||||
let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
|
||||
dynstrsz += nmlen: u64;
|
||||
dynstrsz += 1u64;
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- fill dynstr ----
|
||||
let dynstr: *u8 = amalloc(a, dynstrsz): *u8;
|
||||
let dynstr: []u8 = alloc([], dynstrsz)!;
|
||||
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;
|
||||
for (pi < nsos) {
|
||||
dwr32(sonamestr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
dwr32(sonamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
let so2: *lso = sosused[pi];
|
||||
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;
|
||||
dynstr[dynstrpos] = 0u8;
|
||||
dynstrpos += 1u64;
|
||||
pi += 1;
|
||||
};
|
||||
let symnamestr: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let symnamestr: []u8 = alloc([], nu * 4u64)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
dwr32(symnamestr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
dwr32(symnamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
let dsm: *lsym = dynsyms[pi];
|
||||
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;
|
||||
dynstr[dynstrpos] = 0u8;
|
||||
dynstrpos += 1u64;
|
||||
@@ -366,10 +366,10 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
pi = 0;
|
||||
for (pi < nvers) {
|
||||
dwr32(verdynstroff, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
dwr32(verdynstroff.ptr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
let nmp: *u8 = vernameptrarr[pi];
|
||||
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64);
|
||||
dbcopy(dynstr, dynstrpos, nmp, nmlen: u64);
|
||||
let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
|
||||
dbcopy(dynstr.ptr, dynstrpos, nmp, nmlen: u64);
|
||||
dynstrpos += nmlen: u64;
|
||||
dynstr[dynstrpos] = 0u8;
|
||||
dynstrpos += 1u64;
|
||||
@@ -377,7 +377,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
|
||||
// ---- per-dyn-sym versym index ----
|
||||
let versymfor: *u8 = amalloc(a, nu * 2u64): *u8;
|
||||
let versymfor: []u8 = alloc([], nu * 2u64)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
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 vname: str = soversion(dl3, nm3);
|
||||
if (vname.len == 0) {
|
||||
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
} else {
|
||||
let matched: i32 = 0;
|
||||
let vk: i32 = 0;
|
||||
for (vk < nvers) {
|
||||
let vlx: i32 = drdi32(verlibidxbuf, (vk: u64) * 4u64);
|
||||
let sosx: i32 = drdi32(vlibsosidxbuf, (vlx: u64) * 4u64);
|
||||
let vlx: i32 = drdi32(verlibidxbuf.ptr, (vk: u64) * 4u64);
|
||||
let sosx: i32 = drdi32(vlibsosidxbuf.ptr, (vlx: u64) * 4u64);
|
||||
if (sosused[sosx] == dl3) {
|
||||
let exi: str;
|
||||
exi.ptr = vernameptrarr[vk];
|
||||
exi.len = drdi32(vernamelenbuf, (vk: u64) * 4u64);
|
||||
exi.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
|
||||
if (streqd(exi, vname)) {
|
||||
let other: u16 = drdu16(vervnaother, (vk: u64) * 2u64);
|
||||
dwr16(versymfor, (pi: u64) * 2u64, other);
|
||||
let other: u16 = drdu16(vervnaother.ptr, (vk: u64) * 2u64);
|
||||
dwr16(versymfor.ptr, (pi: u64) * 2u64, other);
|
||||
matched = 1;
|
||||
vk = nvers;
|
||||
} else { vk += 1; };
|
||||
} else { vk += 1; };
|
||||
};
|
||||
if (matched == 0) {
|
||||
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
};
|
||||
};
|
||||
pi += 1;
|
||||
@@ -432,7 +432,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
let verneedsz: u64 = 0u64;
|
||||
let vli: i32 = 0;
|
||||
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);
|
||||
vli += 1;
|
||||
};
|
||||
@@ -498,96 +498,96 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
let filedataend: u64 = dataoff + datafilelen;
|
||||
|
||||
// ---- build .dynsym ----
|
||||
let dynsymbuf: *u8 = amalloc(a, dynsymsz): *u8;
|
||||
let dynsymbuf: []u8 = alloc([], dynsymsz)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
let eoff: u64 = (1u64 + (pi: u64)) * 24u64;
|
||||
dwr32(dynsymbuf, eoff + 0u64, drdu32(symnamestr, (pi: u64) * 4u64));
|
||||
dwr8(dynsymbuf, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8));
|
||||
dwr8(dynsymbuf, eoff + 5u64, 0u8);
|
||||
dwr16(dynsymbuf, eoff + 6u64, 0u16);
|
||||
dwr64(dynsymbuf, eoff + 8u64, 0u64);
|
||||
dwr64(dynsymbuf, eoff + 16u64, 0u64);
|
||||
dwr32(dynsymbuf.ptr, eoff + 0u64, drdu32(symnamestr.ptr, (pi: u64) * 4u64));
|
||||
dwr8(dynsymbuf.ptr, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8));
|
||||
dwr8(dynsymbuf.ptr, eoff + 5u64, 0u8);
|
||||
dwr16(dynsymbuf.ptr, eoff + 6u64, 0u16);
|
||||
dwr64(dynsymbuf.ptr, eoff + 8u64, 0u64);
|
||||
dwr64(dynsymbuf.ptr, eoff + 16u64, 0u64);
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- build .hash (SysV, 1 bucket) ----
|
||||
let hashbuf: *u8 = amalloc(a, hashsz): *u8;
|
||||
dwr32(hashbuf, 0u64, nbuckets);
|
||||
dwr32(hashbuf, 4u64, nchain);
|
||||
let hashbuf: []u8 = alloc([], hashsz)!;
|
||||
dwr32(hashbuf.ptr, 0u64, nbuckets);
|
||||
dwr32(hashbuf.ptr, 4u64, nchain);
|
||||
let bucket0: u32 = 0u32;
|
||||
if (nsymstotal > 1u64) { bucket0 = 1u32; };
|
||||
dwr32(hashbuf, 8u64, bucket0);
|
||||
dwr32(hashbuf.ptr, 8u64, bucket0);
|
||||
let ci: u64 = 1u64;
|
||||
for (ci < nsymstotal) {
|
||||
let nxt: u32 = 0u32;
|
||||
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;
|
||||
};
|
||||
|
||||
// ---- build .rela.plt ----
|
||||
let relapltbuf: *u8 = amalloc(a, relapltsz): *u8;
|
||||
let relapltbuf: []u8 = alloc([], relapltsz)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
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);
|
||||
dwr64(relapltbuf, roff + 8u64, info);
|
||||
dwri64(relapltbuf, roff + 16u64, 0i64);
|
||||
dwr64(relapltbuf.ptr, roff + 8u64, info);
|
||||
dwri64(relapltbuf.ptr, roff + 16u64, 0i64);
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- build .gnu.version (u16 per dynsym entry) ----
|
||||
let versymbuf: *u8 = amalloc(a, versymsz): *u8;
|
||||
dwr16(versymbuf, 0u64, VER_NDX_LOCAL_D);
|
||||
let versymbuf: []u8 = alloc([], versymsz)!;
|
||||
dwr16(versymbuf.ptr, 0u64, VER_NDX_LOCAL_D);
|
||||
pi = 0;
|
||||
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;
|
||||
};
|
||||
|
||||
// ---- build .gnu.version_r ----
|
||||
let verneedbuf: *u8 = amalloc(a, verneedsz): *u8;
|
||||
let verneedbuf: []u8 = alloc([], verneedsz)!;
|
||||
if (verneedsz > 0u64) {
|
||||
let vnoff: u64 = 0u64;
|
||||
vli = 0;
|
||||
for (vli < nvlibs) {
|
||||
let sosidx: i32 = drdi32(vlibsosidxbuf, (vli: u64) * 4u64);
|
||||
let first: i32 = drdi32(vlibfirstbuf, (vli: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf, (vli: u64) * 4u64);
|
||||
let sosidx: i32 = drdi32(vlibsosidxbuf.ptr, (vli: u64) * 4u64);
|
||||
let first: i32 = drdi32(vlibfirstbuf.ptr, (vli: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf.ptr, (vli: u64) * 4u64);
|
||||
let vnstart: u64 = vnoff;
|
||||
dwr16(verneedbuf, vnoff + 0u64, 1u16);
|
||||
dwr16(verneedbuf, vnoff + 2u64, cnt: u16);
|
||||
dwr32(verneedbuf, vnoff + 4u64, drdu32(sonamestr, (sosidx: u64) * 4u64));
|
||||
dwr32(verneedbuf, vnoff + 8u64, 16u32);
|
||||
dwr16(verneedbuf.ptr, vnoff + 0u64, 1u16);
|
||||
dwr16(verneedbuf.ptr, vnoff + 2u64, cnt: u16);
|
||||
dwr32(verneedbuf.ptr, vnoff + 4u64, drdu32(sonamestr.ptr, (sosidx: u64) * 4u64));
|
||||
dwr32(verneedbuf.ptr, vnoff + 8u64, 16u32);
|
||||
vnoff += 16u64;
|
||||
let k: i32 = 0;
|
||||
for (k < cnt) {
|
||||
let vk: i32 = first + k;
|
||||
let nm: str;
|
||||
nm.ptr = vernameptrarr[vk];
|
||||
nm.len = drdi32(vernamelenbuf, (vk: u64) * 4u64);
|
||||
nm.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
|
||||
let h: u32 = elfhash(nm);
|
||||
dwr32(verneedbuf, vnoff + 0u64, h);
|
||||
dwr16(verneedbuf, vnoff + 4u64, 0u16);
|
||||
dwr16(verneedbuf, vnoff + 6u64, drdu16(vervnaother, (vk: u64) * 2u64));
|
||||
dwr32(verneedbuf, vnoff + 8u64, drdu32(verdynstroff, (vk: u64) * 4u64));
|
||||
dwr32(verneedbuf.ptr, vnoff + 0u64, h);
|
||||
dwr16(verneedbuf.ptr, vnoff + 4u64, 0u16);
|
||||
dwr16(verneedbuf.ptr, vnoff + 6u64, drdu16(vervnaother.ptr, (vk: u64) * 2u64));
|
||||
dwr32(verneedbuf.ptr, vnoff + 8u64, drdu32(verdynstroff.ptr, (vk: u64) * 4u64));
|
||||
let nxt: u32 = 0u32;
|
||||
if (k + 1 < cnt) { nxt = 16u32; };
|
||||
dwr32(verneedbuf, vnoff + 12u64, nxt);
|
||||
dwr32(verneedbuf.ptr, vnoff + 12u64, nxt);
|
||||
vnoff += 16u64;
|
||||
k += 1;
|
||||
};
|
||||
let vnnxt: u32 = 0u32;
|
||||
if (vli + 1 < nvlibs) { vnnxt = (vnoff - vnstart): u32; };
|
||||
dwr32(verneedbuf, vnstart + 12u64, vnnxt);
|
||||
dwr32(verneedbuf.ptr, vnstart + 12u64, vnnxt);
|
||||
vli += 1;
|
||||
};
|
||||
};
|
||||
|
||||
// ---- build .plt ----
|
||||
let pltbuf: *u8 = amalloc(a, pltsz): *u8;
|
||||
let pltbuf: []u8 = alloc([], pltsz)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
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 slotva: u64 = gotpltva + (3u64 + (pi: u64)) * 8u64;
|
||||
let disp: i64 = (slotva: i64) - (nextip: i64);
|
||||
dwr8(pltbuf, poff + 0u64, 255u8);
|
||||
dwr8(pltbuf, poff + 1u64, 37u8);
|
||||
dwr32(pltbuf, poff + 2u64, (disp: i32): u32);
|
||||
dwr8(pltbuf.ptr, poff + 0u64, 255u8);
|
||||
dwr8(pltbuf.ptr, poff + 1u64, 37u8);
|
||||
dwr32(pltbuf.ptr, poff + 2u64, (disp: i32): u32);
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- build .got.plt ----
|
||||
let gotpltbuf: *u8 = amalloc(a, gotpltsz): *u8;
|
||||
dwr64(gotpltbuf, 0u64, dynamicva);
|
||||
let gotpltbuf: []u8 = alloc([], gotpltsz)!;
|
||||
dwr64(gotpltbuf.ptr, 0u64, dynamicva);
|
||||
|
||||
// ---- build .dynamic ----
|
||||
let dynamicbuf: *u8 = amalloc(a, dynamicsz): *u8;
|
||||
let dynamicbuf: []u8 = alloc([], dynamicsz)!;
|
||||
let dk: u64 = 0u64;
|
||||
pi = 0;
|
||||
for (pi < nsos) {
|
||||
dwri64(dynamicbuf, dk * 16u64 + 0u64, DT_NEEDED);
|
||||
dwr64(dynamicbuf, dk * 16u64 + 8u64, drdu32(sonamestr, (pi: u64) * 4u64): u64);
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64 + 0u64, DT_NEEDED);
|
||||
dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, drdu32(sonamestr.ptr, (pi: u64) * 4u64): u64);
|
||||
dk += 1u64;
|
||||
pi += 1;
|
||||
};
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_HASH); dwr64(dynamicbuf, dk * 16u64 + 8u64, hashva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynsymva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrsz); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf, dk * 16u64 + 8u64, 24u64); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf, dk * 16u64 + 8u64, gotpltva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, relapltsz); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf, 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_HASH); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, hashva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynsymva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrsz); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 24u64); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, gotpltva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltsz); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_BIND_NOW); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 0u64); dk += 1u64;
|
||||
if (withver != 0) {
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_VERSYM); dwr64(dynamicbuf, dk * 16u64 + 8u64, versymva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf, 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_VERSYM); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, versymva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, verneedva); 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) {
|
||||
os.write(2, "w6l: dynamic entry count mismatch\n".ptr, 33u64);
|
||||
return 1;
|
||||
@@ -729,20 +729,20 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
// Sections.
|
||||
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);
|
||||
dbcopy(filebuf.ptr, dynstroff, dynstr.ptr, dynstrsz);
|
||||
dbcopy(filebuf.ptr, dynsymoff, dynsymbuf.ptr, dynsymsz);
|
||||
dbcopy(filebuf.ptr, hashoff, hashbuf.ptr, hashsz);
|
||||
dbcopy(filebuf.ptr, versymoff, versymbuf.ptr, versymsz);
|
||||
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) {
|
||||
dbcopy(filebuf.ptr, textoff, l.text, l.textlen);
|
||||
};
|
||||
dbcopy(filebuf.ptr, pltoff, pltbuf, pltsz);
|
||||
dbcopy(filebuf.ptr, gotpltoff, gotpltbuf, gotpltsz);
|
||||
dbcopy(filebuf.ptr, dynamicoff, dynamicbuf, dynamicsz);
|
||||
dbcopy(filebuf.ptr, pltoff, pltbuf.ptr, pltsz);
|
||||
dbcopy(filebuf.ptr, gotpltoff, gotpltbuf.ptr, gotpltsz);
|
||||
dbcopy(filebuf.ptr, dynamicoff, dynamicbuf.ptr, dynamicsz);
|
||||
if (datafilelen > 0u64) {
|
||||
dbcopy(filebuf.ptr, dataoff, l.data, datafilelen);
|
||||
};
|
||||
|
||||
@@ -1317,7 +1317,8 @@ fn loadarchive(l: *lnk, path: *u8, buf: *u8, len: u64) i32 = {
|
||||
// any padding entries (NUL or space leading byte).
|
||||
if (first != 47u8) { if (first != 0u8) { if (first != 32u8) {
|
||||
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;
|
||||
for (i < hdrsize) {
|
||||
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;
|
||||
|
||||
// ---- 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;
|
||||
for (s != nil) {
|
||||
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 so: *lso = l.sos;
|
||||
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;
|
||||
so = l.sos;
|
||||
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_vna_other[v] = versym index (starting at 2).
|
||||
|
||||
let vlibsosidxbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8;
|
||||
let vlibfirstbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8;
|
||||
let vlibcountbuf: *u8 = amalloc(a, (maxsos: u64) * 4u64): *u8;
|
||||
let vlibsosidxbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
|
||||
let vlibfirstbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
|
||||
let vlibcountbuf: []u8 = alloc([], (maxsos: u64) * 4u64)!;
|
||||
let nvlibs: i32 = 0;
|
||||
|
||||
let verlibidxbuf: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let vernameptrarr: **u8 = amalloc(a, nu * 8u64): **u8;
|
||||
let vernamelenbuf: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let verdynstroff: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let vervnaother: *u8 = amalloc(a, nu * 2u64): *u8;
|
||||
let verlibidxbuf: []u8 = alloc([], nu * 4u64)!;
|
||||
let vernameptrarr: []*u8 = alloc([], nu)!;
|
||||
let vernamelenbuf: []u8 = alloc([], nu * 4u64)!;
|
||||
let verdynstroff: []u8 = alloc([], nu * 4u64)!;
|
||||
let vervnaother: []u8 = alloc([], nu * 2u64)!;
|
||||
let nvers: 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; };
|
||||
};
|
||||
if (has != 0) {
|
||||
dwr32(vlibsosidxbuf, (nvlibs: u64) * 4u64, si: u32);
|
||||
dwr32(vlibfirstbuf, (nvlibs: u64) * 4u64, nvers: u32);
|
||||
dwr32(vlibsosidxbuf.ptr, (nvlibs: u64) * 4u64, si: u32);
|
||||
dwr32(vlibfirstbuf.ptr, (nvlibs: u64) * 4u64, nvers: u32);
|
||||
let added: i32 = 0;
|
||||
let jj: i32 = 0;
|
||||
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 existing: str;
|
||||
existing.ptr = vernameptrarr[kk];
|
||||
existing.len = drdi32(vernamelenbuf, (kk: u64) * 4u64);
|
||||
existing.len = drdi32(vernamelenbuf.ptr, (kk: u64) * 4u64);
|
||||
if (streqd(existing, vname)) {
|
||||
seen = 1; k = added;
|
||||
} else { k += 1; };
|
||||
};
|
||||
if (seen == 0) {
|
||||
dwr32(verlibidxbuf, (nvers: u64) * 4u64, nvlibs: u32);
|
||||
dwr32(verlibidxbuf.ptr, (nvers: u64) * 4u64, nvlibs: u32);
|
||||
vernameptrarr[nvers] = vname.ptr;
|
||||
dwri32(vernamelenbuf, (nvers: u64) * 4u64, vname.len);
|
||||
dwri32(vernamelenbuf.ptr, (nvers: u64) * 4u64, vname.len);
|
||||
nvers += 1;
|
||||
added += 1;
|
||||
};
|
||||
@@ -2417,7 +2418,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
jj += 1;
|
||||
};
|
||||
dwr32(vlibcountbuf, (nvlibs: u64) * 4u64, added: u32);
|
||||
dwr32(vlibcountbuf.ptr, (nvlibs: u64) * 4u64, added: u32);
|
||||
nvlibs += 1;
|
||||
};
|
||||
si += 1;
|
||||
@@ -2427,11 +2428,11 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
let nextvna: u16 = 2u16;
|
||||
let vi: i32 = 0;
|
||||
for (vi < nvlibs) {
|
||||
let first: i32 = drdi32(vlibfirstbuf, (vi: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf, (vi: u64) * 4u64);
|
||||
let first: i32 = drdi32(vlibfirstbuf.ptr, (vi: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf.ptr, (vi: u64) * 4u64);
|
||||
let k: i32 = 0;
|
||||
for (k < cnt) {
|
||||
dwr16(vervnaother, ((first + k): u64) * 2u64, nextvna);
|
||||
dwr16(vervnaother.ptr, ((first + k): u64) * 2u64, nextvna);
|
||||
nextvna += 1u16;
|
||||
k += 1;
|
||||
};
|
||||
@@ -2456,35 +2457,35 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
pi = 0;
|
||||
for (pi < nvers) {
|
||||
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64);
|
||||
let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
|
||||
dynstrsz += nmlen: u64;
|
||||
dynstrsz += 1u64;
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- fill dynstr ----
|
||||
let dynstr: *u8 = amalloc(a, dynstrsz): *u8;
|
||||
let dynstr: []u8 = alloc([], dynstrsz)!;
|
||||
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;
|
||||
for (pi < nsos) {
|
||||
dwr32(sonamestr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
dwr32(sonamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
let so2: *lso = sosused[pi];
|
||||
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;
|
||||
dynstr[dynstrpos] = 0u8;
|
||||
dynstrpos += 1u64;
|
||||
pi += 1;
|
||||
};
|
||||
let symnamestr: *u8 = amalloc(a, nu * 4u64): *u8;
|
||||
let symnamestr: []u8 = alloc([], nu * 4u64)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
dwr32(symnamestr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
dwr32(symnamestr.ptr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
let dsm: *lsym = dynsyms[pi];
|
||||
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;
|
||||
dynstr[dynstrpos] = 0u8;
|
||||
dynstrpos += 1u64;
|
||||
@@ -2492,10 +2493,10 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
pi = 0;
|
||||
for (pi < nvers) {
|
||||
dwr32(verdynstroff, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
dwr32(verdynstroff.ptr, (pi: u64) * 4u64, dynstrpos: u32);
|
||||
let nmp: *u8 = vernameptrarr[pi];
|
||||
let nmlen: i32 = drdi32(vernamelenbuf, (pi: u64) * 4u64);
|
||||
dbcopy(dynstr, dynstrpos, nmp, nmlen: u64);
|
||||
let nmlen: i32 = drdi32(vernamelenbuf.ptr, (pi: u64) * 4u64);
|
||||
dbcopy(dynstr.ptr, dynstrpos, nmp, nmlen: u64);
|
||||
dynstrpos += nmlen: u64;
|
||||
dynstr[dynstrpos] = 0u8;
|
||||
dynstrpos += 1u64;
|
||||
@@ -2503,7 +2504,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
};
|
||||
|
||||
// ---- per-dyn-sym versym index ----
|
||||
let versymfor: *u8 = amalloc(a, nu * 2u64): *u8;
|
||||
let versymfor: []u8 = alloc([], nu * 2u64)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
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 vname: str = soversion(dl3, nm3);
|
||||
if (vname.len == 0) {
|
||||
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
} else {
|
||||
let matched: i32 = 0;
|
||||
let vk: i32 = 0;
|
||||
for (vk < nvers) {
|
||||
let vlx: i32 = drdi32(verlibidxbuf, (vk: u64) * 4u64);
|
||||
let sosx: i32 = drdi32(vlibsosidxbuf, (vlx: u64) * 4u64);
|
||||
let vlx: i32 = drdi32(verlibidxbuf.ptr, (vk: u64) * 4u64);
|
||||
let sosx: i32 = drdi32(vlibsosidxbuf.ptr, (vlx: u64) * 4u64);
|
||||
if (sosused[sosx] == dl3) {
|
||||
let exi: str;
|
||||
exi.ptr = vernameptrarr[vk];
|
||||
exi.len = drdi32(vernamelenbuf, (vk: u64) * 4u64);
|
||||
exi.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
|
||||
if (streqd(exi, vname)) {
|
||||
let other: u16 = drdu16(vervnaother, (vk: u64) * 2u64);
|
||||
dwr16(versymfor, (pi: u64) * 2u64, other);
|
||||
let other: u16 = drdu16(vervnaother.ptr, (vk: u64) * 2u64);
|
||||
dwr16(versymfor.ptr, (pi: u64) * 2u64, other);
|
||||
matched = 1;
|
||||
vk = nvers;
|
||||
} else { vk += 1; };
|
||||
} else { vk += 1; };
|
||||
};
|
||||
if (matched == 0) {
|
||||
dwr16(versymfor, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
dwr16(versymfor.ptr, (pi: u64) * 2u64, VER_NDX_GLOBAL_D);
|
||||
};
|
||||
};
|
||||
pi += 1;
|
||||
@@ -2558,7 +2559,7 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
let verneedsz: u64 = 0u64;
|
||||
let vli: i32 = 0;
|
||||
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);
|
||||
vli += 1;
|
||||
};
|
||||
@@ -2624,96 +2625,96 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
let filedataend: u64 = dataoff + datafilelen;
|
||||
|
||||
// ---- build .dynsym ----
|
||||
let dynsymbuf: *u8 = amalloc(a, dynsymsz): *u8;
|
||||
let dynsymbuf: []u8 = alloc([], dynsymsz)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
let eoff: u64 = (1u64 + (pi: u64)) * 24u64;
|
||||
dwr32(dynsymbuf, eoff + 0u64, drdu32(symnamestr, (pi: u64) * 4u64));
|
||||
dwr8(dynsymbuf, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8));
|
||||
dwr8(dynsymbuf, eoff + 5u64, 0u8);
|
||||
dwr16(dynsymbuf, eoff + 6u64, 0u16);
|
||||
dwr64(dynsymbuf, eoff + 8u64, 0u64);
|
||||
dwr64(dynsymbuf, eoff + 16u64, 0u64);
|
||||
dwr32(dynsymbuf.ptr, eoff + 0u64, drdu32(symnamestr.ptr, (pi: u64) * 4u64));
|
||||
dwr8(dynsymbuf.ptr, eoff + 4u64, (STB_GLOBAL_D << 4u8) | (STT_FUNC_D & 15u8));
|
||||
dwr8(dynsymbuf.ptr, eoff + 5u64, 0u8);
|
||||
dwr16(dynsymbuf.ptr, eoff + 6u64, 0u16);
|
||||
dwr64(dynsymbuf.ptr, eoff + 8u64, 0u64);
|
||||
dwr64(dynsymbuf.ptr, eoff + 16u64, 0u64);
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- build .hash (SysV, 1 bucket) ----
|
||||
let hashbuf: *u8 = amalloc(a, hashsz): *u8;
|
||||
dwr32(hashbuf, 0u64, nbuckets);
|
||||
dwr32(hashbuf, 4u64, nchain);
|
||||
let hashbuf: []u8 = alloc([], hashsz)!;
|
||||
dwr32(hashbuf.ptr, 0u64, nbuckets);
|
||||
dwr32(hashbuf.ptr, 4u64, nchain);
|
||||
let bucket0: u32 = 0u32;
|
||||
if (nsymstotal > 1u64) { bucket0 = 1u32; };
|
||||
dwr32(hashbuf, 8u64, bucket0);
|
||||
dwr32(hashbuf.ptr, 8u64, bucket0);
|
||||
let ci: u64 = 1u64;
|
||||
for (ci < nsymstotal) {
|
||||
let nxt: u32 = 0u32;
|
||||
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;
|
||||
};
|
||||
|
||||
// ---- build .rela.plt ----
|
||||
let relapltbuf: *u8 = amalloc(a, relapltsz): *u8;
|
||||
let relapltbuf: []u8 = alloc([], relapltsz)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
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);
|
||||
dwr64(relapltbuf, roff + 8u64, info);
|
||||
dwri64(relapltbuf, roff + 16u64, 0i64);
|
||||
dwr64(relapltbuf.ptr, roff + 8u64, info);
|
||||
dwri64(relapltbuf.ptr, roff + 16u64, 0i64);
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- build .gnu.version (u16 per dynsym entry) ----
|
||||
let versymbuf: *u8 = amalloc(a, versymsz): *u8;
|
||||
dwr16(versymbuf, 0u64, VER_NDX_LOCAL_D);
|
||||
let versymbuf: []u8 = alloc([], versymsz)!;
|
||||
dwr16(versymbuf.ptr, 0u64, VER_NDX_LOCAL_D);
|
||||
pi = 0;
|
||||
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;
|
||||
};
|
||||
|
||||
// ---- build .gnu.version_r ----
|
||||
let verneedbuf: *u8 = amalloc(a, verneedsz): *u8;
|
||||
let verneedbuf: []u8 = alloc([], verneedsz)!;
|
||||
if (verneedsz > 0u64) {
|
||||
let vnoff: u64 = 0u64;
|
||||
vli = 0;
|
||||
for (vli < nvlibs) {
|
||||
let sosidx: i32 = drdi32(vlibsosidxbuf, (vli: u64) * 4u64);
|
||||
let first: i32 = drdi32(vlibfirstbuf, (vli: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf, (vli: u64) * 4u64);
|
||||
let sosidx: i32 = drdi32(vlibsosidxbuf.ptr, (vli: u64) * 4u64);
|
||||
let first: i32 = drdi32(vlibfirstbuf.ptr, (vli: u64) * 4u64);
|
||||
let cnt: i32 = drdi32(vlibcountbuf.ptr, (vli: u64) * 4u64);
|
||||
let vnstart: u64 = vnoff;
|
||||
dwr16(verneedbuf, vnoff + 0u64, 1u16);
|
||||
dwr16(verneedbuf, vnoff + 2u64, cnt: u16);
|
||||
dwr32(verneedbuf, vnoff + 4u64, drdu32(sonamestr, (sosidx: u64) * 4u64));
|
||||
dwr32(verneedbuf, vnoff + 8u64, 16u32);
|
||||
dwr16(verneedbuf.ptr, vnoff + 0u64, 1u16);
|
||||
dwr16(verneedbuf.ptr, vnoff + 2u64, cnt: u16);
|
||||
dwr32(verneedbuf.ptr, vnoff + 4u64, drdu32(sonamestr.ptr, (sosidx: u64) * 4u64));
|
||||
dwr32(verneedbuf.ptr, vnoff + 8u64, 16u32);
|
||||
vnoff += 16u64;
|
||||
let k: i32 = 0;
|
||||
for (k < cnt) {
|
||||
let vk: i32 = first + k;
|
||||
let nm: str;
|
||||
nm.ptr = vernameptrarr[vk];
|
||||
nm.len = drdi32(vernamelenbuf, (vk: u64) * 4u64);
|
||||
nm.len = drdi32(vernamelenbuf.ptr, (vk: u64) * 4u64);
|
||||
let h: u32 = elfhash(nm);
|
||||
dwr32(verneedbuf, vnoff + 0u64, h);
|
||||
dwr16(verneedbuf, vnoff + 4u64, 0u16);
|
||||
dwr16(verneedbuf, vnoff + 6u64, drdu16(vervnaother, (vk: u64) * 2u64));
|
||||
dwr32(verneedbuf, vnoff + 8u64, drdu32(verdynstroff, (vk: u64) * 4u64));
|
||||
dwr32(verneedbuf.ptr, vnoff + 0u64, h);
|
||||
dwr16(verneedbuf.ptr, vnoff + 4u64, 0u16);
|
||||
dwr16(verneedbuf.ptr, vnoff + 6u64, drdu16(vervnaother.ptr, (vk: u64) * 2u64));
|
||||
dwr32(verneedbuf.ptr, vnoff + 8u64, drdu32(verdynstroff.ptr, (vk: u64) * 4u64));
|
||||
let nxt: u32 = 0u32;
|
||||
if (k + 1 < cnt) { nxt = 16u32; };
|
||||
dwr32(verneedbuf, vnoff + 12u64, nxt);
|
||||
dwr32(verneedbuf.ptr, vnoff + 12u64, nxt);
|
||||
vnoff += 16u64;
|
||||
k += 1;
|
||||
};
|
||||
let vnnxt: u32 = 0u32;
|
||||
if (vli + 1 < nvlibs) { vnnxt = (vnoff - vnstart): u32; };
|
||||
dwr32(verneedbuf, vnstart + 12u64, vnnxt);
|
||||
dwr32(verneedbuf.ptr, vnstart + 12u64, vnnxt);
|
||||
vli += 1;
|
||||
};
|
||||
};
|
||||
|
||||
// ---- build .plt ----
|
||||
let pltbuf: *u8 = amalloc(a, pltsz): *u8;
|
||||
let pltbuf: []u8 = alloc([], pltsz)!;
|
||||
pi = 0;
|
||||
for (pi < n) {
|
||||
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 slotva: u64 = gotpltva + (3u64 + (pi: u64)) * 8u64;
|
||||
let disp: i64 = (slotva: i64) - (nextip: i64);
|
||||
dwr8(pltbuf, poff + 0u64, 255u8);
|
||||
dwr8(pltbuf, poff + 1u64, 37u8);
|
||||
dwr32(pltbuf, poff + 2u64, (disp: i32): u32);
|
||||
dwr8(pltbuf.ptr, poff + 0u64, 255u8);
|
||||
dwr8(pltbuf.ptr, poff + 1u64, 37u8);
|
||||
dwr32(pltbuf.ptr, poff + 2u64, (disp: i32): u32);
|
||||
pi += 1;
|
||||
};
|
||||
|
||||
// ---- build .got.plt ----
|
||||
let gotpltbuf: *u8 = amalloc(a, gotpltsz): *u8;
|
||||
dwr64(gotpltbuf, 0u64, dynamicva);
|
||||
let gotpltbuf: []u8 = alloc([], gotpltsz)!;
|
||||
dwr64(gotpltbuf.ptr, 0u64, dynamicva);
|
||||
|
||||
// ---- build .dynamic ----
|
||||
let dynamicbuf: *u8 = amalloc(a, dynamicsz): *u8;
|
||||
let dynamicbuf: []u8 = alloc([], dynamicsz)!;
|
||||
let dk: u64 = 0u64;
|
||||
pi = 0;
|
||||
for (pi < nsos) {
|
||||
dwri64(dynamicbuf, dk * 16u64 + 0u64, DT_NEEDED);
|
||||
dwr64(dynamicbuf, dk * 16u64 + 8u64, drdu32(sonamestr, (pi: u64) * 4u64): u64);
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64 + 0u64, DT_NEEDED);
|
||||
dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, drdu32(sonamestr.ptr, (pi: u64) * 4u64): u64);
|
||||
dk += 1u64;
|
||||
pi += 1;
|
||||
};
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_HASH); dwr64(dynamicbuf, dk * 16u64 + 8u64, hashva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynsymva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, dynstrsz); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf, dk * 16u64 + 8u64, 24u64); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf, dk * 16u64 + 8u64, gotpltva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf, dk * 16u64 + 8u64, relapltsz); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf, 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_HASH); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, hashva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMTAB); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynsymva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_STRSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, dynstrsz); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_SYMENT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 24u64); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTGOT); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, gotpltva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTRELSZ); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltsz); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_PLTREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, DT_RELA: u64);dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_JMPREL); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, relapltva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_BIND_NOW); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, 0u64); dk += 1u64;
|
||||
if (withver != 0) {
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_VERSYM); dwr64(dynamicbuf, dk * 16u64 + 8u64, versymva); dk += 1u64;
|
||||
dwri64(dynamicbuf, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf, 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_VERSYM); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, versymva); dk += 1u64;
|
||||
dwri64(dynamicbuf.ptr, dk * 16u64, DT_VERNEED); dwr64(dynamicbuf.ptr, dk * 16u64 + 8u64, verneedva); 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) {
|
||||
os.write(2, "w6l: dynamic entry count mismatch\n".ptr, 33u64);
|
||||
return 1;
|
||||
@@ -2855,20 +2856,20 @@ export fn emitdynelf(l: *lnk, fd: i32, base: u64, entry: u64) i32 = {
|
||||
// Sections.
|
||||
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);
|
||||
dbcopy(filebuf.ptr, dynstroff, dynstr.ptr, dynstrsz);
|
||||
dbcopy(filebuf.ptr, dynsymoff, dynsymbuf.ptr, dynsymsz);
|
||||
dbcopy(filebuf.ptr, hashoff, hashbuf.ptr, hashsz);
|
||||
dbcopy(filebuf.ptr, versymoff, versymbuf.ptr, versymsz);
|
||||
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) {
|
||||
dbcopy(filebuf.ptr, textoff, l.text, l.textlen);
|
||||
};
|
||||
dbcopy(filebuf.ptr, pltoff, pltbuf, pltsz);
|
||||
dbcopy(filebuf.ptr, gotpltoff, gotpltbuf, gotpltsz);
|
||||
dbcopy(filebuf.ptr, dynamicoff, dynamicbuf, dynamicsz);
|
||||
dbcopy(filebuf.ptr, pltoff, pltbuf.ptr, pltsz);
|
||||
dbcopy(filebuf.ptr, gotpltoff, gotpltbuf.ptr, gotpltsz);
|
||||
dbcopy(filebuf.ptr, dynamicoff, dynamicbuf.ptr, dynamicsz);
|
||||
if (datafilelen > 0u64) {
|
||||
dbcopy(filebuf.ptr, dataoff, l.data, datafilelen);
|
||||
};
|
||||
|
||||
@@ -343,7 +343,8 @@ fn loadarchive(l: *lnk, path: *u8, buf: *u8, len: u64) i32 = {
|
||||
// any padding entries (NUL or space leading byte).
|
||||
if (first != 47u8) { if (first != 0u8) { if (first != 32u8) {
|
||||
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;
|
||||
for (i < hdrsize) {
|
||||
mb[i] = buf[hdrend + i];
|
||||
|
||||
Reference in New Issue
Block a user