Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2fb37bd

Browse files
jgowdyamusman
andcommitted
cmd/link,cmd/compile: add -tls flag for TLS model control
Add -tls flag to control Thread Local Storage model selection with options: auto, LE (Local Exec), IE (Initial Exec), GD (General Dynamic). Default behavior selects GD for c-shared/c-archive builds on Unix platforms to enable dlopen() compatibility with non-glibc systems. Validates TLS model selection to prevent invalid combinations such as LE with shared libraries. Updates all architectures (x86, ARM64, ARM, PowerPC64, s390x, RISC-V, LoongArch64, MIPS) to use centralized TLS model selection logic through ShouldUseTLSGD() and ShouldUseTLSLE() helper functions. Also fixes missing variable declaration in runtime/os_linux.go that was causing build failures. Fixes #13492 Co-Authored-By: Alexander Musman <alexander.musman@gmail.com>
1 parent f42e695 commit 2fb37bd

File tree

17 files changed

+213
-47
lines changed

17 files changed

+213
-47
lines changed

‎src/cmd/compile/internal/base/flag.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ type CmdFlags struct {
119119
Race bool "help:\"enable race detector\""
120120
Shared *bool "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below
121121
SmallFrames bool "help:\"reduce the size limit for stack allocated objects\"" // small stacks, to diagnose GC latency; see golang.org/issue/27732
122+
TLS string "help:\"set TLS model (auto, LE, IE, GD)\""
122123
Spectre string "help:\"enable spectre mitigations in `list` (all, index, ret)\""
123124
Std bool "help:\"compiling standard library\""
124125
SymABIs string "help:\"read symbol ABIs from `file`\""
@@ -292,6 +293,11 @@ func ParseFlags() {
292293
log.Fatalf("%s/%s does not support -shared", buildcfg.GOOS, buildcfg.GOARCH)
293294
}
294295
parseSpectre(Flag.Spectre) // left as string for RecordFlags
296+
297+
// Parse TLS model before setting other flags that depend on it
298+
if err := parseTLSModel(Flag.TLS); err != nil {
299+
log.Fatalf("%v", err)
300+
}
295301

296302
Ctxt.Flag_shared = Ctxt.Flag_dynlink || Ctxt.Flag_shared
297303
Ctxt.Flag_optimize = Flag.N == 0
@@ -568,6 +574,27 @@ func readEmbedCfg(file string) {
568574
}
569575
}
570576

