Skip to content

Commit 530fce7

Browse files
committed
cmd/internal/obj,etc: replace -shared with -buildmode=c-shared
Currently some compilers and the assembler take a -shared flag which means approximately what the -buildmode=c-shared flag means in the proposed "Go Execution Modes" document. As part of implementing other modes, the term "shared" becomes horribly overloaded, so this adds a -buildmode argument instead (which currently only handles -buildmode=c-shared, no new behaviour here). The compilers retain a -shared argument as an alias for -buildmode=c-shared. The assemblers in 1.4 did not support -shared and the tool has a different name now in any case, so I don't see a reason to maintain compatibility there.
1 parent 180fbb1 commit 530fce7

File tree

9 files changed

+76
-19
lines changed

9 files changed

+76
-19
lines changed

src/cmd/asm/internal/flags/flags.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package flags
77

88
import (
9+
"cmd/internal/obj"
910
"flag"
1011
"fmt"
1112
"os"
@@ -18,7 +19,7 @@ var (
1819
OutputFile = flag.String("o", "", "output file; default foo.6 for /a/b/c/foo.s on amd64")
1920
PrintOut = flag.Bool("S", false, "print assembly and machine code")
2021
TrimPath = flag.String("trimpath", "", "remove prefix from recorded source file paths")
21-
Shared = flag.Bool("shared", false, "generate code that can be linked into a shared library")
22+
Buildmode = obj.Buildmode_None
2223
)
2324

2425
var (
@@ -29,6 +30,7 @@ var (
2930
func init() {
3031
flag.Var(&D, "D", "predefined symbol with optional simple value -D=identifer=value; can be set multiple times")
3132
flag.Var(&I, "I", "include directory; can be set multiple times")
33+
flag.Var(&Buildmode, "buildmode", "build mode to use")
3234
}
3335

3436
// MultiFlag allows setting a value multiple times to collect a list, as in -I=dir1 -I=dir2.

src/cmd/asm/main.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ func main() {
4141
ctxt.Debugasm = 1
4242
}
4343
ctxt.Trimpath = *flags.TrimPath
44-
if *flags.Shared {
45-
ctxt.Flag_shared = 1
46-
}
44+
ctxt.Buildmode = flags.Buildmode
4745
ctxt.Bso = obj.Binitw(os.Stdout)
4846
defer obj.Bflush(ctxt.Bso)
4947
ctxt.Diag = log.Fatalf

src/cmd/internal/gc/lex.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ func Main() {
195195
obj.Flagfn0("V", "print compiler version", doversion)
196196
obj.Flagcount("W", "debug parse tree after type checking", &Debug['W'])
197197
obj.Flagstr("asmhdr", "file: write assembly header to named file", &asmhdr)
198+
flag.Var(&Ctxt.Buildmode, "buildmode", "build mode to use")
198199
obj.Flagcount("complete", "compiling complete package (no C or assembly)", &pure_go)
199200
obj.Flagstr("d", "list: print debug information about items in list", &debugstr)
200201
obj.Flagcount("e", "no limit on number of errors reported", &Debug['e'])
@@ -231,7 +232,13 @@ func Main() {
231232
obj.Flagstr("cpuprofile", "file: write cpu profile to file", &cpuprofile)
232233
obj.Flagstr("memprofile", "file: write memory profile to file", &memprofile)
233234
obj.Flagparse(usage)
234-
Ctxt.Flag_shared = int32(flag_shared)
235+
if flag_shared != 0 {
236+
if Ctxt.Buildmode == obj.Buildmode_None {
237+
Ctxt.Buildmode = obj.Buildmode_CShared
238+
} else if Ctxt.Buildmode != obj.Buildmode_CShared {
239+
log.Fatalf("-shared and -buildmode=%s are incompatible\n", Ctxt.Buildmode.String())
240+
}
241+
}
235242
Ctxt.Debugasm = int32(Debug['S'])
236243
Ctxt.Debugvlog = int32(Debug['v'])
237244

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
900900
t.To.Type = a.Type
901901
t.To.Name = a.Name
902902

903-
if ctxt.Flag_shared != 0 && t.To.Sym != nil {
903+
if needsPcrel(ctxt) && t.To.Sym != nil {
904904
t.Pcrel = p
905905
}
906906

@@ -1352,7 +1352,7 @@ func buildop(ctxt *obj.Link) {
13521352
}
13531353
for n = 0; optab[n].as != obj.AXXX; n++ {
13541354
if optab[n].flag&LPCREL != 0 {
1355-
if ctxt.Flag_shared != 0 {
1355+
if needsPcrel(ctxt) {
13561356
optab[n].size += int8(optab[n].pcrelsiz)
13571357
} else {
13581358
optab[n].flag &^= LPCREL
@@ -1674,12 +1674,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
16741674
// its type declaration if necessary.
16751675
if rel.Sym == ctxt.Tlsg && ctxt.Tlsg.Type == 0 {
16761676
rel.Type = obj.R_TLS
1677-
if ctxt.Flag_shared != 0 {
1677+
if needsPcrel(ctxt) { //TODO(mwhudson): maybe this should be needsInitalExecTLS
16781678
rel.Add += ctxt.Pc - p.Pcrel.Pc - 8 - int64(rel.Siz)
16791679
}
16801680
rel.Xadd = rel.Add
16811681
rel.Xsym = rel.Sym
1682-
} else if ctxt.Flag_shared != 0 {
1682+
} else if needsPcrel(ctxt) {
16831683
rel.Type = obj.R_PCREL
16841684
rel.Add += ctxt.Pc - p.Pcrel.Pc - 8
16851685
} else {

src/cmd/internal/obj/arm/obj5.go

+18-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ import (
3838
"math"
3939
)
4040

41+
func needsInitalExecTLS(ctxt *obj.Link) bool {
42+
switch ctxt.Buildmode {
43+
case obj.Buildmode_CShared:
44+
return true
45+
}
46+
return false
47+
}
48+
49+
func needsPcrel(ctxt *obj.Link) bool {
50+
switch ctxt.Buildmode {
51+
case obj.Buildmode_CShared:
52+
return true
53+
}
54+
return false
55+
}
56+
4157
var progedit_tlsfallback *obj.LSym
4258

4359
func progedit(ctxt *obj.Link, p *obj.Prog) {
@@ -142,7 +158,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
142158
}
143159
}
144160

145-
if ctxt.Flag_shared != 0 {
161+
if needsInitalExecTLS(ctxt) {
146162
// Shared libraries use R_ARM_TLS_IE32 instead of
147163
// R_ARM_TLS_LE32, replacing the link time constant TLS offset in
148164
// runtime.tlsg with an address to a GOT entry containing the
@@ -273,7 +289,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
273289
for p := cursym.Text; p != nil; p = p.Link {
274290
switch p.As {
275291
case ACASE:
276-
if ctxt.Flag_shared != 0 {
292+
if needsPcrel(ctxt) {
277293
linkcase(p)
278294
}
279295

src/cmd/internal/obj/flag.go

+26
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package obj
66

77
import (
8+
"errors"
89
"flag"
910
"fmt"
1011
"os"
@@ -118,3 +119,28 @@ func (f fn1) Set(s string) error {
118119
}
119120

120121
func (f fn1) String() string { return "" }
122+
123+
type Buildmode uint8
124+
125+
const (
126+
Buildmode_None Buildmode = iota
127+
Buildmode_CShared
128+
)
129+
130+
func (mode *Buildmode) Set(s string) error {
131+
switch s {
132+
default:
133+
return errors.New("buildmode %s not recognized")
134+
case "c-shared":
135+
*mode = Buildmode_CShared
136+
}
137+
return nil
138+
}
139+
140+
func (mode *Buildmode) String() string {
141+
switch *mode {
142+
case Buildmode_CShared:
143+
return "c-shared"
144+
}
145+
return fmt.Sprintf("Buildmode(%d)", uint8(*mode))
146+
}

src/cmd/internal/obj/link.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ type Link struct {
475475
Debugdivmod int32
476476
Debugfloat int32
477477
Debugpcln int32
478-
Flag_shared int32
478+
Buildmode Buildmode
479479
Iself int32
480480
Bso *Biobuf
481481
Pathname string

src/cmd/internal/obj/x86/asm6.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -1950,8 +1950,8 @@ func prefixof(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
19501950
log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype))
19511951

19521952
case obj.Hlinux:
1953-
if ctxt.Flag_shared != 0 {
1954-
log.Fatalf("unknown TLS base register for linux with -shared")
1953+
if needsInitalExecTLS(ctxt) {
1954+
log.Fatalf("unknown TLS base register for linux with IE model")
19551955
} else {
19561956
return 0x64 // FS
19571957
}
@@ -1984,7 +1984,7 @@ func prefixof(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
19841984
return 0x26
19851985

19861986
case REG_TLS:
1987-
if ctxt.Flag_shared != 0 {
1987+
if needsInitalExecTLS(ctxt) {
19881988
// When building for inclusion into a shared library, an instruction of the form
19891989
// MOV 0(CX)(TLS*1), AX
19901990
// becomes
@@ -2624,7 +2624,7 @@ func asmandsz(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int)
26242624
}
26252625

26262626
if REG_AX <= base && base <= REG_R15 {
2627-
if a.Index == REG_TLS && ctxt.Flag_shared == 0 {
2627+
if a.Index == REG_TLS && needsInitalExecTLS(ctxt) {
26282628
rel = obj.Reloc{}
26292629
rel.Type = obj.R_TLS_IE
26302630
rel.Siz = 4
@@ -3834,8 +3834,8 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
38343834
log.Fatalf("unknown TLS base location for %s", obj.Headstr(ctxt.Headtype))
38353835

38363836
case obj.Hlinux:
3837-
if ctxt.Flag_shared == 0 {
3838-
log.Fatalf("unknown TLS base location for linux without -shared")
3837+
if !needsInitalExecTLS(ctxt) {
3838+
log.Fatalf("unknown TLS base location for linux with LE model")
38393839
}
38403840
// Note that this is not generating the same insn as the other cases.
38413841
// MOV TLS, R_to

src/cmd/internal/obj/x86/obj6.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ import (
3838
"math"
3939
)
4040

41+
func needsInitalExecTLS(ctxt *obj.Link) bool {
42+
switch ctxt.Buildmode {
43+
case obj.Buildmode_CShared:
44+
return true
45+
}
46+
return false
47+
}
48+
4149
func canuselocaltls(ctxt *obj.Link) bool {
4250
if ctxt.Arch.Regsize == 4 {
4351
switch ctxt.Headtype {
@@ -56,7 +64,7 @@ func canuselocaltls(ctxt *obj.Link) bool {
5664
obj.Hwindows:
5765
return false
5866
case obj.Hlinux:
59-
return ctxt.Flag_shared == 0
67+
return !needsInitalExecTLS(ctxt)
6068
}
6169

6270
return true

0 commit comments

Comments
 (0)