2 Specific relocation fixups for ARM architecture.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "BasePeCoffLibInternals.h"
11 #include <Library/BaseLib.h>
14 Pass in a pointer to an ARM MOVT or MOVW immediate instruciton and
15 return the immediate data encoded in the instruction.
17 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
19 @return Immediate address encoded in the instruction
23 ThumbMovtImmediateAddress (
24 IN UINT16
*Instruction
30 // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction
31 // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000
32 Movt
= (*Instruction
<< 16) | (*(Instruction
+ 1));
34 // imm16 = imm4:i:imm3:imm8
35 // imm4 -> Bit19:Bit16
37 // imm3 -> Bit14:Bit12
39 Address
= (UINT16
)(Movt
& 0x000000ff); // imm8
40 Address
|= (UINT16
)((Movt
>> 4) & 0x0000f700); // imm4 imm3
41 Address
|= (((Movt
& BIT26
) != 0) ? BIT11
: 0); // i
46 Update an ARM MOVT or MOVW immediate instruction immediate data.
48 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
49 @param Address New addres to patch into the instruction
52 ThumbMovtImmediatePatch (
53 IN OUT UINT16
*Instruction
,
59 // First 16-bit chunk of instruciton
60 Patch
= ((Address
>> 12) & 0x000f); // imm4
61 Patch
|= (((Address
& BIT11
) != 0) ? BIT10
: 0); // i
62 // Mask out instruction bits and or in address
63 *(Instruction
) = (*Instruction
& ~0x040f) | Patch
;
65 // Second 16-bit chunk of instruction
66 Patch
= Address
& 0x000000ff; // imm8
67 Patch
|= ((Address
<< 4) & 0x00007000); // imm3
68 // Mask out instruction bits and or in address
70 *Instruction
= (*Instruction
& ~0x70ff) | Patch
;
74 Pass in a pointer to an ARM MOVW/MOVT instruciton pair and
75 return the immediate data encoded in the two` instruction.
77 @param Instructions Pointer to ARM MOVW/MOVT insturction pair
79 @return Immediate address encoded in the instructions
83 ThumbMovwMovtImmediateAddress (
84 IN UINT16
*Instructions
90 Word
= Instructions
; // MOVW
91 Top
= Word
+ 2; // MOVT
93 return (ThumbMovtImmediateAddress (Top
) << 16) + ThumbMovtImmediateAddress (Word
);
97 Update an ARM MOVW/MOVT immediate instruction instruction pair.
99 @param Instructions Pointer to ARM MOVW/MOVT instruction pair
100 @param Address New addres to patch into the instructions
103 ThumbMovwMovtImmediatePatch (
104 IN OUT UINT16
*Instructions
,
111 Word
= Instructions
; // MOVW
112 Top
= Word
+ 2; // MOVT
114 ThumbMovtImmediatePatch (Word
, (UINT16
)(Address
& 0xffff));
115 ThumbMovtImmediatePatch (Top
, (UINT16
)(Address
>> 16));
119 Performs an ARM-based specific relocation fixup and is a no-op on other
122 @param Reloc The pointer to the relocation record.
123 @param Fixup The pointer to the address to fix up.
124 @param FixupData The pointer to a buffer to log the fixups.
125 @param Adjust The offset to adjust the fixup.
131 PeCoffLoaderRelocateImageEx (
134 IN OUT CHAR8
**FixupData
,
141 Fixup16
= (UINT16
*)Fixup
;
143 switch ((*Reloc
) >> 12) {
144 case EFI_IMAGE_REL_BASED_ARM_MOV32T
:
145 FixupVal
= ThumbMovwMovtImmediateAddress (Fixup16
) + (UINT32
)Adjust
;
146 ThumbMovwMovtImmediatePatch (Fixup16
, FixupVal
);
148 if (*FixupData
!= NULL
) {
149 *FixupData
= ALIGN_POINTER (*FixupData
, sizeof (UINT64
));
150 // Fixup16 is not aligned so we must copy it. Thumb instructions are streams of 16 bytes.
151 CopyMem (*FixupData
, Fixup16
, sizeof (UINT64
));
152 *FixupData
= *FixupData
+ sizeof (UINT64
);
157 case EFI_IMAGE_REL_BASED_ARM_MOV32A
:
159 // break omitted - ARM instruction encoding not implemented
161 return RETURN_UNSUPPORTED
;
164 return RETURN_SUCCESS
;
168 Returns TRUE if the machine type of PE/COFF image is supported. Supported
169 does not mean the image can be executed it means the PE/COFF loader supports
170 loading and relocating of the image type. It's up to the caller to support
173 @param Machine Machine type from the PE Header.
175 @return TRUE if this PE/COFF loader can load the image
179 PeCoffLoaderImageFormatSupported (
183 if ((Machine
== IMAGE_FILE_MACHINE_ARMTHUMB_MIXED
) || (Machine
== IMAGE_FILE_MACHINE_EBC
)) {
191 Performs an ARM-based specific re-relocation fixup and is a no-op on other
192 instruction sets. This is used to re-relocated the image into the EFI virtual
193 space for runtime calls.
195 @param Reloc The pointer to the relocation record.
196 @param Fixup The pointer to the address to fix up.
197 @param FixupData The pointer to a buffer to log the fixups.
198 @param Adjust The offset to adjust the fixup.
204 PeHotRelocateImageEx (
207 IN OUT CHAR8
**FixupData
,
214 Fixup16
= (UINT16
*)Fixup
;
216 switch ((*Reloc
) >> 12) {
217 case EFI_IMAGE_REL_BASED_ARM_MOV32T
:
218 *FixupData
= ALIGN_POINTER (*FixupData
, sizeof (UINT64
));
219 if (*(UINT64
*)(*FixupData
) == ReadUnaligned64 ((UINT64
*)Fixup16
)) {
220 FixupVal
= ThumbMovwMovtImmediateAddress (Fixup16
) + (UINT32
)Adjust
;
221 ThumbMovwMovtImmediatePatch (Fixup16
, FixupVal
);
224 *FixupData
= *FixupData
+ sizeof (UINT64
);
227 case EFI_IMAGE_REL_BASED_ARM_MOV32A
:
229 // break omitted - ARM instruction encoding not implemented
231 DEBUG ((DEBUG_ERROR
, "PeHotRelocateEx:unknown fixed type\n"));
232 return RETURN_UNSUPPORTED
;
235 return RETURN_SUCCESS
;