]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/PeCoffLoaderEx.c
Check In tool source code based on Build tool project revision r1655.
[mirror_edk2.git] / BaseTools / Source / C / Common / PeCoffLoaderEx.c
1 /** @file
2
3 Copyright (c) 2004 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 PeCoffLoaderEx.c
15
16 Abstract:
17
18 IA32, X64 and IPF Specific relocation fixups
19
20 Revision History
21
22 --*/
23
24 #include <Common/UefiBaseTypes.h>
25 #include <IndustryStandard/PeImage.h>
26 #include "PeCoffLib.h"
27
28 #define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
29 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
30
31 #define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
32 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
33 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
34
35 #define IMM64_IMM7B_INST_WORD_X 3
36 #define IMM64_IMM7B_SIZE_X 7
37 #define IMM64_IMM7B_INST_WORD_POS_X 4
38 #define IMM64_IMM7B_VAL_POS_X 0
39
40 #define IMM64_IMM9D_INST_WORD_X 3
41 #define IMM64_IMM9D_SIZE_X 9
42 #define IMM64_IMM9D_INST_WORD_POS_X 18
43 #define IMM64_IMM9D_VAL_POS_X 7
44
45 #define IMM64_IMM5C_INST_WORD_X 3
46 #define IMM64_IMM5C_SIZE_X 5
47 #define IMM64_IMM5C_INST_WORD_POS_X 13
48 #define IMM64_IMM5C_VAL_POS_X 16
49
50 #define IMM64_IC_INST_WORD_X 3
51 #define IMM64_IC_SIZE_X 1
52 #define IMM64_IC_INST_WORD_POS_X 12
53 #define IMM64_IC_VAL_POS_X 21
54
55 #define IMM64_IMM41a_INST_WORD_X 1
56 #define IMM64_IMM41a_SIZE_X 10
57 #define IMM64_IMM41a_INST_WORD_POS_X 14
58 #define IMM64_IMM41a_VAL_POS_X 22
59
60 #define IMM64_IMM41b_INST_WORD_X 1
61 #define IMM64_IMM41b_SIZE_X 8
62 #define IMM64_IMM41b_INST_WORD_POS_X 24
63 #define IMM64_IMM41b_VAL_POS_X 32
64
65 #define IMM64_IMM41c_INST_WORD_X 2
66 #define IMM64_IMM41c_SIZE_X 23
67 #define IMM64_IMM41c_INST_WORD_POS_X 0
68 #define IMM64_IMM41c_VAL_POS_X 40
69
70 #define IMM64_SIGN_INST_WORD_X 3
71 #define IMM64_SIGN_SIZE_X 1
72 #define IMM64_SIGN_INST_WORD_POS_X 27
73 #define IMM64_SIGN_VAL_POS_X 63
74
75 RETURN_STATUS
76 PeCoffLoaderRelocateIa32Image (
77 IN UINT16 *Reloc,
78 IN OUT CHAR8 *Fixup,
79 IN OUT CHAR8 **FixupData,
80 IN UINT64 Adjust
81 )
82 /*++
83
84 Routine Description:
85
86 Performs an IA-32 specific relocation fixup
87
88 Arguments:
89
90 Reloc - Pointer to the relocation record
91
92 Fixup - Pointer to the address to fix up
93
94 FixupData - Pointer to a buffer to log the fixups
95
96 Adjust - The offset to adjust the fixup
97
98 Returns:
99
100 EFI_UNSUPPORTED - Unsupported now
101
102 --*/
103 {
104 return RETURN_UNSUPPORTED;
105 }
106
107 RETURN_STATUS
108 PeCoffLoaderRelocateIpfImage (
109 IN UINT16 *Reloc,
110 IN OUT CHAR8 *Fixup,
111 IN OUT CHAR8 **FixupData,
112 IN UINT64 Adjust
113 )
114 /*++
115
116 Routine Description:
117
118 Performs an Itanium-based specific relocation fixup
119
120 Arguments:
121
122 Reloc - Pointer to the relocation record
123
124 Fixup - Pointer to the address to fix up
125
126 FixupData - Pointer to a buffer to log the fixups
127
128 Adjust - The offset to adjust the fixup
129
130 Returns:
131
132 Status code
133
134 --*/
135 {
136 UINT64 *F64;
137 UINT64 FixupVal;
138
139 switch ((*Reloc) >> 12) {
140
141 case EFI_IMAGE_REL_BASED_DIR64:
142 F64 = (UINT64 *) Fixup;
143 *F64 = *F64 + (UINT64) Adjust;
144 if (*FixupData != NULL) {
145 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
146 *(UINT64 *)(*FixupData) = *F64;
147 *FixupData = *FixupData + sizeof(UINT64);
148 }
149 break;
150
151 case EFI_IMAGE_REL_BASED_IA64_IMM64:
152
153 //
154 // Align it to bundle address before fixing up the
155 // 64-bit immediate value of the movl instruction.
156 //
157
158 Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
159 FixupVal = (UINT64)0;
160
161 //
162 // Extract the lower 32 bits of IMM64 from bundle
163 //
164 EXT_IMM64(FixupVal,
165 (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
166 IMM64_IMM7B_SIZE_X,
167 IMM64_IMM7B_INST_WORD_POS_X,
168 IMM64_IMM7B_VAL_POS_X
169 );
170
171 EXT_IMM64(FixupVal,
172 (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
173 IMM64_IMM9D_SIZE_X,
174 IMM64_IMM9D_INST_WORD_POS_X,
175 IMM64_IMM9D_VAL_POS_X
176 );
177
178 EXT_IMM64(FixupVal,
179 (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
180 IMM64_IMM5C_SIZE_X,
181 IMM64_IMM5C_INST_WORD_POS_X,
182 IMM64_IMM5C_VAL_POS_X
183 );
184
185 EXT_IMM64(FixupVal,
186 (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
187 IMM64_IC_SIZE_X,
188 IMM64_IC_INST_WORD_POS_X,
189 IMM64_IC_VAL_POS_X
190 );
191
192 EXT_IMM64(FixupVal,
193 (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,
194 IMM64_IMM41a_SIZE_X,
195 IMM64_IMM41a_INST_WORD_POS_X,
196 IMM64_IMM41a_VAL_POS_X
197 );
198
199 //
200 // Update 64-bit address
201 //
202 FixupVal += Adjust;
203
204 //
205 // Insert IMM64 into bundle
206 //
207 INS_IMM64(FixupVal,
208 ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
209 IMM64_IMM7B_SIZE_X,
210 IMM64_IMM7B_INST_WORD_POS_X,
211 IMM64_IMM7B_VAL_POS_X
212 );
213
214 INS_IMM64(FixupVal,
215 ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
216 IMM64_IMM9D_SIZE_X,
217 IMM64_IMM9D_INST_WORD_POS_X,
218 IMM64_IMM9D_VAL_POS_X
219 );
220
221 INS_IMM64(FixupVal,
222 ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
223 IMM64_IMM5C_SIZE_X,
224 IMM64_IMM5C_INST_WORD_POS_X,
225 IMM64_IMM5C_VAL_POS_X
226 );
227
228 INS_IMM64(FixupVal,
229 ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
230 IMM64_IC_SIZE_X,
231 IMM64_IC_INST_WORD_POS_X,
232 IMM64_IC_VAL_POS_X
233 );
234
235 INS_IMM64(FixupVal,
236 ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),
237 IMM64_IMM41a_SIZE_X,
238 IMM64_IMM41a_INST_WORD_POS_X,
239 IMM64_IMM41a_VAL_POS_X
240 );
241
242 INS_IMM64(FixupVal,
243 ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),
244 IMM64_IMM41b_SIZE_X,
245 IMM64_IMM41b_INST_WORD_POS_X,
246 IMM64_IMM41b_VAL_POS_X
247 );
248
249 INS_IMM64(FixupVal,
250 ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),
251 IMM64_IMM41c_SIZE_X,
252 IMM64_IMM41c_INST_WORD_POS_X,
253 IMM64_IMM41c_VAL_POS_X
254 );
255
256 INS_IMM64(FixupVal,
257 ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
258 IMM64_SIGN_SIZE_X,
259 IMM64_SIGN_INST_WORD_POS_X,
260 IMM64_SIGN_VAL_POS_X
261 );
262
263 F64 = (UINT64 *) Fixup;
264 if (*FixupData != NULL) {
265 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
266 *(UINT64 *)(*FixupData) = *F64;
267 *FixupData = *FixupData + sizeof(UINT64);
268 }
269 break;
270
271 default:
272 return RETURN_UNSUPPORTED;
273 }
274
275 return RETURN_SUCCESS;
276 }
277
278 RETURN_STATUS
279 PeCoffLoaderRelocateX64Image (
280 IN UINT16 *Reloc,
281 IN OUT CHAR8 *Fixup,
282 IN OUT CHAR8 **FixupData,
283 IN UINT64 Adjust
284 )
285 /**
286 Performs an x64 specific relocation fixup
287
288 @param Reloc Pointer to the relocation record
289 @param Fixup Pointer to the address to fix up
290 @param FixupData Pointer to a buffer to log the fixups
291 @param Adjust The offset to adjust the fixup
292
293 @retval RETURN_SUCCESS Success to perform relocation
294 @retval RETURN_UNSUPPORTED Unsupported.
295 **/
296 {
297 UINT64 *F64;
298
299 switch ((*Reloc) >> 12) {
300
301 case EFI_IMAGE_REL_BASED_DIR64:
302 F64 = (UINT64 *) Fixup;
303 *F64 = *F64 + (UINT64) Adjust;
304 if (*FixupData != NULL) {
305 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
306 *(UINT64 *)(*FixupData) = *F64;
307 *FixupData = *FixupData + sizeof(UINT64);
308 }
309 break;
310
311 default:
312 return RETURN_UNSUPPORTED;
313 }
314
315 return RETURN_SUCCESS;
316 }
317