typedef struct Oprang Oprang;
typedef uchar Opcross[32][2][32];
typedef struct Count Count;
-typedef struct Use Use;
#define P ((Prog*)0)
#define S ((Sym*)0)
-#define U ((Use*)0)
#define TNAME (cursym?cursym->name:noname)
struct Adr
uchar thumb; // thumb code
uchar foreign; // called by arm if thumb, by thumb if arm
uchar fnptr; // used as fn ptr
- Use* use;
Sym* hash; // in hash table
Sym* next; // in text or data list
+ Sym* sub;
Sym* gotype;
char* file;
char* dynimpname;
int32 count;
int32 outof;
};
-struct Use
-{
- Prog* p; /* use */
- Prog* ct; /* curtext */
- Use* link;
-};
enum
{
SFILE,
SCONST,
+ SSUB = 1<<8,
+
LFROM = 1<<0,
LTO = 1<<1,
LPOOL = 1<<2,
int32 sig;
Sym* hash; // in hash table
Sym* next; // in text or data list
+ Sym* sub; // in SSUB list
vlong value;
vlong size;
Sym* gotype;
SELFDATA,
SRODATA,
SDATA,
+ SMACHO,
SBSS,
SXREF,
- SMACHO,
SFILE,
SCONST,
+ SSUB = 1<<8,
NHASH = 10007,
NHUNK = 100000,
EXTERN vlong textstksiz;
EXTERN vlong textarg;
extern char thechar;
-EXTERN int dynptrsize;
EXTERN int elfstrsize;
EXTERN char* elfstrdat;
EXTERN int elftextsh;
int n, m, i;
cursym = s;
+
+ if(s->p != nil)
+ return;
for(p = s->text; p != P; p = p->link) {
p->back = 2; // use short branches first time through
// NOTE(rsc): If we get rid of the globals we should
// be able to parallelize these iterations.
for(cursym = textp; cursym != nil; cursym = cursym->next) {
+ if(cursym->p != nil)
+ continue;
// TODO: move into span1
for(p = cursym->text; p != P; p = p->link) {
n = 0;
vlong
symaddr(Sym *s)
{
- switch(s->type) {
- case SMACHO:
- return segdata.vaddr + segdata.filelen - dynptrsize + s->value;
-
- default:
- if(!s->reachable)
- diag("unreachable symbol in symaddr - %s", s->name);
- return s->value;
- }
+ if(!s->reachable)
+ diag("unreachable symbol in symaddr - %s", s->name);
+ return s->value;
}
static vlong
int32 sig;
Sym* hash; // in hash table
Sym* next; // in text or data list
+ Sym* sub; // in sub list
Sym* gotype;
char* file;
char* dynimpname;
/* order here is order in output file */
STEXT,
SELFDATA,
- SRODATA, // TODO(rsc): move
+ SRODATA,
SDATA,
+ SMACHO, /* Mach-O __nl_symbol_ptr */
SBSS,
SXREF,
- SMACHO, // TODO(rsc): maybe move between DATA1 and BSS?
SFILE,
SCONST,
+
+ SSUB = 1<<8, /* sub-symbol, linked from parent via ->sub list */
NHASH = 10007,
NHUNK = 100000,
EXTERN Sym* cursym;
EXTERN Sym* datap;
EXTERN int32 elfdatsize;
-EXTERN int32 dynptrsize;
EXTERN char debug[128];
EXTERN char literal[32];
EXTERN Sym* etextp;
int32
symaddr(Sym *s)
{
- switch(s->type) {
- case SMACHO:
- return segdata.vaddr + segdata.filelen - dynptrsize + s->value;
-
- default:
- if(!s->reachable)
- diag("unreachable symbol in symaddr - %s", s->name);
- return s->value;
- }
+ if(!s->reachable)
+ diag("unreachable symbol in symaddr - %s", s->name);
+ return s->value;
}
static int32
Bprint(&bso, "\n");
}
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);
for(p = p->link; p != P; p = p->link) {
if(p->link != P)
datsize += t;
}
sect->len = datsize - sect->vaddr;
- datsize += dynptrsize;
/* bss */
sect = addsection(&segdata, ".bss", 06);
address(void)
{
Section *s, *text, *data, *rodata, *bss;
- Sym *sym;
+ Sym *sym, *sub;
uvlong va;
va = INITTEXT;
for(s=segdata.sect; s != nil; s=s->next) {
s->vaddr = va;
va += s->len;
- if(s == segdata.sect)
- va += dynptrsize;
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;
rodata = segtext.sect->next;
sym->value += rodata->vaddr;
else
sym->value += data->vaddr;
+ for(sub = sym->sub; sub != nil; sub = sub->sub)
+ sub->value += sym->value;
}
xdefine("text", STEXT, text->vaddr);
char *p;
uchar *dat;
uint32 x;
- Sym *s;
+ Sym *s, *smacho;
Sym **impsym;
ptrsize = 4;
}
}
+ smacho = lookup("__nl_symbol_ptr", 0);
+ smacho->type = SMACHO;
+ smacho->reachable = 1;
for(h=0; h<nimpsym; h++) {
s = impsym[h];
- s->type = SMACHO;
+ s->type = SMACHO | SSUB;
+ s->sub = smacho->sub;
+ smacho->sub = s;
s->value = (nexpsym+h) * ptrsize;
+ s->reachable = 1;
/* symbol table entry - darwin still puts _ prefixes on all C symbols */
x = nstrtab;
dat[3] = x>>24;
}
- dynptrsize = (nexpsym+nimpsym) * ptrsize;
+ smacho->size = (nexpsym+nimpsym) * ptrsize;
+ if(smacho->size == 0)
+ smacho->reachable = 0;
}
vlong
uchar *p;
Sym *s;
uint64 val;
+ Sym *smacho;
+
+ smacho = lookup("__nl_symbol_ptr", 0);
linkoff = 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);
for(i = 0; i<nexpsym; ++i) {
MachoSeg *ms;
MachoDebug *md;
MachoLoad *ml;
+ Sym *smacho;
/* apple MACH */
va = INITTEXT - HEADR;
msect->flag = 0x400; /* flag - some instructions */
/* data */
+ smacho = lookup("__nl_symbol_ptr", 0);
w = segdata.len;
- ms = newMachoSeg("__DATA", 2+(dynptrsize>0));
+ ms = newMachoSeg("__DATA", 2+(smacho->size > 0));
ms->vaddr = va+v;
ms->vsize = w;
ms->fileoffset = v;
msect = newMachoSect(ms, "__data");
msect->addr = va+v;
- msect->size = segdata.filelen - dynptrsize;
+ msect->size = segdata.filelen - smacho->size;
msect->off = v;
- if(dynptrsize > 0) {
+ if(smacho->size > 0) {
msect = newMachoSect(ms, "__nl_symbol_ptr");
- msect->addr = va+v+segdata.filelen - dynptrsize;
- msect->size = dynptrsize;
- msect->off = v+segdata.filelen - dynptrsize;
+ msect->addr = smacho->value;
+ msect->size = smacho->size;
+ msect->off = datoff(msect->addr);
msect->align = 2;
msect->flag = 6; /* section with nonlazy symbol pointers */
/*
if(!debug['d']) {
int nsym;
- nsym = dynptrsize/ptrsize;
+ nsym = smacho->size/ptrsize;
ms = newMachoSeg("__LINKEDIT", 0);
ms->vaddr = va+v+rnd(segdata.len, INITRND);