summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShenghou Ma <minux.ma@gmail.com>2014-02-23 16:20:40 -0500
committerShenghou Ma <minux.ma@gmail.com>2014-02-23 16:20:40 -0500
commitfeb64cf95e8baf73f8a36c7e009c1a3fa925608a (patch)
tree4ef653aee42e386f9d4f85aee8e8103937993547
parentc5e144bdbfdcecef4e6f125b2cef41da84779cdf (diff)
downloadgo-feb64cf95e8baf73f8a36c7e009c1a3fa925608a.tar.gz
cmd/ld: don't emit unreachable dynimport symbols in ELF symtab.
Fix build for Dragonfly BSD. Fixes issue 7318. Fixes issue 7367. LGTM=jsing, iant R=jsing, iant, mikioh.mikioh CC=golang-codereviews https://codereview.appspot.com/64340043
-rw-r--r--misc/cgo/testso/cgoso_c.c1
-rw-r--r--misc/cgo/testso/cgoso_unix.go20
-rw-r--r--src/cmd/ld/data.c9
-rw-r--r--src/cmd/ld/symtab.c2
4 files changed, 29 insertions, 3 deletions
diff --git a/misc/cgo/testso/cgoso_c.c b/misc/cgo/testso/cgoso_c.c
index 27155c27f..9b77a76fc 100644
--- a/misc/cgo/testso/cgoso_c.c
+++ b/misc/cgo/testso/cgoso_c.c
@@ -17,6 +17,7 @@ __declspec(dllexport) void sofunc(void);
#else
extern void goCallback(void);
void setCallback(void *f) { (void)f; }
+__thread int tlsvar = 12345;
#endif
void sofunc(void)
diff --git a/misc/cgo/testso/cgoso_unix.go b/misc/cgo/testso/cgoso_unix.go
new file mode 100644
index 000000000..e86f99264
--- /dev/null
+++ b/misc/cgo/testso/cgoso_unix.go
@@ -0,0 +1,20 @@
+// Copyright 2014 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.
+
+// +build darwin dragonfly freebsd linux netbsd
+
+package cgosotest
+
+/*
+extern int __thread tlsvar;
+int *getTLS() { return &tlsvar; }
+*/
+import "C"
+
+func init() {
+ if v := *C.getTLS(); v != 12345 {
+ println("got", v)
+ panic("BAD TLS value")
+ }
+}
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 8acb72331..8c6cfed86 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -303,7 +303,7 @@ void
dynrelocsym(LSym *s)
{
Reloc *r;
-
+
if(HEADTYPE == Hwindows) {
LSym *rel, *targ;
@@ -312,6 +312,8 @@ dynrelocsym(LSym *s)
return;
for(r=s->r; r<s->r+s->nr; r++) {
targ = r->sym;
+ if(!targ->reachable)
+ diag("internal inconsistency: dynamic symbol %s is not reachable.", targ->name);
if(r->sym->plt == -2 && r->sym->got != -2) { // make dynimport JMP table for PE object files.
targ->plt = rel->size;
r->sym = rel;
@@ -340,8 +342,11 @@ dynrelocsym(LSym *s)
}
for(r=s->r; r<s->r+s->nr; r++) {
- if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256)
+ if(r->sym != S && r->sym->type == SDYNIMPORT || r->type >= 256) {
+ if(!r->sym->reachable)
+ diag("internal inconsistency: dynamic symbol %s is not reachable.", r->sym->name);
adddynrel(s, r);
+ }
}
}
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index c585f96e0..d26ea0d04 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -197,7 +197,7 @@ asmelfsym(void)
genasmsym(putelfsym);
for(s=ctxt->allsym; s!=S; s=s->allsym) {
- if(s->type != SHOSTOBJ && s->type != SDYNIMPORT)
+ if(s->type != SHOSTOBJ && !(s->type == SDYNIMPORT && s->reachable))
continue;
if(s->type == SDYNIMPORT)
name = s->extname;