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:
@@ -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; };
|
||||
|
||||
@@ -170,6 +170,7 @@ type asym = struct {
|
||||
istext: i32,
|
||||
isdata: i32, // mutually exclusive with istext; DATAW symbols
|
||||
isglobal: i32,
|
||||
hasreloc: i32, // referenced by a relocation — must be in the symtab
|
||||
addr: u64, // offset within its section (.text or .data)
|
||||
idx: i32,
|
||||
snext: *asym,
|
||||
|
||||
Reference in New Issue
Block a user