selfhost/cmd/w6l: drop l_* prefix from exports + snake fields/helpers

This commit is contained in:
2026-05-11 14:34:11 +09:00
parent f250bcfb3a
commit fce0a54d62
8 changed files with 334 additions and 370 deletions

View File

@@ -123,8 +123,8 @@ fn d_basename(p: *u8) *u8 = {
// ---- file slurp --------------------------------------------------------
fn read_all_so(path_cs: *u8) (*u8, u64) = {
let fd: i32 = os.open(path_cs, os.O_RDONLY, 0i32);
fn readallso(path: *u8) (*u8, u64) = {
let fd: i32 = os.open(path, os.O_RDONLY, 0i32);
if (fd < 0) { return nil, 0u64; };
let n: i64 = os.filesize(fd);
if (n < 0i64) { os.close(fd); return nil, 0u64; };
@@ -137,11 +137,11 @@ fn read_all_so(path_cs: *u8) (*u8, u64) = {
// ---- verdef helpers ----------------------------------------------------
// vd_name_at — walk verdef records and return the name (as *u8 into
// vdnameat — walk verdef records and return the name (as *u8 into
// the .so's verstr buffer) for the entry whose vd_ndx == ndx. The name
// is the first Verdaux's vda_name (subsequent auxes are predecessor
// names). Returns nil if no entry matches.
fn vd_name_at(buf: *u8, verdef_off: u64, verdef_size: u64,
fn vdnameat(buf: *u8, verdef_off: u64, verdef_size: u64,
verstr: *u8, ndx: u16) *u8 = {
let off: u64 = 0u64;
for (off < verdef_size) {
@@ -162,10 +162,10 @@ fn vd_name_at(buf: *u8, verdef_off: u64, verdef_size: u64,
// ---- entry points ------------------------------------------------------
export fn l_load_so(l: *lnk, path_cs: *u8) i32 = {
export fn loadso(l: *lnk, path: *u8) i32 = {
let buf: *u8;
let blen: u64;
buf, blen = read_all_so(path_cs);
buf, blen = readallso(path);
if (buf == nil) {
os.write(2, "w6l: cannot read .so\n".ptr, 20u64);
return -1;
@@ -174,22 +174,22 @@ export fn l_load_so(l: *lnk, path_cs: *u8) i32 = {
os.write(2, "w6l: short ELF\n".ptr, 14u64);
return -1;
};
if (buf[0u64] != 127u8) { return so_err("not ELF"); };
if (buf[1u64] != 69u8) { return so_err("not ELF"); };
if (buf[2u64] != 76u8) { return so_err("not ELF"); };
if (buf[3u64] != 70u8) { return so_err("not ELF"); };
if (buf[4u64] != 2u8) { return so_err("not ELFCLASS64"); };
if (buf[0u64] != 127u8) { return soerr("not ELF"); };
if (buf[1u64] != 69u8) { return soerr("not ELF"); };
if (buf[2u64] != 76u8) { return soerr("not ELF"); };
if (buf[3u64] != 70u8) { return soerr("not ELF"); };
if (buf[4u64] != 2u8) { return soerr("not ELFCLASS64"); };
if (d_u16(buf, EH_EMACHINE) != EM_X86_64_SO) {
return so_err("not amd64");
return soerr("not amd64");
};
if (d_u16(buf, EH_ETYPE) != ET_DYN_SO) {
return so_err("not ET_DYN");
return soerr("not ET_DYN");
};
let shoff: u64 = d_u64(buf, EH_SHOFF);
let shnum: u32 = d_u16(buf, EH_SHNUM): u32;
if (shoff == 0u64) { return so_err("stripped .so unsupported"); };
if (shnum == 0u32) { return so_err("stripped .so unsupported"); };
if (shoff == 0u64) { return soerr("stripped .so unsupported"); };
if (shnum == 0u32) { return soerr("stripped .so unsupported"); };
// Locate the four sections we care about.
let idx_dynsym: i32 = -1;
@@ -207,7 +207,7 @@ export fn l_load_so(l: *lnk, path_cs: *u8) i32 = {
i += 1u32;
};
if (idx_dynsym < 0) {
return so_err("no .dynsym");
return soerr("no .dynsym");
};
let dynsym_sh: u64 = shoff + (idx_dynsym: u64) * SH_SIZE;
@@ -250,7 +250,7 @@ export fn l_load_so(l: *lnk, path_cs: *u8) i32 = {
};
};
if (soname_cs == nil) {
soname_cs = d_basename(path_cs);
soname_cs = d_basename(path);
};
// Versym is one u16 per dynsym entry.
@@ -277,9 +277,9 @@ export fn l_load_so(l: *lnk, path_cs: *u8) i32 = {
};
// Build the lso. Exports are appended in dynsym order so
// l_so_provides_v's first-match semantics match the C version.
// soprovides_v's first-match semantics match the C version.
let so: *lso = amalloc(l.a, 64u64): *lso;
so.path = d_cstr_to_str(l.a, path_cs);
so.path = d_cstr_to_str(l.a, path);
so.soname = d_cstr_to_str(l.a, soname_cs);
so.exports = nil;
let tail: *lexport = nil;
@@ -325,7 +325,7 @@ export fn l_load_so(l: *lnk, path_cs: *u8) i32 = {
vername_cs = nil;
} else {
if (verstr != nil) {
let nm: *u8 = vd_name_at(buf, verdef_off, verdef_size, verstr, vidx);
let nm: *u8 = vdnameat(buf, verdef_off, verdef_size, verstr, vidx);
vername_cs = nm;
};
}; }; };
@@ -358,34 +358,34 @@ export fn l_load_so(l: *lnk, path_cs: *u8) i32 = {
return 0;
};
fn so_err(msg: str) i32 = {
fn soerr(msg: str) i32 = {
os.write(2, "w6l: ".ptr, 4u64);
os.write(2, msg.ptr, msg.len: u64);
os.write(2, "\n".ptr, 1u64);
return -1;
};
// l_so_provides — 1 if so exports name, 0 otherwise.
export fn l_so_provides(so: *lso, name: str) i32 = {
// soprovides — 1 if so exports name, 0 otherwise.
export fn soprovides(so: *lso, name: str) i32 = {
if (so == nil) { return 0; };
let e: *lexport = so.exports;
for (e != nil) {
if (s_eq(e.name, name)) { return 1; };
if (streq(e.name, name)) { return 1; };
e = e.enext;
};
return 0;
};
// l_so_version — the version of so's export named `name`, or an empty
// soversion — the version of so's export named `name`, or an empty
// str (ptr=nil, len=0) if the export is unversioned or not present.
export fn l_so_version(so: *lso, name: str) str = {
export fn soversion(so: *lso, name: str) str = {
let result: str;
result.ptr = nil;
result.len = 0i32;
if (so == nil) { return result; };
let e: *lexport = so.exports;
for (e != nil) {
if (s_eq(e.name, name)) {
if (streq(e.name, name)) {
result.ptr = e.version.ptr;
result.len = e.version.len;
return result;
@@ -395,12 +395,4 @@ export fn l_so_version(so: *lso, name: str) str = {
return result;
};
fn s_eq(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;
};
// `streq` lives in sym.ww — same bundle, single definition.