diff options
Diffstat (limited to 'libgo/go/cmd/internal/objabi')
-rw-r--r-- | libgo/go/cmd/internal/objabi/flag.go | 27 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/funcdata.go | 1 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/funcid.go | 125 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/line.go | 5 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/path.go | 4 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/reloctype.go | 31 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/reloctype_string.go | 48 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/stack.go | 8 | ||||
-rw-r--r-- | libgo/go/cmd/internal/objabi/util.go | 191 |
9 files changed, 136 insertions, 304 deletions
diff --git a/libgo/go/cmd/internal/objabi/flag.go b/libgo/go/cmd/internal/objabi/flag.go index 3fd73f3c576..e41fc570b08 100644 --- a/libgo/go/cmd/internal/objabi/flag.go +++ b/libgo/go/cmd/internal/objabi/flag.go @@ -8,6 +8,7 @@ import ( "bytes" "flag" "fmt" + "internal/buildcfg" "io" "io/ioutil" "log" @@ -91,16 +92,18 @@ func (versionFlag) Set(s string) error { name = name[strings.LastIndex(name, `\`)+1:] name = strings.TrimSuffix(name, ".exe") - // If there's an active experiment, include that, - // to distinguish go1.10.2 with an experiment - // from go1.10.2 without an experiment. - p := Expstring() - if p == DefaultExpstring() { - p = "" - } - sep := "" - if p != "" { - sep = " " + p := "" + + if s == "goexperiment" { + // test/run.go uses this to discover the full set of + // experiment tags. Report everything. + p = " X:" + strings.Join(buildcfg.AllExperiments(), ",") + } else { + // If the enabled experiments differ from the defaults, + // include that difference. + if goexperiment := buildcfg.GOEXPERIMENT(); goexperiment != "" { + p = " X:" + goexperiment + } } // The go command invokes -V=full to get a unique identifier @@ -109,12 +112,12 @@ func (versionFlag) Set(s string) error { // build ID of the binary, so that if the compiler is changed and // rebuilt, we notice and rebuild all packages. if s == "full" { - if strings.HasPrefix(Version, "devel") { + if strings.HasPrefix(buildcfg.Version, "devel") { p += " buildID=" + buildID } } - fmt.Printf("%s version %s%s%s\n", name, Version, sep, p) + fmt.Printf("%s version %s%s\n", name, buildcfg.Version, p) os.Exit(0) return nil } diff --git a/libgo/go/cmd/internal/objabi/funcdata.go b/libgo/go/cmd/internal/objabi/funcdata.go index faa2863325d..4ff0ebe13d8 100644 --- a/libgo/go/cmd/internal/objabi/funcdata.go +++ b/libgo/go/cmd/internal/objabi/funcdata.go @@ -20,6 +20,7 @@ const ( FUNCDATA_StackObjects = 2 FUNCDATA_InlTree = 3 FUNCDATA_OpenCodedDeferInfo = 4 + FUNCDATA_ArgInfo = 5 // ArgsSizeUnknown is set in Func.argsize to mark all functions // whose argument size is unknown (C vararg functions, and diff --git a/libgo/go/cmd/internal/objabi/funcid.go b/libgo/go/cmd/internal/objabi/funcid.go index 1d098ee1725..93ebd7be943 100644 --- a/libgo/go/cmd/internal/objabi/funcid.go +++ b/libgo/go/cmd/internal/objabi/funcid.go @@ -4,97 +4,90 @@ package objabi +import "strings" + +// A FuncFlag records bits about a function, passed to the runtime. +type FuncFlag uint8 + +// Note: This list must match the list in runtime/symtab.go. +const ( + FuncFlag_TOPFRAME = 1 << iota + FuncFlag_SPWRITE +) + // A FuncID identifies particular functions that need to be treated // specially by the runtime. // Note that in some situations involving plugins, there may be multiple // copies of a particular special runtime function. -// Note: this list must match the list in runtime/symtab.go. type FuncID uint8 +// Note: this list must match the list in runtime/symtab.go. const ( FuncID_normal FuncID = iota // not a special function - FuncID_runtime_main + FuncID_abort + FuncID_asmcgocall + FuncID_asyncPreempt + FuncID_cgocallback + FuncID_debugCallV2 + FuncID_gcBgMarkWorker FuncID_goexit + FuncID_gogo + FuncID_gopanic + FuncID_handleAsyncEvent FuncID_jmpdefer FuncID_mcall FuncID_morestack FuncID_mstart + FuncID_panicwrap FuncID_rt0_go - FuncID_asmcgocall - FuncID_sigpanic FuncID_runfinq - FuncID_gcBgMarkWorker - FuncID_systemstack_switch + FuncID_runtime_main + FuncID_sigpanic FuncID_systemstack - FuncID_cgocallback - FuncID_gogo - FuncID_externalthreadhandler - FuncID_debugCallV1 - FuncID_gopanic - FuncID_panicwrap - FuncID_handleAsyncEvent - FuncID_asyncPreempt + FuncID_systemstack_switch FuncID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.) ) +var funcIDs = map[string]FuncID{ + "abort": FuncID_abort, + "asmcgocall": FuncID_asmcgocall, + "asyncPreempt": FuncID_asyncPreempt, + "cgocallback": FuncID_cgocallback, + "debugCallV2": FuncID_debugCallV2, + "gcBgMarkWorker": FuncID_gcBgMarkWorker, + "go": FuncID_rt0_go, + "goexit": FuncID_goexit, + "gogo": FuncID_gogo, + "gopanic": FuncID_gopanic, + "handleAsyncEvent": FuncID_handleAsyncEvent, + "jmpdefer": FuncID_jmpdefer, + "main": FuncID_runtime_main, + "mcall": FuncID_mcall, + "morestack": FuncID_morestack, + "mstart": FuncID_mstart, + "panicwrap": FuncID_panicwrap, + "runfinq": FuncID_runfinq, + "sigpanic": FuncID_sigpanic, + "switch": FuncID_systemstack_switch, + "systemstack": FuncID_systemstack, + + // Don't show in call stack but otherwise not special. + "deferreturn": FuncID_wrapper, + "runOpenDeferFrame": FuncID_wrapper, + "reflectcallSave": FuncID_wrapper, + "deferCallSave": FuncID_wrapper, +} + // Get the function ID for the named function in the named file. // The function should be package-qualified. func GetFuncID(name string, isWrapper bool) FuncID { if isWrapper { return FuncID_wrapper } - switch name { - case "runtime.main": - return FuncID_runtime_main - case "runtime.goexit": - return FuncID_goexit - case "runtime.jmpdefer": - return FuncID_jmpdefer - case "runtime.mcall": - return FuncID_mcall - case "runtime.morestack": - return FuncID_morestack - case "runtime.mstart": - return FuncID_mstart - case "runtime.rt0_go": - return FuncID_rt0_go - case "runtime.asmcgocall": - return FuncID_asmcgocall - case "runtime.sigpanic": - return FuncID_sigpanic - case "runtime.runfinq": - return FuncID_runfinq - case "runtime.gcBgMarkWorker": - return FuncID_gcBgMarkWorker - case "runtime.systemstack_switch": - return FuncID_systemstack_switch - case "runtime.systemstack": - return FuncID_systemstack - case "runtime.cgocallback": - return FuncID_cgocallback - case "runtime.gogo": - return FuncID_gogo - case "runtime.externalthreadhandler": - return FuncID_externalthreadhandler - case "runtime.debugCallV1": - return FuncID_debugCallV1 - case "runtime.gopanic": - return FuncID_gopanic - case "runtime.panicwrap": - return FuncID_panicwrap - case "runtime.handleAsyncEvent": - return FuncID_handleAsyncEvent - case "runtime.asyncPreempt": - return FuncID_asyncPreempt - case "runtime.deferreturn": - // Don't show in the call stack (used when invoking defer functions) - return FuncID_wrapper - case "runtime.runOpenDeferFrame": - // Don't show in the call stack (used when invoking defer functions) - return FuncID_wrapper - case "runtime.reflectcallSave": - // Don't show in the call stack (used when invoking defer functions) - return FuncID_wrapper + if strings.HasPrefix(name, "runtime.") { + if id, ok := funcIDs[name[len("runtime."):]]; ok { + return id + } } return FuncID_normal } diff --git a/libgo/go/cmd/internal/objabi/line.go b/libgo/go/cmd/internal/objabi/line.go index 0733b65138d..0b1e0bb181c 100644 --- a/libgo/go/cmd/internal/objabi/line.go +++ b/libgo/go/cmd/internal/objabi/line.go @@ -5,6 +5,7 @@ package objabi import ( + "internal/buildcfg" "os" "path/filepath" "strings" @@ -38,8 +39,8 @@ func AbsFile(dir, file, rewrites string) string { } abs, rewritten := ApplyRewrites(abs, rewrites) - if !rewritten && hasPathPrefix(abs, GOROOT) { - abs = "$GOROOT" + abs[len(GOROOT):] + if !rewritten && hasPathPrefix(abs, buildcfg.GOROOT) { + abs = "$GOROOT" + abs[len(buildcfg.GOROOT):] } if abs == "" { diff --git a/libgo/go/cmd/internal/objabi/path.go b/libgo/go/cmd/internal/objabi/path.go index fd1c9981c69..aacab9a0ca7 100644 --- a/libgo/go/cmd/internal/objabi/path.go +++ b/libgo/go/cmd/internal/objabi/path.go @@ -47,6 +47,8 @@ func PathToPrefix(s string) string { // some cases need to be aware of when they are building such a // package, for example to enable features such as ABI selectors in // assembly sources. +// +// Keep in sync with cmd/dist/build.go:IsRuntimePackagePath. func IsRuntimePackagePath(pkgpath string) bool { rval := false switch pkgpath { @@ -56,6 +58,8 @@ func IsRuntimePackagePath(pkgpath string) bool { rval = true case "syscall": rval = true + case "internal/bytealg": + rval = true default: rval = strings.HasPrefix(pkgpath, "runtime/internal") } diff --git a/libgo/go/cmd/internal/objabi/reloctype.go b/libgo/go/cmd/internal/objabi/reloctype.go index 649f6901944..52827a6deee 100644 --- a/libgo/go/cmd/internal/objabi/reloctype.go +++ b/libgo/go/cmd/internal/objabi/reloctype.go @@ -50,11 +50,6 @@ const ( // R_ADDROFF resolves to a 32-bit offset from the beginning of the section // holding the data being relocated to the referenced symbol. R_ADDROFF - // R_WEAKADDROFF resolves just like R_ADDROFF but is a weak relocation. - // A weak relocation does not make the symbol it refers to reachable, - // and is only honored by the linker if the symbol is in some other way - // reachable. - R_WEAKADDROFF R_SIZE R_CALL R_CALLARM @@ -106,6 +101,9 @@ const ( // *rtype, and may be set to zero by the linker if it determines the method // text is unreachable by the linked program. R_METHODOFF + // R_KEEP tells the linker to keep the referred-to symbol in the final binary + // if the symbol containing the R_KEEP relocation is in the final binary. + R_KEEP R_POWER_TOC R_GOTPCREL // R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address @@ -172,8 +170,8 @@ const ( // R_POWER_TLS_LE is used to implement the "local exec" model for tls // access. It resolves to the offset of the thread-local symbol from the - // thread pointer (R13) and inserts this value into the low 16 bits of an - // instruction word. + // thread pointer (R13) and is split against a pair of instructions to + // support a 32 bit displacement. R_POWER_TLS_LE // R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It @@ -183,10 +181,12 @@ const ( // symbol from the thread pointer (R13)). R_POWER_TLS_IE - // R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as - // accessing a particular thread-local symbol. It does not affect code generation - // but is used by the system linker when relaxing "initial exec" model code to - // "local exec" model code. + // R_POWER_TLS marks an X-form instruction such as "ADD R3,R13,R4" as completing + // a sequence of GOT-relative relocations to compute a TLS address. This can be + // used by the system linker to to rewrite the GOT-relative TLS relocation into a + // simpler thread-pointer relative relocation. See table 3.26 and 3.28 in the + // ppc64 elfv2 1.4 ABI on this transformation. Likewise, the second argument + // (usually called RB in X-form instructions) is assumed to be R13. R_POWER_TLS // R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second @@ -256,6 +256,15 @@ const ( // of a symbol. This isn't a real relocation, it can be placed in anywhere // in a symbol and target any symbols. R_XCOFFREF + + // R_WEAK marks the relocation as a weak reference. + // A weak relocation does not make the symbol it refers to reachable, + // and is only honored by the linker if the symbol is in some other way + // reachable. + R_WEAK = -1 << 15 + + R_WEAKADDR = R_WEAK | R_ADDR + R_WEAKADDROFF = R_WEAK | R_ADDROFF ) // IsDirectCall reports whether r is a relocation for a direct call. diff --git a/libgo/go/cmd/internal/objabi/reloctype_string.go b/libgo/go/cmd/internal/objabi/reloctype_string.go index 658a44f8b81..4638ef14d91 100644 --- a/libgo/go/cmd/internal/objabi/reloctype_string.go +++ b/libgo/go/cmd/internal/objabi/reloctype_string.go @@ -13,28 +13,28 @@ func _() { _ = x[R_ADDRARM64-3] _ = x[R_ADDRMIPS-4] _ = x[R_ADDROFF-5] - _ = x[R_WEAKADDROFF-6] - _ = x[R_SIZE-7] - _ = x[R_CALL-8] - _ = x[R_CALLARM-9] - _ = x[R_CALLARM64-10] - _ = x[R_CALLIND-11] - _ = x[R_CALLPOWER-12] - _ = x[R_CALLMIPS-13] - _ = x[R_CALLRISCV-14] - _ = x[R_CONST-15] - _ = x[R_PCREL-16] - _ = x[R_TLS_LE-17] - _ = x[R_TLS_IE-18] - _ = x[R_GOTOFF-19] - _ = x[R_PLT0-20] - _ = x[R_PLT1-21] - _ = x[R_PLT2-22] - _ = x[R_USEFIELD-23] - _ = x[R_USETYPE-24] - _ = x[R_USEIFACE-25] - _ = x[R_USEIFACEMETHOD-26] - _ = x[R_METHODOFF-27] + _ = x[R_SIZE-6] + _ = x[R_CALL-7] + _ = x[R_CALLARM-8] + _ = x[R_CALLARM64-9] + _ = x[R_CALLIND-10] + _ = x[R_CALLPOWER-11] + _ = x[R_CALLMIPS-12] + _ = x[R_CALLRISCV-13] + _ = x[R_CONST-14] + _ = x[R_PCREL-15] + _ = x[R_TLS_LE-16] + _ = x[R_TLS_IE-17] + _ = x[R_GOTOFF-18] + _ = x[R_PLT0-19] + _ = x[R_PLT1-20] + _ = x[R_PLT2-21] + _ = x[R_USEFIELD-22] + _ = x[R_USETYPE-23] + _ = x[R_USEIFACE-24] + _ = x[R_USEIFACEMETHOD-25] + _ = x[R_METHODOFF-26] + _ = x[R_KEEP-27] _ = x[R_POWER_TOC-28] _ = x[R_GOTPCREL-29] _ = x[R_JMPMIPS-30] @@ -70,9 +70,9 @@ func _() { _ = x[R_XCOFFREF-60] } -const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" +const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" -var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 218, 234, 245, 256, 266, 275, 288, 302, 316, 330, 346, 357, 370, 383, 397, 411, 425, 440, 454, 468, 479, 493, 508, 525, 543, 564, 583, 602, 622, 642, 652, 663, 676, 687, 699, 709} +var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 120, 127, 134, 142, 150, 158, 164, 170, 176, 186, 195, 205, 221, 232, 238, 249, 259, 268, 281, 295, 309, 323, 339, 350, 363, 376, 390, 404, 418, 433, 447, 461, 472, 486, 501, 518, 536, 557, 576, 595, 615, 635, 645, 656, 669, 680, 692, 702} func (i RelocType) String() string { i -= 1 diff --git a/libgo/go/cmd/internal/objabi/stack.go b/libgo/go/cmd/internal/objabi/stack.go index 05a1d4a4b58..0c82a7c6dd1 100644 --- a/libgo/go/cmd/internal/objabi/stack.go +++ b/libgo/go/cmd/internal/objabi/stack.go @@ -4,6 +4,8 @@ package objabi +import "internal/buildcfg" + // For the linkers. Must match Go definitions. const ( @@ -13,10 +15,6 @@ const ( StackSmall = 128 ) -const ( - StackPreempt = -1314 // 0xfff...fade -) - // Initialize StackGuard and StackLimit according to target system. var StackGuard = 928*stackGuardMultiplier() + StackSystem var StackLimit = StackGuard - StackSystem - StackSmall @@ -26,7 +24,7 @@ var StackLimit = StackGuard - StackSystem - StackSmall // builds that have larger stack frames or for specific targets. func stackGuardMultiplier() int { // On AIX, a larger stack is needed for syscalls. - if GOOS == "aix" { + if buildcfg.GOOS == "aix" { return 2 } return stackGuardMultiplierDefault diff --git a/libgo/go/cmd/internal/objabi/util.go b/libgo/go/cmd/internal/objabi/util.go index d9cf4955f2f..fcda97d515b 100644 --- a/libgo/go/cmd/internal/objabi/util.go +++ b/libgo/go/cmd/internal/objabi/util.go @@ -6,196 +6,19 @@ package objabi import ( "fmt" - "log" - "os" + "internal/buildcfg" "strings" ) -func envOr(key, value string) string { - if x := os.Getenv(key); x != "" { - return x - } - return value -} - -var ( - defaultGOROOT = defaultGOROOTValue() - - GOROOT = envOr("GOROOT", defaultGOROOT) - GOARCH = envOr("GOARCH", defaultGOARCH) - GOOS = envOr("GOOS", defaultGOOS) - GO386 = envOr("GO386", defaultGO386) - GOARM = goarm() - GOMIPS = gomips() - GOMIPS64 = gomips64() - GOPPC64 = goppc64() - GOWASM = gowasm() - GO_LDSO = defaultGO_LDSO - Version = version -) - const ( ElfRelocOffset = 256 MachoRelocOffset = 2048 // reserve enough space for ELF relocations ) -func goarm() int { - def := defaultGOARM - if GOOS == "android" && GOARCH == "arm" { - // Android arm devices always support GOARM=7. - def = "7" - } - switch v := envOr("GOARM", def); v { - case "5": - return 5 - case "6": - return 6 - case "7": - return 7 - } - // Fail here, rather than validate at multiple call sites. - log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.") - panic("unreachable") -} - -func gomips() string { - switch v := envOr("GOMIPS", defaultGOMIPS); v { - case "hardfloat", "softfloat": - return v - } - log.Fatalf("Invalid GOMIPS value. Must be hardfloat or softfloat.") - panic("unreachable") -} - -func gomips64() string { - switch v := envOr("GOMIPS64", defaultGOMIPS64); v { - case "hardfloat", "softfloat": - return v - } - log.Fatalf("Invalid GOMIPS64 value. Must be hardfloat or softfloat.") - panic("unreachable") -} - -func goppc64() int { - switch v := envOr("GOPPC64", defaultGOPPC64); v { - case "power8": - return 8 - case "power9": - return 9 - } - log.Fatalf("Invalid GOPPC64 value. Must be power8 or power9.") - panic("unreachable") -} - -type gowasmFeatures struct { - SignExt bool - SatConv bool -} - -func (f gowasmFeatures) String() string { - var flags []string - if f.SatConv { - flags = append(flags, "satconv") - } - if f.SignExt { - flags = append(flags, "signext") - } - return strings.Join(flags, ",") -} - -func gowasm() (f gowasmFeatures) { - for _, opt := range strings.Split(envOr("GOWASM", ""), ",") { - switch opt { - case "satconv": - f.SatConv = true - case "signext": - f.SignExt = true - case "": - // ignore - default: - log.Fatalf("Invalid GOWASM value. No such feature: " + opt) - } - } - return -} - -func Getgoextlinkenabled() string { - return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED) -} - -func init() { - for _, f := range strings.Split(goexperiment, ",") { - if f != "" { - addexp(f) - } - } - - // regabi is only supported on amd64. - if GOARCH != "amd64" { - Regabi_enabled = 0 - } -} - -// Note: must agree with runtime.framepointer_enabled. -var Framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64" && (GOOS == "linux" || GOOS == "darwin" || GOOS == "ios") - -func addexp(s string) { - // Could do general integer parsing here, but the runtime copy doesn't yet. - v := 1 - name := s - if len(name) > 2 && name[:2] == "no" { - v = 0 - name = name[2:] - } - for i := 0; i < len(exper); i++ { - if exper[i].name == name { - if exper[i].val != nil { - *exper[i].val = v - } - return - } - } - - fmt.Printf("unknown experiment %s\n", s) - os.Exit(2) -} - -var ( - Fieldtrack_enabled int - Preemptibleloops_enabled int - Staticlockranking_enabled int - Regabi_enabled int -) - -// Toolchain experiments. -// These are controlled by the GOEXPERIMENT environment -// variable recorded when the toolchain is built. -// This list is also known to cmd/gc. -var exper = []struct { - name string - val *int -}{ - {"fieldtrack", &Fieldtrack_enabled}, - {"preemptibleloops", &Preemptibleloops_enabled}, - {"staticlockranking", &Staticlockranking_enabled}, - {"regabi", &Regabi_enabled}, -} - -var defaultExpstring = Expstring() - -func DefaultExpstring() string { - return defaultExpstring -} - -func Expstring() string { - buf := "X" - for i := range exper { - if *exper[i].val != 0 { - buf += "," + exper[i].name - } - } - if buf == "X" { - buf += ",none" - } - return "X:" + buf[2:] +// HeaderString returns the toolchain configuration string written in +// Go object headers. This string ensures we don't attempt to import +// or link object files that are incompatible with each other. This +// string always starts with "go object ". +func HeaderString() string { + return fmt.Sprintf("go object %s %s %s X:%s\n", buildcfg.GOOS, buildcfg.GOARCH, buildcfg.Version, strings.Join(buildcfg.EnabledExperiments(), ",")) } |