Commit e5e92110 authored by Russ Cox's avatar Russ Cox

5l, 6l, 8l: introduce sub-symbols

Sub-symbols are laid out inside a larger symbol
but can be addressed directly.

Use to make Mach-O pointer array not a special case.

Will use later to describe ELF sections.

Glimpses of the beginning of ELF loading.

R=ken2
CC=golang-dev
https://golang.org/cl/2623043
parent 5d906469
...@@ -56,11 +56,9 @@ typedef struct Optab Optab; ...@@ -56,11 +56,9 @@ typedef struct Optab Optab;
typedef struct Oprang Oprang; typedef struct Oprang Oprang;
typedef uchar Opcross[32][2][32]; typedef uchar Opcross[32][2][32];
typedef struct Count Count; typedef struct Count Count;
typedef struct Use Use;
#define P ((Prog*)0) #define P ((Prog*)0)
#define S ((Sym*)0) #define S ((Sym*)0)
#define U ((Use*)0)
#define TNAME (cursym?cursym->name:noname) #define TNAME (cursym?cursym->name:noname)
struct Adr struct Adr
...@@ -139,9 +137,9 @@ struct Sym ...@@ -139,9 +137,9 @@ struct Sym
uchar thumb; // thumb code uchar thumb; // thumb code
uchar foreign; // called by arm if thumb, by thumb if arm uchar foreign; // called by arm if thumb, by thumb if arm
uchar fnptr; // used as fn ptr uchar fnptr; // used as fn ptr
Use* use;
Sym* hash; // in hash table Sym* hash; // in hash table
Sym* next; // in text or data list Sym* next; // in text or data list
Sym* sub;
Sym* gotype; Sym* gotype;
char* file; char* file;
char* dynimpname; char* dynimpname;
...@@ -191,12 +189,6 @@ struct Count ...@@ -191,12 +189,6 @@ struct Count
int32 count; int32 count;
int32 outof; int32 outof;
}; };
struct Use
{
Prog* p; /* use */
Prog* ct; /* curtext */
Use* link;
};
enum enum
{ {
...@@ -213,6 +205,8 @@ enum ...@@ -213,6 +205,8 @@ enum
SFILE, SFILE,
SCONST, SCONST,
SSUB = 1<<8,
LFROM = 1<<0, LFROM = 1<<0,
LTO = 1<<1, LTO = 1<<1,
LPOOL = 1<<2, LPOOL = 1<<2,
......
...@@ -131,6 +131,7 @@ struct Sym ...@@ -131,6 +131,7 @@ struct Sym
int32 sig; int32 sig;
Sym* hash; // in hash table Sym* hash; // in hash table
Sym* next; // in text or data list Sym* next; // in text or data list
Sym* sub; // in SSUB list
vlong value; vlong value;
vlong size; vlong size;
Sym* gotype; Sym* gotype;
...@@ -175,12 +176,13 @@ enum ...@@ -175,12 +176,13 @@ enum
SELFDATA, SELFDATA,
SRODATA, SRODATA,
SDATA, SDATA,
SMACHO,
SBSS, SBSS,
SXREF, SXREF,
SMACHO,
SFILE, SFILE,
SCONST, SCONST,
SSUB = 1<<8,
NHASH = 10007, NHASH = 10007,
NHUNK = 100000, NHUNK = 100000,
...@@ -354,7 +356,6 @@ EXTERN Sym* fromgotype; // type symbol on last p->from read ...@@ -354,7 +356,6 @@ EXTERN Sym* fromgotype; // type symbol on last p->from read
EXTERN vlong textstksiz; EXTERN vlong textstksiz;
EXTERN vlong textarg; EXTERN vlong textarg;
extern char thechar; extern char thechar;
EXTERN int dynptrsize;
EXTERN int elfstrsize; EXTERN int elfstrsize;
EXTERN char* elfstrdat; EXTERN char* elfstrdat;
EXTERN int elftextsh; EXTERN int elftextsh;
......
...@@ -47,6 +47,9 @@ span1(Sym *s) ...@@ -47,6 +47,9 @@ span1(Sym *s)
cursym = s; cursym = s;
if(s->p != nil)
return;
for(p = s->text; p != P; p = p->link) { for(p = s->text; p != P; p = p->link) {
p->back = 2; // use short branches first time through p->back = 2; // use short branches first time through
if((q = p->pcond) != P && (q->back & 2)) if((q = p->pcond) != P && (q->back & 2))
...@@ -145,6 +148,8 @@ span(void) ...@@ -145,6 +148,8 @@ span(void)
// NOTE(rsc): If we get rid of the globals we should // NOTE(rsc): If we get rid of the globals we should
// be able to parallelize these iterations. // be able to parallelize these iterations.
for(cursym = textp; cursym != nil; cursym = cursym->next) { for(cursym = textp; cursym != nil; cursym = cursym->next) {
if(cursym->p != nil)
continue;
// TODO: move into span1 // TODO: move into span1
for(p = cursym->text; p != P; p = p->link) { for(p = cursym->text; p != P; p = p->link) {
n = 0; n = 0;
...@@ -671,15 +676,9 @@ relput8(Prog *p, Adr *a) ...@@ -671,15 +676,9 @@ relput8(Prog *p, Adr *a)
vlong vlong
symaddr(Sym *s) symaddr(Sym *s)
{ {
switch(s->type) {
case SMACHO:
return segdata.vaddr + segdata.filelen - dynptrsize + s->value;
default:
if(!s->reachable) if(!s->reachable)
diag("unreachable symbol in symaddr - %s", s->name); diag("unreachable symbol in symaddr - %s", s->name);
return s->value; return s->value;
}
} }
static vlong static vlong
......
...@@ -132,6 +132,7 @@ struct Sym ...@@ -132,6 +132,7 @@ struct Sym
int32 sig; int32 sig;
Sym* hash; // in hash table Sym* hash; // in hash table
Sym* next; // in text or data list Sym* next; // in text or data list
Sym* sub; // in sub list
Sym* gotype; Sym* gotype;
char* file; char* file;
char* dynimpname; char* dynimpname;
...@@ -164,15 +165,17 @@ enum ...@@ -164,15 +165,17 @@ enum
/* order here is order in output file */ /* order here is order in output file */
STEXT, STEXT,
SELFDATA, SELFDATA,
SRODATA, // TODO(rsc): move SRODATA,
SDATA, SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */
SBSS, SBSS,
SXREF, SXREF,
SMACHO, // TODO(rsc): maybe move between DATA1 and BSS?
SFILE, SFILE,
SCONST, SCONST,
SSUB = 1<<8, /* sub-symbol, linked from parent via ->sub list */
NHASH = 10007, NHASH = 10007,
NHUNK = 100000, NHUNK = 100000,
MINSIZ = 4, MINSIZ = 4,
...@@ -287,7 +290,6 @@ EXTERN Prog* curp; ...@@ -287,7 +290,6 @@ EXTERN Prog* curp;
EXTERN Sym* cursym; EXTERN Sym* cursym;
EXTERN Sym* datap; EXTERN Sym* datap;
EXTERN int32 elfdatsize; EXTERN int32 elfdatsize;
EXTERN int32 dynptrsize;
EXTERN char debug[128]; EXTERN char debug[128];
EXTERN char literal[32]; EXTERN char literal[32];
EXTERN Sym* etextp; EXTERN Sym* etextp;
......
...@@ -503,15 +503,9 @@ relput4(Prog *p, Adr *a) ...@@ -503,15 +503,9 @@ relput4(Prog *p, Adr *a)
int32 int32
symaddr(Sym *s) symaddr(Sym *s)
{ {
switch(s->type) {
case SMACHO:
return segdata.vaddr + segdata.filelen - dynptrsize + s->value;
default:
if(!s->reachable) if(!s->reachable)
diag("unreachable symbol in symaddr - %s", s->name); diag("unreachable symbol in symaddr - %s", s->name);
return s->value; return s->value;
}
} }
static int32 static int32
......
...@@ -393,6 +393,23 @@ codeblk(int32 addr, int32 size) ...@@ -393,6 +393,23 @@ codeblk(int32 addr, int32 size)
Bprint(&bso, "\n"); Bprint(&bso, "\n");
} }
p = sym->text; p = sym->text;
if(p == nil) {
Bprint(&bso, "%.6llux\t%-20s | foreign text\n", (vlong)addr, sym->name);
n = sym->size;
q = sym->p;
while(n >= 16) {
Bprint(&bso, "%.6ux\t%-20.16I\n", addr, q);
addr += 16;
q += 16;
n -= 16;
}
if(n > 0)
Bprint(&bso, "%.6ux\t%-20.*I\n", addr, n, q);
addr += n;
continue;
}
Bprint(&bso, "%.6llux\t%-20s | %P\n", (vlong)addr, sym->name, p); Bprint(&bso, "%.6llux\t%-20s | %P\n", (vlong)addr, sym->name, p);
for(p = p->link; p != P; p = p->link) { for(p = p->link; p != P; p = p->link) {
if(p->link != P) if(p->link != P)
...@@ -671,7 +688,6 @@ dodata(void) ...@@ -671,7 +688,6 @@ dodata(void)
datsize += t; datsize += t;
} }
sect->len = datsize - sect->vaddr; sect->len = datsize - sect->vaddr;
datsize += dynptrsize;
/* bss */ /* bss */
sect = addsection(&segdata, ".bss", 06); sect = addsection(&segdata, ".bss", 06);
...@@ -702,7 +718,7 @@ void ...@@ -702,7 +718,7 @@ void
address(void) address(void)
{ {
Section *s, *text, *data, *rodata, *bss; Section *s, *text, *data, *rodata, *bss;
Sym *sym; Sym *sym, *sub;
uvlong va; uvlong va;
va = INITTEXT; va = INITTEXT;
...@@ -723,11 +739,9 @@ address(void) ...@@ -723,11 +739,9 @@ address(void)
for(s=segdata.sect; s != nil; s=s->next) { for(s=segdata.sect; s != nil; s=s->next) {
s->vaddr = va; s->vaddr = va;
va += s->len; va += s->len;
if(s == segdata.sect)
va += dynptrsize;
segdata.len = va - segdata.vaddr; segdata.len = va - segdata.vaddr;
} }
segdata.filelen = segdata.sect->len + dynptrsize; // assume .data is first segdata.filelen = segdata.sect->len; // assume .data is first
text = segtext.sect; text = segtext.sect;
rodata = segtext.sect->next; rodata = segtext.sect->next;
...@@ -740,6 +754,8 @@ address(void) ...@@ -740,6 +754,8 @@ address(void)
sym->value += rodata->vaddr; sym->value += rodata->vaddr;
else else
sym->value += data->vaddr; sym->value += data->vaddr;
for(sub = sym->sub; sub != nil; sub = sub->sub)
sub->value += sym->value;
} }
xdefine("text", STEXT, text->vaddr); xdefine("text", STEXT, text->vaddr);
......
...@@ -281,7 +281,7 @@ domacho(void) ...@@ -281,7 +281,7 @@ domacho(void)
char *p; char *p;
uchar *dat; uchar *dat;
uint32 x; uint32 x;
Sym *s; Sym *s, *smacho;
Sym **impsym; Sym **impsym;
ptrsize = 4; ptrsize = 4;
...@@ -352,10 +352,16 @@ domacho(void) ...@@ -352,10 +352,16 @@ domacho(void)
} }
} }
smacho = lookup("__nl_symbol_ptr", 0);
smacho->type = SMACHO;
smacho->reachable = 1;
for(h=0; h<nimpsym; h++) { for(h=0; h<nimpsym; h++) {
s = impsym[h]; s = impsym[h];
s->type = SMACHO; s->type = SMACHO | SSUB;
s->sub = smacho->sub;
smacho->sub = s;
s->value = (nexpsym+h) * ptrsize; s->value = (nexpsym+h) * ptrsize;
s->reachable = 1;
/* symbol table entry - darwin still puts _ prefixes on all C symbols */ /* symbol table entry - darwin still puts _ prefixes on all C symbols */
x = nstrtab; x = nstrtab;
...@@ -398,7 +404,9 @@ domacho(void) ...@@ -398,7 +404,9 @@ domacho(void)
dat[3] = x>>24; dat[3] = x>>24;
} }
dynptrsize = (nexpsym+nimpsym) * ptrsize; smacho->size = (nexpsym+nimpsym) * ptrsize;
if(smacho->size == 0)
smacho->reachable = 0;
} }
vlong vlong
...@@ -408,10 +416,13 @@ domacholink(void) ...@@ -408,10 +416,13 @@ domacholink(void)
uchar *p; uchar *p;
Sym *s; Sym *s;
uint64 val; uint64 val;
Sym *smacho;
smacho = lookup("__nl_symbol_ptr", 0);
linkoff = 0; linkoff = 0;
if(nlinkdata > 0 || nstrtab > 0) { if(nlinkdata > 0 || nstrtab > 0) {
linkoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen - dynptrsize, INITRND); linkoff = rnd(HEADR+segtext.len, INITRND) + rnd(segdata.filelen - smacho->size, INITRND);
seek(cout, linkoff, 0); seek(cout, linkoff, 0);
for(i = 0; i<nexpsym; ++i) { for(i = 0; i<nexpsym; ++i) {
...@@ -452,6 +463,7 @@ asmbmacho(void) ...@@ -452,6 +463,7 @@ asmbmacho(void)
MachoSeg *ms; MachoSeg *ms;
MachoDebug *md; MachoDebug *md;
MachoLoad *ml; MachoLoad *ml;
Sym *smacho;
/* apple MACH */ /* apple MACH */
va = INITTEXT - HEADR; va = INITTEXT - HEADR;
...@@ -492,8 +504,9 @@ asmbmacho(void) ...@@ -492,8 +504,9 @@ asmbmacho(void)
msect->flag = 0x400; /* flag - some instructions */ msect->flag = 0x400; /* flag - some instructions */
/* data */ /* data */
smacho = lookup("__nl_symbol_ptr", 0);
w = segdata.len; w = segdata.len;
ms = newMachoSeg("__DATA", 2+(dynptrsize>0)); ms = newMachoSeg("__DATA", 2+(smacho->size > 0));
ms->vaddr = va+v; ms->vaddr = va+v;
ms->vsize = w; ms->vsize = w;
ms->fileoffset = v; ms->fileoffset = v;
...@@ -503,14 +516,14 @@ asmbmacho(void) ...@@ -503,14 +516,14 @@ asmbmacho(void)
msect = newMachoSect(ms, "__data"); msect = newMachoSect(ms, "__data");
msect->addr = va+v; msect->addr = va+v;
msect->size = segdata.filelen - dynptrsize; msect->size = segdata.filelen - smacho->size;
msect->off = v; msect->off = v;
if(dynptrsize > 0) { if(smacho->size > 0) {
msect = newMachoSect(ms, "__nl_symbol_ptr"); msect = newMachoSect(ms, "__nl_symbol_ptr");
msect->addr = va+v+segdata.filelen - dynptrsize; msect->addr = smacho->value;
msect->size = dynptrsize; msect->size = smacho->size;
msect->off = v+segdata.filelen - dynptrsize; msect->off = datoff(msect->addr);
msect->align = 2; msect->align = 2;
msect->flag = 6; /* section with nonlazy symbol pointers */ msect->flag = 6; /* section with nonlazy symbol pointers */
/* /*
...@@ -551,7 +564,7 @@ asmbmacho(void) ...@@ -551,7 +564,7 @@ asmbmacho(void)
if(!debug['d']) { if(!debug['d']) {
int nsym; int nsym;
nsym = dynptrsize/ptrsize; nsym = smacho->size/ptrsize;
ms = newMachoSeg("__LINKEDIT", 0); ms = newMachoSeg("__LINKEDIT", 0);
ms->vaddr = va+v+rnd(segdata.len, INITRND); ms->vaddr = va+v+rnd(segdata.len, INITRND);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment