2 Fixes Intel Itanium(TM) specific relocation types.
4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 Module Name: PeCoffLoaderEx.c
18 // Include common header file for this module.
20 #include "CommonHeader.h"
22 #include "BasePeCoffLibInternals.h"
26 #define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
27 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
29 #define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
30 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
31 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
33 #define IMM64_IMM7B_INST_WORD_X 3
34 #define IMM64_IMM7B_SIZE_X 7
35 #define IMM64_IMM7B_INST_WORD_POS_X 4
36 #define IMM64_IMM7B_VAL_POS_X 0
38 #define IMM64_IMM9D_INST_WORD_X 3
39 #define IMM64_IMM9D_SIZE_X 9
40 #define IMM64_IMM9D_INST_WORD_POS_X 18
41 #define IMM64_IMM9D_VAL_POS_X 7
43 #define IMM64_IMM5C_INST_WORD_X 3
44 #define IMM64_IMM5C_SIZE_X 5
45 #define IMM64_IMM5C_INST_WORD_POS_X 13
46 #define IMM64_IMM5C_VAL_POS_X 16
48 #define IMM64_IC_INST_WORD_X 3
49 #define IMM64_IC_SIZE_X 1
50 #define IMM64_IC_INST_WORD_POS_X 12
51 #define IMM64_IC_VAL_POS_X 21
53 #define IMM64_IMM41a_INST_WORD_X 1
54 #define IMM64_IMM41a_SIZE_X 10
55 #define IMM64_IMM41a_INST_WORD_POS_X 14
56 #define IMM64_IMM41a_VAL_POS_X 22
58 #define IMM64_IMM41b_INST_WORD_X 1
59 #define IMM64_IMM41b_SIZE_X 8
60 #define IMM64_IMM41b_INST_WORD_POS_X 24
61 #define IMM64_IMM41b_VAL_POS_X 32
63 #define IMM64_IMM41c_INST_WORD_X 2
64 #define IMM64_IMM41c_SIZE_X 23
65 #define IMM64_IMM41c_INST_WORD_POS_X 0
66 #define IMM64_IMM41c_VAL_POS_X 40
68 #define IMM64_SIGN_INST_WORD_X 3
69 #define IMM64_SIGN_SIZE_X 1
70 #define IMM64_SIGN_INST_WORD_POS_X 27
71 #define IMM64_SIGN_VAL_POS_X 63
74 Performs an Itanium-based specific relocation fixup.
76 @param Reloc Pointer to the relocation record.
77 @param Fixup Pointer to the address to fix up.
78 @param FixupData Pointer to a buffer to log the fixups.
79 @param Adjust The offset to adjust the fixup.
85 PeCoffLoaderRelocateImageEx (
88 IN OUT CHAR8
**FixupData
,
95 switch ((*Reloc
) >> 12) {
96 case EFI_IMAGE_REL_BASED_IA64_IMM64
:
99 // Align it to bundle address before fixing up the
100 // 64-bit immediate value of the movl instruction.
103 Fixup
= (CHAR8
*)((UINTN
) Fixup
& (UINTN
) ~(15));
104 FixupVal
= (UINT64
)0;
107 // Extract the lower 32 bits of IMM64 from bundle
110 (UINT32
*)Fixup
+ IMM64_IMM7B_INST_WORD_X
,
112 IMM64_IMM7B_INST_WORD_POS_X
,
113 IMM64_IMM7B_VAL_POS_X
117 (UINT32
*)Fixup
+ IMM64_IMM9D_INST_WORD_X
,
119 IMM64_IMM9D_INST_WORD_POS_X
,
120 IMM64_IMM9D_VAL_POS_X
124 (UINT32
*)Fixup
+ IMM64_IMM5C_INST_WORD_X
,
126 IMM64_IMM5C_INST_WORD_POS_X
,
127 IMM64_IMM5C_VAL_POS_X
131 (UINT32
*)Fixup
+ IMM64_IC_INST_WORD_X
,
133 IMM64_IC_INST_WORD_POS_X
,
138 (UINT32
*)Fixup
+ IMM64_IMM41a_INST_WORD_X
,
140 IMM64_IMM41a_INST_WORD_POS_X
,
141 IMM64_IMM41a_VAL_POS_X
145 // Update 64-bit address
150 // Insert IMM64 into bundle
153 ((UINT32
*)Fixup
+ IMM64_IMM7B_INST_WORD_X
),
155 IMM64_IMM7B_INST_WORD_POS_X
,
156 IMM64_IMM7B_VAL_POS_X
160 ((UINT32
*)Fixup
+ IMM64_IMM9D_INST_WORD_X
),
162 IMM64_IMM9D_INST_WORD_POS_X
,
163 IMM64_IMM9D_VAL_POS_X
167 ((UINT32
*)Fixup
+ IMM64_IMM5C_INST_WORD_X
),
169 IMM64_IMM5C_INST_WORD_POS_X
,
170 IMM64_IMM5C_VAL_POS_X
174 ((UINT32
*)Fixup
+ IMM64_IC_INST_WORD_X
),
176 IMM64_IC_INST_WORD_POS_X
,
181 ((UINT32
*)Fixup
+ IMM64_IMM41a_INST_WORD_X
),
183 IMM64_IMM41a_INST_WORD_POS_X
,
184 IMM64_IMM41a_VAL_POS_X
188 ((UINT32
*)Fixup
+ IMM64_IMM41b_INST_WORD_X
),
190 IMM64_IMM41b_INST_WORD_POS_X
,
191 IMM64_IMM41b_VAL_POS_X
195 ((UINT32
*)Fixup
+ IMM64_IMM41c_INST_WORD_X
),
197 IMM64_IMM41c_INST_WORD_POS_X
,
198 IMM64_IMM41c_VAL_POS_X
202 ((UINT32
*)Fixup
+ IMM64_SIGN_INST_WORD_X
),
204 IMM64_SIGN_INST_WORD_POS_X
,
208 F64
= (UINT64
*) Fixup
;
209 if (*FixupData
!= NULL
) {
210 *FixupData
= ALIGN_POINTER(*FixupData
, sizeof(UINT64
));
211 *(UINT64
*)(*FixupData
) = *F64
;
212 *FixupData
= *FixupData
+ sizeof(UINT64
);
217 return RETURN_UNSUPPORTED
;
220 return RETURN_SUCCESS
;
224 Returns TRUE if the machine type of PE/COFF image is supported. Supported
225 does not mean the image can be executed it means the PE/COFF loader supports
226 loading and relocating of the image type. It's up to the caller to support
229 This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
230 & X64 images. Calling the entry point in a correct mannor is up to the
231 consumer of this library. This version also supports the special relocations
234 @param Machine Machine type from the PE Header.
236 @return TRUE if this PE/COFF loader can load the image
240 PeCoffLoaderImageFormatSupported (
244 if ((Machine
== EFI_IMAGE_MACHINE_IPF
) || (Machine
== EFI_IMAGE_MACHINE_IA32
) ||
245 (Machine
== EFI_IMAGE_MACHINE_EBC
) || (Machine
== EFI_IMAGE_MACHINE_X64
)) {
254 ImageRead function that operates on a memory buffer whos base is passed into
257 @param Reloc Ponter to baes of the input stream
258 @param Fixup Offset to the start of the buffer
259 @param FixupData Number of bytes to copy into the buffer
260 @param Adjust Location to place results of read
262 @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into
266 PeHotRelocateImageEx (
269 IN OUT CHAR8
**FixupData
,
276 switch ((*Reloc
) >> 12) {
277 case EFI_IMAGE_REL_BASED_DIR64
:
278 F64
= (UINT64
*) Fixup
;
279 *FixupData
= ALIGN_POINTER (*FixupData
, sizeof (UINT64
));
280 if (*(UINT64
*) (*FixupData
) == *F64
) {
281 *F64
= *F64
+ (UINT64
) Adjust
;
284 *FixupData
= *FixupData
+ sizeof (UINT64
);
287 case EFI_IMAGE_REL_BASED_IA64_IMM64
:
288 F64
= (UINT64
*) Fixup
;
289 *FixupData
= ALIGN_POINTER (*FixupData
, sizeof (UINT64
));
290 if (*(UINT64
*) (*FixupData
) == *F64
) {
292 // Align it to bundle address before fixing up the
293 // 64-bit immediate value of the movl instruction.
296 Fixup
= (CHAR8
*) ((UINT64
) Fixup
& (UINT64
)~(15));
297 FixupVal
= (UINT64
) 0;
300 // Extract the lower 32 bits of IMM64 from bundle
304 (UINT32
*) Fixup
+ IMM64_IMM7B_INST_WORD_X
,
306 IMM64_IMM7B_INST_WORD_POS_X
,
307 IMM64_IMM7B_VAL_POS_X
312 (UINT32
*) Fixup
+ IMM64_IMM9D_INST_WORD_X
,
314 IMM64_IMM9D_INST_WORD_POS_X
,
315 IMM64_IMM9D_VAL_POS_X
320 (UINT32
*) Fixup
+ IMM64_IMM5C_INST_WORD_X
,
322 IMM64_IMM5C_INST_WORD_POS_X
,
323 IMM64_IMM5C_VAL_POS_X
328 (UINT32
*) Fixup
+ IMM64_IC_INST_WORD_X
,
330 IMM64_IC_INST_WORD_POS_X
,
336 (UINT32
*) Fixup
+ IMM64_IMM41a_INST_WORD_X
,
338 IMM64_IMM41a_INST_WORD_POS_X
,
339 IMM64_IMM41a_VAL_POS_X
343 // Update 64-bit address
348 // Insert IMM64 into bundle
352 ((UINT32
*) Fixup
+ IMM64_IMM7B_INST_WORD_X
),
354 IMM64_IMM7B_INST_WORD_POS_X
,
355 IMM64_IMM7B_VAL_POS_X
360 ((UINT32
*) Fixup
+ IMM64_IMM9D_INST_WORD_X
),
362 IMM64_IMM9D_INST_WORD_POS_X
,
363 IMM64_IMM9D_VAL_POS_X
368 ((UINT32
*) Fixup
+ IMM64_IMM5C_INST_WORD_X
),
370 IMM64_IMM5C_INST_WORD_POS_X
,
371 IMM64_IMM5C_VAL_POS_X
376 ((UINT32
*) Fixup
+ IMM64_IC_INST_WORD_X
),
378 IMM64_IC_INST_WORD_POS_X
,
384 ((UINT32
*) Fixup
+ IMM64_IMM41a_INST_WORD_X
),
386 IMM64_IMM41a_INST_WORD_POS_X
,
387 IMM64_IMM41a_VAL_POS_X
392 ((UINT32
*) Fixup
+ IMM64_IMM41b_INST_WORD_X
),
394 IMM64_IMM41b_INST_WORD_POS_X
,
395 IMM64_IMM41b_VAL_POS_X
400 ((UINT32
*) Fixup
+ IMM64_IMM41c_INST_WORD_X
),
402 IMM64_IMM41c_INST_WORD_POS_X
,
403 IMM64_IMM41c_VAL_POS_X
408 ((UINT32
*) Fixup
+ IMM64_SIGN_INST_WORD_X
),
410 IMM64_SIGN_INST_WORD_POS_X
,
414 *(UINT64
*) (*FixupData
) = *F64
;
417 *FixupData
= *FixupData
+ sizeof (UINT64
);
421 DEBUG ((EFI_D_ERROR
, "PeHotRelocateEx:unknown fixed type\n"));
422 return RETURN_UNSUPPORTED
;
425 return RETURN_SUCCESS
;