util.go 4.1 KB

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