1// Derived from Inferno utils/6l/l.h and related files.
2// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/l.h
3//
4//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
5//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6//	Portions Copyright © 1997-1999 Vita Nuova Limited
7//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8//	Portions Copyright © 2004,2006 Bruce Ellis
9//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11//	Portions Copyright © 2009 The Go Authors. All rights reserved.
12//
13// Permission is hereby granted, free of charge, to any person obtaining a copy
14// of this software and associated documentation files (the "Software"), to deal
15// in the Software without restriction, including without limitation the rights
16// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17// copies of the Software, and to permit persons to whom the Software is
18// furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included in
21// all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
26// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29// THE SOFTWARE.
30
31package objabi
32
33type RelocType int16
34
35//go:generate stringer -type=RelocType
36const (
37	R_ADDR RelocType = 1 + iota
38	// R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit
39	// immediates in the low half of the instruction word), usually addis followed by
40	// another add or a load, inserting the "high adjusted" 16 bits of the address of
41	// the referenced symbol into the immediate field of the first instruction and the
42	// low 16 bits into that of the second instruction.
43	R_ADDRPOWER
44	// R_ADDRARM64 relocates an adrp, add pair to compute the address of the
45	// referenced symbol.
46	R_ADDRARM64
47	// R_ADDRMIPS (only used on mips/mips64) resolves to the low 16 bits of an external
48	// address, by encoding it into the instruction.
49	R_ADDRMIPS
50	// R_ADDROFF resolves to a 32-bit offset from the beginning of the section
51	// holding the data being relocated to the referenced symbol.
52	R_ADDROFF
53	// R_WEAKADDROFF resolves just like R_ADDROFF but is a weak relocation.
54	// A weak relocation does not make the symbol it refers to reachable,
55	// and is only honored by the linker if the symbol is in some other way
56	// reachable.
57	R_WEAKADDROFF
58	R_SIZE
59	R_CALL
60	R_CALLARM
61	R_CALLARM64
62	R_CALLIND
63	R_CALLPOWER
64	// R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address
65	// of a CALL (JAL) instruction, by encoding the address into the instruction.
66	R_CALLMIPS
67	// R_CALLRISCV marks RISC-V CALLs for stack checking.
68	R_CALLRISCV
69	R_CONST
70	R_PCREL
71	// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
72	// thread-local symbol from the thread local base and is used to implement the
73	// "local exec" model for tls access (r.Sym is not set on intel platforms but is
74	// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
75	R_TLS_LE
76	// R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT
77	// slot containing the offset from the thread-local symbol from the thread local
78	// base and is used to implemented the "initial exec" model for tls access (r.Sym
79	// is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in
80	// the linker when externally linking).
81	R_TLS_IE
82	R_GOTOFF
83	R_PLT0
84	R_PLT1
85	R_PLT2
86	R_USEFIELD
87	// R_USETYPE resolves to an *rtype, but no relocation is created. The
88	// linker uses this as a signal that the pointed-to type information
89	// should be linked into the final binary, even if there are no other
90	// direct references. (This is used for types reachable by reflection.)
91	R_USETYPE
92	// R_USEIFACE marks a type is converted to an interface in the function this
93	// relocation is applied to. The target is a type descriptor.
94	// This is a marker relocation (0-sized), for the linker's reachabililty
95	// analysis.
96	R_USEIFACE
97	// R_USEIFACEMETHOD marks an interface method that is used in the function
98	// this relocation is applied to. The target is an interface type descriptor.
99	// The addend is the offset of the method in the type descriptor.
100	// This is a marker relocation (0-sized), for the linker's reachabililty
101	// analysis.
102	R_USEIFACEMETHOD
103	// R_METHODOFF resolves to a 32-bit offset from the beginning of the section
104	// holding the data being relocated to the referenced symbol.
105	// It is a variant of R_ADDROFF used when linking from the uncommonType of a
106	// *rtype, and may be set to zero by the linker if it determines the method
107	// text is unreachable by the linked program.
108	R_METHODOFF
109	R_POWER_TOC
110	R_GOTPCREL
111	// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
112	// of a JMP instruction, by encoding the address into the instruction.
113	// The stack nosplit check ignores this since it is not a function call.
114	R_JMPMIPS
115
116	// R_DWARFSECREF resolves to the offset of the symbol from its section.
117	// Target of relocation must be size 4 (in current implementation).
118	R_DWARFSECREF
119
120	// R_DWARFFILEREF resolves to an index into the DWARF .debug_line
121	// file table for the specified file symbol. Must be applied to an
122	// attribute of form DW_FORM_data4.
123	R_DWARFFILEREF
124
125	// Platform dependent relocations. Architectures with fixed width instructions
126	// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
127	// stuffed into a 32-bit instruction, so an address needs to be spread across
128	// several instructions, and in turn this requires a sequence of relocations, each
129	// updating a part of an instruction. This leads to relocation codes that are
130	// inherently processor specific.
131
132	// Arm64.
133
134	// Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread
135	// local base to the thread local variable defined by the referenced (thread
136	// local) symbol. Error if the offset does not fit into 16 bits.
137	R_ARM64_TLS_LE
138
139	// Relocates an ADRP; LD64 instruction sequence to load the offset between
140	// the thread local base and the thread local variable defined by the
141	// referenced (thread local) symbol from the GOT.
142	R_ARM64_TLS_IE
143
144	// R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT
145	// slot of the referenced symbol.
146	R_ARM64_GOTPCREL
147
148	// R_ARM64_GOT resolves a GOT-relative instruction sequence, usually an adrp
149	// followed by another ld instruction.
150	R_ARM64_GOT
151
152	// R_ARM64_PCREL resolves a PC-relative addresses instruction sequence, usually an
153	// adrp followed by another add instruction.
154	R_ARM64_PCREL
155
156	// R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address.
157	R_ARM64_LDST8
158
159	// R_ARM64_LDST16 sets a LD/ST immediate value to bits [11:1] of a local address.
160	R_ARM64_LDST16
161
162	// R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address.
163	R_ARM64_LDST32
164
165	// R_ARM64_LDST64 sets a LD/ST immediate value to bits [11:3] of a local address.
166	R_ARM64_LDST64
167
168	// R_ARM64_LDST128 sets a LD/ST immediate value to bits [11:4] of a local address.
169	R_ARM64_LDST128
170
171	// PPC64.
172
173	// R_POWER_TLS_LE is used to implement the "local exec" model for tls
174	// access. It resolves to the offset of the thread-local symbol from the
175	// thread pointer (R13) and inserts this value into the low 16 bits of an
176	// instruction word.
177	R_POWER_TLS_LE
178
179	// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
180	// relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It
181	// inserts to the offset of GOT slot for the thread-local symbol from the TOC (the
182	// GOT slot is filled by the dynamic linker with the offset of the thread-local
183	// symbol from the thread pointer (R13)).
184	R_POWER_TLS_IE
185
186	// R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as
187	// accessing a particular thread-local symbol. It does not affect code generation
188	// but is used by the system linker when relaxing "initial exec" model code to
189	// "local exec" model code.
190	R_POWER_TLS
191
192	// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
193	// instruction is a "DS-form" instruction, which has an immediate field occupying
194	// bits [15:2] of the instruction word. Bits [15:2] of the address of the
195	// relocated symbol are inserted into this field; it is an error if the last two
196	// bits of the address are not 0.
197	R_ADDRPOWER_DS
198
199	// R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like
200	// R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol
201	// from the TOC rather than the symbol's address.
202	R_ADDRPOWER_GOT
203
204	// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
205	// inserts the displacement from the place being relocated to the address of the
206	// relocated symbol instead of just its address.
207	R_ADDRPOWER_PCREL
208
209	// R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but
210	// inserts the offset from the TOC to the address of the relocated symbol
211	// rather than the symbol's address.
212	R_ADDRPOWER_TOCREL
213
214	// R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like
215	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the
216	// relocated symbol rather than the symbol's address.
217	R_ADDRPOWER_TOCREL_DS
218
219	// RISC-V.
220
221	// R_RISCV_PCREL_ITYPE resolves a 32-bit PC-relative address using an
222	// AUIPC + I-type instruction pair.
223	R_RISCV_PCREL_ITYPE
224
225	// R_RISCV_PCREL_STYPE resolves a 32-bit PC-relative address using an
226	// AUIPC + S-type instruction pair.
227	R_RISCV_PCREL_STYPE
228
229	// R_RISCV_TLS_IE_ITYPE resolves a 32-bit TLS initial-exec TOC offset
230	// address using an AUIPC + I-type instruction pair.
231	R_RISCV_TLS_IE_ITYPE
232
233	// R_RISCV_TLS_IE_STYPE resolves a 32-bit TLS initial-exec TOC offset
234	// address using an AUIPC + S-type instruction pair.
235	R_RISCV_TLS_IE_STYPE
236
237	// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
238	// TODO(mundaym): remove once variants can be serialized - see issue 14218.
239	R_PCRELDBL
240
241	// R_ADDRMIPSU (only used on mips/mips64) resolves to the sign-adjusted "upper" 16
242	// bits (bit 16-31) of an external address, by encoding it into the instruction.
243	R_ADDRMIPSU
244	// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
245	// address (offset from thread pointer), by encoding it into the instruction.
246	R_ADDRMIPSTLS
247
248	// R_ADDRCUOFF resolves to a pointer-sized offset from the start of the
249	// symbol's DWARF compile unit.
250	R_ADDRCUOFF
251
252	// R_WASMIMPORT resolves to the index of the WebAssembly function import.
253	R_WASMIMPORT
254
255	// R_XCOFFREF (only used on aix/ppc64) prevents garbage collection by ld
256	// of a symbol. This isn't a real relocation, it can be placed in anywhere
257	// in a symbol and target any symbols.
258	R_XCOFFREF
259)
260
261// IsDirectCall reports whether r is a relocation for a direct call.
262// A direct call is a CALL instruction that takes the target address
263// as an immediate. The address is embedded into the instruction, possibly
264// with limited width. An indirect call is a CALL instruction that takes
265// the target address in register or memory.
266func (r RelocType) IsDirectCall() bool {
267	switch r {
268	case R_CALL, R_CALLARM, R_CALLARM64, R_CALLMIPS, R_CALLPOWER, R_CALLRISCV:
269		return true
270	}
271	return false
272}
273
274// IsDirectJump reports whether r is a relocation for a direct jump.
275// A direct jump is a JMP instruction that takes the target address
276// as an immediate. The address is embedded into the instruction, possibly
277// with limited width. An indirect jump is a JMP instruction that takes
278// the target address in register or memory.
279func (r RelocType) IsDirectJump() bool {
280	switch r {
281	case R_JMPMIPS:
282		return true
283	}
284	return false
285}
286
287// IsDirectCallOrJump reports whether r is a relocation for a direct
288// call or a direct jump.
289func (r RelocType) IsDirectCallOrJump() bool {
290	return r.IsDirectCall() || r.IsDirectJump()
291}
292