w6a: branch labels stay out of the symtab (isglobal wired)

Every interned symbol -- including branch labels defined via
p.label -- was emitted STB_GLOBAL, so labels were collide-able
across objects and the header's "GLOBAL symbols only" contract was
enforced nowhere (asym.isglobal was set but never read). Labels
stay interned for fixup resolution; the symtab now carries only
exported definitions, undefined externs, and reloc-referenced syms
(a reloc pre-pass marks those). rt/ensure.o drops from 15 emitted
syms to 2. Bootstrap 991-995 hold byte-identical on the new format.
This commit is contained in:
2026-08-09 01:07:19 +09:00
parent 06c40a8bef
commit 4fe2e25da4
4 changed files with 29 additions and 4 deletions

View File

@@ -187,9 +187,23 @@ export fn emitelf(a: *asm_, fd: i32) i32 = {
for (zi < 24) { zsym[zi] = 0u8; zi += 1; };
bufputb(&sym, zsym.ptr, 24u64);
// Branch labels are interned for fixup resolution but are NOT
// link-visible: emitting them (all bindings here are GLOBAL)
// made every label collide-able across objects. Only exported
// definitions (isglobal), undefined externs, and reloc-
// referenced syms reach the symtab.
let rr: *areloc = a.relocs;
for (rr != nil) {
rr.asy.hasreloc = 1;
rr = rr.rnext;
};
let idx: i32 = 1;
let s: *asym = a.syms;
for (s != nil) {
if (s.defined != 0 && s.isglobal == 0 && s.hasreloc == 0) {
s = s.snext;
continue;
};
let entry: [24]u8;
let ei: i32 = 0;
for (ei < 24) { entry[ei] = 0u8; ei += 1; };