// selfhost/cmd/6l/sym.ww — port of cmd/6l/sym.c. // // Linker symbol table. Singly-linked list, usually a few hundred // entries; hashing isn't worth it yet. use mem; type lsym = struct { name: str, val: u64, // offset within combined .text once linked defined: i32, // 1 if some lobj defines this symbol owner: *lobj, idx_in_owner: i32, snext: *lsym, }; type lrel = struct { off: u64, // offset within combined .text kind: i32, // R_X86_64_* sym: *lsym, addend: i64, rnext: *lrel, }; type lobj = struct { path: str, buf: *u8, // object bytes len: u64, text_off: u64, // offset of .text in combined output text_size: u64, onext: *lobj, }; type lnk = struct { a: *arena, objs: *lobj, syms: *lsym, rels: *lrel, text: *u8, // combined .text textcap: u64, textlen: u64, errs: i32, }; fn streq(a: str, b: str) bool = { if (a.len != b.len) { return false; }; let i: i32 = 0; for (i < a.len) { if (a[i] != b[i]) { return false; }; i += 1; }; return true; }; export fn l_intern(l: *lnk, name: str) *lsym = { let s: *lsym = l.syms; for (s != nil) { if (streq(s.name, name)) { return s; }; s = s.snext; }; let n: *lsym = amalloc(l.a, 64u64): *lsym; n.name = name; n.snext = l.syms; l.syms = n; return n; }; export fn l_lookup(l: *lnk, name: str) *lsym = { let s: *lsym = l.syms; for (s != nil) { if (streq(s.name, name)) { return s; }; s = s.snext; }; return nil; };