aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-12-08 22:49:37 -0500
committerRuss Cox <rsc@golang.org>2013-12-08 22:49:37 -0500
commit7d507dc6e608e800bc26a5850259bbdb05abdf65 (patch)
tree185c30263233f4d172355f1aba12f61a03bb7e3b /src/cmd/ld
parent8642cbd660cd8f62f77a37227c640b234fcf9c30 (diff)
downloadgo-7d507dc6e608e800bc26a5850259bbdb05abdf65.tar.xz
liblink: create new library based on linker code
There is an enormous amount of code moving around in this CL, but the code is the same, and it is invoked in the same ways. This CL is preparation for the new linker structure, not the new structure itself. The new library's definition is in include/link.h. The main change is the use of a Link structure to hold all the linker-relevant state, replacing the smattering of global variables. The Link structure should both make it clearer which state must be carried around and make it possible to parallelize more easily later. The main body of the linker has moved into the architecture-independent cmd/ld directory. That includes the list of known header types, so the distinction between Hplan9x32 and Hplan9x64 is removed (no other header type distinguished 32- and 64-bit formats), and code for unused formats such as ipaq kernels has been deleted. The code being deleted from 5l, 6l, and 8l reappears in liblink or in ld. Because multiple files are being merged in the liblink directory, it is not possible to show the diffs nicely in hg. The Prog and Addr structures have been unified into an architecture-independent form and moved to link.h, where they will be shared by all tools: the assemblers, the compilers, and the linkers. The unification makes it possible to write architecture-independent traversal of Prog lists, among other benefits. The Sym structures cannot be unified: they are too fundamentally different between the linker and the compilers. Instead, liblink defines an LSym - a linker Sym - to be used in the Prog and Addr structures, and the linker now refers exclusively to LSyms. The compilers will keep using their own syms but will fill out the corresponding LSyms in the Prog and Addr structures. Although code from 5l, 6l, and 8l is now in a single library, the code has been arranged so that only one architecture needs to be linked into a particular program: 5l will not contain the code needed for x86 instruction layout, for example. The object file writing code in liblink/obj.c is from cmd/gc/obj.c. Preparation for golang.org/s/go13linker work. This CL does not build by itself. It depends on 35740044 and will be submitted at the same time. R=iant CC=golang-dev https://golang.org/cl/35790044
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/data.c535
-rw-r--r--src/cmd/ld/decodesym.c62
-rw-r--r--src/cmd/ld/dwarf.c86
-rw-r--r--src/cmd/ld/dwarf.h2
-rw-r--r--src/cmd/ld/elf.c184
-rw-r--r--src/cmd/ld/elf.h14
-rw-r--r--src/cmd/ld/go.c83
-rw-r--r--src/cmd/ld/ldelf.c42
-rw-r--r--src/cmd/ld/ldmacho.c34
-rw-r--r--src/cmd/ld/ldpe.c36
-rw-r--r--src/cmd/ld/lib.c1306
-rw-r--r--src/cmd/ld/lib.h383
-rw-r--r--src/cmd/ld/macho.c106
-rw-r--r--src/cmd/ld/pass.c104
-rw-r--r--src/cmd/ld/pcln.c258
-rw-r--r--src/cmd/ld/pe.c40
-rw-r--r--src/cmd/ld/pe.h2
-rw-r--r--src/cmd/ld/pobj.c223
-rw-r--r--src/cmd/ld/symtab.c50
19 files changed, 1277 insertions, 2273 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 30d7c81856..ac28041fbb 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -38,15 +38,14 @@
#include "../../pkg/runtime/mgc0.h"
void dynreloc(void);
-static vlong addaddrplus4(Sym *s, Sym *t, vlong add);
/*
* divide-and-conquer list-link
- * sort of Sym* structures.
+ * sort of LSym* structures.
* Used for the data block.
*/
int
-datcmp(Sym *s1, Sym *s2)
+datcmp(LSym *s1, LSym *s2)
{
if(s1->type != s2->type)
return (int)s1->type - (int)s2->type;
@@ -58,11 +57,11 @@ datcmp(Sym *s1, Sym *s2)
return strcmp(s1->name, s2->name);
}
-Sym*
-listsort(Sym *l, int (*cmp)(Sym*, Sym*), int off)
+LSym*
+listsort(LSym *l, int (*cmp)(LSym*, LSym*), int off)
{
- Sym *l1, *l2, *le;
- #define NEXT(l) (*(Sym**)((char*)(l)+off))
+ LSym *l1, *l2, *le;
+ #define NEXT(l) (*(LSym**)((char*)(l)+off))
if(l == 0 || NEXT(l) == 0)
return l;
@@ -128,31 +127,17 @@ listsort(Sym *l, int (*cmp)(Sym*, Sym*), int off)
#undef NEXT
}
-Reloc*
-addrel(Sym *s)
-{
- if(s->nr >= s->maxr) {
- if(s->maxr == 0)
- s->maxr = 4;
- else
- s->maxr <<= 1;
- s->r = erealloc(s->r, s->maxr*sizeof s->r[0]);
- memset(s->r+s->nr, 0, (s->maxr-s->nr)*sizeof s->r[0]);
- }
- return &s->r[s->nr++];
-}
-
void
-relocsym(Sym *s)
+relocsym(LSym *s)
{
Reloc *r;
- Sym *rs;
+ LSym *rs;
Prog p;
int32 i, off, siz, fl;
vlong o;
uchar *cast;
- cursym = s;
+ ctxt->cursym = s;
memset(&p, 0, sizeof p);
for(r=s->r; r<s->r+s->nr; r++) {
r->done = 1;
@@ -218,7 +203,7 @@ relocsym(Sym *s)
break;
case D_PCREL:
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
- if(linkmode == LinkExternal && r->sym && r->sym->type != SCONST && r->sym->sect != cursym->sect) {
+ if(linkmode == LinkExternal && r->sym && r->sym->type != SCONST && r->sym->sect != ctxt->cursym->sect) {
r->done = 0;
// set up addend for eventual relocation via outer symbol.
@@ -264,7 +249,7 @@ relocsym(Sym *s)
//print("relocate %s %p %s => %p %p %p %p [%p]\n", s->name, s->value+off, r->sym ? r->sym->name : "<nil>", (void*)symaddr(r->sym), (void*)s->value, (void*)r->off, (void*)r->siz, (void*)o);
switch(siz) {
default:
- cursym = s;
+ ctxt->cursym = s;
diag("bad reloc size %#ux for %s", siz, r->sym->name);
case 4:
if(r->type == D_PCREL) {
@@ -291,27 +276,27 @@ relocsym(Sym *s)
void
reloc(void)
{
- Sym *s;
+ LSym *s;
if(debug['v'])
Bprint(&bso, "%5.2f reloc\n", cputime());
Bflush(&bso);
- for(s=textp; s!=S; s=s->next)
+ for(s=ctxt->textp; s!=S; s=s->next)
relocsym(s);
for(s=datap; s!=S; s=s->next)
relocsym(s);
}
void
-dynrelocsym(Sym *s)
+dynrelocsym(LSym *s)
{
Reloc *r;
if(HEADTYPE == Hwindows) {
- Sym *rel, *targ;
+ LSym *rel, *targ;
- rel = lookup(".rel", 0);
+ rel = linklookup(ctxt, ".rel", 0);
if(s == rel)
return;
for(r=s->r; r<s->r+s->nr; r++) {
@@ -323,17 +308,17 @@ dynrelocsym(Sym *s)
// jmp *addr
if(thechar == '8') {
- adduint8(rel, 0xff);
- adduint8(rel, 0x25);
- addaddr(rel, targ);
- adduint8(rel, 0x90);
- adduint8(rel, 0x90);
+ adduint8(ctxt, rel, 0xff);
+ adduint8(ctxt, rel, 0x25);
+ addaddr(ctxt, rel, targ);
+ adduint8(ctxt, rel, 0x90);
+ adduint8(ctxt, rel, 0x90);
} else {
- adduint8(rel, 0xff);
- adduint8(rel, 0x24);
- adduint8(rel, 0x25);
- addaddrplus4(rel, targ, 0);
- adduint8(rel, 0x90);
+ adduint8(ctxt, rel, 0xff);
+ adduint8(ctxt, rel, 0x24);
+ adduint8(ctxt, rel, 0x25);
+ addaddrplus4(ctxt, rel, targ, 0);
+ adduint8(ctxt, rel, 0x90);
}
} else if(r->sym->plt >= 0) {
r->sym = rel;
@@ -352,7 +337,7 @@ dynrelocsym(Sym *s)
void
dynreloc(void)
{
- Sym *s;
+ LSym *s;
// -d suppresses dynamic loader format, so we may as well not
// compute these sections or mark their symbols as reachable.
@@ -362,7 +347,7 @@ dynreloc(void)
Bprint(&bso, "%5.2f reloc\n", cputime());
Bflush(&bso);
- for(s=textp; s!=S; s=s->next)
+ for(s=ctxt->textp; s!=S; s=s->next)
dynrelocsym(s);
for(s=datap; s!=S; s=s->next)
dynrelocsym(s);
@@ -370,118 +355,10 @@ dynreloc(void)
elfdynhash();
}
-void
-symgrow(Sym *s, int32 siz)
-{
- if(s->np >= siz)
- return;
-
- if(s->np > s->maxp) {
- cursym = s;
- diag("corrupt symbol data: np=%lld > maxp=%lld", (vlong)s->np, (vlong)s->maxp);
- errorexit();
- }
-
- if(s->maxp < siz) {
- if(s->maxp == 0)
- s->maxp = 8;
- while(s->maxp < siz)
- s->maxp <<= 1;
- s->p = erealloc(s->p, s->maxp);
- memset(s->p+s->np, 0, s->maxp-s->np);
- }
- s->np = siz;
-}
-
-void
-savedata(Sym *s, Prog *p, char *pn)
-{
- int32 off, siz, i, fl;
- uchar *cast;
- vlong o;
- Reloc *r;
-
- off = p->from.offset;
- siz = p->datasize;
- if(off < 0 || siz < 0 || off >= 1<<30 || siz >= 100)
- mangle(pn);
- symgrow(s, off+siz);
-
- switch(p->to.type) {
- default:
- diag("bad data: %P", p);
- break;
-
- case D_FCONST:
- switch(siz) {
- default:
- case 4:
- fl = ieeedtof(&p->to.ieee);
- cast = (uchar*)&fl;
- for(i=0; i<4; i++)
- s->p[off+i] = cast[fnuxi4[i]];
- break;
- case 8:
- cast = (uchar*)&p->to.ieee;
- for(i=0; i<8; i++)
- s->p[off+i] = cast[fnuxi8[i]];
- break;
- }
- break;
-
- case D_SCONST:
- for(i=0; i<siz; i++)
- s->p[off+i] = p->to.scon[i];
- break;
-
- case D_CONST:
- if(p->to.sym)
- goto Addr;
- o = p->to.offset;
- fl = o;
- cast = (uchar*)&fl;
- switch(siz) {
- default:
- diag("bad nuxi %d\n%P", siz, p);
- break;
- case 1:
- s->p[off] = cast[inuxi1[0]];
- break;
- case 2:
- for(i=0; i<2; i++)
- s->p[off+i] = cast[inuxi2[i]];
- break;
- case 4:
- for(i=0; i<4; i++)
- s->p[off+i] = cast[inuxi4[i]];
- break;
- case 8:
- cast = (uchar*)&o;
- for(i=0; i<8; i++)
- s->p[off+i] = cast[inuxi8[i]];
- break;
- }
- break;
-
- case D_ADDR:
- case D_SIZE:
- Addr:
- r = addrel(s);
- r->off = off;
- r->siz = siz;
- r->sym = p->to.sym;
- r->type = p->to.type;
- if(r->type != D_SIZE)
- r->type = D_ADDR;
- r->add = p->to.offset;
- break;
- }
-}
-
static void
-blk(Sym *start, int32 addr, int32 size)
+blk(LSym *start, int32 addr, int32 size)
{
- Sym *sym;
+ LSym *sym;
int32 eaddr;
uchar *p, *ep;
@@ -499,7 +376,7 @@ blk(Sym *start, int32 addr, int32 size)
diag("phase error: addr=%#llx but sym=%#llx type=%d", (vlong)addr, (vlong)sym->value, sym->type);
errorexit();
}
- cursym = sym;
+ ctxt->cursym = sym;
for(; addr < sym->value; addr++)
cput(0);
p = sym->p;
@@ -523,7 +400,7 @@ blk(Sym *start, int32 addr, int32 size)
void
codeblk(int32 addr, int32 size)
{
- Sym *sym;
+ LSym *sym;
int32 eaddr, n, epc;
Prog *p;
uchar *q;
@@ -531,13 +408,13 @@ codeblk(int32 addr, int32 size)
if(debug['a'])
Bprint(&bso, "codeblk [%#x,%#x) at offset %#llx\n", addr, addr+size, cpos());
- blk(textp, addr, size);
+ blk(ctxt->textp, addr, size);
/* again for printing */
if(!debug['a'])
return;
- for(sym = textp; sym != nil; sym = sym->next) {
+ for(sym = ctxt->textp; sym != nil; sym = sym->next) {
if(!sym->reachable)
continue;
if(sym->value >= addr)
@@ -600,7 +477,7 @@ codeblk(int32 addr, int32 size)
void
datblk(int32 addr, int32 size)
{
- Sym *sym;
+ LSym *sym;
int32 i, eaddr;
uchar *p, *ep;
char *typ, *rsname;
@@ -682,28 +559,28 @@ strnput(char *s, int n)
void
addstrdata(char *name, char *value)
{
- Sym *s, *sp;
+ LSym *s, *sp;
char *p;
p = smprint("%s.str", name);
- sp = lookup(p, 0);
+ sp = linklookup(ctxt, p, 0);
free(p);
addstring(sp, value);
- s = lookup(name, 0);
+ s = linklookup(ctxt, name, 0);
s->size = 0;
s->dupok = 1;
- addaddr(s, sp);
- adduint32(s, strlen(value));
+ addaddr(ctxt, s, sp);
+ adduint32(ctxt, s, strlen(value));
if(PtrSize == 8)
- adduint32(s, 0); // round struct to pointer width
+ adduint32(ctxt, s, 0); // round struct to pointer width
// in case reachability has already been computed
sp->reachable = s->reachable;
}
vlong
-addstring(Sym *s, char *str)
+addstring(LSym *s, char *str)
{
int n;
int32 r;
@@ -715,230 +592,18 @@ addstring(Sym *s, char *str)
n = strlen(str)+1;
if(strcmp(s->name, ".shstrtab") == 0)
elfsetstring(str, r);
- symgrow(s, r+n);
+ symgrow(ctxt, s, r+n);
memmove(s->p+r, str, n);
s->size += n;
return r;
}
-vlong
-setuintxx(Sym *s, vlong off, uint64 v, vlong wid)
-{
- int32 i, fl;
- vlong o;
- uchar *cast;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- if(s->size < off+wid) {
- s->size = off+wid;
- symgrow(s, s->size);
- }
- fl = v;
- cast = (uchar*)&fl;
- switch(wid) {
- case 1:
- s->p[off] = cast[inuxi1[0]];
- break;
- case 2:
- for(i=0; i<2; i++)
- s->p[off+i] = cast[inuxi2[i]];
- break;
- case 4:
- for(i=0; i<4; i++)
- s->p[off+i] = cast[inuxi4[i]];
- break;
- case 8:
- o = v;
- cast = (uchar*)&o;
- for(i=0; i<8; i++)
- s->p[off+i] = cast[inuxi8[i]];
- break;
- }
- return off+wid;
-}
-
-vlong
-adduintxx(Sym *s, uint64 v, int wid)
-{
- vlong off;
-
- off = s->size;
- setuintxx(s, off, v, wid);
- return off;
-}
-
-vlong
-adduint8(Sym *s, uint8 v)
-{
- return adduintxx(s, v, 1);
-}
-
-vlong
-adduint16(Sym *s, uint16 v)
-{
- return adduintxx(s, v, 2);
-}
-
-vlong
-adduint32(Sym *s, uint32 v)
-{
- return adduintxx(s, v, 4);
-}
-
-vlong
-adduint64(Sym *s, uint64 v)
-{
- return adduintxx(s, v, 8);
-}
-
-vlong
-setuint8(Sym *s, vlong r, uint8 v)
-{
- return setuintxx(s, r, v, 1);
-}
-
-vlong
-setuint16(Sym *s, vlong r, uint16 v)
-{
- return setuintxx(s, r, v, 2);
-}
-
-vlong
-setuint32(Sym *s, vlong r, uint32 v)
-{
- return setuintxx(s, r, v, 4);
-}
-
-vlong
-setuint64(Sym *s, vlong r, uint64 v)
-{
- return setuintxx(s, r, v, 8);
-}
-
-vlong
-addaddrplus(Sym *s, Sym *t, vlong add)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += PtrSize;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->siz = PtrSize;
- r->type = D_ADDR;
- r->add = add;
- return i + r->siz;
-}
-
-static vlong
-addaddrplus4(Sym *s, Sym *t, vlong add)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += 4;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->siz = 4;
- r->type = D_ADDR;
- r->add = add;
- return i + r->siz;
-}
-
-vlong
-addpcrelplus(Sym *s, Sym *t, vlong add)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += 4;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->add = add;
- r->type = D_PCREL;
- r->siz = 4;
- return i + r->siz;
-}
-
-vlong
-addaddr(Sym *s, Sym *t)
-{
- return addaddrplus(s, t, 0);
-}
-
-vlong
-setaddrplus(Sym *s, vlong off, Sym *t, vlong add)
-{
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- if(off+PtrSize > s->size) {
- s->size = off + PtrSize;
- symgrow(s, s->size);
- }
- r = addrel(s);
- r->sym = t;
- r->off = off;
- r->siz = PtrSize;
- r->type = D_ADDR;
- r->add = add;
- return off + r->siz;
-}
-
-vlong
-setaddr(Sym *s, vlong off, Sym *t)
-{
- return setaddrplus(s, off, t, 0);
-}
-
-vlong
-addsize(Sym *s, Sym *t)
-{
- vlong i;
- Reloc *r;
-
- if(s->type == 0)
- s->type = SDATA;
- s->reachable = 1;
- i = s->size;
- s->size += PtrSize;
- symgrow(s, s->size);
- r = addrel(s);
- r->sym = t;
- r->off = i;
- r->siz = PtrSize;
- r->type = D_SIZE;
- return i + r->siz;
-}
-
void
dosymtype(void)
{
- Sym *s;
+ LSym *s;
- for(s = allsym; s != nil; s = s->allsym) {
+ for(s = ctxt->allsym; s != nil; s = s->allsym) {
if(s->np > 0) {
if(s->type == SBSS)
s->type = SDATA;
@@ -949,7 +614,7 @@ dosymtype(void)
}
static int32
-symalign(Sym *s)
+symalign(LSym *s)
{
int32 align;
@@ -965,7 +630,7 @@ symalign(Sym *s)
}
static vlong
-aligndatsize(vlong datsize, Sym *s)
+aligndatsize(vlong datsize, LSym *s)
{
return rnd(datsize, symalign(s));
}
@@ -973,7 +638,7 @@ aligndatsize(vlong datsize, Sym *s)
// maxalign returns the maximum required alignment for
// the list of symbols s; the list stops when s->type exceeds type.
static int32
-maxalign(Sym *s, int type)
+maxalign(LSym *s, int type)
{
int32 align, max;
@@ -987,10 +652,10 @@ maxalign(Sym *s, int type)
}
static void
-gcaddsym(Sym *gc, Sym *s, vlong off)
+gcaddsym(LSym *gc, LSym *s, vlong off)
{
vlong a;
- Sym *gotype;
+ LSym *gotype;
if(s->size < PtrSize)
return;
@@ -1000,22 +665,22 @@ gcaddsym(Sym *gc, Sym *s, vlong off)
gotype = s->gotype;
if(gotype != nil) {
//print("gcaddsym: %s %d %s\n", s->name, s->size, gotype->name);
- adduintxx(gc, GC_CALL, PtrSize);
- adduintxx(gc, off, PtrSize);
- addpcrelplus(gc, decodetype_gc(gotype), 3*PtrSize+4);
+ adduintxx(ctxt, gc, GC_CALL, PtrSize);
+ adduintxx(ctxt, gc, off, PtrSize);
+ addpcrelplus(ctxt, gc, decodetype_gc(gotype), 3*PtrSize+4);
if(PtrSize == 8)
- adduintxx(gc, 0, 4);
+ adduintxx(ctxt, gc, 0, 4);
} else {
//print("gcaddsym: %s %d <unknown type>\n", s->name, s->size);
for(a = -off&(PtrSize-1); a+PtrSize<=s->size; a+=PtrSize) {
- adduintxx(gc, GC_APTR, PtrSize);
- adduintxx(gc, off+a, PtrSize);
+ adduintxx(ctxt, gc, GC_APTR, PtrSize);
+ adduintxx(ctxt, gc, off+a, PtrSize);
}
}
}
void
-growdatsize(vlong *datsizep, Sym *s)
+growdatsize(vlong *datsizep, LSym *s)
{
vlong datsize;
@@ -1034,24 +699,24 @@ dodata(void)
vlong datsize;
Section *sect;
Segment *segro;
- Sym *s, *last, **l;
- Sym *gcdata1, *gcbss1;
+ LSym *s, *last, **l;
+ LSym *gcdata1, *gcbss1;
if(debug['v'])
Bprint(&bso, "%5.2f dodata\n", cputime());
Bflush(&bso);
- gcdata1 = lookup("gcdata", 0);
- gcbss1 = lookup("gcbss", 0);
+ gcdata1 = linklookup(ctxt, "gcdata", 0);
+ gcbss1 = linklookup(ctxt, "gcbss", 0);
// size of .data and .bss section. the zero value is later replaced by the actual size of the section.
- adduintxx(gcdata1, 0, PtrSize);
- adduintxx(gcbss1, 0, PtrSize);
+ adduintxx(ctxt, gcdata1, 0, PtrSize);
+ adduintxx(ctxt, gcbss1, 0, PtrSize);
last = nil;
datap = nil;
- for(s=allsym; s!=S; s=s->allsym) {
+ for(s=ctxt->allsym; s!=S; s=s->allsym) {
if(!s->reachable || s->special)
continue;
if(STEXT < s->type && s->type < SXREF) {
@@ -1092,7 +757,7 @@ dodata(void)
}
*l = nil;
- datap = listsort(datap, datcmp, offsetof(Sym, next));
+ datap = listsort(datap, datcmp, offsetof(LSym, next));
/*
* allocate sections. list is sorted by type,
@@ -1128,8 +793,8 @@ dodata(void)
sect->align = maxalign(s, SINITARR-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("noptrdata", 0)->sect = sect;
- lookup("enoptrdata", 0)->sect = sect;
+ linklookup(ctxt, "noptrdata", 0)->sect = sect;
+ linklookup(ctxt, "enoptrdata", 0)->sect = sect;
for(; s != nil && s->type < SINITARR; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1159,11 +824,11 @@ dodata(void)
sect->align = maxalign(s, SBSS-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("data", 0)->sect = sect;
- lookup("edata", 0)->sect = sect;
+ linklookup(ctxt, "data", 0)->sect = sect;
+ linklookup(ctxt, "edata", 0)->sect = sect;
for(; s != nil && s->type < SBSS; s = s->next) {
if(s->type == SINITARR) {
- cursym = s;
+ ctxt->cursym = s;
diag("unexpected symbol type %d", s->type);
}
s->sect = sect;
@@ -1175,16 +840,16 @@ dodata(void)
}
sect->len = datsize - sect->vaddr;
- adduintxx(gcdata1, GC_END, PtrSize);
- setuintxx(gcdata1, 0, sect->len, PtrSize);
+ adduintxx(ctxt, gcdata1, GC_END, PtrSize);
+ setuintxx(ctxt, gcdata1, 0, sect->len, PtrSize);
/* bss */
sect = addsection(&segdata, ".bss", 06);
sect->align = maxalign(s, SNOPTRBSS-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("bss", 0)->sect = sect;
- lookup("ebss", 0)->sect = sect;
+ linklookup(ctxt, "bss", 0)->sect = sect;
+ linklookup(ctxt, "ebss", 0)->sect = sect;
for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
s->sect = sect;
datsize = aligndatsize(datsize, s);
@@ -1194,16 +859,16 @@ dodata(void)
}
sect->len = datsize - sect->vaddr;
- adduintxx(gcbss1, GC_END, PtrSize);
- setuintxx(gcbss1, 0, sect->len, PtrSize);
+ adduintxx(ctxt, gcbss1, GC_END, PtrSize);
+ setuintxx(ctxt, gcbss1, 0, sect->len, PtrSize);
/* pointer-free bss */
sect = addsection(&segdata, ".noptrbss", 06);
sect->align = maxalign(s, SNOPTRBSS);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("noptrbss", 0)->sect = sect;
- lookup("enoptrbss", 0)->sect = sect;
+ linklookup(ctxt, "noptrbss", 0)->sect = sect;
+ linklookup(ctxt, "enoptrbss", 0)->sect = sect;
for(; s != nil && s->type == SNOPTRBSS; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1211,7 +876,7 @@ dodata(void)
growdatsize(&datsize, s);
}
sect->len = datsize - sect->vaddr;
- lookup("end", 0)->sect = sect;
+ linklookup(ctxt, "end", 0)->sect = sect;
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
if(datsize != (uint32)datsize) {
@@ -1233,7 +898,7 @@ dodata(void)
}
if(s != nil) {
- cursym = nil;
+ ctxt->cursym = nil;
diag("unexpected symbol type %d for %s", s->type, s->name);
}
@@ -1274,8 +939,8 @@ dodata(void)
sect->align = maxalign(s, STYPELINK-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = 0;
- lookup("rodata", 0)->sect = sect;
- lookup("erodata", 0)->sect = sect;
+ linklookup(ctxt, "rodata", 0)->sect = sect;
+ linklookup(ctxt, "erodata", 0)->sect = sect;
for(; s != nil && s->type < STYPELINK; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1290,8 +955,8 @@ dodata(void)
sect->align = maxalign(s, STYPELINK);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("typelink", 0)->sect = sect;
- lookup("etypelink", 0)->sect = sect;
+ linklookup(ctxt, "typelink", 0)->sect = sect;
+ linklookup(ctxt, "etypelink", 0)->sect = sect;
for(; s != nil && s->type == STYPELINK; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1306,8 +971,8 @@ dodata(void)
sect->align = maxalign(s, SPCLNTAB-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("symtab", 0)->sect = sect;
- lookup("esymtab", 0)->sect = sect;
+ linklookup(ctxt, "symtab", 0)->sect = sect;
+ linklookup(ctxt, "esymtab", 0)->sect = sect;
for(; s != nil && s->type < SPCLNTAB; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1322,8 +987,8 @@ dodata(void)
sect->align = maxalign(s, SELFROSECT-1);
datsize = rnd(datsize, sect->align);
sect->vaddr = datsize;
- lookup("pclntab", 0)->sect = sect;
- lookup("epclntab", 0)->sect = sect;
+ linklookup(ctxt, "pclntab", 0)->sect = sect;
+ linklookup(ctxt, "epclntab", 0)->sect = sect;
for(; s != nil && s->type < SELFROSECT; s = s->next) {
datsize = aligndatsize(datsize, s);
s->sect = sect;
@@ -1368,7 +1033,7 @@ textaddress(void)
uvlong va;
Prog *p;
Section *sect;
- Sym *sym, *sub;
+ LSym *sym, *sub;
addsection(&segtext, ".text", 05);
@@ -1377,11 +1042,11 @@ textaddress(void)
// and then letting threads copy down, but probably not worth it.
sect = segtext.sect;
sect->align = FuncAlign;
- lookup("text", 0)->sect = sect;
- lookup("etext", 0)->sect = sect;
+ linklookup(ctxt, "text", 0)->sect = sect;
+ linklookup(ctxt, "etext", 0)->sect = sect;
va = INITTEXT;
sect->vaddr = va;
- for(sym = textp; sym != nil; sym = sym->next) {
+ for(sym = ctxt->textp; sym != nil; sym = sym->next) {
sym->sect = sect;
if(sym->type & SSUB)
continue;
@@ -1396,7 +1061,7 @@ textaddress(void)
p->pc += sub->value;
}
if(sym->size == 0 && sym->sub != S) {
- cursym = sym;
+ ctxt->cursym = sym;
}
va += sym->size;
}
@@ -1409,7 +1074,7 @@ address(void)
{
Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
Section *typelink;
- Sym *sym, *sub;
+ LSym *sym, *sub;
uvlong va;
vlong vlen;
@@ -1451,7 +1116,7 @@ address(void)
segdata.filelen = 0;
if(HEADTYPE == Hwindows)
segdata.fileoff = segtext.fileoff + rnd(segtext.len, PEFILEALIGN);
- if(HEADTYPE == Hplan9x64 || HEADTYPE == Hplan9x32)
+ if(HEADTYPE == Hplan9)
segdata.fileoff = segtext.fileoff + segtext.filelen;
data = nil;
noptr = nil;
@@ -1485,7 +1150,7 @@ address(void)
pclntab = symtab->next;
for(sym = datap; sym != nil; sym = sym->next) {
- cursym = sym;
+ ctxt->cursym = sym;
sym->value += sym->sect->vaddr;
for(sub = sym->sub; sub != nil; sub = sub->sub)
sub->value += sym->value;
@@ -1498,13 +1163,13 @@ address(void)
xdefine("typelink", SRODATA, typelink->vaddr);
xdefine("etypelink", SRODATA, typelink->vaddr + typelink->len);
- sym = lookup("gcdata", 0);
+ sym = linklookup(ctxt, "gcdata", 0);
xdefine("egcdata", SRODATA, symaddr(sym) + sym->size);
- lookup("egcdata", 0)->sect = sym->sect;
+ linklookup(ctxt, "egcdata", 0)->sect = sym->sect;
- sym = lookup("gcbss", 0);
+ sym = linklookup(ctxt, "gcbss", 0);
xdefine("egcbss", SRODATA, symaddr(sym) + sym->size);
- lookup("egcbss", 0)->sect = sym->sect;
+ linklookup(ctxt, "egcbss", 0)->sect = sym->sect;
xdefine("symtab", SRODATA, symtab->vaddr);
xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
diff --git a/src/cmd/ld/decodesym.c b/src/cmd/ld/decodesym.c
index ab3f4fbd55..3859d1c6d8 100644
--- a/src/cmd/ld/decodesym.c
+++ b/src/cmd/ld/decodesym.c
@@ -11,7 +11,7 @@
// ../gc/reflect.c stuffs in these.
static Reloc*
-decode_reloc(Sym *s, int32 off)
+decode_reloc(LSym *s, int32 off)
{
int i;
@@ -21,8 +21,8 @@ decode_reloc(Sym *s, int32 off)
return nil;
}
-static Sym*
-decode_reloc_sym(Sym *s, int32 off)
+static LSym*
+decode_reloc_sym(LSym *s, int32 off)
{
Reloc *r;
@@ -69,86 +69,86 @@ decode_inuxi(uchar* p, int sz)
// Type.commonType.kind
uint8
-decodetype_kind(Sym *s)
+decodetype_kind(LSym *s)
{
return s->p[1*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
}
// Type.commonType.size
vlong
-decodetype_size(Sym *s)
+decodetype_size(LSym *s)
{
return decode_inuxi(s->p, PtrSize); // 0x8 / 0x10
}
// Type.commonType.gc
-Sym*
-decodetype_gc(Sym *s)
+LSym*
+decodetype_gc(LSym *s)
{
return decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize);
}
// Type.ArrayType.elem and Type.SliceType.Elem
-Sym*
-decodetype_arrayelem(Sym *s)
+LSym*
+decodetype_arrayelem(LSym *s)
{
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
}
vlong
-decodetype_arraylen(Sym *s)
+decodetype_arraylen(LSym *s)
{
return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
}
// Type.PtrType.elem
-Sym*
-decodetype_ptrelem(Sym *s)
+LSym*
+decodetype_ptrelem(LSym *s)
{
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
}
// Type.MapType.key, elem
-Sym*
-decodetype_mapkey(Sym *s)
+LSym*
+decodetype_mapkey(LSym *s)
{
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
}
-Sym*
-decodetype_mapvalue(Sym *s)
+LSym*
+decodetype_mapvalue(LSym *s)
{
return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
}
// Type.ChanType.elem
-Sym*
-decodetype_chanelem(Sym *s)
+LSym*
+decodetype_chanelem(LSym *s)
{
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
}
// Type.FuncType.dotdotdot
int
-decodetype_funcdotdotdot(Sym *s)
+decodetype_funcdotdotdot(LSym *s)
{
return s->p[CommonSize];
}
// Type.FuncType.in.len
int
-decodetype_funcincount(Sym *s)
+decodetype_funcincount(LSym *s)
{
return decode_inuxi(s->p + CommonSize+2*PtrSize, IntSize);
}
int
-decodetype_funcoutcount(Sym *s)
+decodetype_funcoutcount(LSym *s)
{
return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*IntSize, IntSize);
}
-Sym*
-decodetype_funcintype(Sym *s, int i)
+LSym*
+decodetype_funcintype(LSym *s, int i)
{
Reloc *r;
@@ -158,8 +158,8 @@ decodetype_funcintype(Sym *s, int i)
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
}
-Sym*
-decodetype_funcouttype(Sym *s, int i)
+LSym*
+decodetype_funcouttype(LSym *s, int i)
{
Reloc *r;
@@ -171,7 +171,7 @@ decodetype_funcouttype(Sym *s, int i)
// Type.StructType.fields.Slice::len
int
-decodetype_structfieldcount(Sym *s)
+decodetype_structfieldcount(LSym *s)
{
return decode_inuxi(s->p + CommonSize + PtrSize, IntSize);
}
@@ -181,7 +181,7 @@ enum {
};
// Type.StructType.fields[]-> name, typ and offset.
char*
-decodetype_structfieldname(Sym *s, int i)
+decodetype_structfieldname(LSym *s, int i)
{
Reloc *r;
@@ -195,21 +195,21 @@ decodetype_structfieldname(Sym *s, int i)
return (char*) r->sym->p + r->add; // the c-string
}
-Sym*
-decodetype_structfieldtype(Sym *s, int i)
+LSym*
+decodetype_structfieldtype(LSym *s, int i)
{
return decode_reloc_sym(s, CommonSize + PtrSize + 2*IntSize + i*StructFieldSize + 2*PtrSize);
}
vlong
-decodetype_structfieldoffs(Sym *s, int i)
+decodetype_structfieldoffs(LSym *s, int i)
{
return decode_inuxi(s->p + CommonSize + PtrSize + 2*IntSize + i*StructFieldSize + 4*PtrSize, IntSize);
}
// InterfaceTYpe.methods.len
vlong
-decodetype_ifacemethodcount(Sym *s)
+decodetype_ifacemethodcount(LSym *s)
{
return decode_inuxi(s->p + CommonSize + PtrSize, IntSize);
}
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index c832bcc944..8170abe335 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -27,19 +27,19 @@
static vlong abbrevo;
static vlong abbrevsize;
-static Sym* abbrevsym;
+static LSym* abbrevsym;
static vlong abbrevsympos;
static vlong lineo;
static vlong linesize;
-static Sym* linesym;
+static LSym* linesym;
static vlong linesympos;
static vlong infoo; // also the base for DWDie->offs and reference attributes.
static vlong infosize;
-static Sym* infosym;
+static LSym* infosym;
static vlong infosympos;
static vlong frameo;
static vlong framesize;
-static Sym* framesym;
+static LSym* framesym;
static vlong framesympos;
static vlong pubnameso;
static vlong pubnamessize;
@@ -50,19 +50,19 @@ static vlong arangessize;
static vlong gdbscripto;
static vlong gdbscriptsize;
-static Sym *infosec;
+static LSym *infosec;
static vlong inforeloco;
static vlong inforelocsize;
-static Sym *arangessec;
+static LSym *arangessec;
static vlong arangesreloco;
static vlong arangesrelocsize;
-static Sym *linesec;
+static LSym *linesec;
static vlong linereloco;
static vlong linerelocsize;
-static Sym *framesec;
+static LSym *framesec;
static vlong framereloco;
static vlong framerelocsize;
@@ -594,7 +594,7 @@ find_or_diag(DWDie *die, char* name)
}
static void
-adddwarfrel(Sym* sec, Sym* sym, vlong offsetbase, int siz, vlong addend)
+adddwarfrel(LSym* sec, LSym* sym, vlong offsetbase, int siz, vlong addend)
{
Reloc *r;
@@ -639,8 +639,8 @@ putattr(int abbrev, int form, int cls, vlong value, char *data)
switch(form) {
case DW_FORM_addr: // address
if(linkmode == LinkExternal) {
- value -= ((Sym*)data)->value;
- adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
+ value -= ((LSym*)data)->value;
+ adddwarfrel(infosec, (LSym*)data, infoo, PtrSize, value);
break;
}
addrput(value);
@@ -651,8 +651,8 @@ putattr(int abbrev, int form, int cls, vlong value, char *data)
cput(1+PtrSize);
cput(DW_OP_addr);
if(linkmode == LinkExternal) {
- value -= ((Sym*)data)->value;
- adddwarfrel(infosec, (Sym*)data, infoo, PtrSize, value);
+ value -= ((LSym*)data)->value;
+ adddwarfrel(infosec, (LSym*)data, infoo, PtrSize, value);
break;
}
addrput(value);
@@ -847,7 +847,7 @@ newmemberoffsetattr(DWDie *die, int32 offs)
// GDB doesn't like DW_FORM_addr for DW_AT_location, so emit a
// location expression that evals to a const.
static void
-newabslocexprattr(DWDie *die, vlong addr, Sym *sym)
+newabslocexprattr(DWDie *die, vlong addr, LSym *sym)
{
newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
}
@@ -864,12 +864,12 @@ enum {
static DWDie* defptrto(DWDie *dwtype); // below
// Lookup predefined types
-static Sym*
+static LSym*
lookup_or_diag(char *n)
{
- Sym *s;
+ LSym *s;
- s = rlookup(n, 0);
+ s = linkrlookup(ctxt, n, 0);
if (s == nil || s->size == 0) {
diag("dwarf: missing type: %s", n);
errorexit();
@@ -904,10 +904,10 @@ dotypedef(DWDie *parent, char *name, DWDie *def)
// Define gotype, for composite ones recurse into constituents.
static DWDie*
-defgotype(Sym *gotype)
+defgotype(LSym *gotype)
{
DWDie *die, *fld;
- Sym *s;
+ LSym *s;
char *name, *f;
uint8 kind;
vlong bytesize;
@@ -1335,7 +1335,7 @@ synthesizechantypes(DWDie *die)
// For use with pass.c::genasmsym
static void
-defdwsymb(Sym* sym, char *s, int t, vlong v, vlong size, int ver, Sym *gotype)
+defdwsymb(LSym* sym, char *s, int t, vlong v, vlong size, int ver, LSym *gotype)
{
DWDie *dv, *dt;
@@ -1607,7 +1607,7 @@ inithist(Auto *a)
absline = a->aoffset;
} else if (a->type == D_FILE1) { // 'Z'
// We could just fixup the current
- // linehist->line, but there doesn't appear to
+ // linehist->lineno, but there doesn't appear to
// be a guarantee that every 'Z' is preceded
// by its own 'z', so do the safe thing and
// update the stack and push a new Linehist
@@ -1719,7 +1719,7 @@ mkvarname(char* name, int da)
// flush previous compilation unit.
static void
-flushunit(DWDie *dwinfo, vlong pc, Sym *pcsym, vlong unitstart, int32 header_length)
+flushunit(DWDie *dwinfo, vlong pc, LSym *pcsym, vlong unitstart, int32 header_length)
{
vlong here;
@@ -1745,7 +1745,7 @@ static void
writelines(void)
{
Prog *q;
- Sym *s, *epcs;
+ LSym *s, *epcs;
Auto *a;
vlong unitstart, headerend, offs;
vlong pc, epc, lc, llc, lline;
@@ -1757,7 +1757,7 @@ writelines(void)
char *n, *nn;
if(linesec == S)
- linesec = lookup(".dwarfline", 0);
+ linesec = linklookup(ctxt, ".dwarfline", 0);
linesec->nr = 0;
unitstart = -1;
@@ -1771,8 +1771,8 @@ writelines(void)
lineo = cpos();
dwinfo = nil;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- s = cursym;
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
+ s = ctxt->cursym;
if(s->text == P)
continue;
@@ -1859,7 +1859,7 @@ writelines(void)
continue;
for(q = s->text; q != P; q = q->link) {
- lh = searchhist(q->line);
+ lh = searchhist(q->lineno);
if (lh == nil) {
diag("dwarf: corrupt history or bad absolute line: %P", q);
continue;
@@ -1870,11 +1870,11 @@ writelines(void)
continue;
}
- lline = lh->line + q->line - lh->absline;
+ lline = lh->line + q->lineno - lh->absline;
if (debug['v'] > 1)
print("%6llux %s[%lld] %P\n", (vlong)q->pc, histfile[lh->file], lline, q);
- if (q->line == lc)
+ if (q->lineno == lc)
continue;
if (currfile != lh->file) {
currfile = lh->file;
@@ -1883,7 +1883,7 @@ writelines(void)
}
putpclcdelta(q->pc - pc, lline - llc);
pc = q->pc;
- lc = q->line;
+ lc = q->lineno;
llc = lline;
}
@@ -1971,11 +1971,11 @@ static void
writeframes(void)
{
Prog *p, *q;
- Sym *s;
+ LSym *s;
vlong fdeo, fdesize, pad, cfa, pc;
if(framesec == S)
- framesec = lookup(".dwarfframe", 0);
+ framesec = linklookup(ctxt, ".dwarfframe", 0);
framesec->nr = 0;
frameo = cpos();
@@ -2003,8 +2003,8 @@ writeframes(void)
}
strnput("", pad);
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- s = cursym;
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next) {
+ s = ctxt->cursym;
if(s->text == nil)
continue;
@@ -2067,11 +2067,11 @@ writeinfo(void)
fwdcount = 0;
if (infosec == S)
- infosec = lookup(".dwarfinfo", 0);
+ infosec = linklookup(ctxt, ".dwarfinfo", 0);
infosec->nr = 0;
if(arangessec == S)
- arangessec = lookup(".dwarfaranges", 0);
+ arangessec = linklookup(ctxt, ".dwarfaranges", 0);
arangessec->nr = 0;
for (compunit = dwroot.child; compunit; compunit = compunit->link) {
@@ -2204,7 +2204,7 @@ writearanges(void)
strnput("", headersize - (4+2+4+1+1)); // align to PtrSize
if(linkmode == LinkExternal)
- adddwarfrel(arangessec, (Sym*)b->data, sectionstart, PtrSize, b->value-((Sym*)b->data)->value);
+ adddwarfrel(arangessec, (LSym*)b->data, sectionstart, PtrSize, b->value-((LSym*)b->data)->value);
else
addrput(b->value);
@@ -2239,7 +2239,7 @@ align(vlong size)
}
static vlong
-writedwarfreloc(Sym* s)
+writedwarfreloc(LSym* s)
{
int i;
vlong start;
@@ -2408,7 +2408,7 @@ enum
vlong elfstrdbg[NElfStrDbg];
void
-dwarfaddshstrings(Sym *shstrtab)
+dwarfaddshstrings(LSym *shstrtab)
{
if(debug['w']) // disable dwarf
return;
@@ -2438,16 +2438,16 @@ dwarfaddshstrings(Sym *shstrtab)
elfstrdbg[ElfStrRelDebugFrame] = addstring(shstrtab, ".rel.debug_frame");
}
- infosym = lookup(".debug_info", 0);
+ infosym = linklookup(ctxt, ".debug_info", 0);
infosym->hide = 1;
- abbrevsym = lookup(".debug_abbrev", 0);
+ abbrevsym = linklookup(ctxt, ".debug_abbrev", 0);
abbrevsym->hide = 1;
- linesym = lookup(".debug_line", 0);
+ linesym = linklookup(ctxt, ".debug_line", 0);
linesym->hide = 1;
- framesym = lookup(".debug_frame", 0);
+ framesym = linklookup(ctxt, ".debug_frame", 0);
framesym->hide = 1;
}
}
diff --git a/src/cmd/ld/dwarf.h b/src/cmd/ld/dwarf.h
index f0df2f9b1e..7952a74369 100644
--- a/src/cmd/ld/dwarf.h
+++ b/src/cmd/ld/dwarf.h
@@ -19,7 +19,7 @@ void dwarfemitdebugsections(void);
* s[ection]h[eader]str[ing]tab. Prerequisite for
* dwarfaddelfheaders().
*/
-void dwarfaddshstrings(Sym *shstrtab);
+void dwarfaddshstrings(LSym *shstrtab);
/*
* Add section headers pointing to the sections emitted in
diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c
index 6b3638ec56..8c7ca86097 100644
--- a/src/cmd/ld/elf.c
+++ b/src/cmd/ld/elf.c
@@ -287,35 +287,35 @@ elfhash(uchar *name)
}
void
-elfwritedynent(Sym *s, int tag, uint64 val)
+elfwritedynent(LSym *s, int tag, uint64 val)
{
if(elf64) {
- adduint64(s, tag);
- adduint64(s, val);
+ adduint64(ctxt, s, tag);
+ adduint64(ctxt, s, val);
} else {
- adduint32(s, tag);
- adduint32(s, val);
+ adduint32(ctxt, s, tag);
+ adduint32(ctxt, s, val);
}
}
void
-elfwritedynentsym(Sym *s, int tag, Sym *t)
+elfwritedynentsym(LSym *s, int tag, LSym *t)
{
if(elf64)
- adduint64(s, tag);
+ adduint64(ctxt, s, tag);
else
- adduint32(s, tag);
- addaddr(s, t);
+ adduint32(ctxt, s, tag);
+ addaddr(ctxt, s, t);
}
void
-elfwritedynentsymsize(Sym *s, int tag, Sym *t)
+elfwritedynentsymsize(LSym *s, int tag, LSym *t)
{
if(elf64)
- adduint64(s, tag);
+ adduint64(ctxt, s, tag);
else
- adduint32(s, tag);
- addsize(s, t);
+ adduint32(ctxt, s, tag);
+ addsize(ctxt, s, t);
}
int
@@ -561,7 +561,7 @@ haveaux:
void
elfdynhash(void)
{
- Sym *s, *sy, *dynstr;
+ LSym *s, *sy, *dynstr;
int i, j, nbucket, b, nfile;
uint32 hc, *chain, *buckets;
int nsym;
@@ -575,7 +575,7 @@ elfdynhash(void)
return;
nsym = nelfsym;
- s = lookup(".hash", 0);
+ s = linklookup(ctxt, ".hash", 0);
s->type = SELFROSECT;
s->reachable = 1;
@@ -591,14 +591,14 @@ elfdynhash(void)
chain = malloc(nsym * sizeof chain[0]);
buckets = malloc(nbucket * sizeof buckets[0]);
if(need == nil || chain == nil || buckets == nil) {
- cursym = nil;
+ ctxt->cursym = nil;
diag("out of memory");
errorexit();
}
memset(need, 0, nsym * sizeof need[0]);
memset(chain, 0, nsym * sizeof chain[0]);
memset(buckets, 0, nbucket * sizeof buckets[0]);
- for(sy=allsym; sy!=S; sy=sy->allsym) {
+ for(sy=ctxt->allsym; sy!=S; sy=sy->allsym) {
if (sy->dynid <= 0)
continue;
@@ -613,69 +613,69 @@ elfdynhash(void)
buckets[b] = sy->dynid;
}
- adduint32(s, nbucket);
- adduint32(s, nsym);
+ adduint32(ctxt, s, nbucket);
+ adduint32(ctxt, s, nsym);
for(i = 0; i<nbucket; i++)
- adduint32(s, buckets[i]);
+ adduint32(ctxt, s, buckets[i]);
for(i = 0; i<nsym; i++)
- adduint32(s, chain[i]);
+ adduint32(ctxt, s, chain[i]);
free(chain);
free(buckets);
// version symbols
- dynstr = lookup(".dynstr", 0);
- s = lookup(".gnu.version_r", 0);
+ dynstr = linklookup(ctxt, ".dynstr", 0);
+ s = linklookup(ctxt, ".gnu.version_r", 0);
i = 2;
nfile = 0;
for(l=needlib; l; l=l->next) {
nfile++;
// header
- adduint16(s, 1); // table version
+ adduint16(ctxt, s, 1); // table version
j = 0;
for(x=l->aux; x; x=x->next)
j++;
- adduint16(s, j); // aux count
- adduint32(s, addstring(dynstr, l->file)); // file string offset
- adduint32(s, 16); // offset from header to first aux
+ adduint16(ctxt, s, j); // aux count
+ adduint32(ctxt, s, addstring(dynstr, l->file)); // file string offset
+ adduint32(ctxt, s, 16); // offset from header to first aux
if(l->next)
- adduint32(s, 16+j*16); // offset from this header to next
+ adduint32(ctxt, s, 16+j*16); // offset from this header to next
else
- adduint32(s, 0);
+ adduint32(ctxt, s, 0);
for(x=l->aux; x; x=x->next) {
x->num = i++;
// aux struct
- adduint32(s, elfhash((uchar*)x->vers)); // hash
- adduint16(s, 0); // flags
- adduint16(s, x->num); // other - index we refer to this by
- adduint32(s, addstring(dynstr, x->vers)); // version string offset
+ adduint32(ctxt, s, elfhash((uchar*)x->vers)); // hash
+ adduint16(ctxt, s, 0); // flags
+ adduint16(ctxt, s, x->num); // other - index we refer to this by
+ adduint32(ctxt, s, addstring(dynstr, x->vers)); // version string offset
if(x->next)
- adduint32(s, 16); // offset from this aux to next
+ adduint32(ctxt, s, 16); // offset from this aux to next
else
- adduint32(s, 0);
+ adduint32(ctxt, s, 0);
}
}
// version references
- s = lookup(".gnu.version", 0);
+ s = linklookup(ctxt, ".gnu.version", 0);
for(i=0; i<nsym; i++) {
if(i == 0)
- adduint16(s, 0); // first entry - no symbol
+ adduint16(ctxt, s, 0); // first entry - no symbol
else if(need[i] == nil)
- adduint16(s, 1); // global
+ adduint16(ctxt, s, 1); // global
else
- adduint16(s, need[i]->num);
+ adduint16(ctxt, s, need[i]->num);
}
free(need);
- s = lookup(".dynamic", 0);
+ s = linklookup(ctxt, ".dynamic", 0);
elfverneed = nfile;
if(elfverneed) {
- elfwritedynentsym(s, DT_VERNEED, lookup(".gnu.version_r", 0));
+ elfwritedynentsym(s, DT_VERNEED, linklookup(ctxt, ".gnu.version_r", 0));
elfwritedynent(s, DT_VERNEEDNUM, nfile);
- elfwritedynentsym(s, DT_VERSYM, lookup(".gnu.version", 0));
+ elfwritedynentsym(s, DT_VERSYM, linklookup(ctxt, ".gnu.version", 0));
}
elfwritedynent(s, DT_NULL, 0);
}
@@ -807,9 +807,9 @@ elfshreloc(Section *sect)
}
void
-elfrelocsect(Section *sect, Sym *first)
+elfrelocsect(Section *sect, LSym *first)
{
- Sym *sym;
+ LSym *sym;
int32 eaddr;
Reloc *r;
@@ -834,7 +834,7 @@ elfrelocsect(Section *sect, Sym *first)
continue;
if(sym->value >= eaddr)
break;
- cursym = sym;
+ ctxt->cursym = sym;
for(r = sym->r; r < sym->r+sym->nr; r++) {
if(r->done)
@@ -861,7 +861,7 @@ elfemitreloc(void)
while(cpos()&7)
cput(0);
- elfrelocsect(segtext.sect, textp);
+ elfrelocsect(segtext.sect, ctxt->textp);
for(sect=segtext.sect->next; sect!=nil; sect=sect->next)
elfrelocsect(sect, datap);
for(sect=segrodata.sect; sect!=nil; sect=sect->next)
@@ -873,13 +873,13 @@ elfemitreloc(void)
void
doelf(void)
{
- Sym *s, *shstrtab, *dynstr;
+ LSym *s, *shstrtab, *dynstr;
if(!iself)
return;
/* predefine strings we need for section headers */
- shstrtab = lookup(".shstrtab", 0);
+ shstrtab = linklookup(ctxt, ".shstrtab", 0);
shstrtab->type = SELFROSECT;
shstrtab->reachable = 1;
@@ -969,7 +969,7 @@ doelf(void)
addstring(shstrtab, ".gnu.version_r");
/* dynamic symbol table - first entry all zeros */
- s = lookup(".dynsym", 0);
+ s = linklookup(ctxt, ".dynsym", 0);
s->type = SELFROSECT;
s->reachable = 1;
if(thechar == '6')
@@ -978,7 +978,7 @@ doelf(void)
s->size += ELF32SYMSIZE;
/* dynamic string table */
- s = lookup(".dynstr", 0);
+ s = linklookup(ctxt, ".dynstr", 0);
s->type = SELFROSECT;
s->reachable = 1;
if(s->size == 0)
@@ -987,85 +987,85 @@ doelf(void)
/* relocation table */
if(thechar == '6')
- s = lookup(".rela", 0);
+ s = linklookup(ctxt, ".rela", 0);
else
- s = lookup(".rel", 0);
+ s = linklookup(ctxt, ".rel", 0);
s->reachable = 1;
s->type = SELFROSECT;
/* global offset table */
- s = lookup(".got", 0);
+ s = linklookup(ctxt, ".got", 0);
s->reachable = 1;
s->type = SELFSECT; // writable
/* hash */
- s = lookup(".hash", 0);
+ s = linklookup(ctxt, ".hash", 0);
s->reachable = 1;
s->type = SELFROSECT;
- s = lookup(".got.plt", 0);
+ s = linklookup(ctxt, ".got.plt", 0);
s->reachable = 1;
s->type = SELFSECT; // writable
- s = lookup(".plt", 0);
+ s = linklookup(ctxt, ".plt", 0);
s->reachable = 1;
s->type = SELFRXSECT;
elfsetupplt();
if(thechar == '6')
- s = lookup(".rela.plt", 0);
+ s = linklookup(ctxt, ".rela.plt", 0);
else
- s = lookup(".rel.plt", 0);
+ s = linklookup(ctxt, ".rel.plt", 0);
s->reachable = 1;
s->type = SELFROSECT;
- s = lookup(".gnu.version", 0);
+ s = linklookup(ctxt, ".gnu.version", 0);
s->reachable = 1;
s->type = SELFROSECT;
- s = lookup(".gnu.version_r", 0);
+ s = linklookup(ctxt, ".gnu.version_r", 0);
s->reachable = 1;
s->type = SELFROSECT;
/* define dynamic elf table */
- s = lookup(".dynamic", 0);
+ s = linklookup(ctxt, ".dynamic", 0);
s->reachable = 1;
s->type = SELFSECT; // writable
/*
* .dynamic table
*/
- elfwritedynentsym(s, DT_HASH, lookup(".hash", 0));
- elfwritedynentsym(s, DT_SYMTAB, lookup(".dynsym", 0));
+ elfwritedynentsym(s, DT_HASH, linklookup(ctxt, ".hash", 0));
+ elfwritedynentsym(s, DT_SYMTAB, linklookup(ctxt, ".dynsym", 0));
if(thechar == '6')
elfwritedynent(s, DT_SYMENT, ELF64SYMSIZE);
else
elfwritedynent(s, DT_SYMENT, ELF32SYMSIZE);
- elfwritedynentsym(s, DT_STRTAB, lookup(".dynstr", 0));
- elfwritedynentsymsize(s, DT_STRSZ, lookup(".dynstr", 0));
+ elfwritedynentsym(s, DT_STRTAB, linklookup(ctxt, ".dynstr", 0));
+ elfwritedynentsymsize(s, DT_STRSZ, linklookup(ctxt, ".dynstr", 0));
if(thechar == '6') {
- elfwritedynentsym(s, DT_RELA, lookup(".rela", 0));
- elfwritedynentsymsize(s, DT_RELASZ, lookup(".rela", 0));
+ elfwritedynentsym(s, DT_RELA, linklookup(ctxt, ".rela", 0));
+ elfwritedynentsymsize(s, DT_RELASZ, linklookup(ctxt, ".rela", 0));
elfwritedynent(s, DT_RELAENT, ELF64RELASIZE);
} else {
- elfwritedynentsym(s, DT_REL, lookup(".rel", 0));
- elfwritedynentsymsize(s, DT_RELSZ, lookup(".rel", 0));
+ elfwritedynentsym(s, DT_REL, linklookup(ctxt, ".rel", 0));
+ elfwritedynentsymsize(s, DT_RELSZ, linklookup(ctxt, ".rel", 0));
elfwritedynent(s, DT_RELENT, ELF32RELSIZE);
}
if(rpath)
elfwritedynent(s, DT_RUNPATH, addstring(dynstr, rpath));
- elfwritedynentsym(s, DT_PLTGOT, lookup(".got.plt", 0));
+ elfwritedynentsym(s, DT_PLTGOT, linklookup(ctxt, ".got.plt", 0));
if(thechar == '6') {
elfwritedynent(s, DT_PLTREL, DT_RELA);
- elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rela.plt", 0));
- elfwritedynentsym(s, DT_JMPREL, lookup(".rela.plt", 0));
+ elfwritedynentsymsize(s, DT_PLTRELSZ, linklookup(ctxt, ".rela.plt", 0));
+ elfwritedynentsym(s, DT_JMPREL, linklookup(ctxt, ".rela.plt", 0));
} else {
elfwritedynent(s, DT_PLTREL, DT_REL);
- elfwritedynentsymsize(s, DT_PLTRELSZ, lookup(".rel.plt", 0));
- elfwritedynentsym(s, DT_JMPREL, lookup(".rel.plt", 0));
+ elfwritedynentsymsize(s, DT_PLTRELSZ, linklookup(ctxt, ".rel.plt", 0));
+ elfwritedynentsym(s, DT_JMPREL, linklookup(ctxt, ".rel.plt", 0));
}
elfwritedynent(s, DT_DEBUG, 0);
@@ -1075,7 +1075,7 @@ doelf(void)
}
void
-shsym(ElfShdr *sh, Sym *s)
+shsym(ElfShdr *sh, LSym *s)
{
vlong addr;
addr = symaddr(s);
@@ -1254,13 +1254,13 @@ asmbelf(vlong symo)
sh->addralign = PtrSize;
sh->link = elfshname(".dynstr")->shnum;
// sh->info = index of first non-local symbol (number of local symbols)
- shsym(sh, lookup(".dynsym", 0));
+ shsym(sh, linklookup(ctxt, ".dynsym", 0));
sh = elfshname(".dynstr");
sh->type = SHT_STRTAB;
sh->flags = SHF_ALLOC;
sh->addralign = 1;
- shsym(sh, lookup(".dynstr", 0));
+ shsym(sh, linklookup(ctxt, ".dynstr", 0));
if(elfverneed) {
sh = elfshname(".gnu.version");
@@ -1269,7 +1269,7 @@ asmbelf(vlong symo)
sh->addralign = 2;
sh->link = elfshname(".dynsym")->shnum;
sh->entsize = 2;
- shsym(sh, lookup(".gnu.version", 0));
+ shsym(sh, linklookup(ctxt, ".gnu.version", 0));
sh = elfshname(".gnu.version_r");
sh->type = SHT_GNU_VERNEED;
@@ -1277,7 +1277,7 @@ asmbelf(vlong symo)
sh->addralign = PtrSize;
sh->info = elfverneed;
sh->link = elfshname(".dynstr")->shnum;
- shsym(sh, lookup(".gnu.version_r", 0));
+ shsym(sh, linklookup(ctxt, ".gnu.version_r", 0));
}
switch(eh->machine) {
@@ -1289,7 +1289,7 @@ asmbelf(vlong symo)
sh->addralign = PtrSize;
sh->link = elfshname(".dynsym")->shnum;
sh->info = elfshname(".plt")->shnum;
- shsym(sh, lookup(".rela.plt", 0));
+ shsym(sh, linklookup(ctxt, ".rela.plt", 0));
sh = elfshname(".rela");
sh->type = SHT_RELA;
@@ -1297,7 +1297,7 @@ asmbelf(vlong symo)
sh->entsize = ELF64RELASIZE;
sh->addralign = 8;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".rela", 0));
+ shsym(sh, linklookup(ctxt, ".rela", 0));
break;
default:
@@ -1306,7 +1306,7 @@ asmbelf(vlong symo)
sh->flags = SHF_ALLOC;
sh->entsize = ELF32RELSIZE;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".rel.plt", 0));
+ shsym(sh, linklookup(ctxt, ".rel.plt", 0));
sh = elfshname(".rel");
sh->type = SHT_REL;
@@ -1314,7 +1314,7 @@ asmbelf(vlong symo)
sh->entsize = ELF32RELSIZE;
sh->addralign = 4;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".rel", 0));
+ shsym(sh, linklookup(ctxt, ".rel", 0));
break;
}
@@ -1326,21 +1326,21 @@ asmbelf(vlong symo)
else
sh->entsize = 4;
sh->addralign = 4;
- shsym(sh, lookup(".plt", 0));
+ shsym(sh, linklookup(ctxt, ".plt", 0));
sh = elfshname(".got");
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC+SHF_WRITE;
sh->entsize = PtrSize;
sh->addralign = PtrSize;
- shsym(sh, lookup(".got", 0));
+ shsym(sh, linklookup(ctxt, ".got", 0));
sh = elfshname(".got.plt");
sh->type = SHT_PROGBITS;
sh->flags = SHF_ALLOC+SHF_WRITE;
sh->entsize = PtrSize;
sh->addralign = PtrSize;
- shsym(sh, lookup(".got.plt", 0));
+ shsym(sh, linklookup(ctxt, ".got.plt", 0));
sh = elfshname(".hash");
sh->type = SHT_HASH;
@@ -1348,7 +1348,7 @@ asmbelf(vlong symo)
sh->entsize = 4;
sh->addralign = PtrSize;
sh->link = elfshname(".dynsym")->shnum;
- shsym(sh, lookup(".hash", 0));
+ shsym(sh, linklookup(ctxt, ".hash", 0));
/* sh and PT_DYNAMIC for .dynamic section */
sh = elfshname(".dynamic");
@@ -1357,7 +1357,7 @@ asmbelf(vlong symo)
sh->entsize = 2*PtrSize;
sh->addralign = PtrSize;
sh->link = elfshname(".dynstr")->shnum;
- shsym(sh, lookup(".dynamic", 0));
+ shsym(sh, linklookup(ctxt, ".dynamic", 0));
ph = newElfPhdr();
ph->type = PT_DYNAMIC;
ph->flags = PF_R + PF_W;
@@ -1369,11 +1369,11 @@ asmbelf(vlong symo)
// Do not emit PT_TLS for OpenBSD since ld.so(1) does
// not currently support it. This is handled
// appropriately in runtime/cgo.
- if(tlsoffset != 0 && HEADTYPE != Hopenbsd) {
+ if(ctxt->tlsoffset != 0 && HEADTYPE != Hopenbsd) {
ph = newElfPhdr();
ph->type = PT_TLS;
ph->flags = PF_R;
- ph->memsz = -tlsoffset;
+ ph->memsz = -ctxt->tlsoffset;
ph->align = PtrSize;
}
}
@@ -1394,7 +1394,7 @@ elfobj:
sh = elfshname(".shstrtab");
sh->type = SHT_STRTAB;
sh->addralign = 1;
- shsym(sh, lookup(".shstrtab", 0));
+ shsym(sh, linklookup(ctxt, ".shstrtab", 0));
eh->shstrndx = sh->shnum;
// put these sections early in the list
@@ -1430,7 +1430,7 @@ elfobj:
sh = elfshname(".tbss");
sh->type = SHT_NOBITS;
sh->addralign = PtrSize;
- sh->size = -tlsoffset;
+ sh->size = -ctxt->tlsoffset;
sh->flags = SHF_ALLOC | SHF_TLS | SHF_WRITE;
}
diff --git a/src/cmd/ld/elf.h b/src/cmd/ld/elf.h
index 5b2ff041a3..76085c7c6e 100644
--- a/src/cmd/ld/elf.h
+++ b/src/cmd/ld/elf.h
@@ -858,7 +858,7 @@ struct Elf64_Shdr {
Elf64_Xword entsize; /* Size of each entry in section. */
int shnum; /* section number, not stored on disk */
- Sym* secsym; /* section symbol, if needed; not on disk */
+ LSym* secsym; /* section symbol, if needed; not on disk */
};
/*
@@ -968,9 +968,9 @@ ElfPhdr *newElfPhdr(void);
uint32 elfwritehdr(void);
uint32 elfwritephdrs(void);
uint32 elfwriteshdrs(void);
-void elfwritedynent(Sym*, int, uint64);
-void elfwritedynentsym(Sym*, int, Sym*);
-void elfwritedynentsymsize(Sym*, int, Sym*);
+void elfwritedynent(LSym*, int, uint64);
+void elfwritedynentsym(LSym*, int, LSym*);
+void elfwritedynentsymsize(LSym*, int, LSym*);
uint32 elfhash(uchar*);
uint64 startelf(void);
uint64 endelf(void);
@@ -994,13 +994,13 @@ ElfShdr* elfshalloc(Section*);
ElfShdr* elfshname(char*);
ElfShdr* elfshreloc(Section*);
void elfsetstring(char*, int);
-void elfaddverneed(Sym*);
+void elfaddverneed(LSym*);
void elfemitreloc(void);
-void shsym(ElfShdr*, Sym*);
+void shsym(ElfShdr*, LSym*);
void phsh(ElfPhdr*, ElfShdr*);
void doelf(void);
void elfsetupplt(void);
-void dwarfaddshstrings(Sym*);
+void dwarfaddshstrings(LSym*);
void dwarfaddelfsectionsyms(void);
void dwarfaddelfheaders(void);
void asmbelf(vlong symo);
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c
index 39ffa3d873..9950a3886e 100644
--- a/src/cmd/ld/go.c
+++ b/src/cmd/ld/go.c
@@ -228,39 +228,6 @@ loadpkgdata(char *file, char *pkg, char *data, int len)
free(file);
}
-// replace all "". with pkg.
-char*
-expandpkg(char *t0, char *pkg)
-{
- int n;
- char *p;
- char *w, *w0, *t;
-
- n = 0;
- for(p=t0; (p=strstr(p, "\"\".")) != nil; p+=3)
- n++;
-
- if(n == 0)
- return estrdup(t0);
-
- // use malloc, not mal, so that caller can free
- w0 = malloc(strlen(t0) + strlen(pkg)*n);
- if(w0 == nil) {
- diag("out of memory");
- errorexit();
- }
- w = w0;
- for(p=t=t0; (p=strstr(p, "\"\".")) != nil; p=t) {
- memmove(w, t, p - t);
- w += p-t;
- strcpy(w, pkg);
- w += strlen(pkg);
- t = p+2;
- }
- strcpy(w, t);
- return w0;
-}
-
static int
parsepkgdata(char *file, char *pkg, char **pp, char *ep, char **prefixp, char **namep, char **defp)
{
@@ -413,7 +380,7 @@ loadcgo(char *file, char *pkg, char *p, int n)
char *pend, *next, *p0, *q;
char *f[10], *local, *remote, *lib;
int nf;
- Sym *s;
+ LSym *s;
USED(file);
pend = p + n;
@@ -459,7 +426,7 @@ loadcgo(char *file, char *pkg, char *p, int n)
q = strchr(remote, '#');
if(q)
*q++ = '\0';
- s = lookup(local, 0);
+ s = linklookup(ctxt, local, 0);
if(local != f[1])
free(local);
if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) {
@@ -477,7 +444,7 @@ loadcgo(char *file, char *pkg, char *p, int n)
if(nf != 2)
goto err;
local = f[1];
- s = lookup(local, 0);
+ s = linklookup(ctxt, local, 0);
s->type = SHOSTOBJ;
s->size = 0;
continue;
@@ -496,9 +463,9 @@ loadcgo(char *file, char *pkg, char *p, int n)
else
remote = local;
local = expandpkg(local, pkg);
- s = lookup(local, 0);
+ s = linklookup(ctxt, local, 0);
- if(flag_shared && s == lookup("main", 0))
+ if(flag_shared && s == linklookup(ctxt, "main", 0))
continue;
// export overrides import, for openbsd/cgo.
@@ -562,11 +529,11 @@ err:
nerrors++;
}
-static Sym *markq;
-static Sym *emarkq;
+static LSym *markq;
+static LSym *emarkq;
static void
-mark1(Sym *s, Sym *parent)
+mark1(LSym *s, LSym *parent)
{
if(s == S || s->reachable)
return;
@@ -582,7 +549,7 @@ mark1(Sym *s, Sym *parent)
}
void
-mark(Sym *s)
+mark(LSym *s)
{
mark1(s, nil);
}
@@ -592,7 +559,7 @@ markflood(void)
{
Auto *a;
Prog *p;
- Sym *s;
+ LSym *s;
int i;
for(s=markq; s!=S; s=s->queue) {
@@ -649,7 +616,7 @@ isz(Auto *a)
}
static void
-addz(Sym *s, Auto *z)
+addz(LSym *s, Auto *z)
{
Auto *a, *last;
@@ -674,16 +641,16 @@ void
deadcode(void)
{
int i;
- Sym *s, *last, *p;
+ LSym *s, *last, *p;
Auto *z;
Fmt fmt;
if(debug['v'])
Bprint(&bso, "%5.2f deadcode\n", cputime());
- mark(lookup(INITENTRY, 0));
+ mark(linklookup(ctxt, INITENTRY, 0));
for(i=0; i<nelem(markextra); i++)
- mark(lookup(markextra[i], 0));
+ mark(linklookup(ctxt, markextra[i], 0));
for(i=0; i<ndynexp; i++)
mark(dynexp[i]);
@@ -691,7 +658,7 @@ deadcode(void)
markflood();
// keep each beginning with 'typelink.' if the symbol it points at is being kept.
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(strncmp(s->name, "go.typelink.", 12) == 0)
s->reachable = s->nr==1 && s->r[0].sym->reachable;
}
@@ -699,14 +666,14 @@ deadcode(void)
// remove dead text but keep file information (z symbols).
last = nil;
z = nil;
- for(s = textp; s != nil; s = s->next) {
+ for(s = ctxt->textp; s != nil; s = s->next) {
if(!s->reachable) {
if(isz(s->autom))
z = s->autom;
continue;
}
if(last == nil)
- textp = s;
+ ctxt->textp = s;
else
last->next = s;
last = s;
@@ -717,11 +684,11 @@ deadcode(void)
}
}
if(last == nil)
- textp = nil;
+ ctxt->textp = nil;
else
last->next = nil;
- for(s = allsym; s != S; s = s->allsym)
+ for(s = ctxt->allsym; s != S; s = s->allsym)
if(strncmp(s->name, "go.weak.", 8) == 0) {
s->special = 1; // do not lay out in data segment
s->reachable = 1;
@@ -730,7 +697,7 @@ deadcode(void)
// record field tracking references
fmtstrinit(&fmt);
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(strncmp(s->name, "go.track.", 9) == 0) {
s->special = 1; // do not lay out in data segment
s->hide = 1;
@@ -746,7 +713,7 @@ deadcode(void)
}
if(tracksym == nil)
return;
- s = lookup(tracksym, 0);
+ s = linklookup(ctxt, tracksym, 0);
if(!s->reachable)
return;
addstrdata(tracksym, fmtstrflush(&fmt));
@@ -755,13 +722,13 @@ deadcode(void)
void
doweak(void)
{
- Sym *s, *t;
+ LSym *s, *t;
// resolve weak references only if
// target symbol will be in binary anyway.
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(strncmp(s->name, "go.weak.", 8) == 0) {
- t = rlookup(s->name+8, s->version);
+ t = linkrlookup(ctxt, s->name+8, s->version);
if(t && t->type != 0 && t->reachable) {
s->value = t->value;
s->type = t->type;
@@ -784,7 +751,7 @@ addexport(void)
return;
for(i=0; i<ndynexp; i++)
- adddynsym(dynexp[i]);
+ adddynsym(ctxt, dynexp[i]);
}
/* %Z from gc, for quoting import paths */
diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c
index 27041bc472..4bc830ef32 100644
--- a/src/cmd/ld/ldelf.c
+++ b/src/cmd/ld/ldelf.c
@@ -258,7 +258,7 @@ struct ElfSect
uint64 align;
uint64 entsize;
uchar *base;
- Sym *sym;
+ LSym *sym;
};
struct ElfObj
@@ -301,7 +301,7 @@ struct ElfSym
uchar type;
uchar other;
uint16 shndx;
- Sym* sym;
+ LSym* sym;
};
uchar ElfMagic[4] = { 0x7F, 'E', 'L', 'F' };
@@ -312,7 +312,7 @@ static int readsym(ElfObj*, int i, ElfSym*, int);
static int reltype(char*, int, uchar*);
int
-valuecmp(Sym *a, Sym *b)
+valuecmp(LSym *a, LSym *b)
{
if(a->value < b->value)
return -1;
@@ -336,15 +336,15 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
ElfSym sym;
Endian *e;
Reloc *r, *rp;
- Sym *s;
- Sym **symbols;
+ LSym *s;
+ LSym **symbols;
symbols = nil;
if(debug['v'])
Bprint(&bso, "%5.2f ldelf %s\n", cputime(), pn);
- version++;
+ ctxt->version++;
base = Boffset(f);
if(Bread(f, hdrbuf, sizeof hdrbuf) != sizeof hdrbuf)
@@ -529,7 +529,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
goto bad;
name = smprint("%s(%s)", pkg, sect->name);
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
free(name);
switch((int)sect->flags&(ElfSectFlagAlloc|ElfSectFlagWrite|ElfSectFlagExec)) {
default:
@@ -609,14 +609,14 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
} else {
// build a TEXT instruction with a unique pc
// just to make the rest of the linker happy.
- p = prg();
+ p = ctxt->arch->prg();
p->as = ATEXT;
p->from.type = D_EXTERN;
p->from.sym = s;
- p->textflag = 7;
+ ctxt->arch->settextflag(p, 7);
p->to.type = D_CONST;
p->link = nil;
- p->pc = pc++;
+ p->pc = ctxt->pc++;
s->text = p;
}
}
@@ -629,16 +629,16 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
if(s == S)
continue;
if(s->sub)
- s->sub = listsort(s->sub, valuecmp, offsetof(Sym, sub));
+ s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
if(s->type == STEXT) {
- if(etextp)
- etextp->next = s;
+ if(ctxt->etextp)
+ ctxt->etextp->next = s;
else
- textp = s;
- etextp = s;
+ ctxt->textp = s;
+ ctxt->etextp = s;
for(s = s->sub; s != S; s = s->sub) {
- etextp->next = s;
- etextp = s;
+ ctxt->etextp->next = s;
+ ctxt->etextp = s;
}
}
}
@@ -761,7 +761,7 @@ map(ElfObj *obj, ElfSect *sect)
static int
readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
{
- Sym *s;
+ LSym *s;
if(i >= obj->nsymtab || i < 0) {
werrstr("invalid elf symbol index");
@@ -808,7 +808,7 @@ readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
switch(sym->bind) {
case ElfSymBindGlobal:
if(needSym) {
- s = lookup(sym->name, 0);
+ s = linklookup(ctxt, sym->name, 0);
// for global scoped hidden symbols we should insert it into
// symbol hash table, but mark them as hidden.
// __i686.get_pc_thunk.bx is allowed to be duplicated, to
@@ -828,13 +828,13 @@ readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
// local names and hidden visiblity global names are unique
// and should only reference by its index, not name, so we
// don't bother to add them into hash table
- s = newsym(sym->name, version);
+ s = linknewsym(ctxt, sym->name, ctxt->version);
s->type |= SHIDDEN;
}
break;
case ElfSymBindWeak:
if(needSym) {
- s = newsym(sym->name, 0);
+ s = linknewsym(ctxt, sym->name, 0);
if(sym->other == 2)
s->type |= SHIDDEN;
}
diff --git a/src/cmd/ld/ldmacho.c b/src/cmd/ld/ldmacho.c
index e0f5405f69..7318381e35 100644
--- a/src/cmd/ld/ldmacho.c
+++ b/src/cmd/ld/ldmacho.c
@@ -102,7 +102,7 @@ struct MachoSect
uint32 flags;
uint32 res1;
uint32 res2;
- Sym *sym;
+ LSym *sym;
MachoRel *rel;
};
@@ -138,7 +138,7 @@ struct MachoSym
uint16 desc;
char kind;
uint64 value;
- Sym *sym;
+ LSym *sym;
};
struct MachoDysymtab
@@ -432,7 +432,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
int64 base;
MachoSect *sect;
MachoRel *rel;
- Sym *s, *s1, *outer;
+ LSym *s, *s1, *outer;
MachoCmd *c;
MachoSymtab *symtab;
MachoDysymtab *dsymtab;
@@ -440,7 +440,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
Reloc *r, *rp;
char *name;
- version++;
+ ctxt->version++;
base = Boffset(f);
if(Bread(f, hdr, sizeof hdr) != sizeof hdr)
goto bad;
@@ -566,7 +566,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
if(strcmp(sect->name, "__eh_frame") == 0)
continue;
name = smprint("%s(%s/%s)", pkg, sect->segname, sect->name);
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
if(s->type != 0) {
werrstr("duplicate %s/%s", sect->segname, sect->name);
goto bad;
@@ -609,8 +609,8 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
name++;
v = 0;
if(!(sym->type&N_EXT))
- v = version;
- s = lookup(name, v);
+ v = ctxt->version;
+ s = linklookup(ctxt, name, v);
if(!(sym->type&N_EXT))
s->dupok = 1;
sym->sym = s;
@@ -647,14 +647,14 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
// build a TEXT instruction with a unique pc
// just to make the rest of the linker happy.
// TODO: this is too 6l-specific ?
- p = prg();
+ p = ctxt->arch->prg();
p->as = ATEXT;
p->from.type = D_EXTERN;
p->from.sym = s;
- p->textflag = 7;
+ ctxt->arch->settextflag(p, 7);
p->to.type = D_CONST;
p->link = nil;
- p->pc = pc++;
+ p->pc = ctxt->pc++;
s->text = p;
}
sym->sym = s;
@@ -667,7 +667,7 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
if((s = sect->sym) == S)
continue;
if(s->sub) {
- s->sub = listsort(s->sub, valuecmp, offsetof(Sym, sub));
+ s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
// assign sizes, now that we know symbols in sorted order.
for(s1 = s->sub; s1 != S; s1 = s1->sub) {
@@ -678,14 +678,14 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
}
}
if(s->type == STEXT) {
- if(etextp)
- etextp->next = s;
+ if(ctxt->etextp)
+ ctxt->etextp->next = s;
else
- textp = s;
- etextp = s;
+ ctxt->textp = s;
+ ctxt->etextp = s;
for(s1 = s->sub; s1 != S; s1 = s1->sub) {
- etextp->next = s1;
- etextp = s1;
+ ctxt->etextp->next = s1;
+ ctxt->etextp = s1;
}
}
}
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c
index 6bcda2cb66..f7e4bfcdb2 100644
--- a/src/cmd/ld/ldpe.c
+++ b/src/cmd/ld/ldpe.c
@@ -102,14 +102,14 @@ struct PeSym {
uint16 type;
uint8 sclass;
uint8 aux;
- Sym* sym;
+ LSym* sym;
};
struct PeSect {
char* name;
uchar* base;
uint64 size;
- Sym* sym;
+ LSym* sym;
IMAGE_SECTION_HEADER sh;
};
@@ -141,7 +141,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
PeSect *sect, *rsect;
IMAGE_SECTION_HEADER sh;
uchar symbuf[18];
- Sym *s;
+ LSym *s;
Reloc *r, *rp;
PeSym *sym;
@@ -150,7 +150,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
Bprint(&bso, "%5.2f ldpe %s\n", cputime(), pn);
sect = nil;
- version++;
+ ctxt->version++;
base = Boffset(f);
obj = mal(sizeof *obj);
@@ -222,7 +222,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
goto bad;
name = smprint("%s(%s)", pkg, sect->name);
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
free(name);
switch(sect->sh.Characteristics&(IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_CNT_INITIALIZED_DATA|
IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE)) {
@@ -372,14 +372,14 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
diag("%s: duplicate definition of %s", pn, s->name);
// build a TEXT instruction with a unique pc
// just to make the rest of the linker happy.
- p = prg();
+ p = ctxt->arch->prg();
p->as = ATEXT;
p->from.type = D_EXTERN;
p->from.sym = s;
- p->textflag = 7;
+ ctxt->arch->settextflag(p, 7);
p->to.type = D_CONST;
p->link = nil;
- p->pc = pc++;
+ p->pc = ctxt->pc++;
s->text = p;
}
}
@@ -391,16 +391,16 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
if(s == S)
continue;
if(s->sub)
- s->sub = listsort(s->sub, valuecmp, offsetof(Sym, sub));
+ s->sub = listsort(s->sub, valuecmp, offsetof(LSym, sub));
if(s->type == STEXT) {
- if(etextp)
- etextp->next = s;
+ if(ctxt->etextp)
+ ctxt->etextp->next = s;
else
- textp = s;
- etextp = s;
+ ctxt->textp = s;
+ ctxt->etextp = s;
for(s = s->sub; s != S; s = s->sub) {
- etextp->next = s;
- etextp = s;
+ ctxt->etextp->next = s;
+ ctxt->etextp = s;
}
}
}
@@ -430,7 +430,7 @@ map(PeObj *obj, PeSect *sect)
static int
readsym(PeObj *obj, int i, PeSym **y)
{
- Sym *s;
+ LSym *s;
PeSym *sym;
char *name, *p;
@@ -464,12 +464,12 @@ readsym(PeObj *obj, int i, PeSym **y)
case IMAGE_SYM_DTYPE_NULL:
switch(sym->sclass) {
case IMAGE_SYM_CLASS_EXTERNAL: //global
- s = lookup(name, 0);
+ s = linklookup(ctxt, name, 0);
break;
case IMAGE_SYM_CLASS_NULL:
case IMAGE_SYM_CLASS_STATIC:
case IMAGE_SYM_CLASS_LABEL:
- s = lookup(name, version);
+ s = linklookup(ctxt, name, ctxt->version);
s->dupok = 1;
break;
default:
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index da522dc0c7..56e50acb95 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -32,6 +32,7 @@
#include "l.h"
#include "lib.h"
#include "../ld/elf.h"
+#include "../ld/dwarf.h"
#include "../../pkg/runtime/stack.h"
#include "../../pkg/runtime/funcdata.h"
@@ -48,18 +49,9 @@ int iconv(Fmt*);
char symname[] = SYMDEF;
char pkgname[] = "__.PKGDEF";
-char** libdir;
-int nlibdir = 0;
-static int maxlibdir = 0;
static int cout = -1;
-// symbol version, incremented each time a file is loaded.
-// version==1 is reserved for savehist.
-enum
-{
- HistVersion = 1,
-};
-int version = HistVersion;
+extern int version;
// Set if we see an object compiled by the host compiler that is not
// from a package that is known to support internal linking mode.
@@ -77,15 +69,15 @@ Lflag(char *arg)
{
char **p;
- if(nlibdir >= maxlibdir) {
- if (maxlibdir == 0)
- maxlibdir = 8;
+ if(ctxt->nlibdir >= ctxt->maxlibdir) {
+ if (ctxt->maxlibdir == 0)
+ ctxt->maxlibdir = 8;
else
- maxlibdir *= 2;
- p = erealloc(libdir, maxlibdir * sizeof(*p));
- libdir = p;
+ ctxt->maxlibdir *= 2;
+ p = erealloc(ctxt->libdir, ctxt->maxlibdir * sizeof(*p));
+ ctxt->libdir = p;
}
- libdir[nlibdir++] = arg;
+ ctxt->libdir[ctxt->nlibdir++] = arg;
}
void
@@ -132,7 +124,7 @@ libinit(void)
sprint(INITENTRY, "_rt0_%s_%s_lib", goarch, goos);
}
}
- lookup(INITENTRY, 0)->type = SXREF;
+ linklookup(ctxt, INITENTRY, 0)->type = SXREF;
}
void
@@ -147,158 +139,18 @@ errorexit(void)
}
void
-addlib(char *src, char *obj)
-{
- char name[1024], pname[1024], comp[256], *p;
- int i, search;
-
- if(histfrogp <= 0)
- return;
-
- search = 0;
- if(histfrog[0]->name[1] == '/') {
- sprint(name, "");
- i = 1;
- } else
- if(isalpha((uchar)histfrog[0]->name[1]) && histfrog[0]->name[2] == ':') {
- strcpy(name, histfrog[0]->name+1);
- i = 1;
- } else
- if(histfrog[0]->name[1] == '.') {
- sprint(name, ".");
- i = 0;
- } else {
- sprint(name, "");
- i = 0;
- search = 1;
- }
-
- for(; i<histfrogp; i++) {
- snprint(comp, sizeof comp, "%s", histfrog[i]->name+1);
- for(;;) {
- p = strstr(comp, "$O");
- if(p == 0)
- break;
- memmove(p+1, p+2, strlen(p+2)+1);
- p[0] = thechar;
- }
- for(;;) {
- p = strstr(comp, "$M");
- if(p == 0)
- break;
- if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
- diag("library component too long");
- return;
- }
- memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
- memmove(p, thestring, strlen(thestring));
- }
- if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
- diag("library component too long");
- return;
- }
- if(i > 0 || !search)
- strcat(name, "/");
- strcat(name, comp);
- }
- cleanname(name);
-
- // runtime.a -> runtime
- p = nil;
- if(strlen(name) > 2 && name[strlen(name)-2] == '.') {
- p = name+strlen(name)-2;
- *p = '\0';
- }
-
- // already loaded?
- for(i=0; i<libraryp; i++)
- if(strcmp(library[i].pkg, name) == 0)
- return;
-
- // runtime -> runtime.a for search
- if(p != nil)
- *p = '.';
-
- if(search) {
- // try dot, -L "libdir", and then goroot.
- for(i=0; i<nlibdir; i++) {
- snprint(pname, sizeof pname, "%s/%s", libdir[i], name);
- if(access(pname, AEXIST) >= 0)
- break;
- }
- }else
- strcpy(pname, name);
- cleanname(pname);
-
- /* runtime.a -> runtime */
- if(p != nil)
- *p = '\0';
-
- if(debug['v'] > 1)
- Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
-
- addlibpath(src, obj, pname, name);
-}
-
-/*
- * add library to library list.
- * srcref: src file referring to package
- * objref: object file referring to package
- * file: object file, e.g., /home/rsc/go/pkg/container/vector.a
- * pkg: package import path, e.g. container/vector
- */
-void
-addlibpath(char *srcref, char *objref, char *file, char *pkg)
-{
- int i;
- Library *l;
- char *p;
-
- for(i=0; i<libraryp; i++)
- if(strcmp(file, library[i].file) == 0)
- return;
-
- if(debug['v'] > 1)
- Bprint(&bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n",
- cputime(), srcref, objref, file, pkg);
-
- if(libraryp == nlibrary){
- nlibrary = 50 + 2*libraryp;
- library = erealloc(library, sizeof library[0] * nlibrary);
- }
-
- l = &library[libraryp++];
-
- p = mal(strlen(objref) + 1);
- strcpy(p, objref);
- l->objref = p;
-
- p = mal(strlen(srcref) + 1);
- strcpy(p, srcref);
- l->srcref = p;
-
- p = mal(strlen(file) + 1);
- strcpy(p, file);
- l->file = p;
-
- p = mal(strlen(pkg) + 1);
- strcpy(p, pkg);
- l->pkg = p;
-}
-
-void
loadinternal(char *name)
{
char pname[1024];
int i, found;
found = 0;
- for(i=0; i<nlibdir; i++) {
- snprint(pname, sizeof pname, "%s/%s.a", libdir[i], name);
+ for(i=0; i<ctxt->nlibdir; i++) {
+ snprint(pname, sizeof pname, "%s/%s.a", ctxt->libdir[i], name);
if(debug['v'])
Bprint(&bso, "searching for %s.a in %s\n", name, pname);
if(access(pname, AEXIST) >= 0) {
- addlibpath("internal", "internal", pname, name);
+ addlibpath(ctxt, "internal", "internal", pname, name);
found = 1;
break;
}
@@ -311,12 +163,12 @@ void
loadlib(void)
{
int i, w, x;
- Sym *s, *gmsym;
+ LSym *s, *gmsym;
if(flag_shared) {
- s = lookup("runtime.islibrary", 0);
+ s = linklookup(ctxt, "runtime.islibrary", 0);
s->dupok = 1;
- adduint8(s, 1);
+ adduint8(ctxt, s, 1);
}
loadinternal("runtime");
@@ -332,17 +184,17 @@ loadlib(void)
loadinternal("runtime/cgo");
// Pretend that we really imported the package.
// This will do no harm if we did in fact import it.
- s = lookup("go.importpath.runtime/cgo.", 0);
+ s = linklookup(ctxt, "go.importpath.runtime/cgo.", 0);
s->type = SDATA;
s->dupok = 1;
s->reachable = 1;
}
- for(i=0; i<libraryp; i++) {
+ for(i=0; i<ctxt->libraryp; i++) {
if(debug['v'] > 1)
- Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref);
- iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0;
- objfile(library[i].file, library[i].pkg);
+ Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), ctxt->library[i].file, ctxt->library[i].objref);
+ iscgo |= strcmp(ctxt->library[i].pkg, "runtime/cgo") == 0;
+ objfile(ctxt->library[i].file, ctxt->library[i].pkg);
}
if(linkmode == LinkAuto) {
@@ -355,7 +207,7 @@ loadlib(void)
if(linkmode == LinkInternal) {
// Drop all the cgo_import_static declarations.
// Turns out we won't be needing them.
- for(s = allsym; s != S; s = s->allsym)
+ for(s = ctxt->allsym; s != S; s = s->allsym)
if(s->type == SHOSTOBJ) {
// If a symbol was marked both
// cgo_import_static and cgo_import_dynamic,
@@ -368,7 +220,7 @@ loadlib(void)
}
}
- gmsym = lookup("runtime.tlsgm", 0);
+ gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
gmsym->type = STLSBSS;
gmsym->size = 2*PtrSize;
gmsym->hide = 1;
@@ -539,7 +391,7 @@ dowrite(int fd, char *p, int n)
while(n > 0) {
m = write(fd, p, n);
if(m <= 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("write error: %r");
errorexit();
}
@@ -628,7 +480,7 @@ hostobjs(void)
h = &hostobj[i];
f = Bopen(h->file, OREAD);
if(f == nil) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot reopen %s: %r", h->pn);
errorexit();
}
@@ -744,7 +596,7 @@ hostlink(void)
h = &hostobj[i];
f = Bopen(h->file, OREAD);
if(f == nil) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot reopen %s: %r", h->pn);
errorexit();
}
@@ -753,7 +605,7 @@ hostlink(void)
argv[argc++] = p;
w = create(p, 1, 0775);
if(w < 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot create %s: %r", p);
errorexit();
}
@@ -765,7 +617,7 @@ hostlink(void)
len -= n;
}
if(close(w) < 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("cannot write %s: %r", p);
errorexit();
}
@@ -798,7 +650,7 @@ hostlink(void)
}
if(runcmd(argv) < 0) {
- cursym = S;
+ ctxt->cursym = S;
diag("%s: running %s failed: %r", argv0, argv[0]);
errorexit();
}
@@ -913,7 +765,7 @@ ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence)
ldpkg(f, pkg, import1 - import0 - 2, pn, whence); // -2 for !\n
Bseek(f, import1, 0);
- ldobj1(f, pkg, eof - Boffset(f), pn);
+ ctxt->arch->ldobj(ctxt, f, pkg, eof - Boffset(f), pn);
free(pn);
return;
@@ -922,318 +774,12 @@ eof:
free(pn);
}
-Sym*
-newsym(char *symb, int v)
-{
- Sym *s;
- int l;
-
- l = strlen(symb) + 1;
- s = mal(sizeof(*s));
- if(debug['v'] > 1)
- Bprint(&bso, "newsym %s\n", symb);
-
- s->dynid = -1;
- s->plt = -1;
- s->got = -1;
- s->name = mal(l + 1);
- memmove(s->name, symb, l);
-
- s->type = 0;
- s->version = v;
- s->value = 0;
- s->sig = 0;
- s->size = 0;
- nsymbol++;
-
- s->allsym = allsym;
- allsym = s;
-
- return s;
-}
-
-static Sym*
-_lookup(char *symb, int v, int creat)
-{
- Sym *s;
- char *p;
- uint32 h;
- int c;
-
- h = v;
- for(p=symb; c = *p; p++)
- h = h+h+h + c;
- // not if(h < 0) h = ~h, because gcc 4.3 -O2 miscompiles it.
- h &= 0xffffff;
- h %= NHASH;
- for(s = hash[h]; s != S; s = s->hash)
- if(strcmp(s->name, symb) == 0)
- return s;
- if(!creat)
- return nil;
-
- s = newsym(symb, v);
- s->extname = s->name;
- s->hash = hash[h];
- hash[h] = s;
-
- return s;
-}
-
-Sym*
-lookup(char *name, int v)
-{
- return _lookup(name, v, 1);
-}
-
-// read-only lookup
-Sym*
-rlookup(char *name, int v)
-{
- return _lookup(name, v, 0);
-}
-
-void
-copyhistfrog(char *buf, int nbuf)
-{
- char *p, *ep;
- int i;
-
- p = buf;
- ep = buf + nbuf;
- for(i=0; i<histfrogp; i++) {
- p = seprint(p, ep, "%s", histfrog[i]->name+1);
- if(i+1<histfrogp && (p == buf || p[-1] != '/'))
- p = seprint(p, ep, "/");
- }
-}
-
-void
-addhist(int32 line, int type)
-{
- Auto *u;
- Sym *s;
- int i, j, k;
-
- u = mal(sizeof(Auto));
- s = mal(sizeof(Sym));
- s->name = mal(2*(histfrogp+1) + 1);
-
- u->asym = s;
- u->type = type;
- u->aoffset = line;
- u->link = curhist;
- curhist = u;
-
- s->name[0] = 0;
- j = 1;
- for(i=0; i<histfrogp; i++) {
- k = histfrog[i]->value;
- s->name[j+0] = k>>8;
- s->name[j+1] = k;
- j += 2;
- }
- s->name[j] = 0;
- s->name[j+1] = 0;
-}
-
-void
-histtoauto(void)
-{
- Auto *l;
-
- while(l = curhist) {
- curhist = l->link;
- l->link = curauto;
- curauto = l;
- }
-}
-
-void
-collapsefrog(Sym *s)
-{
- int i;
-
- /*
- * bad encoding of path components only allows
- * MAXHIST components. if there is an overflow,
- * first try to collapse xxx/..
- */
- for(i=1; i<histfrogp; i++)
- if(strcmp(histfrog[i]->name+1, "..") == 0) {
- memmove(histfrog+i-1, histfrog+i+1,
- (histfrogp-i-1)*sizeof(histfrog[0]));
- histfrogp--;
- goto out;
- }
-
- /*
- * next try to collapse .
- */
- for(i=0; i<histfrogp; i++)
- if(strcmp(histfrog[i]->name+1, ".") == 0) {
- memmove(histfrog+i, histfrog+i+1,
- (histfrogp-i-1)*sizeof(histfrog[0]));
- goto out;
- }
-
- /*
- * last chance, just truncate from front
- */
- memmove(histfrog+0, histfrog+1,
- (histfrogp-1)*sizeof(histfrog[0]));
-
-out:
- histfrog[histfrogp-1] = s;
-}
-
-void
-nuxiinit(void)
-{
- int i, c;
-
- for(i=0; i<4; i++) {
- c = find1(0x04030201L, i+1);
- if(i < 2)
- inuxi2[i] = c;
- if(i < 1)
- inuxi1[i] = c;
- inuxi4[i] = c;
- if(c == i) {
- inuxi8[i] = c;
- inuxi8[i+4] = c+4;
- } else {
- inuxi8[i] = c+4;
- inuxi8[i+4] = c;
- }
- fnuxi4[i] = c;
- fnuxi8[i] = c;
- fnuxi8[i+4] = c+4;
- }
- if(debug['v']) {
- Bprint(&bso, "inuxi = ");
- for(i=0; i<1; i++)
- Bprint(&bso, "%d", inuxi1[i]);
- Bprint(&bso, " ");
- for(i=0; i<2; i++)
- Bprint(&bso, "%d", inuxi2[i]);
- Bprint(&bso, " ");
- for(i=0; i<4; i++)
- Bprint(&bso, "%d", inuxi4[i]);
- Bprint(&bso, " ");
- for(i=0; i<8; i++)
- Bprint(&bso, "%d", inuxi8[i]);
- Bprint(&bso, "\nfnuxi = ");
- for(i=0; i<4; i++)
- Bprint(&bso, "%d", fnuxi4[i]);
- Bprint(&bso, " ");
- for(i=0; i<8; i++)
- Bprint(&bso, "%d", fnuxi8[i]);
- Bprint(&bso, "\n");
- }
- Bflush(&bso);
-}
-
-int
-find1(int32 l, int c)
-{
- char *p;
- int i;
-
- p = (char*)&l;
- for(i=0; i<4; i++)
- if(*p++ == c)
- return i;
- return 0;
-}
-
-int
-find2(int32 l, int c)
-{
- union {
- int32 l;
- short p[2];
- } u;
- short *p;
- int i;
-
- u.l = l;
- p = u.p;
- for(i=0; i<4; i+=2) {
- if(((*p >> 8) & 0xff) == c)
- return i;
- if((*p++ & 0xff) == c)
- return i+1;
- }
- return 0;
-}
-
-int32
-ieeedtof(Ieee *e)
-{
- int exp;
- int32 v;
-
- if(e->h == 0)
- return 0;
- exp = (e->h>>20) & ((1L<<11)-1L);
- exp -= (1L<<10) - 2L;
- v = (e->h & 0xfffffL) << 3;
- v |= (e->l >> 29) & 0x7L;
- if((e->l >> 28) & 1) {
- v++;
- if(v & 0x800000L) {
- v = (v & 0x7fffffL) >> 1;
- exp++;
- }
- }
- if(-148 <= exp && exp <= -126) {
- v |= 1<<23;
- v >>= -125 - exp;
- exp = -126;
- }
- else if(exp < -148 || exp >= 130)
- diag("double fp to single fp overflow: %.17g", ieeedtod(e));
- v |= ((exp + 126) & 0xffL) << 23;
- v |= e->h & 0x80000000L;
- return v;
-}
-
-double
-ieeedtod(Ieee *ieeep)
-{
- Ieee e;
- double fr;
- int exp;
-
- if(ieeep->h & (1L<<31)) {
- e.h = ieeep->h & ~(1L<<31);
- e.l = ieeep->l;
- return -ieeedtod(&e);
- }
- if(ieeep->l == 0 && ieeep->h == 0)
- return 0;
- exp = (ieeep->h>>20) & ((1L<<11)-1L);
- exp -= (1L<<10) - 2L;
- fr = ieeep->l & ((1L<<16)-1L);
- fr /= 1L<<16;
- fr += (ieeep->l>>16) & ((1L<<16)-1L);
- fr /= 1L<<16;
- if(exp == -(1L<<10) - 2L) {
- fr += (ieeep->h & (1L<<20)-1L);
- exp++;
- } else
- fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
- fr /= 1L<<21;
- return ldexp(fr, exp);
-}
-
void
zerosig(char *sp)
{
- Sym *s;
+ LSym *s;
- s = lookup(sp, 0);
+ s = linklookup(ctxt, sp, 0);
s->sig = 0;
}
@@ -1357,13 +903,6 @@ iconv(Fmt *fp)
return 0;
}
-void
-mangle(char *file)
-{
- fprint(2, "%s: mangled input file\n", file);
- errorexit();
-}
-
Section*
addsection(Segment *seg, char *name, int rwx)
{
@@ -1381,235 +920,6 @@ addsection(Segment *seg, char *name, int rwx)
return sect;
}
-void
-addvarint(Sym *s, uint32 val)
-{
- int32 n;
- uint32 v;
- uchar *p;
-
- n = 0;
- for(v = val; v >= 0x80; v >>= 7)
- n++;
- n++;
-
- symgrow(s, s->np+n);
-
- p = s->p + s->np - n;
- for(v = val; v >= 0x80; v >>= 7)
- *p++ = v | 0x80;
- *p = v;
-}
-
-// funcpctab appends to dst a pc-value table mapping the code in func to the values
-// returned by valfunc parameterized by arg. The invocation of valfunc to update the
-// current value is, for each p,
-//
-// val = valfunc(func, val, p, 0, arg);
-// record val as value at p->pc;
-// val = valfunc(func, val, p, 1, arg);
-//
-// where func is the function, val is the current value, p is the instruction being
-// considered, and arg can be used to further parameterize valfunc.
-void
-funcpctab(Sym *dst, Sym *func, char *desc, int32 (*valfunc)(Sym*, int32, Prog*, int32, int32), int32 arg)
-{
- int dbg, i, start;
- int32 oldval, val, started;
- uint32 delta;
- vlong pc;
- Prog *p;
-
- // To debug a specific function, uncomment second line and change name.
- dbg = 0;
- //dbg = strcmp(func->name, "main.main") == 0;
-
- debug['O'] += dbg;
-
- start = dst->np;
-
- if(debug['O'])
- Bprint(&bso, "funcpctab %s -> %s [valfunc=%s]\n", func->name, dst->name, desc);
-
- val = -1;
- oldval = val;
- pc = func->value;
-
- if(debug['O'])
- Bprint(&bso, "%6llux %6d %P\n", pc, val, func->text);
-
- started = 0;
- for(p=func->text; p != P; p = p->link) {
- // Update val. If it's not changing, keep going.
- val = valfunc(func, val, p, 0, arg);
- if(val == oldval && started) {
- val = valfunc(func, val, p, 1, arg);
- if(debug['O'])
- Bprint(&bso, "%6llux %6s %P\n", (vlong)p->pc, "", p);
- continue;
- }
-
- // If the pc of the next instruction is the same as the
- // pc of this instruction, this instruction is not a real
- // instruction. Keep going, so that we only emit a delta
- // for a true instruction boundary in the program.
- if(p->link && p->link->pc == p->pc) {
- val = valfunc(func, val, p, 1, arg);
- if(debug['O'])
- Bprint(&bso, "%6llux %6s %P\n", (vlong)p->pc, "", p);
- continue;
- }
-
- // The table is a sequence of (value, pc) pairs, where each
- // pair states that the given value is in effect from the current position
- // up to the given pc, which becomes the new current position.
- // To generate the table as we scan over the program instructions,
- // we emit a "(value" when pc == func->value, and then
- // each time we observe a change in value we emit ", pc) (value".
- // When the scan is over, we emit the closing ", pc)".
- //
- // The table is delta-encoded. The value deltas are signed and
- // transmitted in zig-zag form, where a complement bit is placed in bit 0,
- // and the pc deltas are unsigned. Both kinds of deltas are sent
- // as variable-length little-endian base-128 integers,
- // where the 0x80 bit indicates that the integer continues.
-
- if(debug['O'])
- Bprint(&bso, "%6llux %6d %P\n", (vlong)p->pc, val, p);
-
- if(started) {
- addvarint(dst, (p->pc - pc) / MINLC);
- pc = p->pc;
- }
- delta = val - oldval;
- if(delta>>31)
- delta = 1 | ~(delta<<1);
- else
- delta <<= 1;
- addvarint(dst, delta);
- oldval = val;
- started = 1;
- val = valfunc(func, val, p, 1, arg);
- }
-
- if(started) {
- if(debug['O'])
- Bprint(&bso, "%6llux done\n", (vlong)func->value+func->size);
- addvarint(dst, (func->value+func->size - pc) / MINLC);
- addvarint(dst, 0); // terminator
- }
-
- if(debug['O']) {
- Bprint(&bso, "wrote %d bytes\n", dst->np - start);
- for(i=start; i<dst->np; i++)
- Bprint(&bso, " %02ux", dst->p[i]);
- Bprint(&bso, "\n");
- }
-
- debug['O'] -= dbg;
-}
-
-// pctofileline computes either the file number (arg == 0)
-// or the line number (arg == 1) to use at p.
-// Because p->lineno applies to p, phase == 0 (before p)
-// takes care of the update.
-static int32
-pctofileline(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg)
-{
- int32 f, l;
-
- if(p->as == ATEXT || p->as == ANOP || p->as == AUSEFIELD || p->line == 0 || phase == 1)
- return oldval;
- getline(sym->hist, p->line, &f, &l);
- if(f == 0) {
- // print("getline failed for %s %P\n", cursym->name, p);
- return oldval;
- }
- if(arg == 0)
- return f;
- return l;
-}
-
-// pctospadj computes the sp adjustment in effect.
-// It is oldval plus any adjustment made by p itself.
-// The adjustment by p takes effect only after p, so we
-// apply the change during phase == 1.
-static int32
-pctospadj(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg)
-{
- USED(arg);
- USED(sym);
-
- if(oldval == -1) // starting
- oldval = 0;
- if(phase == 0)
- return oldval;
- if(oldval + p->spadj < -10000 || oldval + p->spadj > 1100000000) {
- diag("overflow in spadj: %d + %d = %d", oldval, p->spadj, oldval + p->spadj);
- errorexit();
- }
- return oldval + p->spadj;
-}
-
-// pctopcdata computes the pcdata value in effect at p.
-// A PCDATA instruction sets the value in effect at future
-// non-PCDATA instructions.
-// Since PCDATA instructions have no width in the final code,
-// it does not matter which phase we use for the update.
-static int32
-pctopcdata(Sym *sym, int32 oldval, Prog *p, int32 phase, int32 arg)
-{
- USED(sym);
-
- if(phase == 0 || p->as != APCDATA || p->from.offset != arg)
- return oldval;
- if((int32)p->to.offset != p->to.offset) {
- diag("overflow in PCDATA instruction: %P", p);
- errorexit();
- }
- return p->to.offset;
-}
-
-#define LOG 5
-void
-mkfwd(void)
-{
- Prog *p;
- int i;
- int32 dwn[LOG], cnt[LOG];
- Prog *lst[LOG];
-
- for(i=0; i<LOG; i++) {
- if(i == 0)
- cnt[i] = 1;
- else
- cnt[i] = LOG * cnt[i-1];
- dwn[i] = 1;
- lst[i] = P;
- }
- i = 0;
- for(cursym = textp; cursym != nil; cursym = cursym->next) {
- for(p = cursym->text; p != P; p = p->link) {
- if(p->link == P) {
- if(cursym->next)
- p->forwd = cursym->next->text;
- break;
- }
- i--;
- if(i < 0)
- i = LOG-1;
- p->forwd = P;
- dwn[i]--;
- if(dwn[i] <= 0) {
- dwn[i] = cnt[i];
- if(lst[i] != P)
- lst[i]->forwd = p;
- lst[i] = p;
- }
- }
- }
-}
-
uint16
le16(uchar *b)
{
@@ -1652,7 +962,7 @@ Endian le = { le16, le32, le64 };
typedef struct Chain Chain;
struct Chain
{
- Sym *sym;
+ LSym *sym;
Chain *up;
int limit; // limit on entry to sym
};
@@ -1660,8 +970,8 @@ struct Chain
static int stkcheck(Chain*, int);
static void stkprint(Chain*, int);
static void stkbroke(Chain*, int);
-static Sym *morestack;
-static Sym *newstack;
+static LSym *morestack;
+static LSym *newstack;
enum
{
@@ -1673,16 +983,16 @@ void
dostkcheck(void)
{
Chain ch;
- Sym *s;
+ LSym *s;
- morestack = lookup("runtime.morestack", 0);
- newstack = lookup("runtime.newstack", 0);
+ morestack = linklookup(ctxt, "runtime.morestack", 0);
+ newstack = linklookup(ctxt, "runtime.newstack", 0);
// First the nosplits on their own.
- for(s = textp; s != nil; s = s->next) {
- if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) == 0)
+ for(s = ctxt->textp; s != nil; s = s->next) {
+ if(s->text == nil || s->text->link == nil || (ctxt->arch->textflag(s->text) & NOSPLIT) == 0)
continue;
- cursym = s;
+ ctxt->cursym = s;
ch.up = nil;
ch.sym = s;
ch.limit = StackLimit - CallSize;
@@ -1695,10 +1005,10 @@ dostkcheck(void)
// like newproc and deferproc. We could hard-code
// that knowledge but it's more robust to look at
// the actual call sites.
- for(s = textp; s != nil; s = s->next) {
- if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) != 0)
+ for(s = ctxt->textp; s != nil; s = s->next) {
+ if(s->text == nil || s->text->link == nil || (ctxt->arch->textflag(s->text) & NOSPLIT) != 0)
continue;
- cursym = s;
+ ctxt->cursym = s;
ch.up = nil;
ch.sym = s;
ch.limit = StackLimit - CallSize;
@@ -1711,7 +1021,7 @@ stkcheck(Chain *up, int depth)
{
Chain ch, ch1;
Prog *p;
- Sym *s;
+ LSym *s;
int limit, prolog;
limit = up->limit;
@@ -1732,7 +1042,7 @@ stkcheck(Chain *up, int depth)
// external function.
// should never be called directly.
// only diagnose the direct caller.
- if(depth == 1)
+ if(depth == 1 && s->type != SXREF)
diag("call to external function %s", s->name);
return -1;
}
@@ -1748,7 +1058,7 @@ stkcheck(Chain *up, int depth)
return 0;
ch.up = up;
- prolog = (s->text->textflag & NOSPLIT) == 0;
+ prolog = (ctxt->arch->textflag(s->text) & NOSPLIT) == 0;
for(p = s->text; p != P; p = p->link) {
limit -= p->spadj;
if(prolog && p->spadj != 0) {
@@ -1768,7 +1078,7 @@ stkcheck(Chain *up, int depth)
stkbroke(up, limit);
return -1;
}
- if(iscall(p)) {
+ if(ctxt->arch->iscall(p)) {
limit -= CallSize;
ch.limit = limit;
if(p->to.type == D_BRANCH) {
@@ -1814,7 +1124,7 @@ stkprint(Chain *ch, int limit)
if(ch->up == nil) {
// top of chain. ch->sym != nil.
- if(ch->sym->text->textflag & NOSPLIT)
+ if(ctxt->arch->textflag(ch->sym->text) & NOSPLIT)
print("\t%d\tassumed on entry to %s\n", ch->limit, name);
else
print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
@@ -1855,25 +1165,15 @@ headstr(int v)
return buf;
}
-void
-undef(void)
-{
- Sym *s;
-
- for(s = allsym; s != S; s = s->allsym)
- if(s->type == SXREF)
- diag("%s(%d): not defined", s->name, s->version);
-}
-
int
Yconv(Fmt *fp)
{
- Sym *s;
+ LSym *s;
Fmt fmt;
int i;
char *str;
- s = va_arg(fp->args, Sym*);
+ s = va_arg(fp->args, LSym*);
if (s == S) {
fmtprint(fp, "<nil>");
} else {
@@ -1985,22 +1285,22 @@ doversion(void)
}
void
-genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
+genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
{
Auto *a;
- Sym *s;
+ LSym *s;
int32 off;
// These symbols won't show up in the first loop below because we
// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
- s = lookup("text", 0);
+ s = linklookup(ctxt, "text", 0);
if(s->type == STEXT)
put(s, s->name, 'T', s->value, s->size, s->version, 0);
- s = lookup("etext", 0);
+ s = linklookup(ctxt, "etext", 0);
if(s->type == STEXT)
put(s, s->name, 'T', s->value, s->size, s->version, 0);
- for(s=allsym; s!=S; s=s->allsym) {
+ for(s=ctxt->allsym; s!=S; s=s->allsym) {
if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0))
continue;
switch(s->type&SMASK) {
@@ -2036,7 +1336,7 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
}
}
- for(s = textp; s != nil; s = s->next) {
+ for(s = ctxt->textp; s != nil; s = s->next) {
if(s->text == nil)
continue;
@@ -2075,461 +1375,83 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
Bflush(&bso);
}
-char*
-estrdup(char *p)
+vlong
+symaddr(LSym *s)
{
- p = strdup(p);
- if(p == nil) {
- cursym = S;
- diag("out of memory");
- errorexit();
- }
- return p;
+ if(!s->reachable)
+ diag("unreachable symbol in symaddr - %s", s->name);
+ return s->value;
}
-void*
-erealloc(void *p, long n)
-{
- p = realloc(p, n);
- if(p == nil) {
- cursym = S;
- diag("out of memory");
- errorexit();
- }
- return p;
-}
-
-// Saved history stacks encountered while reading archives.
-// Keeping them allows us to answer virtual lineno -> file:line
-// queries.
-//
-// The history stack is a complex data structure, described best at the
-// bottom of http://plan9.bell-labs.com/magic/man2html/6/a.out.
-// One of the key benefits of interpreting it here is that the runtime
-// does not have to. Perhaps some day the compilers could generate
-// a simpler linker input too.
-
-struct Hist
-{
- int32 line;
- int32 off;
- Sym *file;
-};
-
-static Hist *histcopy;
-static Hist *hist;
-static int32 nhist;
-static int32 maxhist;
-static int32 histdepth;
-static int32 nhistfile;
-static Sym *filesyms;
-
-// savehist processes a single line, off history directive
-// found in the input object file.
void
-savehist(int32 line, int32 off)
+xdefine(char *p, int t, vlong v)
{
- char tmp[1024];
- Sym *file;
- Hist *h;
-
- // NOTE(rsc): We used to do the copyhistfrog first and this
- // condition was if(tmp[0] != '\0') to check for an empty string,
- // implying that histfrogp == 0, implying that this is a history pop.
- // However, on Windows in the misc/cgo test, the linker is
- // presented with an ANAME corresponding to an empty string,
- // that ANAME ends up being the only histfrog, and thus we have
- // a situation where histfrogp > 0 (not a pop) but the path we find
- // is the empty string. Really that shouldn't happen, but it doesn't
- // seem to be bothering anyone yet, and it's easier to fix the condition
- // to test histfrogp than to track down where that empty string is
- // coming from. Probably it is coming from go tool pack's P command.
- if(histfrogp > 0) {
- tmp[0] = '\0';
- copyhistfrog(tmp, sizeof tmp);
- file = lookup(tmp, HistVersion);
- if(file->type != SFILEPATH) {
- file->value = ++nhistfile;
- file->type = SFILEPATH;
- file->next = filesyms;
- filesyms = file;
- }
- } else
- file = nil;
+ LSym *s;
- if(file != nil && line == 1 && off == 0) {
- // start of new stack
- if(histdepth != 0) {
- diag("history stack phase error: unexpected start of new stack depth=%d file=%s", histdepth, tmp);
- errorexit();
- }
- nhist = 0;
- histcopy = nil;
- }
-
- if(nhist >= maxhist) {
- if(maxhist == 0)
- maxhist = 1;
- maxhist *= 2;
- hist = erealloc(hist, maxhist*sizeof hist[0]);
- }
- h = &hist[nhist++];
- h->line = line;
- h->off = off;
- h->file = file;
-
- if(file != nil) {
- if(off == 0)
- histdepth++;
- } else {
- if(off != 0) {
- diag("history stack phase error: bad offset in pop");
- errorexit();
- }
- histdepth--;
- }
+ s = linklookup(ctxt, p, 0);
+ s->type = t;
+ s->value = v;
+ s->reachable = 1;
+ s->special = 1;
}
-// gethist returns the history stack currently in effect.
-// The result is valid indefinitely.
-Hist*
-gethist(void)
+vlong
+datoff(vlong addr)
{
- if(histcopy == nil) {
- if(nhist == 0)
- return nil;
- histcopy = mal((nhist+1)*sizeof hist[0]);
- memmove(histcopy, hist, nhist*sizeof hist[0]);
- histcopy[nhist].line = -1;
- }
- return histcopy;
+ if(addr >= segdata.vaddr)
+ return addr - segdata.vaddr + segdata.fileoff;
+ if(addr >= segtext.vaddr)
+ return addr - segtext.vaddr + segtext.fileoff;
+ diag("datoff %#llx", addr);
+ return 0;
}
-typedef struct Hstack Hstack;
-struct Hstack
-{
- Hist *h;
- int delta;
-};
-
-// getline sets *f to the file number and *l to the line number
-// of the virtual line number line according to the history stack h.
-void
-getline(Hist *h, int32 line, int32 *f, int32 *l)
+vlong
+entryvalue(void)
{
- Hstack stk[100];
- int nstk, start;
- Hist *top, *h0;
- static Hist *lasth;
- static int32 laststart, lastend, lastdelta, lastfile;
+ char *a;
+ LSym *s;
- h0 = h;
- *f = 0;
- *l = 0;
- start = 0;
- if(h == nil || line == 0) {
- print("%s: getline: h=%p line=%d\n", cursym->name, h, line);
- return;
- }
-
- // Cache span used during last lookup, so that sequential
- // translation of line numbers in compiled code is efficient.
- if(!debug['O'] && lasth == h && laststart <= line && line < lastend) {
- *f = lastfile;
- *l = line - lastdelta;
- return;
- }
-
- if(debug['O'])
- print("getline %d laststart=%d lastend=%d\n", line, laststart, lastend);
-
- nstk = 0;
- for(; h->line != -1; h++) {
- if(debug['O'])
- print("\t%s %d %d\n", h->file ? h->file->name : "?", h->line, h->off);
-
- if(h->line > line) {
- if(nstk == 0) {
- diag("history stack phase error: empty stack at line %d", (int)line);
- errorexit();
- }
- top = stk[nstk-1].h;
- lasth = h;
- lastfile = top->file->value;
- laststart = start;
- lastend = h->line;
- lastdelta = stk[nstk-1].delta;
- *f = lastfile;
- *l = line - lastdelta;
- if(debug['O'])
- print("\tgot %d %d [%d %d %d]\n", *f, *l, laststart, lastend, lastdelta);
- return;
- }
- if(h->file == nil) {
- // pop included file
- if(nstk == 0) {
- diag("history stack phase error: stack underflow");
- errorexit();
- }
- nstk--;
- if(nstk > 0)
- stk[nstk-1].delta += h->line - stk[nstk].h->line;
- start = h->line;
- } else if(h->off == 0) {
- // push included file
- if(nstk >= nelem(stk)) {
- diag("history stack phase error: stack overflow");
- errorexit();
- }
- start = h->line;
- stk[nstk].h = h;
- stk[nstk].delta = h->line - 1;
- nstk++;
- } else {
- // #line directive
- if(nstk == 0) {
- diag("history stack phase error: stack underflow");
- errorexit();
- }
- stk[nstk-1].h = h;
- stk[nstk-1].delta = h->line - h->off;
- start = h->line;
- }
- if(debug['O'])
- print("\t\tnstk=%d delta=%d\n", nstk, stk[nstk].delta);
- }
-
- diag("history stack phase error: cannot find line for %d", line);
- nstk = 0;
- for(h = h0; h->line != -1; h++) {
- print("\t%d %d %s\n", h->line, h->off, h->file ? h->file->name : "");
- if(h->file == nil)
- nstk--;
- else if(h->off == 0)
- nstk++;
- }
+ a = INITENTRY;
+ if(*a >= '0' && *a <= '9')
+ return atolwhex(a);
+ s = linklookup(ctxt, a, 0);
+ if(s->type == 0)
+ return INITTEXT;
+ if(s->type != STEXT)
+ diag("entry not text: %s", s->name);
+ return s->value;
}
-// defgostring returns a symbol for the Go string containing text.
-Sym*
-defgostring(char *text)
+static void
+undefsym(LSym *s)
{
- char *p;
- Sym *s;
- int32 n;
-
- n = strlen(text);
- p = smprint("go.string.\"%Z\"", text);
- s = lookup(p, 0);
- if(s->size == 0) {
- s->type = SGOSTRING;
- s->reachable = 1;
- s->size = 2*PtrSize+n;
- symgrow(s, 2*PtrSize+n);
- setaddrplus(s, 0, s, 2*PtrSize);
- setuintxx(s, PtrSize, n, PtrSize);
- memmove(s->p+2*PtrSize, text, n);
- }
- s->reachable = 1;
- return s;
-}
+ int i;
+ Reloc *r;
-// addpctab appends to f a pc-value table, storing its offset at off.
-// The pc-value table is for func and reports the value of valfunc
-// parameterized by arg.
-static int32
-addpctab(Sym *f, int32 off, Sym *func, char *desc, int32 (*valfunc)(Sym*, int32, Prog*, int32, int32), int32 arg)
-{
- int32 start;
-
- start = f->np;
- funcpctab(f, func, desc, valfunc, arg);
- if(start == f->np) {
- // no table
- return setuint32(f, off, 0);
- }
- if((int32)start > (int32)f->np) {
- diag("overflow adding pc-table: symbol too large");
- errorexit();
+ ctxt->cursym = s;
+ for(i=0; i<s->nr; i++) {
+ r = &s->r[i];
+ if(r->sym == nil) // happens for some external ARM relocs
+ continue;
+ if(r->sym->type == Sxxx || r->sym->type == SXREF) {
+ diag("undefined: %s", r->sym->name);
+ continue;
+ }
+ if(!r->sym->reachable)
+ diag("use of unreachable symbol: %s", r->sym->name);
}
- return setuint32(f, off, start);
}
-static int32
-ftabaddstring(Sym *ftab, char *s)
-{
- int32 n, start;
-
- n = strlen(s)+1;
- start = ftab->np;
- symgrow(ftab, start+n+1);
- strcpy((char*)ftab->p + start, s);
- return start;
-}
-
-// pclntab initializes the pclntab symbol with
-// runtime function and file name information.
void
-pclntab(void)
+undef(void)
{
- Prog *p;
- int32 i, n, nfunc, start, funcstart;
- uint32 *havepc, *havefunc;
- Sym *ftab, *s;
- int32 npcdata, nfuncdata, off, end;
- int64 funcdata_bytes;
-
- funcdata_bytes = 0;
- ftab = lookup("pclntab", 0);
- ftab->type = SPCLNTAB;
- ftab->reachable = 1;
-
- // See golang.org/s/go12symtab for the format. Briefly:
- // 8-byte header
- // nfunc [PtrSize bytes]
- // function table, alternating PC and offset to func struct [each entry PtrSize bytes]
- // end PC [PtrSize bytes]
- // offset to file table [4 bytes]
- nfunc = 0;
- for(cursym = textp; cursym != nil; cursym = cursym->next)
- nfunc++;
- symgrow(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize+4);
- setuint32(ftab, 0, 0xfffffffb);
- setuint8(ftab, 6, MINLC);
- setuint8(ftab, 7, PtrSize);
- setuintxx(ftab, 8, nfunc, PtrSize);
-
- nfunc = 0;
- for(cursym = textp; cursym != nil; cursym = cursym->next, nfunc++) {
- funcstart = ftab->np;
- funcstart += -ftab->np & (PtrSize-1);
-
- setaddr(ftab, 8+PtrSize+nfunc*2*PtrSize, cursym);
- setuintxx(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, funcstart, PtrSize);
-
- npcdata = 0;
- nfuncdata = 0;
- for(p = cursym->text; p != P; p = p->link) {
- if(p->as == APCDATA && p->from.offset >= npcdata)
- npcdata = p->from.offset+1;
- if(p->as == AFUNCDATA && p->from.offset >= nfuncdata)
- nfuncdata = p->from.offset+1;
- }
-
- // fixed size of struct, checked below
- off = funcstart;
- end = funcstart + PtrSize + 3*4 + 5*4 + npcdata*4 + nfuncdata*PtrSize;
- if(nfuncdata > 0 && (end&(PtrSize-1)))
- end += 4;
- symgrow(ftab, end);
-
- // entry uintptr
- off = setaddr(ftab, off, cursym);
-
- // name int32
- off = setuint32(ftab, off, ftabaddstring(ftab, cursym->name));
-
- // args int32
- // TODO: Move into funcinfo.
- if(cursym->text == nil)
- off = setuint32(ftab, off, ArgsSizeUnknown);
- else
- off = setuint32(ftab, off, cursym->args);
-
- // frame int32
- // TODO: Remove entirely. The pcsp table is more precise.
- // This is only used by a fallback case during stack walking
- // when a called function doesn't have argument information.
- // We need to make sure everything has argument information
- // and then remove this.
- if(cursym->text == nil)
- off = setuint32(ftab, off, 0);
- else
- off = setuint32(ftab, off, (uint32)cursym->text->to.offset+PtrSize);
-
- // pcsp table (offset int32)
- off = addpctab(ftab, off, cursym, "pctospadj", pctospadj, 0);
-
- // pcfile table (offset int32)
- off = addpctab(ftab, off, cursym, "pctofileline file", pctofileline, 0);
-
- // pcln table (offset int32)
- off = addpctab(ftab, off, cursym, "pctofileline line", pctofileline, 1);
-
- // npcdata int32
- off = setuint32(ftab, off, npcdata);
-
- // nfuncdata int32
- off = setuint32(ftab, off, nfuncdata);
-
- // tabulate which pc and func data we have.
- n = ((npcdata+31)/32 + (nfuncdata+31)/32)*4;
- havepc = mal(n);
- havefunc = havepc + (npcdata+31)/32;
- for(p = cursym->text; p != P; p = p->link) {
- if(p->as == AFUNCDATA) {
- if((havefunc[p->from.offset/32]>>(p->from.offset%32))&1)
- diag("multiple definitions for FUNCDATA $%d", p->from.offset);
- havefunc[p->from.offset/32] |= 1<<(p->from.offset%32);
- }
- if(p->as == APCDATA)
- havepc[p->from.offset/32] |= 1<<(p->from.offset%32);
- }
-
- // pcdata.
- for(i=0; i<npcdata; i++) {
- if(!(havepc[i/32]>>(i%32))&1) {
- off = setuint32(ftab, off, 0);
- continue;
- }
- off = addpctab(ftab, off, cursym, "pctopcdata", pctopcdata, i);
- }
-
- unmal(havepc, n);
-
- // funcdata, must be pointer-aligned and we're only int32-aligned.
- // Unlike pcdata, can gather in a single pass.
- // Missing funcdata will be 0 (nil pointer).
- if(nfuncdata > 0) {
- if(off&(PtrSize-1))
- off += 4;
- for(p = cursym->text; p != P; p = p->link) {
- if(p->as == AFUNCDATA) {
- i = p->from.offset;
- if(p->to.type == D_CONST)
- setuintxx(ftab, off+PtrSize*i, p->to.offset, PtrSize);
- else {
- // TODO: Dedup.
- funcdata_bytes += p->to.sym->size;
- setaddrplus(ftab, off+PtrSize*i, p->to.sym, p->to.offset);
- }
- }
- }
- off += nfuncdata*PtrSize;
- }
-
- if(off != end) {
- diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d)", funcstart, off, end, npcdata, nfuncdata);
- errorexit();
- }
-
- // Final entry of table is just end pc.
- if(cursym->next == nil)
- setaddrplus(ftab, 8+PtrSize+(nfunc+1)*2*PtrSize, cursym, cursym->size);
- }
+ LSym *s;
- // Start file table.
- start = ftab->np;
- start += -ftab->np & (PtrSize-1);
- setuint32(ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, start);
-
- symgrow(ftab, start+(nhistfile+1)*4);
- setuint32(ftab, start, nhistfile);
- for(s = filesyms; s != S; s = s->next)
- setuint32(ftab, start + s->value*4, ftabaddstring(ftab, s->name));
-
- ftab->size = ftab->np;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
-}
+ for(s = ctxt->textp; s != nil; s = s->next)
+ undefsym(s);
+ for(s = datap; s != nil; s = s->next)
+ undefsym(s);
+ if(nerrors > 0)
+ errorexit();
+}
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index be95bb46e8..63e2825119 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -28,68 +28,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-enum
-{
- Sxxx,
-
- /* order here is order in output file */
- /* readonly, executable */
- STEXT,
- SELFRXSECT,
-
- /* readonly, non-executable */
- STYPE,
- SSTRING,
- SGOSTRING,
- SGOFUNC,
- SRODATA,
- SFUNCTAB,
- STYPELINK,
- SSYMTAB, // TODO: move to unmapped section
- SPCLNTAB,
- SELFROSECT,
-
- /* writable, non-executable */
- SMACHOPLT,
- SELFSECT,
- SMACHO, /* Mach-O __nl_symbol_ptr */
- SMACHOGOT,
- SNOPTRDATA,
- SINITARR,
- SDATA,
- SWINDOWS,
- SBSS,
- SNOPTRBSS,
- STLSBSS,
-
- /* not mapped */
- SXREF,
- SMACHOSYMSTR,
- SMACHOSYMTAB,
- SMACHOINDIRECTPLT,
- SMACHOINDIRECTGOT,
- SFILE,
- SFILEPATH,
- SCONST,
- SDYNIMPORT,
- SHOSTOBJ,
-
- SSUB = 1<<8, /* sub-symbol, linked from parent via ->sub list */
- SMASK = SSUB - 1,
- SHIDDEN = 1<<9, // hidden or local symbol
-
- NHASH = 100003,
-};
-
-typedef struct Library Library;
-struct Library
-{
- char *objref; // object where we found the reference
- char *srcref; // src file where we found the reference
- char *file; // object file
- char *pkg; // import path
-};
-
// Terrible but standard terminology.
// A segment describes a block of file to load into memory.
// A section further describes the pieces of that block for
@@ -125,36 +63,14 @@ struct Section
uvlong rellen;
};
-typedef struct Hist Hist;
-
-#pragma incomplete struct Hist
-
extern char symname[];
-extern char **libdir;
-extern int nlibdir;
-extern int version;
EXTERN char* INITENTRY;
-EXTERN char* thestring;
-EXTERN Library* library;
-EXTERN int libraryp;
-EXTERN int nlibrary;
-EXTERN Sym* hash[NHASH];
-EXTERN Sym* allsym;
-EXTERN Sym* histfrog[MAXHIST];
-EXTERN uchar fnuxi8[8];
-EXTERN uchar fnuxi4[4];
-EXTERN int histfrogp;
-EXTERN int histgen;
-EXTERN uchar inuxi1[1];
-EXTERN uchar inuxi2[2];
-EXTERN uchar inuxi4[4];
-EXTERN uchar inuxi8[8];
+extern char* thestring;
+extern LinkArch* thelinkarch;
EXTERN char* outfile;
-EXTERN int32 nsymbol;
-EXTERN char* thestring;
EXTERN int ndynexp;
-EXTERN Sym** dynexp;
+EXTERN LSym** dynexp;
EXTERN int nldflag;
EXTERN char** ldflag;
EXTERN int havedynamic;
@@ -169,16 +85,20 @@ EXTERN char* tmpdir;
EXTERN char* extld;
EXTERN char* extldflags;
EXTERN int debug_s; // backup old value of debug['s']
+EXTERN Link* ctxt;
+EXTERN int32 HEADR;
+EXTERN int32 HEADTYPE;
+EXTERN int32 INITRND;
+EXTERN int64 INITTEXT;
+EXTERN int64 INITDAT;
+EXTERN char* INITENTRY; /* entry point */
+EXTERN char* noname;
+EXTERN char* paramspace;
+EXTERN int nerrors;
-enum
-{
- LinkAuto = 0,
- LinkInternal,
- LinkExternal,
-};
EXTERN int linkmode;
-// for dynexport field of Sym
+// for dynexport field of LSym
enum
{
CgoExportDynamic = 1<<0,
@@ -190,119 +110,6 @@ EXTERN Segment segrodata;
EXTERN Segment segdata;
EXTERN Segment segdwarf;
-void setlinkmode(char*);
-void addlib(char *src, char *obj);
-void addlibpath(char *srcref, char *objref, char *file, char *pkg);
-Section* addsection(Segment*, char*, int);
-void copyhistfrog(char *buf, int nbuf);
-void addhist(int32 line, int type);
-void savehist(int32 line, int32 off);
-Hist* gethist(void);
-void getline(Hist*, int32 line, int32 *f, int32 *l);
-void asmlc(void);
-void histtoauto(void);
-void collapsefrog(Sym *s);
-Sym* newsym(char *symb, int v);
-Sym* lookup(char *symb, int v);
-Sym* rlookup(char *symb, int v);
-void nuxiinit(void);
-int find1(int32 l, int c);
-int find2(int32 l, int c);
-int32 ieeedtof(Ieee *e);
-double ieeedtod(Ieee *e);
-void undefsym(Sym *s);
-void zerosig(char *sp);
-void readundefs(char *f, int t);
-void loadlib(void);
-void errorexit(void);
-void mangle(char*);
-void objfile(char *file, char *pkg);
-void libinit(void);
-void pclntab(void);
-void symtab(void);
-void Lflag(char *arg);
-void usage(void);
-void adddynrel(Sym*, Reloc*);
-void adddynrela(Sym*, Sym*, Reloc*);
-void ldobj1(Biobuf *f, char*, int64 len, char *pn);
-void ldobj(Biobuf*, char*, int64, char*, char*, int);
-void ldelf(Biobuf*, char*, int64, char*);
-void ldmacho(Biobuf*, char*, int64, char*);
-void ldpe(Biobuf*, char*, int64, char*);
-void ldpkg(Biobuf*, char*, int64, char*, int);
-void mark(Sym *s);
-void mkfwd(void);
-char* expandpkg(char*, char*);
-void deadcode(void);
-Reloc* addrel(Sym*);
-void codeblk(int32, int32);
-void datblk(int32, int32);
-void reloc(void);
-void relocsym(Sym*);
-void savedata(Sym*, Prog*, char*);
-void symgrow(Sym*, int32);
-void addstrdata(char*, char*);
-vlong addstring(Sym*, char*);
-vlong adduint8(Sym*, uint8);
-vlong adduint16(Sym*, uint16);
-vlong adduint32(Sym*, uint32);
-vlong adduint64(Sym*, uint64);
-vlong adduintxx(Sym*, uint64, int);
-vlong addaddr(Sym*, Sym*);
-vlong addaddrplus(Sym*, Sym*, vlong);
-vlong addpcrelplus(Sym*, Sym*, vlong);
-vlong addsize(Sym*, Sym*);
-vlong setaddrplus(Sym*, vlong, Sym*, vlong);
-vlong setaddr(Sym*, vlong, Sym*);
-vlong setuint8(Sym*, vlong, uint8);
-vlong setuint16(Sym*, vlong, uint16);
-vlong setuint32(Sym*, vlong, uint32);
-vlong setuint64(Sym*, vlong, uint64);
-vlong setuintxx(Sym*, vlong, uint64, vlong);
-void asmsym(void);
-void asmelfsym(void);
-void asmplan9sym(void);
-void putelfsectionsym(Sym*, int);
-void putelfsymshndx(vlong, int);
-void strnput(char*, int);
-void dodata(void);
-void dosymtype(void);
-void address(void);
-void textaddress(void);
-void genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*));
-vlong datoff(vlong);
-void adddynlib(char*);
-int archreloc(Reloc*, Sym*, vlong*);
-void adddynsym(Sym*);
-void addexport(void);
-void dostkcheck(void);
-void undef(void);
-void doweak(void);
-void setpersrc(Sym*);
-void doversion(void);
-void usage(void);
-void setinterp(char*);
-Sym* listsort(Sym*, int(*cmp)(Sym*, Sym*), int);
-int valuecmp(Sym*, Sym*);
-void hostobjs(void);
-void hostlink(void);
-char* estrdup(char*);
-void* erealloc(void*, long);
-Sym* defgostring(char*);
-
-int pathchar(void);
-void* mal(uint32);
-void unmal(void*, uint32);
-void mywhatsys(void);
-int rbyoff(const void*, const void*);
-
-uint16 le16(uchar*);
-uint32 le32(uchar*);
-uint64 le64(uchar*);
-uint16 be16(uchar*);
-uint32 be32(uchar*);
-uint64 be64(uchar*);
-
typedef struct Endian Endian;
struct Endian
{
@@ -325,28 +132,6 @@ enum {
Pkgdef
};
-/* executable header types */
-enum {
- Hgarbunix = 0, // garbage unix
- Hnoheader, // no header
- Hunixcoff, // unix coff
- Hrisc, // aif for risc os
- Hplan9x32, // plan 9 32-bit format
- Hplan9x64, // plan 9 64-bit format
- Hmsdoscom, // MS-DOS .COM
- Hnetbsd, // NetBSD
- Hmsdosexe, // fake MS-DOS .EXE
- Hixp1200, // IXP1200 (raw)
- Helf, // ELF32
- Hipaq, // ipaq
- Hdarwin, // Apple Mach-O
- Hlinux, // Linux ELF
- Hfreebsd, // FreeBSD ELF
- Hwindows, // MS Windows PE
- Hopenbsd, // OpenBSD ELF
- Hdragonfly, // DragonFly ELF
-};
-
typedef struct Header Header;
struct Header {
char *name;
@@ -356,14 +141,8 @@ struct Header {
EXTERN char* headstring;
extern Header headers[];
-int headtype(char*);
-char* headstr(int);
-void setheadtype(char*);
-
-int Yconv(Fmt*);
-
#pragma varargck type "O" int
-#pragma varargck type "Y" Sym*
+#pragma varargck type "Y" LSym*
// buffered output
@@ -383,29 +162,115 @@ EXTERN char* cbpmax;
if(--cbc <= 0)\
cflush(); }
+EXTERN int goarm;
+
+void Lflag(char *arg);
+int Yconv(Fmt *fp);
+int Zconv(Fmt *fp);
+void addexport(void);
+void address(void);
+Section*addsection(Segment *seg, char *name, int rwx);
+void addstrdata(char *name, char *value);
+vlong addstring(LSym *s, char *str);
+void asmelfsym(void);
+void asmplan9sym(void);
+uint16 be16(uchar *b);
+uint32 be32(uchar *b);
+uint64 be64(uchar *b);
void cflush(void);
+void codeblk(int32 addr, int32 size);
vlong cpos(void);
-void cseek(vlong);
-void cwrite(void*, int);
+void cseek(vlong p);
+void cwrite(void *buf, int n);
+void datblk(int32 addr, int32 size);
+int datcmp(LSym *s1, LSym *s2);
+vlong datoff(vlong addr);
+void deadcode(void);
+LSym* decodetype_arrayelem(LSym *s);
+vlong decodetype_arraylen(LSym *s);
+LSym* decodetype_chanelem(LSym *s);
+int decodetype_funcdotdotdot(LSym *s);
+int decodetype_funcincount(LSym *s);
+LSym* decodetype_funcintype(LSym *s, int i);
+int decodetype_funcoutcount(LSym *s);
+LSym* decodetype_funcouttype(LSym *s, int i);
+LSym* decodetype_gc(LSym *s);
+vlong decodetype_ifacemethodcount(LSym *s);
+uint8 decodetype_kind(LSym *s);
+LSym* decodetype_mapkey(LSym *s);
+LSym* decodetype_mapvalue(LSym *s);
+LSym* decodetype_ptrelem(LSym *s);
+vlong decodetype_size(LSym *s);
+int decodetype_structfieldcount(LSym *s);
+char* decodetype_structfieldname(LSym *s, int i);
+vlong decodetype_structfieldoffs(LSym *s, int i);
+LSym* decodetype_structfieldtype(LSym *s, int i);
+void dodata(void);
+void dostkcheck(void);
+void dostkoff(void);
+void dosymtype(void);
+void doversion(void);
+void doweak(void);
+void dynreloc(void);
+void dynrelocsym(LSym *s);
+vlong entryvalue(void);
+void errorexit(void);
+void follow(void);
+void genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*));
+void growdatsize(vlong *datsizep, LSym *s);
+char* headstr(int v);
+int headtype(char *name);
+void hostlink(void);
+void hostobjs(void);
+int iconv(Fmt *fp);
void importcycles(void);
-int Zconv(Fmt*);
-
-uint8 decodetype_kind(Sym*);
-vlong decodetype_size(Sym*);
-Sym* decodetype_gc(Sym*);
-Sym* decodetype_arrayelem(Sym*);
-vlong decodetype_arraylen(Sym*);
-Sym* decodetype_ptrelem(Sym*);
-Sym* decodetype_mapkey(Sym*);
-Sym* decodetype_mapvalue(Sym*);
-Sym* decodetype_chanelem(Sym*);
-int decodetype_funcdotdotdot(Sym*);
-int decodetype_funcincount(Sym*);
-int decodetype_funcoutcount(Sym*);
-Sym* decodetype_funcintype(Sym*, int);
-Sym* decodetype_funcouttype(Sym*, int);
-int decodetype_structfieldcount(Sym*);
-char* decodetype_structfieldname(Sym*, int);
-Sym* decodetype_structfieldtype(Sym*, int);
-vlong decodetype_structfieldoffs(Sym*, int);
-vlong decodetype_ifacemethodcount(Sym*);
+void ldelf(Biobuf *f, char *pkg, int64 len, char *pn);
+void ldhostobj(void (*ld)(Biobuf*, char*, int64, char*), Biobuf *f, char *pkg, int64 len, char *pn, char *file);
+void ldmacho(Biobuf *f, char *pkg, int64 len, char *pn);
+void ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence);
+void ldpe(Biobuf *f, char *pkg, int64 len, char *pn);
+void ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence);
+uint16 le16(uchar *b);
+uint32 le32(uchar *b);
+uint64 le64(uchar *b);
+void libinit(void);
+LSym* listsort(LSym *l, int (*cmp)(LSym*, LSym*), int off);
+void loadinternal(char *name);
+void loadlib(void);
+void lputb(int32 l);
+void lputl(int32 l);
+void* mal(uint32 n);
+void mark(LSym *s);
+void mywhatsys(void);
+struct ar_hdr;
+int nextar(Biobuf *bp, int off, struct ar_hdr *a);
+void objfile(char *file, char *pkg);
+void patch(void);
+int pathchar(void);
+void pcln(void);
+void pclntab(void);
+void putelfsectionsym(LSym* s, int shndx);
+void putelfsymshndx(vlong sympos, int shndx);
+void putsymb(LSym *s, char *name, int t, vlong v, vlong size, int ver, LSym *typ);
+int rbyoff(const void *va, const void *vb);
+void reloc(void);
+void relocsym(LSym *s);
+void setheadtype(char *s);
+void setinterp(char *s);
+void setlinkmode(char *arg);
+void span(void);
+void strnput(char *s, int n);
+vlong symaddr(LSym *s);
+void symtab(void);
+void textaddress(void);
+void undef(void);
+void unmal(void *v, uint32 n);
+void usage(void);
+void vputb(uint64 v);
+int valuecmp(LSym *a, LSym *b);
+void vputl(uint64 v);
+void wputb(ushort w);
+void wputl(ushort w);
+void xdefine(char *p, int t, vlong v);
+void zerosig(char *sp);
+void archinit(void);
diff --git a/src/cmd/ld/macho.c b/src/cmd/ld/macho.c
index d135a92daf..49db83eea2 100644
--- a/src/cmd/ld/macho.c
+++ b/src/cmd/ld/macho.c
@@ -25,7 +25,7 @@ enum
};
static int nkind[NumSymKind];
-static Sym** sortsym;
+static LSym** sortsym;
static int nsortsym;
// Amount of space left for adding load commands
@@ -232,37 +232,37 @@ machowrite(void)
void
domacho(void)
{
- Sym *s;
+ LSym *s;
if(debug['d'])
return;
// empirically, string table must begin with " \x00".
- s = lookup(".machosymstr", 0);
+ s = linklookup(ctxt, ".machosymstr", 0);
s->type = SMACHOSYMSTR;
s->reachable = 1;
- adduint8(s, ' ');
- adduint8(s, '\0');
+ adduint8(ctxt, s, ' ');
+ adduint8(ctxt, s, '\0');
- s = lookup(".machosymtab", 0);
+ s = linklookup(ctxt, ".machosymtab", 0);
s->type = SMACHOSYMTAB;
s->reachable = 1;
if(linkmode != LinkExternal) {
- s = lookup(".plt", 0); // will be __symbol_stub
+ s = linklookup(ctxt, ".plt", 0); // will be __symbol_stub
s->type = SMACHOPLT;
s->reachable = 1;
- s = lookup(".got", 0); // will be __nl_symbol_ptr
+ s = linklookup(ctxt, ".got", 0); // will be __nl_symbol_ptr
s->type = SMACHOGOT;
s->reachable = 1;
s->align = 4;
- s = lookup(".linkedit.plt", 0); // indirect table for .plt
+ s = linklookup(ctxt, ".linkedit.plt", 0); // indirect table for .plt
s->type = SMACHOINDIRECTPLT;
s->reachable = 1;
- s = lookup(".linkedit.got", 0); // indirect table for .got
+ s = linklookup(ctxt, ".linkedit.got", 0); // indirect table for .got
s->type = SMACHOINDIRECTGOT;
s->reachable = 1;
}
@@ -334,7 +334,7 @@ machoshbits(MachoSeg *mseg, Section *sect, char *segname)
if(strcmp(sect->name, ".got") == 0) {
msect->name = "__nl_symbol_ptr";
msect->flag = 6; /* section with nonlazy symbol pointers */
- msect->res1 = lookup(".linkedit.plt", 0)->size / 4; /* offset into indirect symbol table */
+ msect->res1 = linklookup(ctxt, ".linkedit.plt", 0)->size / 4; /* offset into indirect symbol table */
}
}
@@ -432,13 +432,13 @@ asmbmacho(void)
}
if(!debug['d']) {
- Sym *s1, *s2, *s3, *s4;
+ LSym *s1, *s2, *s3, *s4;
// must match domacholink below
- s1 = lookup(".machosymtab", 0);
- s2 = lookup(".linkedit.plt", 0);
- s3 = lookup(".linkedit.got", 0);
- s4 = lookup(".machosymstr", 0);
+ s1 = linklookup(ctxt, ".machosymtab", 0);
+ s2 = linklookup(ctxt, ".linkedit.plt", 0);
+ s3 = linklookup(ctxt, ".linkedit.got", 0);
+ s4 = linklookup(ctxt, ".machosymstr", 0);
if(linkmode != LinkExternal) {
ms = newMachoSeg("__LINKEDIT", 0);
@@ -484,7 +484,7 @@ asmbmacho(void)
}
static int
-symkind(Sym *s)
+symkind(LSym *s)
{
if(s->type == SDYNIMPORT)
return SymKindUndef;
@@ -494,7 +494,7 @@ symkind(Sym *s)
}
static void
-addsym(Sym *s, char *name, int type, vlong addr, vlong size, int ver, Sym *gotype)
+addsym(LSym *s, char *name, int type, vlong addr, vlong size, int ver, LSym *gotype)
{
USED(name);
USED(addr);
@@ -524,11 +524,11 @@ addsym(Sym *s, char *name, int type, vlong addr, vlong size, int ver, Sym *gotyp
static int
scmp(const void *p1, const void *p2)
{
- Sym *s1, *s2;
+ LSym *s1, *s2;
int k1, k2;
- s1 = *(Sym**)p1;
- s2 = *(Sym**)p2;
+ s1 = *(LSym**)p1;
+ s2 = *(LSym**)p2;
k1 = symkind(s1);
k2 = symkind(s2);
@@ -539,12 +539,12 @@ scmp(const void *p1, const void *p2)
}
static void
-machogenasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
+machogenasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
{
- Sym *s;
+ LSym *s;
genasmsym(put);
- for(s=allsym; s; s=s->allsym)
+ for(s=ctxt->allsym; s; s=s->allsym)
if(s->type == SDYNIMPORT || s->type == SHOSTOBJ)
if(s->reachable)
put(s, nil, 'D', 0, 0, 0, nil);
@@ -573,39 +573,39 @@ static void
machosymtab(void)
{
int i;
- Sym *symtab, *symstr, *s, *o;
+ LSym *symtab, *symstr, *s, *o;
- symtab = lookup(".machosymtab", 0);
- symstr = lookup(".machosymstr", 0);
+ symtab = linklookup(ctxt, ".machosymtab", 0);
+ symstr = linklookup(ctxt, ".machosymstr", 0);
for(i=0; i<nsortsym; i++) {
s = sortsym[i];
- adduint32(symtab, symstr->size);
+ adduint32(ctxt, symtab, symstr->size);
// Only add _ to C symbols. Go symbols have dot in the name.
if(strstr(s->extname, ".") == nil)
- adduint8(symstr, '_');
+ adduint8(ctxt, symstr, '_');
addstring(symstr, s->extname);
if(s->type == SDYNIMPORT || s->type == SHOSTOBJ) {
- adduint8(symtab, 0x01); // type N_EXT, external symbol
- adduint8(symtab, 0); // no section
- adduint16(symtab, 0); // desc
- adduintxx(symtab, 0, PtrSize); // no value
+ adduint8(ctxt, symtab, 0x01); // type N_EXT, external symbol
+ adduint8(ctxt, symtab, 0); // no section
+ adduint16(ctxt, symtab, 0); // desc
+ adduintxx(ctxt, symtab, 0, PtrSize); // no value
} else {
if(s->cgoexport)
- adduint8(symtab, 0x0f);
+ adduint8(ctxt, symtab, 0x0f);
else
- adduint8(symtab, 0x0e);
+ adduint8(ctxt, symtab, 0x0e);
o = s;
while(o->outer != nil)
o = o->outer;
if(o->sect == nil) {
diag("missing section for %s", s->name);
- adduint8(symtab, 0);
+ adduint8(ctxt, symtab, 0);
} else
- adduint8(symtab, o->sect->extnum);
- adduint16(symtab, 0); // desc
- adduintxx(symtab, symaddr(s), PtrSize);
+ adduint8(ctxt, symtab, o->sect->extnum);
+ adduint16(ctxt, symtab, 0); // desc
+ adduintxx(ctxt, symtab, symaddr(s), PtrSize);
}
}
}
@@ -615,7 +615,7 @@ machodysymtab(void)
{
int n;
MachoLoad *ml;
- Sym *s1, *s2, *s3;
+ LSym *s1, *s2, *s3;
ml = newMachoLoad(11, 18); /* LC_DYSYMTAB */
@@ -639,9 +639,9 @@ machodysymtab(void)
ml->data[11] = 0; /* nextrefsyms */
// must match domacholink below
- s1 = lookup(".machosymtab", 0);
- s2 = lookup(".linkedit.plt", 0);
- s3 = lookup(".linkedit.got", 0);
+ s1 = linklookup(ctxt, ".machosymtab", 0);
+ s2 = linklookup(ctxt, ".linkedit.plt", 0);
+ s3 = linklookup(ctxt, ".linkedit.got", 0);
ml->data[12] = linkoff + s1->size; /* indirectsymoff */
ml->data[13] = (s2->size + s3->size) / 4; /* nindirectsyms */
@@ -655,15 +655,15 @@ vlong
domacholink(void)
{
int size;
- Sym *s1, *s2, *s3, *s4;
+ LSym *s1, *s2, *s3, *s4;
machosymtab();
// write data that will be linkedit section
- s1 = lookup(".machosymtab", 0);
- s2 = lookup(".linkedit.plt", 0);
- s3 = lookup(".linkedit.got", 0);
- s4 = lookup(".machosymstr", 0);
+ s1 = linklookup(ctxt, ".machosymtab", 0);
+ s2 = linklookup(ctxt, ".linkedit.plt", 0);
+ s3 = linklookup(ctxt, ".linkedit.got", 0);
+ s4 = linklookup(ctxt, ".machosymstr", 0);
// Force the linkedit section to end on a 16-byte
// boundary. This allows pure (non-cgo) Go binaries
@@ -683,7 +683,7 @@ domacholink(void)
// any alignment padding itself, working around the
// issue.
while(s4->size%16)
- adduint8(s4, 0);
+ adduint8(ctxt, s4, 0);
size = s1->size + s2->size + s3->size + s4->size;
@@ -702,9 +702,9 @@ domacholink(void)
void
-machorelocsect(Section *sect, Sym *first)
+machorelocsect(Section *sect, LSym *first)
{
- Sym *sym;
+ LSym *sym;
int32 eaddr;
Reloc *r;
@@ -726,7 +726,7 @@ machorelocsect(Section *sect, Sym *first)
continue;
if(sym->value >= eaddr)
break;
- cursym = sym;
+ ctxt->cursym = sym;
for(r = sym->r; r < sym->r+sym->nr; r++) {
if(r->done)
@@ -747,7 +747,7 @@ machoemitreloc(void)
while(cpos()&7)
cput(0);
- machorelocsect(segtext.sect, textp);
+ machorelocsect(segtext.sect, ctxt->textp);
for(sect=segtext.sect->next; sect!=nil; sect=sect->next)
machorelocsect(sect, datap);
for(sect=segdata.sect; sect!=nil; sect=sect->next)
diff --git a/src/cmd/ld/pass.c b/src/cmd/ld/pass.c
new file mode 100644
index 0000000000..788b7c75a6
--- /dev/null
+++ b/src/cmd/ld/pass.c
@@ -0,0 +1,104 @@
+// Inferno utils/6l/pass.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6l/pass.c
+//
+// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+// Portions Copyright © 1997-1999 Vita Nuova Limited
+// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+// Portions Copyright © 2004,2006 Bruce Ellis
+// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+// Portions Copyright © 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// Code and data passes.
+
+#include "l.h"
+#include "../ld/lib.h"
+#include "../../pkg/runtime/stack.h"
+
+void
+follow(void)
+{
+ LSym *s;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f follow\n", cputime());
+ Bflush(&bso);
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ ctxt->arch->follow(ctxt, s);
+}
+
+void
+patch(void)
+{
+ LSym *s;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f mkfwd\n", cputime());
+ Bflush(&bso);
+ for(s = ctxt->textp; s != nil; s = s->next)
+ mkfwd(s);
+ if(debug['v'])
+ Bprint(&bso, "%5.2f patch\n", cputime());
+ Bflush(&bso);
+
+ if(flag_shared) {
+ s = linklookup(ctxt, "init_array", 0);
+ s->type = SINITARR;
+ s->reachable = 1;
+ s->hide = 1;
+ addaddr(ctxt, s, linklookup(ctxt, INITENTRY, 0));
+ }
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ linkpatch(ctxt, s);
+}
+
+void
+dostkoff(void)
+{
+ LSym *s;
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ ctxt->arch->addstacksplit(ctxt, s);
+}
+
+void
+span(void)
+{
+ LSym *s;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f span\n", cputime());
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ ctxt->arch->assemble(ctxt, s);
+}
+
+void
+pcln(void)
+{
+ LSym *s;
+
+ for(s = ctxt->textp; s != nil; s = s->next)
+ linkpcln(ctxt, s);
+}
diff --git a/src/cmd/ld/pcln.c b/src/cmd/ld/pcln.c
new file mode 100644
index 0000000000..5934dbcdfa
--- /dev/null
+++ b/src/cmd/ld/pcln.c
@@ -0,0 +1,258 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "l.h"
+#include "lib.h"
+#include "../../pkg/runtime/funcdata.h"
+
+static void
+addvarint(Pcdata *d, uint32 val)
+{
+ int32 n;
+ uint32 v;
+ uchar *p;
+
+ n = 0;
+ for(v = val; v >= 0x80; v >>= 7)
+ n++;
+ n++;
+
+ if(d->n + n > d->m) {
+ d->m = (d->n + n)*2;
+ d->p = erealloc(d->p, d->m);
+ }
+
+ p = d->p + d->n;
+ for(v = val; v >= 0x80; v >>= 7)
+ *p++ = v | 0x80;
+ *p++ = v;
+ d->n += n;
+}
+
+static int32
+addpctab(LSym *ftab, int32 off, Pcdata *d)
+{
+ int32 start;
+
+ start = ftab->np;
+ symgrow(ctxt, ftab, start + d->n);
+ memmove(ftab->p + start, d->p, d->n);
+
+ return setuint32(ctxt, ftab, off, start);
+}
+
+static int32
+ftabaddstring(LSym *ftab, char *s)
+{
+ int32 n, start;
+
+ n = strlen(s)+1;
+ start = ftab->np;
+ symgrow(ctxt, ftab, start+n+1);
+ strcpy((char*)ftab->p + start, s);
+ return start;
+}
+
+static uint32
+getvarint(uchar **pp)
+{
+ uchar *p;
+ int shift;
+ uint32 v;
+
+ v = 0;
+ p = *pp;
+ for(shift = 0;; shift += 7) {
+ v |= (*p & 0x7F) << shift;
+ if(!(*p++ & 0x80))
+ break;
+ }
+ *pp = p;
+ return v;
+}
+
+static void
+renumberfiles(LSym **files, int nfiles, Pcdata *d)
+{
+ int i;
+ LSym *f;
+ Pcdata out;
+ uint32 v;
+ int32 oldval, newval, val, dv;
+ uchar *p;
+
+ // Give files numbers.
+ for(i=0; i<nfiles; i++) {
+ f = files[i];
+ if(f->type != SFILEPATH) {
+ f->value = ++ctxt->nhistfile;
+ f->type = SFILEPATH;
+ f->next = ctxt->filesyms;
+ ctxt->filesyms = f;
+ }
+ }
+
+ oldval = -1;
+ newval = -1;
+ memset(&out, 0, sizeof out);
+ p = d->p;
+ while(p < d->p + d->n) {
+ // value delta
+ v = getvarint(&p);
+ if(v == 0 && p != d->p) {
+ addvarint(&out, 0);
+ break;
+ }
+ dv = (int32)(v>>1) ^ ((int32)(v<<31)>>31);
+ oldval += dv;
+ if(oldval == -1)
+ val = -1;
+ else {
+ if(oldval < 0 || oldval >= nfiles)
+ sysfatal("bad pcdata %d", oldval);
+ val = files[oldval]->value;
+ }
+ dv = val - newval;
+ v = (uint32)(dv<<1) ^ (uint32)(dv>>31);
+ addvarint(&out, v);
+
+ // pc delta
+ v = getvarint(&p);
+ addvarint(&out, v);
+ }
+
+ free(d->p);
+ *d = out;
+}
+
+
+// pclntab initializes the pclntab symbol with
+// runtime function and file name information.
+void
+pclntab(void)
+{
+ int32 i, nfunc, start, funcstart;
+ LSym *ftab, *s;
+ int32 off, end;
+ int64 funcdata_bytes;
+ Pcln *pcln;
+ static Pcln zpcln;
+
+ funcdata_bytes = 0;
+ ftab = linklookup(ctxt, "pclntab", 0);
+ ftab->type = SPCLNTAB;
+ ftab->reachable = 1;
+
+ // See golang.org/s/go12symtab for the format. Briefly:
+ // 8-byte header
+ // nfunc [PtrSize bytes]
+ // function table, alternating PC and offset to func struct [each entry PtrSize bytes]
+ // end PC [PtrSize bytes]
+ // offset to file table [4 bytes]
+ nfunc = 0;
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next)
+ nfunc++;
+ symgrow(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize+4);
+ setuint32(ctxt, ftab, 0, 0xfffffffb);
+ setuint8(ctxt, ftab, 6, MINLC);
+ setuint8(ctxt, ftab, 7, PtrSize);
+ setuintxx(ctxt, ftab, 8, nfunc, PtrSize);
+
+ nfunc = 0;
+ for(ctxt->cursym = ctxt->textp; ctxt->cursym != nil; ctxt->cursym = ctxt->cursym->next, nfunc++) {
+ pcln = ctxt->cursym->pcln;
+ if(pcln == nil)
+ pcln = &zpcln;
+
+ funcstart = ftab->np;
+ funcstart += -ftab->np & (PtrSize-1);
+
+ setaddr(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize, ctxt->cursym);
+ setuintxx(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, funcstart, PtrSize);
+
+ // fixed size of struct, checked below
+ off = funcstart;
+ end = funcstart + PtrSize + 3*4 + 5*4 + pcln->npcdata*4 + pcln->nfuncdata*PtrSize;
+ if(pcln->nfuncdata > 0 && (end&(PtrSize-1)))
+ end += 4;
+ symgrow(ctxt, ftab, end);
+
+ // entry uintptr
+ off = setaddr(ctxt, ftab, off, ctxt->cursym);
+
+ // name int32
+ off = setuint32(ctxt, ftab, off, ftabaddstring(ftab, ctxt->cursym->name));
+
+ // args int32
+ // TODO: Move into funcinfo.
+ if(ctxt->cursym->text == nil)
+ off = setuint32(ctxt, ftab, off, ArgsSizeUnknown);
+ else
+ off = setuint32(ctxt, ftab, off, ctxt->cursym->args);
+
+ // frame int32
+ // TODO: Remove entirely. The pcsp table is more precise.
+ // This is only used by a fallback case during stack walking
+ // when a called function doesn't have argument information.
+ // We need to make sure everything has argument information
+ // and then remove this.
+ if(ctxt->cursym->text == nil)
+ off = setuint32(ctxt, ftab, off, 0);
+ else
+ off = setuint32(ctxt, ftab, off, (uint32)ctxt->cursym->text->to.offset+PtrSize);
+
+ if(pcln != &zpcln)
+ renumberfiles(pcln->file, pcln->nfile, &pcln->pcfile);
+
+ // pcdata
+ off = addpctab(ftab, off, &pcln->pcsp);
+ off = addpctab(ftab, off, &pcln->pcfile);
+ off = addpctab(ftab, off, &pcln->pcline);
+ off = setuint32(ctxt, ftab, off, pcln->npcdata);
+ off = setuint32(ctxt, ftab, off, pcln->nfuncdata);
+ for(i=0; i<pcln->npcdata; i++)
+ off = addpctab(ftab, off, &pcln->pcdata[i]);
+
+ // funcdata, must be pointer-aligned and we're only int32-aligned.
+ // Missing funcdata will be 0 (nil pointer).
+ if(pcln->nfuncdata > 0) {
+ if(off&(PtrSize-1))
+ off += 4;
+ for(i=0; i<pcln->nfuncdata; i++) {
+ if(pcln->funcdata[i] == nil)
+ setuintxx(ctxt, ftab, off+PtrSize*i, pcln->funcdataoff[i], PtrSize);
+ else {
+ // TODO: Dedup.
+ funcdata_bytes += pcln->funcdata[i]->size;
+ setaddrplus(ctxt, ftab, off+PtrSize*i, pcln->funcdata[i], pcln->funcdataoff[i]);
+ }
+ }
+ off += pcln->nfuncdata*PtrSize;
+ }
+
+ if(off != end) {
+ diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d)", funcstart, off, end, pcln->npcdata, pcln->nfuncdata);
+ errorexit();
+ }
+
+ // Final entry of table is just end pc.
+ if(ctxt->cursym->next == nil)
+ setaddrplus(ctxt, ftab, 8+PtrSize+(nfunc+1)*2*PtrSize, ctxt->cursym, ctxt->cursym->size);
+ }
+
+ // Start file table.
+ start = ftab->np;
+ start += -ftab->np & (PtrSize-1);
+ setuint32(ctxt, ftab, 8+PtrSize+nfunc*2*PtrSize+PtrSize, start);
+
+ symgrow(ctxt, ftab, start+(ctxt->nhistfile+1)*4);
+ setuint32(ctxt, ftab, start, ctxt->nhistfile);
+ for(s = ctxt->filesyms; s != S; s = s->next)
+ setuint32(ctxt, ftab, start + s->value*4, ftabaddstring(ftab, s->name));
+
+ ftab->size = ftab->np;
+
+ if(debug['v'])
+ Bprint(&bso, "%5.2f pclntab=%lld bytes, funcdata total %lld bytes\n", cputime(), (vlong)ftab->size, (vlong)funcdata_bytes);
+}
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
index 7b9a596fce..e4848643ee 100644
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -37,7 +37,7 @@ static char *symlabels[] = {
"symtab", "esymtab", "pclntab", "epclntab"
};
-static Sym *rsrcsym;
+static LSym *rsrcsym;
static char symnames[256];
static int nextsymoff;
@@ -62,7 +62,7 @@ static IMAGE_DATA_DIRECTORY* dd;
typedef struct Imp Imp;
struct Imp {
- Sym* s;
+ LSym* s;
uvlong off;
Imp* next;
};
@@ -78,7 +78,7 @@ struct Dll {
static Dll* dr;
-static Sym *dexport[1024];
+static LSym *dexport[1024];
static int nexport;
static IMAGE_SECTION_HEADER*
@@ -191,11 +191,11 @@ initdynimport(void)
{
Imp *m;
Dll *d;
- Sym *s, *dynamic;
+ LSym *s, *dynamic;
dr = nil;
m = nil;
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(!s->reachable || s->type != SDYNIMPORT)
continue;
for(d = dr; d != nil; d = d->next) {
@@ -216,7 +216,7 @@ initdynimport(void)
d->ms = m;
}
- dynamic = lookup(".windynamic", 0);
+ dynamic = linklookup(ctxt, ".windynamic", 0);
dynamic->reachable = 1;
dynamic->type = SWINDOWS;
for(d = dr; d != nil; d = d->next) {
@@ -241,10 +241,10 @@ addimports(IMAGE_SECTION_HEADER *datsect)
vlong startoff, endoff;
Imp *m;
Dll *d;
- Sym* dynamic;
+ LSym* dynamic;
startoff = cpos();
- dynamic = lookup(".windynamic", 0);
+ dynamic = linklookup(ctxt, ".windynamic", 0);
// skip import descriptor table (will write it later)
n = 0;
@@ -322,20 +322,20 @@ addimports(IMAGE_SECTION_HEADER *datsect)
static int
scmp(const void *p1, const void *p2)
{
- Sym *s1, *s2;
+ LSym *s1, *s2;
- s1 = *(Sym**)p1;
- s2 = *(Sym**)p2;
+ s1 = *(LSym**)p1;
+ s2 = *(LSym**)p2;
return strcmp(s1->extname, s2->extname);
}
static void
initdynexport(void)
{
- Sym *s;
+ LSym *s;
nexport = 0;
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(!s->reachable || !(s->cgoexport & CgoExportDynamic))
continue;
if(nexport+1 > sizeof(dexport)/sizeof(dexport[0])) {
@@ -410,10 +410,10 @@ addexports(void)
void
dope(void)
{
- Sym *rel;
+ LSym *rel;
/* relocation table */
- rel = lookup(".rel", 0);
+ rel = linklookup(ctxt, ".rel", 0);
rel->reachable = 1;
rel->type = SELFROSECT;
@@ -459,7 +459,7 @@ addsymtable(void)
{
IMAGE_SECTION_HEADER *h;
int i, size;
- Sym *s;
+ LSym *s;
fh.NumberOfSymbols = sizeof(symlabels)/sizeof(symlabels[0]);
size = nextsymoff + 4 + 18*fh.NumberOfSymbols;
@@ -471,7 +471,7 @@ addsymtable(void)
// put COFF symbol table
for (i=0; i<fh.NumberOfSymbols; i++) {
- s = rlookup(symlabels[i], 0);
+ s = linkrlookup(ctxt, symlabels[i], 0);
strnput(s->name, 8);
lputl(datoff(s->value));
wputl(textsect);
@@ -488,7 +488,7 @@ addsymtable(void)
}
void
-setpersrc(Sym *sym)
+setpersrc(LSym *sym)
{
if(rsrcsym != nil)
diag("too many .rsrc sections");
@@ -535,14 +535,14 @@ addexcept(IMAGE_SECTION_HEADER *text)
IMAGE_SECTION_HEADER *pdata, *xdata;
vlong startoff;
uvlong n;
- Sym *sym;
+ LSym *sym;
USED(text);
if(thechar != '6')
return;
// write unwind info
- sym = lookup("runtime.sigtramp", 0);
+ sym = linklookup(ctxt, "runtime.sigtramp", 0);
startoff = cpos();
lputl(9); // version=1, flags=UNW_FLAG_EHANDLER, rest 0
lputl(sym->value - PEBASE);
diff --git a/src/cmd/ld/pe.h b/src/cmd/ld/pe.h
index 7aa9388293..03ed8d830a 100644
--- a/src/cmd/ld/pe.h
+++ b/src/cmd/ld/pe.h
@@ -176,4 +176,4 @@ typedef struct {
IMAGE_DATA_DIRECTORY DataDirectory[16];
} PE64_IMAGE_OPTIONAL_HEADER;
-void setpersrc(Sym *sym);
+void setpersrc(LSym *sym);
diff --git a/src/cmd/ld/pobj.c b/src/cmd/ld/pobj.c
new file mode 100644
index 0000000000..8883d37866
--- /dev/null
+++ b/src/cmd/ld/pobj.c
@@ -0,0 +1,223 @@
+// Inferno utils/6l/obj.c
+// http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
+//
+// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
+// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
+// Portions Copyright © 1997-1999 Vita Nuova Limited
+// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
+// Portions Copyright © 2004,2006 Bruce Ellis
+// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
+// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
+// Portions Copyright © 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// Reading object files.
+
+#define EXTERN
+#include "l.h"
+#include "../ld/lib.h"
+#include "../ld/elf.h"
+#include "../ld/macho.h"
+#include "../ld/dwarf.h"
+#include "../ld/pe.h"
+#include <ar.h>
+
+char *noname = "<none>";
+char* paramspace = "FP";
+
+Header headers[] = {
+ "darwin", Hdarwin,
+ "dragonfly", Hdragonfly,
+ "elf", Helf,
+ "freebsd", Hfreebsd,
+ "linux", Hlinux,
+ "netbsd", Hnetbsd,
+ "openbsd", Hopenbsd,
+ "plan9", Hplan9,
+ "windows", Hwindows,
+ "windowsgui", Hwindows,
+ 0, 0
+};
+
+void
+main(int argc, char *argv[])
+{
+ char *p;
+
+ ctxt = linknew(thelinkarch);
+ ctxt->thechar = thechar;
+ ctxt->thestring = thestring;
+ ctxt->diag = diag;
+ ctxt->dwarfaddfrag = dwarfaddfrag;
+ ctxt->bso = &bso;
+
+ Binit(&bso, 1, OWRITE);
+ listinit();
+ memset(debug, 0, sizeof(debug));
+ nerrors = 0;
+ outfile = nil;
+ HEADTYPE = -1;
+ INITTEXT = -1;
+ INITDAT = -1;
+ INITRND = -1;
+ INITENTRY = 0;
+ linkmode = LinkAuto;
+ nuxiinit();
+
+ if(thechar == '5') {
+ p = getgoarm();
+ if(p != nil)
+ goarm = atoi(p);
+ else
+ goarm = 6;
+ if(goarm == 5)
+ debug['F'] = 1;
+ ctxt->goarm = goarm;
+ }
+
+ flagcount("1", "use alternate profiling code", &debug['1']);
+ if(thechar == '6')
+ flagcount("8", "assume 64-bit addresses", &debug['8']);
+ flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
+ flagint64("D", "addr: data address", &INITDAT);
+ flagstr("E", "sym: entry symbol", &INITENTRY);
+ if(thechar == '5')
+ flagcount("G", "debug pseudo-ops", &debug['G']);
+ flagfn1("I", "interp: set ELF interp", setinterp);
+ flagfn1("L", "dir: add dir to library path", Lflag);
+ flagfn1("H", "head: header type", setheadtype);
+ flagcount("K", "add stack underflow checks", &debug['K']);
+ if(thechar == '5')
+ flagcount("M", "disable software div/mod", &debug['M']);
+ flagcount("O", "print pc-line tables", &debug['O']);
+ flagcount("Q", "debug byte-register code gen", &debug['Q']);
+ if(thechar == '5')
+ flagcount("P", "debug code generation", &debug['P']);
+ flagint32("R", "rnd: address rounding", &INITRND);
+ flagcount("S", "check type signatures", &debug['S']);
+ flagint64("T", "addr: text address", &INITTEXT);
+ flagfn0("V", "print version and exit", doversion);
+ flagcount("W", "disassemble input", &debug['W']);
+ flagfn2("X", "name value: define string data", addstrdata);
+ flagcount("Z", "clear stack frame on entry", &debug['Z']);
+ flagcount("a", "disassemble output", &debug['a']);
+ flagcount("c", "dump call graph", &debug['c']);
+ flagcount("d", "disable dynamic executable", &debug['d']);
+ flagstr("extld", "linker to run in external mode", &extld);
+ flagstr("extldflags", "flags for external linker", &extldflags);
+ flagcount("f", "ignore version mismatch", &debug['f']);
+ flagcount("g", "disable go package data checks", &debug['g']);
+ flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
+ flagstr("k", "sym: set field tracking symbol", &tracksym);
+ flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
+ flagcount("n", "dump symbol table", &debug['n']);
+ flagstr("o", "outfile: set output file", &outfile);
+ flagstr("r", "dir1:dir2:...: set ELF dynamic linker search path", &rpath);
+ flagcount("race", "enable race detector", &flag_race);
+ flagcount("s", "disable symbol table", &debug['s']);
+ if(thechar == '5' || thechar == '6')
+ flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
+ flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
+ flagcount("u", "reject unsafe packages", &debug['u']);
+ flagcount("v", "print link trace", &debug['v']);
+ flagcount("w", "disable DWARF generation", &debug['w']);
+
+ flagparse(&argc, &argv, usage);
+ ctxt->bso = &bso;
+ ctxt->debugdivmod = debug['M'];
+ ctxt->debugfloat = debug['F'];
+ ctxt->debughist = debug['O'];
+ ctxt->debugpcln = debug['O'];
+ ctxt->debugread = debug['W'];
+ ctxt->debugstack = debug['K'];
+ ctxt->debugvlog = debug['v'];
+
+ if(argc != 1)
+ usage();
+
+ if(outfile == nil) {
+ if(HEADTYPE == Hwindows)
+ outfile = smprint("%c.out.exe", thechar);
+ else
+ outfile = smprint("%c.out", thechar);
+ }
+ libinit(); // creates outfile
+
+ if(HEADTYPE == -1)
+ HEADTYPE = headtype(goos);
+ ctxt->headtype = HEADTYPE;
+
+ archinit();
+ ctxt->linkmode = linkmode;
+ ctxt->debugfloat = debug['F'];
+
+ if(debug['v'])
+ Bprint(&bso, "HEADER = -H%d -T0x%llux -D0x%llux -R0x%ux\n",
+ HEADTYPE, INITTEXT, INITDAT, INITRND);
+ Bflush(&bso);
+
+ cbp = buf.cbuf;
+ cbc = sizeof(buf.cbuf);
+
+ addlibpath(ctxt, "command line", "command line", argv[0], "main");
+ loadlib();
+
+ if(thechar == '5') {
+ // mark some functions that are only referenced after linker code editing
+ if(debug['F'])
+ mark(linkrlookup(ctxt, "_sfloat", 0));
+ mark(linklookup(ctxt, "runtime.read_tls_fallback", 0));
+ }
+
+ deadcode();
+ patch();
+ follow();
+ dostkoff();
+ paramspace = "SP"; /* (FP) now (SP) on output */
+ span();
+ pcln();
+
+ doelf();
+ if(HEADTYPE == Hdarwin)
+ domacho();
+ dostkcheck();
+ if(HEADTYPE == Hwindows)
+ dope();
+ addexport();
+ textaddress();
+ pclntab();
+ symtab();
+ dodata();
+ address();
+ doweak();
+ reloc();
+ asmb();
+ undef();
+ hostlink();
+ if(debug['v']) {
+ Bprint(&bso, "%5.2f cpu time\n", cputime());
+ Bprint(&bso, "%d symbols\n", ctxt->nsymbol);
+ Bprint(&bso, "%d sizeof adr\n", sizeof(Addr));
+ Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
+ }
+ Bflush(&bso);
+
+ errorexit();
+}
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index c9b4657f70..54e6041483 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -86,10 +86,10 @@ static int numelfsym = 1; // 0 is reserved
static int elfbind;
static void
-putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
+putelfsym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
{
int bind, type, off;
- Sym *xo;
+ LSym *xo;
USED(go);
switch(t) {
@@ -109,12 +109,12 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
while(xo->outer != nil)
xo = xo->outer;
if(xo->sect == nil) {
- cursym = x;
+ ctxt->cursym = x;
diag("missing section in putelfsym");
return;
}
if(xo->sect->elfsect == nil) {
- cursym = x;
+ ctxt->cursym = x;
diag("missing ELF section in putelfsym");
return;
}
@@ -143,7 +143,7 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
}
void
-putelfsectionsym(Sym* s, int shndx)
+putelfsectionsym(LSym* s, int shndx)
{
putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_SECTION, shndx, 0);
s->elfsym = numelfsym++;
@@ -170,7 +170,7 @@ putelfsymshndx(vlong sympos, int shndx)
void
asmelfsym(void)
{
- Sym *s;
+ LSym *s;
// the first symbol entry is reserved
putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
@@ -181,9 +181,9 @@ asmelfsym(void)
genasmsym(putelfsym);
if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) {
- s = lookup("runtime.tlsgm", 0);
+ s = linklookup(ctxt, "runtime.tlsgm", 0);
if(s->sect == nil) {
- cursym = nil;
+ ctxt->cursym = nil;
diag("missing section for %s", s->name);
errorexit();
}
@@ -195,7 +195,7 @@ asmelfsym(void)
elfglobalsymndx = numelfsym;
genasmsym(putelfsym);
- for(s=allsym; s!=S; s=s->allsym) {
+ for(s=ctxt->allsym; s!=S; s=s->allsym) {
if(s->type != SHOSTOBJ)
continue;
putelfsyment(putelfstr(s->name), 0, 0, (STB_GLOBAL<<4)|STT_NOTYPE, 0, 0);
@@ -204,7 +204,7 @@ asmelfsym(void)
}
static void
-putplan9sym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
+putplan9sym(LSym *x, char *s, int t, vlong addr, vlong size, int ver, LSym *go)
{
int i, l;
@@ -226,7 +226,7 @@ putplan9sym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
case 'Z':
case 'm':
l = 4;
- if(HEADTYPE == Hplan9x64 && !debug['8']) {
+ if(HEADTYPE == Hplan9 && thechar == '6' && !debug['8']) {
lputb(addr>>32);
l = 8;
}
@@ -263,14 +263,14 @@ asmplan9sym(void)
genasmsym(putplan9sym);
}
-static Sym *symt;
+static LSym *symt;
static void
scput(int b)
{
uchar *p;
- symgrow(symt, symt->size+1);
+ symgrow(ctxt, symt, symt->size+1);
p = symt->p + symt->size;
*p = b;
symt->size++;
@@ -281,7 +281,7 @@ slputb(int32 v)
{
uchar *p;
- symgrow(symt, symt->size+4);
+ symgrow(ctxt, symt, symt->size+4);
p = symt->p + symt->size;
*p++ = v>>24;
*p++ = v>>16;
@@ -295,7 +295,7 @@ slputl(int32 v)
{
uchar *p;
- symgrow(symt, symt->size+4);
+ symgrow(ctxt, symt, symt->size+4);
p = symt->p + symt->size;
*p++ = v;
*p++ = v>>8;
@@ -355,7 +355,7 @@ vputl(uint64 v)
// Emit symbol table entry.
// The table format is described at the top of ../../pkg/runtime/symtab.c.
void
-putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
+putsymb(LSym *s, char *name, int t, vlong v, vlong size, int ver, LSym *typ)
{
int i, f, c;
vlong v1;
@@ -457,7 +457,7 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
void
symtab(void)
{
- Sym *s, *symtype, *symtypelink, *symgostring, *symgofunc;
+ LSym *s, *symtype, *symtypelink, *symgostring, *symgofunc;
dosymtype();
@@ -482,40 +482,40 @@ symtab(void)
xdefine("esymtab", SRODATA, 0);
// garbage collection symbols
- s = lookup("gcdata", 0);
+ s = linklookup(ctxt, "gcdata", 0);
s->type = SRODATA;
s->size = 0;
s->reachable = 1;
xdefine("egcdata", SRODATA, 0);
- s = lookup("gcbss", 0);
+ s = linklookup(ctxt, "gcbss", 0);
s->type = SRODATA;
s->size = 0;
s->reachable = 1;
xdefine("egcbss", SRODATA, 0);
// pseudo-symbols to mark locations of type, string, and go string data.
- s = lookup("type.*", 0);
+ s = linklookup(ctxt, "type.*", 0);
s->type = STYPE;
s->size = 0;
s->reachable = 1;
symtype = s;
- s = lookup("go.string.*", 0);
+ s = linklookup(ctxt, "go.string.*", 0);
s->type = SGOSTRING;
s->size = 0;
s->reachable = 1;
symgostring = s;
- s = lookup("go.func.*", 0);
+ s = linklookup(ctxt, "go.func.*", 0);
s->type = SGOFUNC;
s->size = 0;
s->reachable = 1;
symgofunc = s;
- symtypelink = lookup("typelink", 0);
+ symtypelink = linklookup(ctxt, "typelink", 0);
- symt = lookup("symtab", 0);
+ symt = linklookup(ctxt, "symtab", 0);
symt->type = SSYMTAB;
symt->size = 0;
symt->reachable = 1;
@@ -524,7 +524,7 @@ symtab(void)
// within a type they sort by size, so the .* symbols
// just defined above will be first.
// hide the specific symbols.
- for(s = allsym; s != S; s = s->allsym) {
+ for(s = ctxt->allsym; s != S; s = s->allsym) {
if(!s->reachable || s->special || s->type != SRODATA)
continue;
if(strncmp(s->name, "type.", 5) == 0) {