Commit b8417854 authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle Committed by Ian Lance Taylor

cmd/internal/ld: handle TLS and imported symbols more regularly

For shared libraries we need to be more flexible in how these symbols
are handled (e.g. sometimes tlsg needs to be global, or you can get
a SDYNIMPORT symbol that has .Hide == true) so handling these cases
in genasmsym makes everything much more regular.

Even ignoring shared libraries, I think this is a bit cleaner.

Change-Id: If5beb093a261e79f4496183226e1765ee7aa6717
Reviewed-on: https://go-review.googlesource.com/8230
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 00e0fe4b
...@@ -430,7 +430,6 @@ func loadlib() { ...@@ -430,7 +430,6 @@ func loadlib() {
tlsg.Type = STLSBSS tlsg.Type = STLSBSS
} }
tlsg.Size = int64(Thearch.Ptrsize) tlsg.Size = int64(Thearch.Ptrsize)
tlsg.Hide = 1
tlsg.Reachable = true tlsg.Reachable = true
Ctxt.Tlsg = tlsg Ctxt.Tlsg = tlsg
...@@ -1375,7 +1374,6 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) { ...@@ -1375,7 +1374,6 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
continue continue
} }
put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype) put(s, s.Name, 'D', Symaddr(s), s.Size, int(s.Version), s.Gotype)
continue
case SBSS, case SBSS,
SNOPTRBSS: SNOPTRBSS:
...@@ -1386,18 +1384,31 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) { ...@@ -1386,18 +1384,31 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
Diag("%s should not be bss (size=%d type=%d special=%d)", s.Name, int(len(s.P)), s.Type, s.Special) Diag("%s should not be bss (size=%d type=%d special=%d)", s.Name, int(len(s.P)), s.Type, s.Special)
} }
put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype) put(s, s.Name, 'B', Symaddr(s), s.Size, int(s.Version), s.Gotype)
continue
case SFILE: case SFILE:
put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil) put(nil, s.Name, 'f', s.Value, 0, int(s.Version), nil)
continue
case SHOSTOBJ: case SHOSTOBJ:
if HEADTYPE == Hwindows { if HEADTYPE == Hwindows || Iself {
put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil) put(s, s.Name, 'U', s.Value, 0, int(s.Version), nil)
} }
continue
case SDYNIMPORT:
if !s.Reachable {
continue
}
put(s, s.Extname, 'U', 0, 0, int(s.Version), nil)
case STLSBSS:
if Linkmode == LinkExternal && HEADTYPE != Hopenbsd {
var type_ int
if goos == "android" {
type_ = 'B'
} else {
type_ = 't'
}
put(s, s.Name, type_, Symaddr(s), s.Size, int(s.Version), s.Gotype)
}
} }
} }
......
...@@ -98,22 +98,34 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L ...@@ -98,22 +98,34 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
case 'B': case 'B':
type_ = STT_OBJECT type_ = STT_OBJECT
case 'U':
type_ = STT_NOTYPE
case 't':
type_ = STT_TLS
} }
xo := x xo := x
for xo.Outer != nil { for xo.Outer != nil {
xo = xo.Outer xo = xo.Outer
} }
if xo.Sect == nil {
Ctxt.Cursym = x
Diag("missing section in putelfsym")
return
}
if (xo.Sect.(*Section)).Elfsect == nil { var elfshnum int
Ctxt.Cursym = x if xo.Type == SDYNIMPORT || xo.Type == SHOSTOBJ {
Diag("missing ELF section in putelfsym") elfshnum = SHN_UNDEF
return } else {
if xo.Sect == nil {
Ctxt.Cursym = x
Diag("missing section in putelfsym")
return
}
if (xo.Sect.(*Section)).Elfsect == nil {
Ctxt.Cursym = x
Diag("missing ELF section in putelfsym")
return
}
elfshnum = ((xo.Sect.(*Section)).Elfsect.(*ElfShdr)).shnum
} }
// One pass for each binding: STB_LOCAL, STB_GLOBAL, // One pass for each binding: STB_LOCAL, STB_GLOBAL,
...@@ -128,7 +140,7 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L ...@@ -128,7 +140,7 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
// to get the exported symbols put into the dynamic symbol table. // to get the exported symbols put into the dynamic symbol table.
// To avoid filling the dynamic table with lots of unnecessary symbols, // To avoid filling the dynamic table with lots of unnecessary symbols,
// mark all Go symbols local (not global) in the final executable. // mark all Go symbols local (not global) in the final executable.
if Linkmode == LinkExternal && x.Cgoexport&CgoExportStatic == 0 { if Linkmode == LinkExternal && x.Cgoexport&CgoExportStatic == 0 && elfshnum != SHN_UNDEF {
bind = STB_LOCAL bind = STB_LOCAL
} }
...@@ -137,14 +149,14 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L ...@@ -137,14 +149,14 @@ func putelfsym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *L
} }
off := putelfstr(s) off := putelfstr(s)
if Linkmode == LinkExternal { if Linkmode == LinkExternal && elfshnum != SHN_UNDEF {
addr -= int64((xo.Sect.(*Section)).Vaddr) addr -= int64((xo.Sect.(*Section)).Vaddr)
} }
other := STV_DEFAULT other := STV_DEFAULT
if x.Type&SHIDDEN != 0 { if x.Type&SHIDDEN != 0 {
other = STV_HIDDEN other = STV_HIDDEN
} }
putelfsyment(off, addr, size, bind<<4|type_&0xf, ((xo.Sect.(*Section)).Elfsect.(*ElfShdr)).shnum, other) putelfsyment(off, addr, size, bind<<4|type_&0xf, elfshnum, other)
x.Elfsym = int32(numelfsym) x.Elfsym = int32(numelfsym)
numelfsym++ numelfsym++
} }
...@@ -178,43 +190,9 @@ func Asmelfsym() { ...@@ -178,43 +190,9 @@ func Asmelfsym() {
elfbind = STB_LOCAL elfbind = STB_LOCAL
genasmsym(putelfsym) genasmsym(putelfsym)
if Linkmode == LinkExternal && HEADTYPE != Hopenbsd {
s := Linklookup(Ctxt, "runtime.tlsg", 0)
if s.Sect == nil {
Ctxt.Cursym = nil
Diag("missing section for %s", s.Name)
Errorexit()
}
if goos == "android" {
// Android emulates runtime.tlsg as a regular variable.
putelfsyment(putelfstr(s.Name), 0, s.Size, STB_LOCAL<<4|STT_OBJECT, ((s.Sect.(*Section)).Elfsect.(*ElfShdr)).shnum, 0)
} else {
putelfsyment(putelfstr(s.Name), 0, s.Size, STB_LOCAL<<4|STT_TLS, ((s.Sect.(*Section)).Elfsect.(*ElfShdr)).shnum, 0)
}
s.Elfsym = int32(numelfsym)
numelfsym++
}
elfbind = STB_GLOBAL elfbind = STB_GLOBAL
elfglobalsymndx = numelfsym elfglobalsymndx = numelfsym
genasmsym(putelfsym) genasmsym(putelfsym)
var name string
for s := Ctxt.Allsym; s != nil; s = s.Allsym {
if s.Type != SHOSTOBJ && (s.Type != SDYNIMPORT || !s.Reachable) {
continue
}
if s.Type == SDYNIMPORT {
name = s.Extname
} else {
name = s.Name
}
putelfsyment(putelfstr(name), 0, 0, STB_GLOBAL<<4|STT_NOTYPE, 0, 0)
s.Elfsym = int32(numelfsym)
numelfsym++
}
} }
func putplan9sym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *LSym) { func putplan9sym(x *LSym, s string, t int, addr int64, size int64, ver int, go_ *LSym) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment