aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorShenghou Ma <minux.ma@gmail.com>2012-10-10 00:55:48 +0800
committerShenghou Ma <minux.ma@gmail.com>2012-10-10 00:55:48 +0800
commitfa563ae82e2d1038656be21c52831e7ad42108a8 (patch)
tree94a7df7dfaab2aae1dc44a7a7b1dc99a7415b509 /src/cmd/ld
parentcffbfaeb1819bfb6770848c4d57615f0ee1a46ba (diff)
downloadgo-fa563ae82e2d1038656be21c52831e7ad42108a8.tar.xz
cmd/ld, cmd/6l, cmd/8l: sort exported dynamic symbols for Darwin
Also corrected cmd/8l's .dynsym handling (differentiate between exported symbols and imported symbols) Fixes #4029. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/6620075
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/data.c27
-rw-r--r--src/cmd/ld/go.c25
-rw-r--r--src/cmd/ld/lib.c1
-rw-r--r--src/cmd/ld/lib.h4
4 files changed, 57 insertions, 0 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 4afe4b801c..e551f72903 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -794,6 +794,33 @@ addaddr(Sym *s, Sym *t)
}
vlong
+setaddrplus(Sym *s, vlong off, Sym *t, int32 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;
+}
+
+vlong
+setaddr(Sym *s, vlong off, Sym *t)
+{
+ return setaddrplus(s, off, t, 0);
+}
+
+vlong
addsize(Sym *s, Sym *t)
{
vlong i;
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c
index 28cf06b8bd..8def9b7301 100644
--- a/src/cmd/ld/go.c
+++ b/src/cmd/ld/go.c
@@ -932,3 +932,28 @@ importcycles(void)
for(p=pkgall; p; p=p->all)
cycle(p);
}
+
+static int
+scmp(const void *p1, const void *p2)
+{
+ Sym *s1, *s2;
+
+ s1 = *(Sym**)p1;
+ s2 = *(Sym**)p2;
+ return strcmp(s1->dynimpname, s2->dynimpname);
+}
+void
+sortdynexp(void)
+{
+ int i;
+
+ // On Mac OS X Mountain Lion, we must sort exported symbols
+ // So we sort them here and pre-allocate dynid for them
+ // See http://golang.org/issue/4029
+ if(HEADTYPE != Hdarwin)
+ return;
+ qsort(dynexp, ndynexp, sizeof dynexp[0], scmp);
+ for(i=0; i<ndynexp; i++) {
+ dynexp[i]->dynid = -i-100; // also known to [68]l/asm.c:^adddynsym
+ }
+}
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index 135426473f..8e3a8dd690 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -309,6 +309,7 @@ loadlib(void)
debug['d'] = 1;
importcycles();
+ sortdynexp();
}
/*
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index d322df5c6b..162e16180f 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -196,6 +196,8 @@ vlong addaddr(Sym*, Sym*);
vlong addaddrplus(Sym*, Sym*, int32);
vlong addpcrelplus(Sym*, Sym*, int32);
vlong addsize(Sym*, Sym*);
+vlong setaddrplus(Sym*, vlong, Sym*, int32);
+vlong setaddr(Sym*, vlong, Sym*);
void setuint8(Sym*, vlong, uint8);
void setuint16(Sym*, vlong, uint16);
void setuint32(Sym*, vlong, uint32);
@@ -341,3 +343,5 @@ char* decodetype_structfieldname(Sym*, int);
Sym* decodetype_structfieldtype(Sym*, int);
vlong decodetype_structfieldoffs(Sym*, int);
vlong decodetype_ifacemethodcount(Sym*);
+
+void sortdynexp(void);