w6l: route writable globals into a second PT_LOAD
Second step toward top-level mutable `let`. The static path now loads .data PROGBITS sections from input .o files, page-aligns them after .text, and emits a second PT_LOAD (R+W) covering them. Relocations targeting data symbols compute against the data VA; text→text displacements still cancel the absolute VAs and stay correct. Inputs without any .data keep the original single-PT_LOAD layout byte-for-byte — 992 (selfhost w6l .o diff) and 995 (self-rebuild) depend on that invariant. Dynamic-link path (-l/-L) rejects .data for now with a clear error; folding writable globals into the existing R+W segment alongside .got.plt/.dynamic is a follow-up.
This commit is contained in:
17
cmd/w6l/l.h
17
cmd/w6l/l.h
@@ -28,8 +28,12 @@ typedef struct Lnk Lnk;
|
||||
|
||||
struct Lsym {
|
||||
const char *name;
|
||||
u64 val; /* offset within combined .text once linked */
|
||||
u64 val; /* offset within combined .text (or .data when
|
||||
* in_data=1) once linked */
|
||||
int defined; /* 1 if a Lobj defines this symbol */
|
||||
int in_data; /* 1 if defined in .data (writable globals);
|
||||
* 0 means .text (the default). Mutually
|
||||
* exclusive with is_dyn. */
|
||||
Lobj *owner;
|
||||
int idx_in_owner;
|
||||
/* Dynamic-linking fields. Set by l_resolve when an undefined sym
|
||||
@@ -57,6 +61,8 @@ struct Lobj {
|
||||
u64 len;
|
||||
u64 text_off; /* offset of .text in combined output */
|
||||
u64 text_size;
|
||||
u64 data_off; /* offset of .data in combined output */
|
||||
u64 data_size; /* bytes contributed to combined .data (0 if none) */
|
||||
Lobj *next;
|
||||
};
|
||||
|
||||
@@ -76,6 +82,9 @@ struct Lnk {
|
||||
Lrel *rels;
|
||||
u8 *text; /* combined .text */
|
||||
u64 textcap, textlen;
|
||||
u8 *data; /* combined .data (writable). Empty unless any
|
||||
* input .o has a .data PROGBITS section. */
|
||||
u64 datacap, datalen;
|
||||
int errs;
|
||||
int dyn_n; /* number of symbols routed through PLT */
|
||||
};
|
||||
@@ -94,7 +103,11 @@ 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);
|
||||
/* Patch relocations in l->text. text_va is the VA where .text will be
|
||||
* mapped; data_va is the VA where .data will be mapped (pass 0 if no
|
||||
* data symbols). PC32/PLT32 displacements between text symbols cancel
|
||||
* the absolute VA, but data targets need the real data_va. */
|
||||
int l_relocate(Lnk*, u64 text_va, u64 data_va);
|
||||
/* out.c */
|
||||
int l_emit_elf(Lnk*, FILE *out, u64 base, u64 entry);
|
||||
/* dynout.c — emit a dynamic-linked ELF executable. Called by
|
||||
|
||||
Reference in New Issue
Block a user