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>
15 Pass in a pointer to an ARM MOVT or MOVW immediate instruciton and
16 return the immediate data encoded in the instruction.
18 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
20 @return Immediate address encoded in the instruction
24 ThumbMovtImmediateAddress (
25 IN UINT16
*Instruction
31 // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction
32 // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000
33 Movt
= (*Instruction
<< 16) | (*(Instruction
+ 1));
35 // imm16 = imm4:i:imm3:imm8
36 // imm4 -> Bit19:Bit16
38 // imm3 -> Bit14:Bit12
40 Address
= (UINT16
)(Movt
& 0x000000ff); // imm8
41 Address
|= (UINT16
)((Movt
>> 4) & 0x0000f700); // imm4 imm3
42 Address
|= (((Movt
& BIT26
) != 0) ? BIT11
: 0); // i
48 Update an ARM MOVT or MOVW immediate instruction immediate data.
50 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction
51 @param Address New addres to patch into the instruction
54 ThumbMovtImmediatePatch (
55 IN OUT UINT16
*Instruction
,
61 // First 16-bit chunk of instruciton
62 Patch
= ((Address
>> 12) & 0x000f); // imm4
63 Patch
|= (((Address
& BIT11
) != 0) ? BIT10
: 0); // i
64 // Mask out instruction bits and or in address
65 *(Instruction
) = (*Instruction
& ~0x040f) | Patch
;
67 // Second 16-bit chunk of instruction
68 Patch
= Address
& 0x000000ff; // imm8
69 Patch
|= ((Address
<< 4) & 0x00007000); // imm3
70 // Mask out instruction bits and or in address
72 *Instruction
= (*Instruction
& ~0x70ff) | Patch
;
78 Pass in a pointer to an ARM MOVW/MOVT instruciton pair and
79 return the immediate data encoded in the two` instruction.
81 @param Instructions Pointer to ARM MOVW/MOVT insturction pair
83 @return Immediate address encoded in the instructions
87 ThumbMovwMovtImmediateAddress (
88 IN UINT16
*Instructions
94 Word
= Instructions
; // MOVW
95 Top
= Word
+ 2; // MOVT
97 return (ThumbMovtImmediateAddress (Top
) << 16) + ThumbMovtImmediateAddress (Word
);
102 Update an ARM MOVW/MOVT immediate instruction instruction pair.
104 @param Instructions Pointer to ARM MOVW/MOVT instruction pair
105 @param Address New addres to patch into the instructions
108 ThumbMovwMovtImmediatePatch (
109 IN OUT UINT16
*Instructions
,
116 Word
= Instructions
; // MOVW
117 Top
= Word
+ 2; // MOVT
119 ThumbMovtImmediatePatch (Word
, (UINT16
)(Address
& 0xffff));
120 ThumbMovtImmediatePatch (Top
, (UINT16
)(Address
>> 16));
126 Performs an ARM-based specific relocation fixup and is a no-op on other
129 @param Reloc The pointer to the relocation record.
130 @param Fixup The pointer to the address to fix up.
131 @param FixupData The pointer to a buffer to log the fixups.
132 @param Adjust The offset to adjust the fixup.
138 PeCoffLoaderRelocateImageEx (
141 IN OUT CHAR8
**FixupData
,
148 Fixup16
= (UINT16
*) Fixup
;
150 switch ((*Reloc
) >> 12) {
152 case EFI_IMAGE_REL_BASED_ARM_MOV32T
:
153 FixupVal
= ThumbMovwMovtImmediateAddress (Fixup16
) + (UINT32
)Adjust
;
154 ThumbMovwMovtImmediatePatch (Fixup16
, FixupVal
);
156 if (*FixupData
!= NULL
) {
157 *FixupData
= ALIGN_POINTER(*FixupData
, sizeof(UINT64
));
158 // Fixup16 is not aligned so we must copy it. Thumb instructions are streams of 16 bytes.
159 CopyMem (*FixupData
, Fixup16
, sizeof (UINT64
));
160 *FixupData
= *FixupData
+ sizeof(UINT64
);
164 case EFI_IMAGE_REL_BASED_ARM_MOV32A
:
166 // break omitted - ARM instruction encoding not implemented
168 return RETURN_UNSUPPORTED
;
171 return RETURN_SUCCESS
;
175 Returns TRUE if the machine type of PE/COFF image is supported. Supported
176 does not mean the image can be executed it means the PE/COFF loader supports
177 loading and relocating of the image type. It's up to the caller to support
180 @param Machine Machine type from the PE Header.
182 @return TRUE if this PE/COFF loader can load the image
186 PeCoffLoaderImageFormatSupported (
190 if ((Machine
== IMAGE_FILE_MACHINE_ARMTHUMB_MIXED
) || (Machine
== IMAGE_FILE_MACHINE_EBC
)) {
198 Performs an ARM-based specific re-relocation fixup and is a no-op on other
199 instruction sets. This is used to re-relocated the image into the EFI virtual
200 space for runtime calls.
202 @param Reloc The pointer to the relocation record.
203 @param Fixup The pointer to the address to fix up.
204 @param FixupData The pointer to a buffer to log the fixups.
205 @param Adjust The offset to adjust the fixup.
211 PeHotRelocateImageEx (
214 IN OUT CHAR8
**FixupData
,
221 Fixup16
= (UINT16
*)Fixup
;
223 switch ((*Reloc
) >> 12) {
225 case EFI_IMAGE_REL_BASED_ARM_MOV32T
:
226 *FixupData
= ALIGN_POINTER (*FixupData
, sizeof (UINT64
));
227 if (*(UINT64
*) (*FixupData
) == ReadUnaligned64 ((UINT64
*)Fixup16
)) {
228 FixupVal
= ThumbMovwMovtImmediateAddress (Fixup16
) + (UINT32
)Adjust
;
229 ThumbMovwMovtImmediatePatch (Fixup16
, FixupVal
);
231 *FixupData
= *FixupData
+ sizeof(UINT64
);
234 case EFI_IMAGE_REL_BASED_ARM_MOV32A
:
236 // break omitted - ARM instruction encoding not implemented
238 DEBUG ((EFI_D_ERROR
, "PeHotRelocateEx:unknown fixed type\n"));
239 return RETURN_UNSUPPORTED
;
242 return RETURN_SUCCESS
;