1// Copyright 2020 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
5package ld
6
7import (
8	"cmd/internal/objabi"
9	"cmd/internal/sys"
10	"encoding/binary"
11)
12
13// Target holds the configuration we're building for.
14type Target struct {
15	Arch *sys.Arch
16
17	HeadType objabi.HeadType
18
19	LinkMode  LinkMode
20	BuildMode BuildMode
21
22	linkShared    bool
23	canUsePlugins bool
24	IsELF         bool
25}
26
27//
28// Target type functions
29//
30
31func (t *Target) IsExe() bool {
32	return t.BuildMode == BuildModeExe
33}
34
35func (t *Target) IsShared() bool {
36	return t.BuildMode == BuildModeShared
37}
38
39func (t *Target) IsPlugin() bool {
40	return t.BuildMode == BuildModePlugin
41}
42
43func (t *Target) IsInternal() bool {
44	return t.LinkMode == LinkInternal
45}
46
47func (t *Target) IsExternal() bool {
48	return t.LinkMode == LinkExternal
49}
50
51func (t *Target) IsPIE() bool {
52	return t.BuildMode == BuildModePIE
53}
54
55func (t *Target) IsSharedGoLink() bool {
56	return t.linkShared
57}
58
59func (t *Target) CanUsePlugins() bool {
60	return t.canUsePlugins
61}
62
63func (t *Target) IsElf() bool {
64	t.mustSetHeadType()
65	return t.IsELF
66}
67
68func (t *Target) IsDynlinkingGo() bool {
69	return t.IsShared() || t.IsSharedGoLink() || t.IsPlugin() || t.CanUsePlugins()
70}
71
72// UseRelro reports whether to make use of "read only relocations" aka
73// relro.
74func (t *Target) UseRelro() bool {
75	switch t.BuildMode {
76	case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
77		return t.IsELF || t.HeadType == objabi.Haix || t.HeadType == objabi.Hdarwin
78	default:
79		if t.HeadType == objabi.Hdarwin && t.IsARM64() {
80			// On darwin/ARM64, everything is PIE.
81			return true
82		}
83		return t.linkShared || (t.HeadType == objabi.Haix && t.LinkMode == LinkExternal)
84	}
85}
86
87//
88// Processor functions
89//
90
91func (t *Target) Is386() bool {
92	return t.Arch.Family == sys.I386
93}
94
95func (t *Target) IsARM() bool {
96	return t.Arch.Family == sys.ARM
97}
98
99func (t *Target) IsARM64() bool {
100	return t.Arch.Family == sys.ARM64
101}
102
103func (t *Target) IsAMD64() bool {
104	return t.Arch.Family == sys.AMD64
105}
106
107func (t *Target) IsMIPS() bool {
108	return t.Arch.Family == sys.MIPS
109}
110
111func (t *Target) IsMIPS64() bool {
112	return t.Arch.Family == sys.MIPS64
113}
114
115func (t *Target) IsLOONG64() bool {
116	return t.Arch.Family == sys.Loong64
117}
118
119func (t *Target) IsPPC64() bool {
120	return t.Arch.Family == sys.PPC64
121}
122
123func (t *Target) IsRISCV64() bool {
124	return t.Arch.Family == sys.RISCV64
125}
126
127func (t *Target) IsS390X() bool {
128	return t.Arch.Family == sys.S390X
129}
130
131func (t *Target) IsWasm() bool {
132	return t.Arch.Family == sys.Wasm
133}
134
135//
136// OS Functions
137//
138
139func (t *Target) IsLinux() bool {
140	t.mustSetHeadType()
141	return t.HeadType == objabi.Hlinux
142}
143
144func (t *Target) IsDarwin() bool {
145	t.mustSetHeadType()
146	return t.HeadType == objabi.Hdarwin
147}
148
149func (t *Target) IsWindows() bool {
150	t.mustSetHeadType()
151	return t.HeadType == objabi.Hwindows
152}
153
154func (t *Target) IsPlan9() bool {
155	t.mustSetHeadType()
156	return t.HeadType == objabi.Hplan9
157}
158
159func (t *Target) IsAIX() bool {
160	t.mustSetHeadType()
161	return t.HeadType == objabi.Haix
162}
163
164func (t *Target) IsSolaris() bool {
165	t.mustSetHeadType()
166	return t.HeadType == objabi.Hsolaris
167}
168
169func (t *Target) IsNetbsd() bool {
170	t.mustSetHeadType()
171	return t.HeadType == objabi.Hnetbsd
172}
173
174func (t *Target) IsOpenbsd() bool {
175	t.mustSetHeadType()
176	return t.HeadType == objabi.Hopenbsd
177}
178
179func (t *Target) IsFreebsd() bool {
180	t.mustSetHeadType()
181	return t.HeadType == objabi.Hfreebsd
182}
183
184func (t *Target) mustSetHeadType() {
185	if t.HeadType == objabi.Hunknown {
186		panic("HeadType is not set")
187	}
188}
189
190//
191// MISC
192//
193
194func (t *Target) IsBigEndian() bool {
195	return t.Arch.ByteOrder == binary.BigEndian
196}
197
198func (t *Target) UsesLibc() bool {
199	t.mustSetHeadType()
200	switch t.HeadType {
201	case objabi.Haix, objabi.Hdarwin, objabi.Hopenbsd, objabi.Hsolaris, objabi.Hwindows:
202		// platforms where we use libc for syscalls.
203		return true
204	}
205	return false
206}
207