Commit 9e6ba37b authored by Michael Hudson-Doyle's avatar Michael Hudson-Doyle Committed by David Crawshaw

cmd/internal/obj: some platform independent bits of proper toolchain support for…

cmd/internal/obj: some platform independent bits of proper toolchain support for thread local storage

Also simplifies some silliness around making the .tbss section wrt internal
vs external linking. The "make TLS make sense" project has quite a few more
steps to go.

Issue #11270

Change-Id: Ia4fa135cb22d916728ead95bdbc0ebc1ae06f05c
Reviewed-on: https://go-review.googlesource.com/13990Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Reviewed-by: 's avatarDavid Crawshaw <crawshaw@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 499c8275
...@@ -63,6 +63,9 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) { ...@@ -63,6 +63,9 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) {
if ctxt.Enforce_data_order != 0 && off < int32(len(s.P)) { if ctxt.Enforce_data_order != 0 && off < int32(len(s.P)) {
ctxt.Diag("data out of order (already have %d)\n%v", len(s.P), p) ctxt.Diag("data out of order (already have %d)\n%v", len(s.P), p)
} }
if s.Type == SBSS || s.Type == STLSBSS {
ctxt.Diag("cannot supply data for BSS var")
}
Symgrow(ctxt, s, int64(off+siz)) Symgrow(ctxt, s, int64(off+siz))
switch int(p.To.Type) { switch int(p.To.Type) {
......
...@@ -194,6 +194,8 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { ...@@ -194,6 +194,8 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
s.Type = SRODATA s.Type = SRODATA
} else if flag&NOPTR != 0 { } else if flag&NOPTR != 0 {
s.Type = SNOPTRBSS s.Type = SNOPTRBSS
} else if flag&TLSBSS != 0 {
s.Type = STLSBSS
} }
edata = s edata = s
continue continue
......
...@@ -35,4 +35,8 @@ const ( ...@@ -35,4 +35,8 @@ const (
// When passed to ggloblsym, causes Local to be set to true on the LSym it creates. // When passed to ggloblsym, causes Local to be set to true on the LSym it creates.
LOCAL = 128 LOCAL = 128
// Allocate a word of thread local storage and store the offset from the
// thread local base to the thread local storage in this variable.
TLSBSS = 256
) )
...@@ -1401,26 +1401,25 @@ func dodata() { ...@@ -1401,26 +1401,25 @@ func dodata() {
Diag("data or bss segment too large") Diag("data or bss segment too large")
} }
if Iself && Linkmode == LinkExternal && s != nil && s.Type == obj.STLSBSS && HEADTYPE != obj.Hopenbsd { if s != nil && s.Type == obj.STLSBSS {
sect := addsection(&Segdata, ".tbss", 06) if Iself && (Linkmode == LinkExternal || Debug['d'] == 0) && HEADTYPE != obj.Hopenbsd {
sect.Align = int32(Thearch.Ptrsize) sect = addsection(&Segdata, ".tbss", 06)
sect.Vaddr = 0 sect.Align = int32(Thearch.Ptrsize)
sect.Vaddr = 0
} else {
sect = nil
}
datsize = 0 datsize = 0
for ; s != nil && s.Type == obj.STLSBSS; s = s.Next { for ; s != nil && s.Type == obj.STLSBSS; s = s.Next {
datsize = aligndatsize(datsize, s) datsize = aligndatsize(datsize, s)
s.Sect = sect s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr) s.Value = datsize
growdatsize(&datsize, s) growdatsize(&datsize, s)
} }
sect.Length = uint64(datsize) if sect != nil {
} else { sect.Length = uint64(datsize)
// Might be internal linking but still using cgo.
// In that case, the only possible STLSBSS symbol is runtime.tlsg.
// Give it offset 0, because it's the only thing here.
if s != nil && s.Type == obj.STLSBSS && s.Name == "runtime.tlsg" {
s.Value = 0
s = s.Next
} }
} }
...@@ -1690,8 +1689,11 @@ func address() { ...@@ -1690,8 +1689,11 @@ func address() {
var noptrbss *Section var noptrbss *Section
var vlen int64 var vlen int64
for s := Segdata.Sect; s != nil; s = s.Next { for s := Segdata.Sect; s != nil; s = s.Next {
if Iself && s.Name == ".tbss" {
continue
}
vlen = int64(s.Length) vlen = int64(s.Length)
if s.Next != nil { if s.Next != nil && !(Iself && s.Next.Name == ".tbss") {
vlen = int64(s.Next.Vaddr - s.Vaddr) vlen = int64(s.Next.Vaddr - s.Vaddr)
} }
s.Vaddr = va s.Vaddr = va
......
...@@ -1508,7 +1508,9 @@ func elfshbits(sect *Section) *ElfShdr { ...@@ -1508,7 +1508,9 @@ func elfshbits(sect *Section) *ElfShdr {
} }
sh.addralign = uint64(sect.Align) sh.addralign = uint64(sect.Align)
sh.size = sect.Length sh.size = sect.Length
sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr if sect.Name != ".tbss" || goos == "android" {
sh.off = sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr
}
return sh return sh
} }
...@@ -2287,12 +2289,20 @@ func Asmbelf(symo int64) { ...@@ -2287,12 +2289,20 @@ func Asmbelf(symo int64) {
// Do not emit PT_TLS for OpenBSD since ld.so(1) does // Do not emit PT_TLS for OpenBSD since ld.so(1) does
// not currently support it. This is handled // not currently support it. This is handled
// appropriately in runtime/cgo. // appropriately in runtime/cgo.
if Ctxt.Tlsoffset != 0 && HEADTYPE != obj.Hopenbsd { if HEADTYPE != obj.Hopenbsd {
ph := newElfPhdr() tlssize := uint64(0)
ph.type_ = PT_TLS for sect := Segdata.Sect; sect != nil; sect = sect.Next {
ph.flags = PF_R if sect.Name == ".tbss" {
ph.memsz = uint64(-Ctxt.Tlsoffset) tlssize = sect.Length
ph.align = uint64(Thearch.Regsize) }
}
if tlssize != 0 {
ph := newElfPhdr()
ph.type_ = PT_TLS
ph.flags = PF_R
ph.memsz = tlssize
ph.align = uint64(Thearch.Regsize)
}
} }
} }
...@@ -2350,16 +2360,6 @@ elfobj: ...@@ -2350,16 +2360,6 @@ elfobj:
sh.flags = 0 sh.flags = 0
} }
// generate .tbss section for dynamic internal linking (except for OpenBSD)
// external linking generates .tbss in data.c
if Linkmode == LinkInternal && Debug['d'] == 0 && HEADTYPE != obj.Hopenbsd {
sh := elfshname(".tbss")
sh.type_ = SHT_NOBITS
sh.addralign = uint64(Thearch.Regsize)
sh.size = uint64(-Ctxt.Tlsoffset)
sh.flags = SHF_ALLOC | SHF_TLS | SHF_WRITE
}
if Debug['s'] == 0 { if Debug['s'] == 0 {
sh := elfshname(".symtab") sh := elfshname(".symtab")
sh.type_ = SHT_SYMTAB sh.type_ = SHT_SYMTAB
......
...@@ -21,3 +21,6 @@ ...@@ -21,3 +21,6 @@
#define WRAPPER 32 #define WRAPPER 32
// This function uses its incoming context register. // This function uses its incoming context register.
#define NEEDCTXT 64 #define NEEDCTXT 64
// Allocate a word of thread local storage and store the offset from the
// thread local base to the thread local storage in this variable.
#define TLSBSS 256
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