// Copyright 2020 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 ld import ( "cmd/internal/objabi" "cmd/internal/sys" "encoding/binary" ) // Target holds the configuration we're building for. type Target struct { Arch *sys.Arch HeadType objabi.HeadType LinkMode LinkMode BuildMode BuildMode linkShared bool canUsePlugins bool IsELF bool } // // Target type functions // func (t *Target) IsExe() bool { return t.BuildMode == BuildModeExe } func (t *Target) IsShared() bool { return t.BuildMode == BuildModeShared } func (t *Target) IsPlugin() bool { return t.BuildMode == BuildModePlugin } func (t *Target) IsInternal() bool { return t.LinkMode == LinkInternal } func (t *Target) IsExternal() bool { return t.LinkMode == LinkExternal } func (t *Target) IsPIE() bool { return t.BuildMode == BuildModePIE } func (t *Target) IsSharedGoLink() bool { return t.linkShared } func (t *Target) CanUsePlugins() bool { return t.canUsePlugins } func (t *Target) IsElf() bool { t.mustSetHeadType() return t.IsELF } func (t *Target) IsDynlinkingGo() bool { return t.IsShared() || t.IsSharedGoLink() || t.IsPlugin() || t.CanUsePlugins() } // UseRelro reports whether to make use of "read only relocations" aka // relro. func (t *Target) UseRelro() bool { switch t.BuildMode { case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin: return t.IsELF || t.HeadType == objabi.Haix || t.HeadType == objabi.Hdarwin default: if t.HeadType == objabi.Hdarwin && t.IsARM64() { // On darwin/ARM64, everything is PIE. return true } return t.linkShared || (t.HeadType == objabi.Haix && t.LinkMode == LinkExternal) } } // // Processor functions // func (t *Target) Is386() bool { return t.Arch.Family == sys.I386 } func (t *Target) IsARM() bool { return t.Arch.Family == sys.ARM } func (t *Target) IsARM64() bool { return t.Arch.Family == sys.ARM64 } func (t *Target) IsAMD64() bool { return t.Arch.Family == sys.AMD64 } func (t *Target) IsMIPS() bool { return t.Arch.Family == sys.MIPS } func (t *Target) IsMIPS64() bool { return t.Arch.Family == sys.MIPS64 } func (t *Target) IsLOONG64() bool { return t.Arch.Family == sys.Loong64 } func (t *Target) IsPPC64() bool { return t.Arch.Family == sys.PPC64 } func (t *Target) IsRISCV64() bool { return t.Arch.Family == sys.RISCV64 } func (t *Target) IsS390X() bool { return t.Arch.Family == sys.S390X } func (t *Target) IsWasm() bool { return t.Arch.Family == sys.Wasm } // // OS Functions // func (t *Target) IsLinux() bool { t.mustSetHeadType() return t.HeadType == objabi.Hlinux } func (t *Target) IsDarwin() bool { t.mustSetHeadType() return t.HeadType == objabi.Hdarwin } func (t *Target) IsWindows() bool { t.mustSetHeadType() return t.HeadType == objabi.Hwindows } func (t *Target) IsPlan9() bool { t.mustSetHeadType() return t.HeadType == objabi.Hplan9 } func (t *Target) IsAIX() bool { t.mustSetHeadType() return t.HeadType == objabi.Haix } func (t *Target) IsSolaris() bool { t.mustSetHeadType() return t.HeadType == objabi.Hsolaris } func (t *Target) IsNetbsd() bool { t.mustSetHeadType() return t.HeadType == objabi.Hnetbsd } func (t *Target) IsOpenbsd() bool { t.mustSetHeadType() return t.HeadType == objabi.Hopenbsd } func (t *Target) IsFreebsd() bool { t.mustSetHeadType() return t.HeadType == objabi.Hfreebsd } func (t *Target) mustSetHeadType() { if t.HeadType == objabi.Hunknown { panic("HeadType is not set") } } // // MISC // func (t *Target) IsBigEndian() bool { return t.Arch.ByteOrder == binary.BigEndian } func (t *Target) UsesLibc() bool { t.mustSetHeadType() switch t.HeadType { case objabi.Haix, objabi.Hdarwin, objabi.Hopenbsd, objabi.Hsolaris, objabi.Hwindows: // platforms where we use libc for syscalls. return true } return false }