util.go (4159B)
1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package objabi 6 7 import ( 8 "fmt" 9 "log" 10 "os" 11 "strings" 12 ) 13 14 func envOr(key, value string) string { 15 if x := os.Getenv(key); x != "" { 16 return x 17 } 18 return value 19 } 20 21 var ( 22 defaultGOROOT string // set by linker 23 24 GOROOT = envOr("GOROOT", defaultGOROOT) 25 GOARCH = envOr("GOARCH", "amd64") 26 GOOS = envOr("GOOS", "linux") 27 GO386 = envOr("GO386", "") 28 GOAMD64 = goamd64() 29 GOARM = goarm() 30 GOMIPS = gomips() 31 GOMIPS64 = gomips64() 32 GOPPC64 = goppc64() 33 GOWASM = gowasm() 34 GO_LDSO = "" 35 Version = "" 36 ) 37 38 const ( 39 ElfRelocOffset = 256 40 MachoRelocOffset = 2048 // reserve enough space for ELF relocations 41 Go115AMD64 = "alignedjumps" // Should be "alignedjumps" or "normaljumps"; this replaces environment variable introduced in CL 219357. 42 ) 43 44 // TODO(1.16): assuming no issues in 1.15 release, remove this and related constant. 45 func goamd64() string { 46 return Go115AMD64 47 } 48 49 func goarm() int { 50 switch v := envOr("GOARM", "7"); v { 51 case "5": 52 return 5 53 case "6": 54 return 6 55 case "7": 56 return 7 57 } 58 // Fail here, rather than validate at multiple call sites. 59 log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.") 60 panic("unreachable") 61 } 62 63 func gomips() string { 64 switch v := envOr("GOMIPS", "hardfloat"); v { 65 case "hardfloat", "softfloat": 66 return v 67 } 68 log.Fatalf("Invalid GOMIPS value. Must be hardfloat or softfloat.") 69 panic("unreachable") 70 } 71 72 func gomips64() string { 73 switch v := envOr("GOMIPS64", "hardfloat"); v { 74 case "hardfloat", "softfloat": 75 return v 76 } 77 log.Fatalf("Invalid GOMIPS64 value. Must be hardfloat or softfloat.") 78 panic("unreachable") 79 } 80 81 func goppc64() int { 82 switch v := envOr("GOPPC64", "power8"); v { 83 case "power8": 84 return 8 85 case "power9": 86 return 9 87 } 88 log.Fatalf("Invalid GOPPC64 value. Must be power8 or power9.") 89 panic("unreachable") 90 } 91 92 type gowasmFeatures struct { 93 SignExt bool 94 SatConv bool 95 } 96 97 func (f gowasmFeatures) String() string { 98 var flags []string 99 if f.SatConv { 100 flags = append(flags, "satconv") 101 } 102 if f.SignExt { 103 flags = append(flags, "signext") 104 } 105 return strings.Join(flags, ",") 106 } 107 108 func gowasm() (f gowasmFeatures) { 109 for _, opt := range strings.Split(envOr("GOWASM", ""), ",") { 110 switch opt { 111 case "satconv": 112 f.SatConv = true 113 case "signext": 114 f.SignExt = true 115 case "": 116 // ignore 117 default: 118 log.Fatalf("Invalid GOWASM value. No such feature: " + opt) 119 } 120 } 121 return 122 } 123 124 func Getgoextlinkenabled() string { 125 return envOr("GO_EXTLINK_ENABLED", "") 126 } 127 128 func init() { 129 for _, f := range strings.Split("", ",") { 130 if f != "" { 131 addexp(f) 132 } 133 } 134 135 // regabi is only supported on amd64. 136 if GOARCH != "amd64" { 137 Regabi_enabled = 0 138 } 139 } 140 141 // Note: must agree with runtime.framepointer_enabled. 142 var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin") 143 144 func addexp(s string) { 145 // Could do general integer parsing here, but the runtime copy doesn't yet. 146 v := 1 147 name := s 148 if len(name) > 2 && name[:2] == "no" { 149 v = 0 150 name = name[2:] 151 } 152 for i := 0; i < len(exper); i++ { 153 if exper[i].name == name { 154 if exper[i].val != nil { 155 *exper[i].val = v 156 } 157 return 158 } 159 } 160 161 fmt.Printf("unknown experiment %s\n", s) 162 os.Exit(2) 163 } 164 165 var ( 166 Fieldtrack_enabled int 167 Preemptibleloops_enabled int 168 Staticlockranking_enabled int 169 Regabi_enabled int 170 ) 171 172 // Toolchain experiments. 173 // These are controlled by the GOEXPERIMENT environment 174 // variable recorded when the toolchain is built. 175 // This list is also known to cmd/gc. 176 var exper = []struct { 177 name string 178 val *int 179 }{ 180 {"fieldtrack", &Fieldtrack_enabled}, 181 {"preemptibleloops", &Preemptibleloops_enabled}, 182 {"staticlockranking", &Staticlockranking_enabled}, 183 {"regabi", &Regabi_enabled}, 184 } 185 186 var defaultExpstring = Expstring() 187 188 func DefaultExpstring() string { 189 return defaultExpstring 190 } 191 192 func Expstring() string { 193 buf := "X" 194 for i := range exper { 195 if *exper[i].val != 0 { 196 buf += "," + exper[i].name 197 } 198 } 199 if buf == "X" { 200 buf += ",none" 201 } 202 return "X:" + buf[2:] 203 }