TianoCore EDK2 master
Loading...
Searching...
No Matches
PeCoffLoaderEx.c
Go to the documentation of this file.
1
11#include <Library/BaseLib.h>
12
22UINT16
24 IN UINT16 *Instruction
25 )
26{
27 UINT32 Movt;
28 UINT16 Address;
29
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));
33
34 // imm16 = imm4:i:imm3:imm8
35 // imm4 -> Bit19:Bit16
36 // i -> Bit26
37 // imm3 -> Bit14:Bit12
38 // imm8 -> Bit7:Bit0
39 Address = (UINT16)(Movt & 0x000000ff); // imm8
40 Address |= (UINT16)((Movt >> 4) & 0x0000f700); // imm4 imm3
41 Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i
42 return Address;
43}
44
51VOID
53 IN OUT UINT16 *Instruction,
54 IN UINT16 Address
55 )
56{
57 UINT16 Patch;
58
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;
64
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
69 Instruction++;
70 *Instruction = (*Instruction & ~0x70ff) | Patch;
71}
72
82UINT32
84 IN UINT16 *Instructions
85 )
86{
87 UINT16 *Word;
88 UINT16 *Top;
89
90 Word = Instructions; // MOVW
91 Top = Word + 2; // MOVT
92
93 return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word);
94}
95
102VOID
104 IN OUT UINT16 *Instructions,
105 IN UINT32 Address
106 )
107{
108 UINT16 *Word;
109 UINT16 *Top;
110
111 Word = Instructions; // MOVW
112 Top = Word + 2; // MOVT
113
114 ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff));
115 ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16));
116}
117
130RETURN_STATUS
132 IN UINT16 *Reloc,
133 IN OUT CHAR8 *Fixup,
134 IN OUT CHAR8 **FixupData,
135 IN UINT64 Adjust
136 )
137{
138 UINT16 *Fixup16;
139 UINT32 FixupVal;
140
141 Fixup16 = (UINT16 *)Fixup;
142
143 switch ((*Reloc) >> 12) {
144 case EFI_IMAGE_REL_BASED_ARM_MOV32T:
145 FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;
146 ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);
147
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);
153 }
154
155 break;
156
157 case EFI_IMAGE_REL_BASED_ARM_MOV32A:
158 ASSERT (FALSE);
159 // break omitted - ARM instruction encoding not implemented
160 default:
161 return RETURN_UNSUPPORTED;
162 }
163
164 return RETURN_SUCCESS;
165}
166
178BOOLEAN
180 IN UINT16 Machine
181 )
182{
183 if ((Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || (Machine == IMAGE_FILE_MACHINE_EBC)) {
184 return TRUE;
185 }
186
187 return FALSE;
188}
189
203RETURN_STATUS
205 IN UINT16 *Reloc,
206 IN OUT CHAR8 *Fixup,
207 IN OUT CHAR8 **FixupData,
208 IN UINT64 Adjust
209 )
210{
211 UINT16 *Fixup16;
212 UINT32 FixupVal;
213
214 Fixup16 = (UINT16 *)Fixup;
215
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);
222 }
223
224 *FixupData = *FixupData + sizeof (UINT64);
225 break;
226
227 case EFI_IMAGE_REL_BASED_ARM_MOV32A:
228 ASSERT (FALSE);
229 // break omitted - ARM instruction encoding not implemented
230 default:
231 DEBUG ((DEBUG_ERROR, "PeHotRelocateEx:unknown fixed type\n"));
232 return RETURN_UNSUPPORTED;
233 }
234
235 return RETURN_SUCCESS;
236}
VOID ThumbMovwMovtImmediatePatch(IN OUT UINT16 *Instructions, IN UINT32 Address)
UINT32 ThumbMovwMovtImmediateAddress(IN UINT16 *Instructions)
VOID ThumbMovtImmediatePatch(IN OUT UINT16 *Instruction, IN UINT16 Address)
UINT16 ThumbMovtImmediateAddress(IN UINT16 *Instruction)
RETURN_STATUS PeHotRelocateImageEx(IN UINT16 *Reloc, IN OUT CHAR8 *Fixup, IN OUT CHAR8 **FixupData, IN UINT64 Adjust)
RETURN_STATUS PeCoffLoaderRelocateImageEx(IN UINT16 *Reloc, IN OUT CHAR8 *Fixup, IN OUT CHAR8 **FixupData, IN UINT64 Adjust)
BOOLEAN PeCoffLoaderImageFormatSupported(IN UINT16 Machine)
UINT64 EFIAPI ReadUnaligned64(IN CONST UINT64 *Buffer)
Definition: Unaligned.c:204
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434