xref: /xnu-11215.81.4/EXTERNAL_HEADERS/mach-o/x86_64/reloc.h (revision d4514f0bc1d3f944c22d92e68b646ac3fb40d452) !
1 /*
2  * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. Please obtain a copy of the License at
10  * http://www.opensource.apple.com/apsl/ and read it before using this
11  * file.
12  *
13  * The Original Code and all software distributed under the License are
14  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18  * Please see the License for the specific language governing rights and
19  * limitations under the License.
20  *
21  * @APPLE_LICENSE_HEADER_END@
22  */
23 /*
24  * Relocations for x86_64 are a bit different than for other architectures in
25  * Mach-O: Scattered relocations are not used.  Almost all relocations produced
26  * by the compiler are external relocations.  An external relocation has the
27  * r_extern bit set to 1 and the r_symbolnum field contains the symbol table
28  * index of the target label.
29  *
30  * When the assembler is generating relocations, if the target label is a local
31  * label (begins with 'L'), then the previous non-local label in the same
32  * section is used as the target of the external relocation.  An addend is used
33  * with the distance from that non-local label to the target label.  Only when
34  * there is no previous non-local label in the section is an internal
35  * relocation used.
36  *
37  * The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does
38  * not have RELA relocations).  For PC-relative relocations, the addend is
39  * stored directly in the instruction.  This is different from other Mach-O
40  * architectures, which encode the addend minus the current section offset.
41  *
42  * The relocation types are:
43  *
44  * 	X86_64_RELOC_UNSIGNED	// for absolute addresses
45  * 	X86_64_RELOC_SIGNED		// for signed 32-bit displacement
46  * 	X86_64_RELOC_BRANCH		// a CALL/JMP instruction with 32-bit displacement
47  * 	X86_64_RELOC_GOT_LOAD	// a MOVQ load of a GOT entry
48  * 	X86_64_RELOC_GOT		// other GOT references
49  * 	X86_64_RELOC_SUBTRACTOR	// must be followed by a X86_64_RELOC_UNSIGNED
50  *
51  * The following are sample assembly instructions, followed by the relocation
52  * and section content they generate in an object file:
53  *
54  * 	call _foo
55  * 		r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
56  * 		E8 00 00 00 00
57  *
58  * 	call _foo+4
59  * 		r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
60  * 		E8 04 00 00 00
61  *
62  * 	movq _foo@GOTPCREL(%rip), %rax
63  * 		r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
64  * 		48 8B 05 00 00 00 00
65  *
66  * 	pushq _foo@GOTPCREL(%rip)
67  * 		r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
68  * 		FF 35 00 00 00 00
69  *
70  * 	movl _foo(%rip), %eax
71  * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
72  * 		8B 05 00 00 00 00
73  *
74  * 	movl _foo+4(%rip), %eax
75  * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
76  * 		8B 05 04 00 00 00
77  *
78  * 	movb  $0x12, _foo(%rip)
79  * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
80  * 		C6 05 FF FF FF FF 12
81  *
82  * 	movl  $0x12345678, _foo(%rip)
83  * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
84  * 		C7 05 FC FF FF FF 78 56 34 12
85  *
86  * 	.quad _foo
87  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
88  * 		00 00 00 00 00 00 00 00
89  *
90  * 	.quad _foo+4
91  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
92  * 		04 00 00 00 00 00 00 00
93  *
94  * 	.quad _foo - _bar
95  * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
96  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
97  * 		00 00 00 00 00 00 00 00
98  *
99  * 	.quad _foo - _bar + 4
100  * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
101  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
102  * 		04 00 00 00 00 00 00 00
103  *
104  * 	.long _foo - _bar
105  * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar
106  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo
107  * 		00 00 00 00
108  *
109  * 	lea L1(%rip), %rax
110  * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev
111  * 		48 8d 05 12 00 00 00
112  * 		// assumes _prev is the first non-local label 0x12 bytes before L1
113  *
114  * 	lea L0(%rip), %rax
115  * 		r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
116  * 		48 8d 05 56 00 00 00
117  *		// assumes L0 is in third section and there is no previous non-local label.
118  *		// The rip-relative-offset of 0x00000056 is L0-address_of_next_instruction.
119  *		// address_of_next_instruction is the address of the relocation + 4.
120  *
121  *     add     $6,L0(%rip)
122  *             r_type=X86_64_RELOC_SIGNED_1, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
123  *		83 05 18 00 00 00 06
124  *		// assumes L0 is in third section and there is no previous non-local label.
125  *		// The rip-relative-offset of 0x00000018 is L0-address_of_next_instruction.
126  *		// address_of_next_instruction is the address of the relocation + 4 + 1.
127  *		// The +1 comes from SIGNED_1.  This is used because the relocation is not
128  *		// at the end of the instruction.
129  *
130  * 	.quad L1
131  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
132  * 		12 00 00 00 00 00 00 00
133  * 		// assumes _prev is the first non-local label 0x12 bytes before L1
134  *
135  * 	.quad L0
136  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3
137  * 		56 00 00 00 00 00 00 00
138  * 		// assumes L0 is in third section, has an address of 0x00000056 in .o
139  * 		// file, and there is no previous non-local label
140  *
141  * 	.quad _foo - .
142  * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
143  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
144  * 		EE FF FF FF FF FF FF FF
145  * 		// assumes _prev is the first non-local label 0x12 bytes before this
146  * 		// .quad
147  *
148  * 	.quad _foo - L1
149  * 		r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
150  * 		r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
151  * 		EE FF FF FF FF FF FF FF
152  * 		// assumes _prev is the first non-local label 0x12 bytes before L1
153  *
154  * 	.quad L1 - _prev
155  * 		// No relocations.  This is an assembly time constant.
156  * 		12 00 00 00 00 00 00 00
157  * 		// assumes _prev is the first non-local label 0x12 bytes before L1
158  *
159  *
160  *
161  * In final linked images, there are only two valid relocation kinds:
162  *
163  *     r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index
164  *	This tells dyld to add the address of a symbol to a pointer sized (8-byte)
165  *  piece of data (i.e on disk the 8-byte piece of data contains the addend). The
166  *  r_symbolnum contains the index into the symbol table of the target symbol.
167  *
168  *     r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0
169  * This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount
170  * the containing image was loaded from its base address (e.g. slide).
171  *
172  */
173 enum reloc_type_x86_64
174 {
175 	X86_64_RELOC_UNSIGNED,		// for absolute addresses
176 	X86_64_RELOC_SIGNED,		// for signed 32-bit displacement
177 	X86_64_RELOC_BRANCH,		// a CALL/JMP instruction with 32-bit displacement
178 	X86_64_RELOC_GOT_LOAD,		// a MOVQ load of a GOT entry
179 	X86_64_RELOC_GOT,			// other GOT references
180 	X86_64_RELOC_SUBTRACTOR,	// must be followed by a X86_64_RELOC_UNSIGNED
181 	X86_64_RELOC_SIGNED_1,		// for signed 32-bit displacement with a -1 addend
182 	X86_64_RELOC_SIGNED_2,		// for signed 32-bit displacement with a -2 addend
183 	X86_64_RELOC_SIGNED_4,		// for signed 32-bit displacement with a -4 addend
184 	X86_64_RELOC_TLV,		// for thread local variables
185 };
186