selfhost/cmd/w6l: drop l_* prefix from exports + snake fields/helpers
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user