ww: rename toolchain to w-prefix + hare-style build/run/test driver
Plan 9-style w-prefix on the per-arch tools, disambiguating from the
real Plan 9 6c/6a/6l in ref/plan9front/:
cmd/wwc/ → cmd/wcc/ libwwc.a → libwcc.a
cmd/6{c,a,l} → cmd/w6{c,a,l} binary names too
test/wwc/ → test/wcc/ 6 test files w/ w6 prefix
selfhost/cmd mirror in lockstep
bootstrap/amd64/{w6c,w6a,w6l} snapshot binaries (gitignored)
WW_6{C,A,L} → WW_W6{C,A,L} env-var overrides
Plan 9 source-tree refs ("Plan 9 6c shape", ref/plan9front/, etc.)
preserved. Hare-style driver, both C and ww sides:
ww test [path] discover *_test.ww in a directory module, run
each; single-file mode for `ww test foo.ww`
Module-by-name `ww build foo` resolves to foo.ww or foo/foo.ww
via search path (cwd : -I dirs : $WW_LIB)
Default-to-cwd `ww build` / `ww test` build the cwd module
Run pass-through `ww run path arg1 arg2` reaches the program
lib/os: getcwd (79) and getdents64 (217) syscalls power `.` resolution
and directory enumeration on the ww side.
Makefile: wwstage tool deps now include lib/os/os.ww (+ lib/strconv
for wwdump_ww) so lib/* edits force their rebuild instead of leaving
stale binaries — surfaced when test 995 first failed against a stale
w6c_ww built before the lib/os additions.
Test 993 byte-identical parity gate (C-side ww vs ww-side ww_ww on a
build corpus) stays green; all 19 tests pass.
This commit is contained in:
104
cmd/w6l/l.h
Normal file
104
cmd/w6l/l.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* l.h — w6l-private header. Loads relocatable ELF64 .o files (the
|
||||
* format produced by w6a) and links them into a static executable.
|
||||
*
|
||||
* No archives yet (phase 8). No dynamic linking ever.
|
||||
*/
|
||||
#ifndef SIX_L_H
|
||||
#define SIX_L_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef int8_t i8;
|
||||
typedef int16_t i16;
|
||||
typedef int32_t i32;
|
||||
typedef int64_t i64;
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef struct Lsym Lsym;
|
||||
typedef struct Lrel Lrel;
|
||||
typedef struct Lobj Lobj;
|
||||
typedef struct Lso Lso;
|
||||
typedef struct Lnk Lnk;
|
||||
|
||||
struct Lsym {
|
||||
const char *name;
|
||||
u64 val; /* offset within combined .text once linked */
|
||||
int defined; /* 1 if a Lobj defines this symbol */
|
||||
Lobj *owner;
|
||||
int idx_in_owner;
|
||||
/* Dynamic-linking fields. Set by l_resolve when an undefined sym
|
||||
* is provided by some loaded Lso. Patched-in PLT slot index lets
|
||||
* the relocator route PC32/PLT32 references through the stub. */
|
||||
int is_dyn;
|
||||
Lso *dyn_lib;
|
||||
const char *dyn_version; /* matched export's version, NULL if none */
|
||||
int plt_idx; /* 0..dyn_n-1, -1 if no PLT slot */
|
||||
int dynsym_idx; /* index in emitted .dynsym, -1 otherwise */
|
||||
Lsym *next;
|
||||
};
|
||||
|
||||
struct Lrel {
|
||||
u64 off; /* offset within combined .text */
|
||||
int kind; /* R_X86_64_* */
|
||||
Lsym *sym;
|
||||
i64 addend;
|
||||
Lrel *next;
|
||||
};
|
||||
|
||||
struct Lobj {
|
||||
const char *path;
|
||||
u8 *buf; /* mmapped or read-in object bytes */
|
||||
u64 len;
|
||||
u64 text_off; /* offset of .text in combined output */
|
||||
u64 text_size;
|
||||
Lobj *next;
|
||||
};
|
||||
|
||||
struct Lso {
|
||||
const char *path; /* full filesystem path used to load */
|
||||
const char *soname; /* DT_SONAME, or basename if missing */
|
||||
char **exports; /* NULL-terminated list of GLOBAL/WEAK syms */
|
||||
char **versions; /* parallel to exports[]; NULL for unversioned,
|
||||
* else strdup'd version name e.g. "GLIBC_2.2.5" */
|
||||
Lso *next;
|
||||
};
|
||||
|
||||
struct Lnk {
|
||||
Lobj *objs;
|
||||
Lso *sos;
|
||||
Lsym *syms;
|
||||
Lrel *rels;
|
||||
u8 *text; /* combined .text */
|
||||
u64 textcap, textlen;
|
||||
int errs;
|
||||
int dyn_n; /* number of symbols routed through PLT */
|
||||
};
|
||||
|
||||
/* obj.c */
|
||||
int l_load(Lnk*, const char *path);
|
||||
int l_read_all(const char *path, u8 **out, u64 *len); /* shared helper */
|
||||
/* dyn.c */
|
||||
int l_load_so(Lnk*, const char *path);
|
||||
int l_so_provides(Lso*, const char *name);
|
||||
/* l_so_provides_v: same, but also returns the export's version name
|
||||
* (NULL for unversioned globals) via *out_version on a hit. */
|
||||
int l_so_provides_v(Lso*, const char *name, const char **out_version);
|
||||
/* sym.c */
|
||||
Lsym *l_intern(Lnk*, const char *name);
|
||||
Lsym *l_lookup(Lnk*, const char *name);
|
||||
/* pass.c */
|
||||
int l_resolve(Lnk*);
|
||||
int l_relocate(Lnk*, u64 base);
|
||||
/* out.c */
|
||||
int l_emit_elf(Lnk*, FILE *out, u64 base, u64 entry);
|
||||
/* dynout.c — emit a dynamic-linked ELF executable. Called by
|
||||
* l_emit_elf when l->sos is non-empty. */
|
||||
int l_emit_dyn_elf(Lnk*, FILE *out, u64 base, u64 entry);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user