2 IA32 and X64 Specific relocation fixups
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Common/UefiBaseTypes.h>
11 #include <IndustryStandard/PeImage.h>
12 #include "PeCoffLib.h"
13 #include "CommonLib.h"
14 #include "EfiUtilityMsgs.h"
17 #define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
18 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
20 #define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
21 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
22 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
24 #define IMM64_IMM7B_INST_WORD_X 3
25 #define IMM64_IMM7B_SIZE_X 7
26 #define IMM64_IMM7B_INST_WORD_POS_X 4
27 #define IMM64_IMM7B_VAL_POS_X 0
29 #define IMM64_IMM9D_INST_WORD_X 3
30 #define IMM64_IMM9D_SIZE_X 9
31 #define IMM64_IMM9D_INST_WORD_POS_X 18
32 #define IMM64_IMM9D_VAL_POS_X 7
34 #define IMM64_IMM5C_INST_WORD_X 3
35 #define IMM64_IMM5C_SIZE_X 5
36 #define IMM64_IMM5C_INST_WORD_POS_X 13
37 #define IMM64_IMM5C_VAL_POS_X 16
39 #define IMM64_IC_INST_WORD_X 3
40 #define IMM64_IC_SIZE_X 1
41 #define IMM64_IC_INST_WORD_POS_X 12
42 #define IMM64_IC_VAL_POS_X 21
44 #define IMM64_IMM41a_INST_WORD_X 1
45 #define IMM64_IMM41a_SIZE_X 10
46 #define IMM64_IMM41a_INST_WORD_POS_X 14
47 #define IMM64_IMM41a_VAL_POS_X 22
49 #define IMM64_IMM41b_INST_WORD_X 1
50 #define IMM64_IMM41b_SIZE_X 8
51 #define IMM64_IMM41b_INST_WORD_POS_X 24
52 #define IMM64_IMM41b_VAL_POS_X 32
54 #define IMM64_IMM41c_INST_WORD_X 2
55 #define IMM64_IMM41c_SIZE_X 23
56 #define IMM64_IMM41c_INST_WORD_POS_X 0
57 #define IMM64_IMM41c_VAL_POS_X 40
59 #define IMM64_SIGN_INST_WORD_X 3
60 #define IMM64_SIGN_SIZE_X 1
61 #define IMM64_SIGN_INST_WORD_POS_X 27
62 #define IMM64_SIGN_VAL_POS_X 63
65 PeCoffLoaderRelocateIa32Image (
68 IN OUT CHAR8
**FixupData
,
75 Performs an IA-32 specific relocation fixup
79 Reloc - Pointer to the relocation record
81 Fixup - Pointer to the address to fix up
83 FixupData - Pointer to a buffer to log the fixups
85 Adjust - The offset to adjust the fixup
89 EFI_UNSUPPORTED - Unsupported now
93 return RETURN_UNSUPPORTED
;
98 Pass in a pointer to an ARM MOVT or MOVW immediate instruction and
99 return the immediate data encoded in the instruction
101 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
103 @return Immediate address encoded in the instruction
107 ThumbMovtImmediateAddress (
108 IN UINT16
*Instruction
114 // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction
115 // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000
116 Movt
= (*Instruction
<< 16) | (*(Instruction
+ 1));
118 // imm16 = imm4:i:imm3:imm8
119 // imm4 -> Bit19:Bit16
121 // imm3 -> Bit14:Bit12
123 Address
= (UINT16
)(Movt
& 0x000000ff); // imm8
124 Address
|= (UINT16
)((Movt
>> 4) & 0x0000f700); // imm4 imm3
125 Address
|= (((Movt
& BIT26
) != 0) ? BIT11
: 0); // i
131 Update an ARM MOVT or MOVW immediate instruction immediate data.
133 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
134 @param Address New address to patch into the instruction
137 ThumbMovtImmediatePatch (
138 IN OUT UINT16
*Instruction
,
144 // First 16-bit chunk of instruction
145 Patch
= ((Address
>> 12) & 0x000f); // imm4
146 Patch
|= (((Address
& BIT11
) != 0) ? BIT10
: 0); // i
147 *Instruction
= (*Instruction
& ~0x040f) | Patch
;
149 // Second 16-bit chunk of instruction
150 Patch
= Address
& 0x000000ff; // imm8
151 Patch
|= ((Address
<< 4) & 0x00007000); // imm3
153 *Instruction
= (*Instruction
& ~0x70ff) | Patch
;
157 Pass in a pointer to an ARM MOVW/MOVT instruction pair and
158 return the immediate data encoded in the two` instruction
160 @param Instructions Pointer to ARM MOVW/MOVT instruction pair
162 @return Immediate address encoded in the instructions
167 ThumbMovwMovtImmediateAddress (
168 IN UINT16
*Instructions
174 Word
= Instructions
; // MOVW
175 Top
= Word
+ 2; // MOVT
177 return (ThumbMovtImmediateAddress (Top
) << 16) + ThumbMovtImmediateAddress (Word
);
182 Update an ARM MOVW/MOVT immediate instruction instruction pair.
184 @param Instructions Pointer to ARM MOVW/MOVT instruction pair
185 @param Address New address to patch into the instructions
189 ThumbMovwMovtImmediatePatch (
190 IN OUT UINT16
*Instructions
,
197 Word
= (UINT16
*)Instructions
; // MOVW
198 Top
= Word
+ 2; // MOVT
200 ThumbMovtImmediatePatch (Word
, (UINT16
)(Address
& 0xffff));
201 ThumbMovtImmediatePatch (Top
, (UINT16
)(Address
>> 16));
206 Performs an ARM-based specific relocation fixup and is a no-op on other
209 @param Reloc Pointer to the relocation record.
210 @param Fixup Pointer to the address to fix up.
211 @param FixupData Pointer to a buffer to log the fixups.
212 @param Adjust The offset to adjust the fixup.
218 PeCoffLoaderRelocateArmImage (
221 IN OUT CHAR8
**FixupData
,
228 Fixup16
= (UINT16
*) Fixup
;
230 switch ((**Reloc
) >> 12) {
232 case EFI_IMAGE_REL_BASED_ARM_MOV32T
:
233 FixupVal
= ThumbMovwMovtImmediateAddress (Fixup16
) + (UINT32
)Adjust
;
234 ThumbMovwMovtImmediatePatch (Fixup16
, FixupVal
);
237 if (*FixupData
!= NULL
) {
238 *FixupData
= ALIGN_POINTER(*FixupData
, sizeof(UINT64
));
239 CopyMem (*FixupData
, Fixup16
, sizeof (UINT64
));
240 *FixupData
= *FixupData
+ sizeof(UINT64
);
244 case EFI_IMAGE_REL_BASED_ARM_MOV32A
:
245 // break omitted - ARM instruction encoding not implemented
247 return RETURN_UNSUPPORTED
;
250 return RETURN_SUCCESS
;