577+
// parseTLSModel parses the TLS model from the string s.
578+
func parseTLSModel(s string) error {
579+
if s == "" {
580+
s = "auto" // Default to auto
581+
}
582+
583+
switch s {
584+
case "auto":
585+
Ctxt.TLSModel = obj.TLSModelAuto
586+
case "LE":
587+
Ctxt.TLSModel = obj.TLSModelLE
588+
case "IE":
589+
Ctxt.TLSModel = obj.TLSModelIE
590+
case "GD":
591+
Ctxt.TLSModel = obj.TLSModelGD
592+
default:
593+
return fmt.Errorf("invalid TLS model %q; valid values are auto, LE, IE, GD", s)
594+
}
595+
return nil
596+
}
597+
571598
// parseSpectre parses the spectre configuration from the string s.
572599
func parseSpectre(s string) {
573600
for _, f := range strings.Split(s, ",") {

‎src/cmd/internal/obj/arm/asm5.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
871871

872872
c.instoffset = 0 // s.b. unused but just in case
873873
if a.Sym.Type == objabi.STLSBSS {
874-
if c.ctxt.Flag_shared&& (c.ctxt.Headtype==objabi.Hlinux||c.ctxt.Headtype==objabi.Hfreebsd||c.ctxt.Headtype==objabi.Hopenbsd) {
874+
if c.ctxt.ShouldUseTLSGD() {
875875
// Use General Dynamic model for shared libraries
876876
// to support non-glibc dlopen()
877877
return C_TLS_GD

‎src/cmd/internal/obj/arm64/asm7.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2103,7 +2103,7 @@ func (c *ctxt7) aclass(a *obj.Addr) int {
21032103
if a.Sym.Type == objabi.STLSBSS {
21042104
// For c-shared/c-archive on standards-compliant systems,
21052105
// use general dynamic model for dlopen compatibility.
2106-
if c.ctxt.Flag_shared&& (c.ctxt.Headtype==objabi.Hlinux||c.ctxt.Headtype==objabi.Hfreebsd||c.ctxt.Headtype==objabi.Hopenbsd) {
2106+
if c.ctxt.ShouldUseTLSGD() {
21072107
return C_TLS_GD
21082108
} else {
21092109
return C_TLS_LE

‎src/cmd/internal/obj/link.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,47 @@ import (
4545
"sync/atomic"
4646
)
4747

48+
// TLSModel represents different Thread Local Storage models
49+
type TLSModel int
50+
51+
const (
52+
TLSModelAuto TLSModel = iota // Automatic selection based on platform and build mode
53+
TLSModelLE // Local Exec - fastest, static executables only
54+
TLSModelIE // Initial Exec - fast, may not work with dlopen on non-glibc
55+
TLSModelGD // General Dynamic - compatible with all dlopen scenarios
56+
)
57+
58+
// ShouldUseTLSGD returns true if General Dynamic TLS model should be used
59+
func (ctxt *Link) ShouldUseTLSGD() bool {
60+
switch ctxt.TLSModel {
61+
case TLSModelGD:
62+
return true
63+
case TLSModelLE, TLSModelIE:
64+
return false
65+
case TLSModelAuto:
66+
// Auto selection logic - matches our current implementation
67+
return ctxt.Flag_shared && (ctxt.Headtype == objabi.Hlinux ||
68+
ctxt.Headtype == objabi.Hfreebsd || ctxt.Headtype == objabi.Hopenbsd)
69+
default:
70+
return false
71+
}
72+
}
73+
74+
// ShouldUseTLSLE returns true if Local Exec TLS model should be used
75+
func (ctxt *Link) ShouldUseTLSLE() bool {
76+
switch ctxt.TLSModel {
77+
case TLSModelLE:
78+
return true
79+
case TLSModelGD, TLSModelIE:
80+
return false
81+
case TLSModelAuto:
82+
// Auto selection: use LE for static executables on supported platforms
83+
return !ctxt.Flag_shared && ctxt.Headtype != objabi.Hwindows && ctxt.Headtype != objabi.Hplan9
84+
default:
85+
return false
86+
}
87+
}
88+
4889
// An Addr is an argument to an instruction.
4990
// The general forms and their encodings are:
5091
//
@@ -1147,6 +1188,7 @@ type Link struct {
11471188
Flag_locationlists bool
11481189
Flag_noRefName bool // do not include referenced symbol names in object file
11491190
Retpoline bool // emit use of retpoline stubs for indirect jmp/call
1191+
TLSModel TLSModel // TLS model selection
11501192
Flag_maymorestack string // If not "", call this function before stack checks
11511193
Bso *bufio.Writer
11521194
Pathname string

‎src/cmd/internal/obj/loong64/asm.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
763763
}
764764
c.instoffset = a.Offset
765765
if a.Sym.Type == objabi.STLSBSS {
766-
if c.ctxt.Flag_shared&& (c.ctxt.Headtype==objabi.Hlinux||c.ctxt.Headtype==objabi.Hfreebsd||c.ctxt.Headtype==objabi.Hopenbsd) {
766+
if c.ctxt.ShouldUseTLSGD() {
767767
return C_TLS_GD
768768
} else {
769769
return C_TLS_LE

‎src/cmd/internal/obj/mips/asm0.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
610610
if a.Sym != nil { // use relocation
611611
if a.Sym.Type == objabi.STLSBSS {
612612
// For shared libraries, use general dynamic TLS model
613-
if c.ctxt.Flag_shared&& (c.ctxt.Headtype==objabi.Hlinux||c.ctxt.Headtype==objabi.Hfreebsd||c.ctxt.Headtype==objabi.Hopenbsd) {
613+
if c.ctxt.ShouldUseTLSGD() {
614614
return C_TLS_GD
615615
}
616616
return C_TLS

‎src/cmd/internal/obj/ppc64/asm9.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,7 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
910910
} else if a.Sym.Type == objabi.STLSBSS {
911911
// For shared libraries, use general dynamic TLS model
912912
// to support non-glibc dlopen()
913-
if c.ctxt.Flag_shared&& (c.ctxt.Headtype==objabi.Hlinux||c.ctxt.Headtype==objabi.Hfreebsd||c.ctxt.Headtype==objabi.Hopenbsd) {
913+
if c.ctxt.ShouldUseTLSGD() {
914914
return C_TLS_GD
915915
}
916916
// Otherwise, use 8 byte local-exec TLS accesses.

‎src/cmd/internal/obj/riscv/obj.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3904,7 +3904,7 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
39043904
break
39053905
}
39063906
if addr.Sym.Type == objabi.STLSBSS {
3907-
if ctxt.Flag_shared&& (ctxt.Headtype==objabi.Hlinux||ctxt.Headtype==objabi.Hfreebsd||ctxt.Headtype==objabi.Hopenbsd) {
3907+
if ctxt.ShouldUseTLSGD() {
39083908
rt = objabi.R_RISCV_TLS_GD
39093909
} else {
39103910
rt = objabi.R_RISCV_TLS_LE

‎src/cmd/internal/obj/s390x/asmz.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
582582
}
583583
c.instoffset = a.Offset
584584
if a.Sym.Type == objabi.STLSBSS {
585-
if c.ctxt.Flag_shared&& (c.ctxt.Headtype==objabi.Hlinux||c.ctxt.Headtype==objabi.Hfreebsd||c.ctxt.Headtype==objabi.Hopenbsd) {
585+
if c.ctxt.ShouldUseTLSGD() {
586586
return C_TLS_GD // general dynamic model
587587
}
588588
return C_TLS_LE // local exec model

‎src/cmd/internal/obj/sym.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ func Linknew(arch *LinkArch) *Link {
5757
}
5858

5959
ctxt.Flag_optimize = true
60+
ctxt.TLSModel = TLSModelAuto // Default to automatic TLS model selection
6061
return ctxt
6162
}
6263

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /