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 ([email protected])
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 ([email protected])
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_SIZE
54	R_CALL
55	R_CALLARM
56	R_CALLARM64
57	R_CALLIND
58	R_CALLPOWER
59	// R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address
60	// of a CALL (JAL) instruction, by encoding the address into the instruction.
61	R_CALLMIPS
62	R_CONST
63	R_PCREL
64	// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
65	// thread-local symbol from the thread local base and is used to implement the
66	// "local exec" model for tls access (r.Sym is not set on intel platforms but is
67	// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
68	R_TLS_LE
69	// R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT
70	// slot containing the offset from the thread-local symbol from the thread local
71	// base and is used to implemented the "initial exec" model for tls access (r.Sym
72	// is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in
73	// the linker when externally linking).
74	R_TLS_IE
75	R_GOTOFF
76	R_PLT0
77	R_PLT1
78	R_PLT2
79	R_USEFIELD
80	// R_USETYPE resolves to an *rtype, but no relocation is created. The
81	// linker uses this as a signal that the pointed-to type information
82	// should be linked into the final binary, even if there are no other
83	// direct references. (This is used for types reachable by reflection.)
84	R_USETYPE
85	// R_USEIFACE marks a type is converted to an interface in the function this
86	// relocation is applied to. The target is a type descriptor or an itab
87	// (in the latter case it refers to the concrete type contained in the itab).
88	// This is a marker relocation (0-sized), for the linker's reachabililty
89	// analysis.
90	R_USEIFACE
91	// R_USEIFACEMETHOD marks an interface method that is used in the function
92	// this relocation is applied to. The target is an interface type descriptor.
93	// The addend is the offset of the method in the type descriptor.
94	// This is a marker relocation (0-sized), for the linker's reachabililty
95	// analysis.
96	R_USEIFACEMETHOD
97	// R_USENAMEDMETHOD marks that methods with a specific name must not be eliminated.
98	// The target is a symbol containing the name of a method called via a generic
99	// interface or looked up via MethodByName("F").
100	R_USENAMEDMETHOD
101	// R_METHODOFF resolves to a 32-bit offset from the beginning of the section
102	// holding the data being relocated to the referenced symbol.
103	// It is a variant of R_ADDROFF used when linking from the uncommonType of a
104	// *rtype, and may be set to zero by the linker if it determines the method
105	// text is unreachable by the linked program.
106	R_METHODOFF
107	// R_KEEP tells the linker to keep the referred-to symbol in the final binary
108	// if the symbol containing the R_KEEP relocation is in the final binary.
109	R_KEEP
110	R_POWER_TOC
111	R_GOTPCREL
112	// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
113	// of a JMP instruction, by encoding the address into the instruction.
114	// The stack nosplit check ignores this since it is not a function call.
115	R_JMPMIPS
116
117	// R_DWARFSECREF resolves to the offset of the symbol from its section.
118	// Target of relocation must be size 4 (in current implementation).
119	R_DWARFSECREF
120
121	// R_DWARFFILEREF resolves to an index into the DWARF .debug_line
122	// file table for the specified file symbol. Must be applied to an
123	// attribute of form DW_FORM_data4.
124	R_DWARFFILEREF
125
126	// Platform dependent relocations. Architectures with fixed width instructions
127	// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
128	// stuffed into a 32-bit instruction, so an address needs to be spread across
129	// several instructions, and in turn this requires a sequence of relocations, each
130	// updating a part of an instruction. This leads to relocation codes that are
131	// inherently processor specific.
132
133	// Arm64.
134
135	// Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread
136	// local base to the thread local variable defined by the referenced (thread
137	// local) symbol. Error if the offset does not fit into 16 bits.
138	R_ARM64_TLS_LE
139
140	// Relocates an ADRP; LD64 instruction sequence to load the offset between
141	// the thread local base and the thread local variable defined by the
142	// referenced (thread local) symbol from the GOT.
143	R_ARM64_TLS_IE
144
145	// R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT
146	// slot of the referenced symbol.
147	R_ARM64_GOTPCREL
148
149	// R_ARM64_GOT resolves a GOT-relative instruction sequence, usually an adrp
150	// followed by another ld instruction.
151	R_ARM64_GOT
152
153	// R_ARM64_PCREL resolves a PC-relative addresses instruction sequence, usually an
154	// adrp followed by another add instruction.
155	R_ARM64_PCREL
156
157	// R_ARM64_PCREL_LDST8 resolves a PC-relative addresses instruction sequence, usually an
158	// adrp followed by a LD8 or ST8 instruction.
159	R_ARM64_PCREL_LDST8
160
161	// R_ARM64_PCREL_LDST16 resolves a PC-relative addresses instruction sequence, usually an
162	// adrp followed by a LD16 or ST16 instruction.
163	R_ARM64_PCREL_LDST16
164
165	// R_ARM64_PCREL_LDST32 resolves a PC-relative addresses instruction sequence, usually an
166	// adrp followed by a LD32 or ST32 instruction.
167	R_ARM64_PCREL_LDST32
168
169	// R_ARM64_PCREL_LDST64 resolves a PC-relative addresses instruction sequence, usually an
170	// adrp followed by a LD64 or ST64 instruction.
171	R_ARM64_PCREL_LDST64
172
173	// R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address.
174	R_ARM64_LDST8
175
176	// R_ARM64_LDST16 sets a LD/ST immediate value to bits [11:1] of a local address.
177	R_ARM64_LDST16
178
179	// R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address.
180	R_ARM64_LDST32
181
182	// R_ARM64_LDST64 sets a LD/ST immediate value to bits [11:3] of a local address.
183	R_ARM64_LDST64
184
185	// R_ARM64_LDST128 sets a LD/ST immediate value to bits [11:4] of a local address.
186	R_ARM64_LDST128
187
188	// PPC64.
189
190	// R_POWER_TLS_LE is used to implement the "local exec" model for tls
191	// access. It resolves to the offset of the thread-local symbol from the
192	// thread pointer (R13) and is split against a pair of instructions to
193	// support a 32 bit displacement.
194	R_POWER_TLS_LE
195
196	// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
197	// relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It
198	// inserts to the offset of GOT slot for the thread-local symbol from the TOC (the
199	// GOT slot is filled by the dynamic linker with the offset of the thread-local
200	// symbol from the thread pointer (R13)).
201	R_POWER_TLS_IE
202
203	// R_POWER_TLS marks an X-form instruction such as "ADD R3,R13,R4" as completing
204	// a sequence of GOT-relative relocations to compute a TLS address. This can be
205	// used by the system linker to to rewrite the GOT-relative TLS relocation into a
206	// simpler thread-pointer relative relocation. See table 3.26 and 3.28 in the
207	// ppc64 elfv2 1.4 ABI on this transformation.  Likewise, the second argument
208	// (usually called RB in X-form instructions) is assumed to be R13.
209	R_POWER_TLS
210
211	// R_POWER_TLS_IE_PCREL34 is similar to R_POWER_TLS_IE, but marks a single MOVD
212	// which has been assembled as a single prefixed load doubleword without using the
213	// TOC.
214	R_POWER_TLS_IE_PCREL34
215
216	// R_POWER_TLS_LE_TPREL34 is similar to R_POWER_TLS_LE, but computes an offset from
217	// the thread pointer in one prefixed instruction.
218	R_POWER_TLS_LE_TPREL34
219
220	// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
221	// instruction is a "DS-form" instruction, which has an immediate field occupying
222	// bits [15:2] of the instruction word. Bits [15:2] of the address of the
223	// relocated symbol are inserted into this field; it is an error if the last two
224	// bits of the address are not 0.
225	R_ADDRPOWER_DS
226
227	// R_ADDRPOWER_GOT relocates a D-form + DS-form instruction sequence by inserting
228	// a relative displacement of referenced symbol's GOT entry to the TOC pointer.
229	R_ADDRPOWER_GOT
230
231	// R_ADDRPOWER_GOT_PCREL34 is identical to R_ADDRPOWER_GOT, but uses a PC relative
232	// sequence to generate a GOT symbol addresses.
233	R_ADDRPOWER_GOT_PCREL34
234
235	// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
236	// inserts the displacement from the place being relocated to the address of the
237	// relocated symbol instead of just its address.
238	R_ADDRPOWER_PCREL
239
240	// R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but
241	// inserts the offset from the TOC to the address of the relocated symbol
242	// rather than the symbol's address.
243	R_ADDRPOWER_TOCREL
244
245	// R_ADDRPOWER_TOCREL_DS relocates a D-form, DS-form instruction sequence like
246	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the
247	// relocated symbol rather than the symbol's address.
248	R_ADDRPOWER_TOCREL_DS
249
250	// R_ADDRPOWER_D34 relocates a single prefixed D-form load/store operation.  All
251	// prefixed forms are D form. The high 18 bits are stored in the prefix,
252	// and the low 16 are stored in the suffix. The address is absolute.
253	R_ADDRPOWER_D34
254
255	// R_ADDRPOWER_PCREL34 relates a single prefixed D-form load/store/add operation.
256	// All prefixed forms are D form. The resulting address is relative to the
257	// PC. It is a signed 34 bit offset.
258	R_ADDRPOWER_PCREL34
259
260	// RISC-V.
261
262	// R_RISCV_JAL resolves a 20 bit offset for a J-type instruction.
263	R_RISCV_JAL
264
265	// R_RISCV_JAL_TRAMP is the same as R_RISCV_JAL but denotes the use of a
266	// trampoline, which we may be able to avoid during relocation. These are
267	// only used by the linker and are not emitted by the compiler or assembler.
268	R_RISCV_JAL_TRAMP
269
270	// R_RISCV_CALL resolves a 32 bit PC-relative address for an AUIPC + JALR
271	// instruction pair.
272	R_RISCV_CALL
273
274	// R_RISCV_PCREL_ITYPE resolves a 32 bit PC-relative address for an
275	// AUIPC + I-type instruction pair.
276	R_RISCV_PCREL_ITYPE
277
278	// R_RISCV_PCREL_STYPE resolves a 32 bit PC-relative address for an
279	// AUIPC + S-type instruction pair.
280	R_RISCV_PCREL_STYPE
281
282	// R_RISCV_TLS_IE resolves a 32 bit TLS initial-exec address for an
283	// AUIPC + I-type instruction pair.
284	R_RISCV_TLS_IE
285
286	// R_RISCV_TLS_LE resolves a 32 bit TLS local-exec address for a
287	// LUI + I-type instruction sequence.
288	R_RISCV_TLS_LE
289
290	// R_RISCV_GOT_HI20 resolves the high 20 bits of a 32-bit PC-relative GOT
291	// address.
292	R_RISCV_GOT_HI20
293
294	// R_RISCV_PCREL_HI20 resolves the high 20 bits of a 32-bit PC-relative
295	// address.
296	R_RISCV_PCREL_HI20
297
298	// R_RISCV_PCREL_LO12_I resolves the low 12 bits of a 32-bit PC-relative
299	// address using an I-type instruction.
300	R_RISCV_PCREL_LO12_I
301
302	// R_RISCV_PCREL_LO12_S resolves the low 12 bits of a 32-bit PC-relative
303	// address using an S-type instruction.
304	R_RISCV_PCREL_LO12_S
305
306	// R_RISCV_BRANCH resolves a 12-bit PC-relative branch offset.
307	R_RISCV_BRANCH
308
309	// R_RISCV_RVC_BRANCH resolves an 8-bit PC-relative offset for a CB-type
310	// instruction.
311	R_RISCV_RVC_BRANCH
312
313	// R_RISCV_RVC_JUMP resolves an 11-bit PC-relative offset for a CJ-type
314	// instruction.
315	R_RISCV_RVC_JUMP
316
317	// R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses.
318	// TODO(mundaym): remove once variants can be serialized - see issue 14218.
319	R_PCRELDBL
320
321	// Loong64.
322
323	// R_LOONG64_ADDR_HI resolves to the sign-adjusted "upper" 20 bits (bit 5-24) of an
324	// external address, by encoding it into the instruction.
325	// R_LOONG64_ADDR_LO resolves to the low 12 bits of an external address, by encoding
326	// it into the instruction.
327	R_LOONG64_ADDR_HI
328	R_LOONG64_ADDR_LO
329
330	// R_LOONG64_TLS_LE_HI resolves to the high 20 bits of a TLS address (offset from
331	// thread pointer), by encoding it into the instruction.
332	// R_LOONG64_TLS_LE_LO resolves to the low 12 bits of a TLS address (offset from
333	// thread pointer), by encoding it into the instruction.
334	R_LOONG64_TLS_LE_HI
335	R_LOONG64_TLS_LE_LO
336
337	// R_CALLLOONG64 resolves to non-PC-relative target address of a CALL (BL/JIRL)
338	// instruction, by encoding the address into the instruction.
339	R_CALLLOONG64
340
341	// R_LOONG64_TLS_IE_HI and R_LOONG64_TLS_IE_LO relocates a pcalau12i, ld.d
342	// pair to compute the address of the GOT slot of the tls symbol.
343	R_LOONG64_TLS_IE_HI
344	R_LOONG64_TLS_IE_LO
345
346	// R_LOONG64_GOT_HI and R_LOONG64_GOT_LO resolves a GOT-relative instruction sequence,
347	// usually an pcalau12i followed by another ld or addi instruction.
348	R_LOONG64_GOT_HI
349	R_LOONG64_GOT_LO
350
351	// R_JMPLOONG64 resolves to non-PC-relative target address of a JMP instruction,
352	// by encoding the address into the instruction.
353	R_JMPLOONG64
354
355	// R_ADDRMIPSU (only used on mips/mips64) resolves to the sign-adjusted "upper" 16
356	// bits (bit 16-31) of an external address, by encoding it into the instruction.
357	R_ADDRMIPSU
358	// R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS
359	// address (offset from thread pointer), by encoding it into the instruction.
360	R_ADDRMIPSTLS
361
362	// R_ADDRCUOFF resolves to a pointer-sized offset from the start of the
363	// symbol's DWARF compile unit.
364	R_ADDRCUOFF
365
366	// R_WASMIMPORT resolves to the index of the WebAssembly function import.
367	R_WASMIMPORT
368
369	// R_XCOFFREF (only used on aix/ppc64) prevents garbage collection by ld
370	// of a symbol. This isn't a real relocation, it can be placed in anywhere
371	// in a symbol and target any symbols.
372	R_XCOFFREF
373
374	// R_PEIMAGEOFF resolves to a 32-bit offset from the start address of where
375	// the executable file is mapped in memory.
376	R_PEIMAGEOFF
377
378	// R_INITORDER specifies an ordering edge between two inittask records.
379	// (From one p..inittask record to another one.)
380	// This relocation does not apply any changes to the actual data, it is
381	// just used in the linker to order the inittask records appropriately.
382	R_INITORDER
383
384	// R_WEAK marks the relocation as a weak reference.
385	// A weak relocation does not make the symbol it refers to reachable,
386	// and is only honored by the linker if the symbol is in some other way
387	// reachable.
388	R_WEAK = -1 << 15
389
390	R_WEAKADDR    = R_WEAK | R_ADDR
391	R_WEAKADDROFF = R_WEAK | R_ADDROFF
392)
393
394// IsDirectCall reports whether r is a relocation for a direct call.
395// A direct call is a CALL instruction that takes the target address
396// as an immediate. The address is embedded into the instruction(s), possibly
397// with limited width. An indirect call is a CALL instruction that takes
398// the target address in register or memory.
399func (r RelocType) IsDirectCall() bool {
400	switch r {
401	case R_CALL, R_CALLARM, R_CALLARM64, R_CALLLOONG64, R_CALLMIPS, R_CALLPOWER,
402		R_RISCV_CALL, R_RISCV_JAL, R_RISCV_JAL_TRAMP:
403		return true
404	}
405	return false
406}
407
408// IsDirectJump reports whether r is a relocation for a direct jump.
409// A direct jump is a JMP instruction that takes the target address
410// as an immediate. The address is embedded into the instruction, possibly
411// with limited width. An indirect jump is a JMP instruction that takes
412// the target address in register or memory.
413func (r RelocType) IsDirectJump() bool {
414	switch r {
415	case R_JMPMIPS:
416		return true
417	case R_JMPLOONG64:
418		return true
419	}
420	return false
421}
422
423// IsDirectCallOrJump reports whether r is a relocation for a direct
424// call or a direct jump.
425func (r RelocType) IsDirectCallOrJump() bool {
426	return r.IsDirectCall() || r.IsDirectJump()
427}
428