3 Copyright (c) 2004 - 2006, 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
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.
19 IA-32 Specific relocation fixups.
23 #include "BasePeCoffLibInternals.h"
25 #define EFI_IMAGE_MACHINE_IPF EFI_IMAGE_MACHINE_IA64
27 #define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
28 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
30 #define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
31 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
32 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
34 #define IMM64_IMM7B_INST_WORD_X 3
35 #define IMM64_IMM7B_SIZE_X 7
36 #define IMM64_IMM7B_INST_WORD_POS_X 4
37 #define IMM64_IMM7B_VAL_POS_X 0
39 #define IMM64_IMM9D_INST_WORD_X 3
40 #define IMM64_IMM9D_SIZE_X 9
41 #define IMM64_IMM9D_INST_WORD_POS_X 18
42 #define IMM64_IMM9D_VAL_POS_X 7
44 #define IMM64_IMM5C_INST_WORD_X 3
45 #define IMM64_IMM5C_SIZE_X 5
46 #define IMM64_IMM5C_INST_WORD_POS_X 13
47 #define IMM64_IMM5C_VAL_POS_X 16
49 #define IMM64_IC_INST_WORD_X 3
50 #define IMM64_IC_SIZE_X 1
51 #define IMM64_IC_INST_WORD_POS_X 12
52 #define IMM64_IC_VAL_POS_X 21
54 #define IMM64_IMM41a_INST_WORD_X 1
55 #define IMM64_IMM41a_SIZE_X 10
56 #define IMM64_IMM41a_INST_WORD_POS_X 14
57 #define IMM64_IMM41a_VAL_POS_X 22
59 #define IMM64_IMM41b_INST_WORD_X 1
60 #define IMM64_IMM41b_SIZE_X 8
61 #define IMM64_IMM41b_INST_WORD_POS_X 24
62 #define IMM64_IMM41b_VAL_POS_X 32
64 #define IMM64_IMM41c_INST_WORD_X 2
65 #define IMM64_IMM41c_SIZE_X 23
66 #define IMM64_IMM41c_INST_WORD_POS_X 0
67 #define IMM64_IMM41c_VAL_POS_X 40
69 #define IMM64_SIGN_INST_WORD_X 3
70 #define IMM64_SIGN_SIZE_X 1
71 #define IMM64_SIGN_INST_WORD_POS_X 27
72 #define IMM64_SIGN_VAL_POS_X 63
75 Performs an Itanium-based specific relocation fixup.
77 @param Reloc Pointer to the relocation record.
78 @param Fixup Pointer to the address to fix up.
79 @param FixupData Pointer to a buffer to log the fixups.
80 @param Adjust The offset to adjust the fixup.
86 GluePeCoffLoaderRelocateImageEx (
89 IN OUT CHAR8
**FixupData
,
96 switch ((*Reloc
) >> 12) {
97 case EFI_IMAGE_REL_BASED_IA64_IMM64
:
100 // Align it to bundle address before fixing up the
101 // 64-bit immediate value of the movl instruction.
104 Fixup
= (CHAR8
*)((UINTN
) Fixup
& (UINTN
) ~(15));
105 FixupVal
= (UINT64
)0;
108 // Extract the lower 32 bits of IMM64 from bundle
111 (UINT32
*)Fixup
+ IMM64_IMM7B_INST_WORD_X
,
113 IMM64_IMM7B_INST_WORD_POS_X
,
114 IMM64_IMM7B_VAL_POS_X
118 (UINT32
*)Fixup
+ IMM64_IMM9D_INST_WORD_X
,
120 IMM64_IMM9D_INST_WORD_POS_X
,
121 IMM64_IMM9D_VAL_POS_X
125 (UINT32
*)Fixup
+ IMM64_IMM5C_INST_WORD_X
,
127 IMM64_IMM5C_INST_WORD_POS_X
,
128 IMM64_IMM5C_VAL_POS_X
132 (UINT32
*)Fixup
+ IMM64_IC_INST_WORD_X
,
134 IMM64_IC_INST_WORD_POS_X
,
139 (UINT32
*)Fixup
+ IMM64_IMM41a_INST_WORD_X
,
141 IMM64_IMM41a_INST_WORD_POS_X
,
142 IMM64_IMM41a_VAL_POS_X
146 // Update 64-bit address
151 // Insert IMM64 into bundle
154 ((UINT32
*)Fixup
+ IMM64_IMM7B_INST_WORD_X
),
156 IMM64_IMM7B_INST_WORD_POS_X
,
157 IMM64_IMM7B_VAL_POS_X
161 ((UINT32
*)Fixup
+ IMM64_IMM9D_INST_WORD_X
),
163 IMM64_IMM9D_INST_WORD_POS_X
,
164 IMM64_IMM9D_VAL_POS_X
168 ((UINT32
*)Fixup
+ IMM64_IMM5C_INST_WORD_X
),
170 IMM64_IMM5C_INST_WORD_POS_X
,
171 IMM64_IMM5C_VAL_POS_X
175 ((UINT32
*)Fixup
+ IMM64_IC_INST_WORD_X
),
177 IMM64_IC_INST_WORD_POS_X
,
182 ((UINT32
*)Fixup
+ IMM64_IMM41a_INST_WORD_X
),
184 IMM64_IMM41a_INST_WORD_POS_X
,
185 IMM64_IMM41a_VAL_POS_X
189 ((UINT32
*)Fixup
+ IMM64_IMM41b_INST_WORD_X
),
191 IMM64_IMM41b_INST_WORD_POS_X
,
192 IMM64_IMM41b_VAL_POS_X
196 ((UINT32
*)Fixup
+ IMM64_IMM41c_INST_WORD_X
),
198 IMM64_IMM41c_INST_WORD_POS_X
,
199 IMM64_IMM41c_VAL_POS_X
203 ((UINT32
*)Fixup
+ IMM64_SIGN_INST_WORD_X
),
205 IMM64_SIGN_INST_WORD_POS_X
,
209 F64
= (UINT64
*) Fixup
;
210 if (*FixupData
!= NULL
) {
211 *FixupData
= ALIGN_POINTER(*FixupData
, sizeof(UINT64
));
212 *(UINT64
*)(*FixupData
) = *F64
;
213 *FixupData
= *FixupData
+ sizeof(UINT64
);
218 return RETURN_UNSUPPORTED
;
221 return RETURN_SUCCESS
;
225 Returns TRUE if the machine type of PE/COFF image is supported. Supported
226 does not mean the image can be executed it means the PE/COFF loader supports
227 loading and relocating of the image type. It's up to the caller to support
230 This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
231 & X64 images. Calling the entry point in a correct mannor is up to the
232 consumer of this library. This version also supports the special relocations
235 @param Machine Machine type from the PE Header.
237 @return TRUE if this PE/COFF loader can load the image
241 PeCoffLoaderImageFormatSupported (
245 if ((Machine
== EFI_IMAGE_MACHINE_IPF
) || (Machine
== EFI_IMAGE_MACHINE_IA32
) ||
246 (Machine
== EFI_IMAGE_MACHINE_EBC
) || (Machine
== EFI_IMAGE_MACHINE_X64
)) {
255 ImageRead function that operates on a memory buffer whos base is passed into
258 @param Reloc Ponter to baes of the input stream
259 @param Fixup Offset to the start of the buffer
260 @param FixupData Number of bytes to copy into the buffer
261 @param Adjust Location to place results of read
263 @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into
267 GluePeHotRelocateImageEx (
270 IN OUT CHAR8
**FixupData
,
277 switch ((*Reloc
) >> 12) {
278 case EFI_IMAGE_REL_BASED_DIR64
:
279 F64
= (UINT64
*) Fixup
;
280 *FixupData
= ALIGN_POINTER (*FixupData
, sizeof (UINT64
));
281 if (*(UINT64
*) (*FixupData
) == *F64
) {
282 *F64
= *F64
+ (UINT64
) Adjust
;
285 *FixupData
= *FixupData
+ sizeof (UINT64
);
288 case EFI_IMAGE_REL_BASED_IA64_IMM64
:
289 F64
= (UINT64
*) Fixup
;
290 *FixupData
= ALIGN_POINTER (*FixupData
, sizeof (UINT64
));
291 if (*(UINT64
*) (*FixupData
) == *F64
) {
293 // Align it to bundle address before fixing up the
294 // 64-bit immediate value of the movl instruction.
297 Fixup
= (CHAR8
*) ((UINT64
) Fixup
& (UINT64
)~(15));
298 FixupVal
= (UINT64
) 0;
301 // Extract the lower 32 bits of IMM64 from bundle
305 (UINT32
*) Fixup
+ IMM64_IMM7B_INST_WORD_X
,
307 IMM64_IMM7B_INST_WORD_POS_X
,
308 IMM64_IMM7B_VAL_POS_X
313 (UINT32
*) Fixup
+ IMM64_IMM9D_INST_WORD_X
,
315 IMM64_IMM9D_INST_WORD_POS_X
,
316 IMM64_IMM9D_VAL_POS_X
321 (UINT32
*) Fixup
+ IMM64_IMM5C_INST_WORD_X
,
323 IMM64_IMM5C_INST_WORD_POS_X
,
324 IMM64_IMM5C_VAL_POS_X
329 (UINT32
*) Fixup
+ IMM64_IC_INST_WORD_X
,
331 IMM64_IC_INST_WORD_POS_X
,
337 (UINT32
*) Fixup
+ IMM64_IMM41a_INST_WORD_X
,
339 IMM64_IMM41a_INST_WORD_POS_X
,
340 IMM64_IMM41a_VAL_POS_X
344 // Update 64-bit address
349 // Insert IMM64 into bundle
353 ((UINT32
*) Fixup
+ IMM64_IMM7B_INST_WORD_X
),
355 IMM64_IMM7B_INST_WORD_POS_X
,
356 IMM64_IMM7B_VAL_POS_X
361 ((UINT32
*) Fixup
+ IMM64_IMM9D_INST_WORD_X
),
363 IMM64_IMM9D_INST_WORD_POS_X
,
364 IMM64_IMM9D_VAL_POS_X
369 ((UINT32
*) Fixup
+ IMM64_IMM5C_INST_WORD_X
),
371 IMM64_IMM5C_INST_WORD_POS_X
,
372 IMM64_IMM5C_VAL_POS_X
377 ((UINT32
*) Fixup
+ IMM64_IC_INST_WORD_X
),
379 IMM64_IC_INST_WORD_POS_X
,
385 ((UINT32
*) Fixup
+ IMM64_IMM41a_INST_WORD_X
),
387 IMM64_IMM41a_INST_WORD_POS_X
,
388 IMM64_IMM41a_VAL_POS_X
393 ((UINT32
*) Fixup
+ IMM64_IMM41b_INST_WORD_X
),
395 IMM64_IMM41b_INST_WORD_POS_X
,
396 IMM64_IMM41b_VAL_POS_X
401 ((UINT32
*) Fixup
+ IMM64_IMM41c_INST_WORD_X
),
403 IMM64_IMM41c_INST_WORD_POS_X
,
404 IMM64_IMM41c_VAL_POS_X
409 ((UINT32
*) Fixup
+ IMM64_SIGN_INST_WORD_X
),
411 IMM64_SIGN_INST_WORD_POS_X
,
415 *(UINT64
*) (*FixupData
) = *F64
;
418 *FixupData
= *FixupData
+ sizeof (UINT64
);
422 DEBUG ((EFI_D_ERROR
, "PeHotRelocateEx:unknown fixed type\n"));
423 return RETURN_UNSUPPORTED
;
426 return RETURN_SUCCESS
;