C bootstrap (phases 0-9):
cmd/wwc, cmd/6c, cmd/6a, cmd/6l, cmd/ww, rt, lib/*.
ww-side self-host (phase 10):
selfhost/cmd/wwc — ww-cgen frontend; bootstrap fixed point.
selfhost/cmd/6a — assembler; byte-identical to C 6a (test 991).
selfhost/cmd/6l — linker w/ archive (.a) support; byte-identical
to C 6l (test 992).
selfhost/cmd/ww — driver (build/run/version); byte-identical to
C ww (test 993).
make test: 15/15. make bootstrap: ww2.s == ww3.s, ww2.o == ww3.o,
ww2 == ww3 byte-identical, with the full ww-tooled chain.
75 lines
1.4 KiB
C
75 lines
1.4 KiB
C
/*
|
|
* l.h — 6l-private header. Loads relocatable ELF64 .o files (the
|
|
* format produced by 6a) 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 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;
|
|
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 Lnk {
|
|
Lobj *objs;
|
|
Lsym *syms;
|
|
Lrel *rels;
|
|
u8 *text; /* combined .text */
|
|
u64 textcap, textlen;
|
|
int errs;
|
|
};
|
|
|
|
/* obj.c */
|
|
int l_load(Lnk*, const char *path);
|
|
/* 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);
|
|
|
|
#endif
|