go/src/cmd/internal/objabi/util.go
erifan01 3b37ff453e cmd/link: increase the reserved space for ELF relocations
Currently the offset values of ELF relocations and Macho relocations
are 256 and 512 respectively, which means that the space reserved for
ELF relocations is only 256. But AARCH64 has more than 256 ELF relocation
types, in fact the maximum AARCH64 ELF relocation type recorded in file
src/debug/elf/elf.go is 1032 currently. So this CL increases the offset
of Macho relocations to 2048 to leave enough space for AARCH64 ELF
relocations.

Change-Id: I784ac38aeb3e102ac7825f6d621086849c8d3146
Reviewed-on: https://go-review.googlesource.com/c/go/+/172497
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2019-04-17 23:31:28 +00:00

190 lines
3.7 KiB
Go

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package objabi
import (
"fmt"
"log"
"os"
"strings"
)
func envOr(key, value string) string {
if x := os.Getenv(key); x != "" {
return x
}
return value
}
var (
defaultGOROOT string // set by linker
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 {
switch v := envOr("GOARM", defaultGOARM); 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)
}
}
}
func Framepointer_enabled(goos, goarch string) bool {
return framepointer_enabled != 0 && (goarch == "amd64" && goos != "nacl" || goarch == "arm64" && goos == "linux")
}
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 (
framepointer_enabled int = 1
Fieldtrack_enabled int
Preemptibleloops_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},
{"framepointer", &framepointer_enabled},
{"preemptibleloops", &Preemptibleloops_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:]
}