wcc/ww: self-hosted deterministic ar-writer + archive dup-detect (M3-tail c5a, #62)
Per-package .a archives are written by a self-hosted deterministic ar writer (zeroed mtime/uid/gid, fixed mode 100644, stable member order) so cstage and wwstage emit byte-identical archives. The linker force-loads the root .o positionally and pulls deps from .a; a post-pull PASS-3 over unloaded members reports duplicate symbols through the archive (#31). Both stages mirrored (cmd/ + selfhost/). USER-ruled D2 (self-hosted ar writer); pike P1/P2 link model. Gate 989_separchive_run proves cs.a==ww.a byte-identity, 3x-determinism, link-consumes-.a (exit 7), and the masked-dup-through-.a loud fire.
This commit is contained in:
@@ -3352,6 +3352,33 @@ fn loadarchive(l: *lnk, path: *u8, buf: *u8, len: u64) i32 = {
|
||||
m = m.mnext;
|
||||
};
|
||||
};
|
||||
|
||||
// Pass 3 (#31, task #62): catch a dup the selective pull MASKED. A
|
||||
// member pass 2 left unloaded yet defining a name some other object
|
||||
// already `defined` is exactly the cross-package collision archive
|
||||
// selective-pull would silently skip. lookup (never intern) keeps
|
||||
// the pull machinery untouched → byte-id-neutral on every clean
|
||||
// link. Pulled-member and direct-`.o` dups stay caught in loadimage.
|
||||
// ww has no weak symbols → a genuine dup. (The bare message matches
|
||||
// loadimage's; the w6l path+name text divergence is #61, separate.)
|
||||
let dm: *armember = head;
|
||||
for (dm != nil) {
|
||||
if (dm.loaded == 0) {
|
||||
let de: *defent = dm.defs;
|
||||
for (de != nil) {
|
||||
let s: *lsym = lookup(l, de.name);
|
||||
if (s != nil) {
|
||||
if (s.defined != 0) {
|
||||
let msg: str = "w6l: duplicate symbol\n";
|
||||
os.write(2, msg.ptr, msg.len: u64);
|
||||
l.errs += 1;
|
||||
};
|
||||
};
|
||||
de = de.dnext;
|
||||
};
|
||||
};
|
||||
dm = dm.mnext;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -376,6 +376,33 @@ fn loadarchive(l: *lnk, path: *u8, buf: *u8, len: u64) i32 = {
|
||||
m = m.mnext;
|
||||
};
|
||||
};
|
||||
|
||||
// Pass 3 (#31, task #62): catch a dup the selective pull MASKED. A
|
||||
// member pass 2 left unloaded yet defining a name some other object
|
||||
// already `defined` is exactly the cross-package collision archive
|
||||
// selective-pull would silently skip. lookup (never intern) keeps
|
||||
// the pull machinery untouched → byte-id-neutral on every clean
|
||||
// link. Pulled-member and direct-`.o` dups stay caught in loadimage.
|
||||
// ww has no weak symbols → a genuine dup. (The bare message matches
|
||||
// loadimage's; the w6l path+name text divergence is #61, separate.)
|
||||
let dm: *armember = head;
|
||||
for (dm != nil) {
|
||||
if (dm.loaded == 0) {
|
||||
let de: *defent = dm.defs;
|
||||
for (de != nil) {
|
||||
let s: *lsym = lookup(l, de.name);
|
||||
if (s != nil) {
|
||||
if (s.defined != 0) {
|
||||
let msg: str = "w6l: duplicate symbol\n";
|
||||
os.write(2, msg.ptr, msg.len: u64);
|
||||
l.errs += 1;
|
||||
};
|
||||
};
|
||||
de = de.dnext;
|
||||
};
|
||||
};
|
||||
dm = dm.mnext;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user