aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-10-22 15:27:50 -0400
committerRuss Cox <rsc@golang.org>2010-10-22 15:27:50 -0400
commite5e9211071d5a2437fd4f41f1fec77840d20da1f (patch)
treebba1c60c5fcb006a0871712beb281a3fbffd1dd8 /src/cmd/ld
parent5d9064697b81fa6e6c23d5566e1d5e456f295777 (diff)
downloadgo-e5e9211071d5a2437fd4f41f1fec77840d20da1f.tar.xz
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
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/data.c26
-rw-r--r--src/cmd/ld/macho.c35
2 files changed, 45 insertions, 16 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 461a39950b..55925f15c3 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -393,6 +393,23 @@ codeblk(int32 addr, int32 size)
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)
@@ -671,7 +688,6 @@ dodata(void)
datsize += t;
}
sect->len = datsize - sect->vaddr;
- datsize += dynptrsize;
/* bss */
sect = addsection(&segdata, ".bss", 06);
@@ -702,7 +718,7 @@ void
address(void)
{
Section *s, *text, *data, *rodata, *bss;
- Sym *sym;
+ Sym *sym, *sub;
uvlong va;
va = INITTEXT;
@@ -723,11 +739,9 @@ address(void)
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;
@@ -740,6 +754,8 @@ address(void)
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);
diff --git a/src/cmd/ld/macho.c b/src/cmd/ld/macho.c
index 75c3ad865a..67264233c7 100644
--- a/src/cmd/ld/macho.c
+++ b/src/cmd/ld/macho.c
@@ -281,7 +281,7 @@ domacho(void)
char *p;
uchar *dat;
uint32 x;
- Sym *s;
+ Sym *s, *smacho;
Sym **impsym;
ptrsize = 4;
@@ -352,10 +352,16 @@ domacho(void)
}
}
+ 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;
@@ -398,7 +404,9 @@ domacho(void)
dat[3] = x>>24;
}
- dynptrsize = (nexpsym+nimpsym) * ptrsize;
+ smacho->size = (nexpsym+nimpsym) * ptrsize;
+ if(smacho->size == 0)
+ smacho->reachable = 0;
}
vlong
@@ -408,10 +416,13 @@ domacholink(void)
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) {
@@ -452,6 +463,7 @@ asmbmacho(void)
MachoSeg *ms;
MachoDebug *md;
MachoLoad *ml;
+ Sym *smacho;
/* apple MACH */
va = INITTEXT - HEADR;
@@ -492,8 +504,9 @@ asmbmacho(void)
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;
@@ -503,14 +516,14 @@ asmbmacho(void)
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 */
/*
@@ -551,7 +564,7 @@ asmbmacho(void)
if(!debug['d']) {
int nsym;
- nsym = dynptrsize/ptrsize;
+ nsym = smacho->size/ptrsize;
ms = newMachoSeg("__LINKEDIT", 0);
ms->vaddr = va+v+rnd(segdata.len, INITRND);