]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePeCoffLib/Arm/PeCoffLoaderEx.c
MdePkg: Apply uncrustify changes
[mirror_edk2.git] / MdePkg / Library / BasePeCoffLib / Arm / PeCoffLoaderEx.c
CommitLineData
ebd04fc2 1/** @file\r
2 Specific relocation fixups for ARM architecture.\r
3\r
9095d37b 4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
bcec20df 5 Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>\r
9344f092 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
ebd04fc2 7\r
8**/\r
9\r
10#include "BasePeCoffLibInternals.h"\r
bcec20df 11#include <Library/BaseLib.h>\r
ebd04fc2 12\r
bcec20df 13/**\r
9095d37b 14 Pass in a pointer to an ARM MOVT or MOVW immediate instruciton and\r
9c3d10b7 15 return the immediate data encoded in the instruction.\r
bcec20df 16\r
17 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction\r
18\r
19 @return Immediate address encoded in the instruction\r
20\r
21**/\r
22UINT16\r
23ThumbMovtImmediateAddress (\r
2f88bd3a 24 IN UINT16 *Instruction\r
bcec20df 25 )\r
26{\r
27 UINT32 Movt;\r
28 UINT16 Address;\r
9095d37b 29\r
bcec20df 30 // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction\r
31 // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000\r
9095d37b 32 Movt = (*Instruction << 16) | (*(Instruction + 1));\r
bcec20df 33\r
34 // imm16 = imm4:i:imm3:imm8\r
35 // imm4 -> Bit19:Bit16\r
36 // i -> Bit26\r
37 // imm3 -> Bit14:Bit12\r
38 // imm8 -> Bit7:Bit0\r
39 Address = (UINT16)(Movt & 0x000000ff); // imm8\r
40 Address |= (UINT16)((Movt >> 4) & 0x0000f700); // imm4 imm3\r
9c3d10b7 41 Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i\r
bcec20df 42 return Address;\r
43}\r
44\r
bcec20df 45/**\r
46 Update an ARM MOVT or MOVW immediate instruction immediate data.\r
47\r
48 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction\r
49 @param Address New addres to patch into the instruction\r
50**/\r
51VOID\r
52ThumbMovtImmediatePatch (\r
2f88bd3a
MK
53 IN OUT UINT16 *Instruction,\r
54 IN UINT16 Address\r
bcec20df 55 )\r
56{\r
57 UINT16 Patch;\r
58\r
59 // First 16-bit chunk of instruciton\r
2f88bd3a 60 Patch = ((Address >> 12) & 0x000f); // imm4\r
bcec20df 61 Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i\r
62 // Mask out instruction bits and or in address\r
63 *(Instruction) = (*Instruction & ~0x040f) | Patch;\r
64\r
65 // Second 16-bit chunk of instruction\r
66 Patch = Address & 0x000000ff; // imm8\r
67 Patch |= ((Address << 4) & 0x00007000); // imm3\r
68 // Mask out instruction bits and or in address\r
69 Instruction++;\r
70 *Instruction = (*Instruction & ~0x70ff) | Patch;\r
71}\r
72\r
bcec20df 73/**\r
9095d37b 74 Pass in a pointer to an ARM MOVW/MOVT instruciton pair and\r
9c3d10b7 75 return the immediate data encoded in the two` instruction.\r
bcec20df 76\r
77 @param Instructions Pointer to ARM MOVW/MOVT insturction pair\r
78\r
79 @return Immediate address encoded in the instructions\r
80\r
81**/\r
82UINT32\r
83ThumbMovwMovtImmediateAddress (\r
2f88bd3a 84 IN UINT16 *Instructions\r
bcec20df 85 )\r
86{\r
87 UINT16 *Word;\r
88 UINT16 *Top;\r
9095d37b 89\r
bcec20df 90 Word = Instructions; // MOVW\r
91 Top = Word + 2; // MOVT\r
9095d37b 92\r
bcec20df 93 return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word);\r
94}\r
95\r
bcec20df 96/**\r
97 Update an ARM MOVW/MOVT immediate instruction instruction pair.\r
98\r
99 @param Instructions Pointer to ARM MOVW/MOVT instruction pair\r
100 @param Address New addres to patch into the instructions\r
101**/\r
102VOID\r
103ThumbMovwMovtImmediatePatch (\r
2f88bd3a
MK
104 IN OUT UINT16 *Instructions,\r
105 IN UINT32 Address\r
bcec20df 106 )\r
107{\r
108 UINT16 *Word;\r
109 UINT16 *Top;\r
9095d37b 110\r
bcec20df 111 Word = Instructions; // MOVW\r
112 Top = Word + 2; // MOVT\r
113\r
114 ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff));\r
115 ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16));\r
116}\r
9095d37b 117\r
ebd04fc2 118/**\r
119 Performs an ARM-based specific relocation fixup and is a no-op on other\r
120 instruction sets.\r
121\r
2fc59a00 122 @param Reloc The pointer to the relocation record.\r
123 @param Fixup The pointer to the address to fix up.\r
124 @param FixupData The pointer to a buffer to log the fixups.\r
ebd04fc2 125 @param Adjust The offset to adjust the fixup.\r
126\r
127 @return Status code.\r
128\r
129**/\r
130RETURN_STATUS\r
131PeCoffLoaderRelocateImageEx (\r
2f88bd3a
MK
132 IN UINT16 *Reloc,\r
133 IN OUT CHAR8 *Fixup,\r
134 IN OUT CHAR8 **FixupData,\r
135 IN UINT64 Adjust\r
ebd04fc2 136 )\r
137{\r
2f88bd3a
MK
138 UINT16 *Fixup16;\r
139 UINT32 FixupVal;\r
bcec20df 140\r
2f88bd3a 141 Fixup16 = (UINT16 *)Fixup;\r
bcec20df 142\r
143 switch ((*Reloc) >> 12) {\r
2f88bd3a
MK
144 case EFI_IMAGE_REL_BASED_ARM_MOV32T:\r
145 FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;\r
146 ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);\r
147\r
148 if (*FixupData != NULL) {\r
149 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
150 // Fixup16 is not aligned so we must copy it. Thumb instructions are streams of 16 bytes.\r
151 CopyMem (*FixupData, Fixup16, sizeof (UINT64));\r
152 *FixupData = *FixupData + sizeof (UINT64);\r
153 }\r
9095d37b 154\r
2f88bd3a
MK
155 break;\r
156\r
157 case EFI_IMAGE_REL_BASED_ARM_MOV32A:\r
158 ASSERT (FALSE);\r
159 // break omitted - ARM instruction encoding not implemented\r
160 default:\r
161 return RETURN_UNSUPPORTED;\r
bcec20df 162 }\r
163\r
164 return RETURN_SUCCESS;\r
ebd04fc2 165}\r
166\r
167/**\r
168 Returns TRUE if the machine type of PE/COFF image is supported. Supported\r
169 does not mean the image can be executed it means the PE/COFF loader supports\r
170 loading and relocating of the image type. It's up to the caller to support\r
171 the entry point.\r
9095d37b 172\r
ebd04fc2 173 @param Machine Machine type from the PE Header.\r
174\r
175 @return TRUE if this PE/COFF loader can load the image\r
176\r
177**/\r
178BOOLEAN\r
179PeCoffLoaderImageFormatSupported (\r
180 IN UINT16 Machine\r
181 )\r
182{\r
183 if ((Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || (Machine == IMAGE_FILE_MACHINE_EBC)) {\r
9095d37b 184 return TRUE;\r
ebd04fc2 185 }\r
186\r
187 return FALSE;\r
188}\r
189\r
190/**\r
191 Performs an ARM-based specific re-relocation fixup and is a no-op on other\r
192 instruction sets. This is used to re-relocated the image into the EFI virtual\r
193 space for runtime calls.\r
194\r
2fc59a00 195 @param Reloc The pointer to the relocation record.\r
196 @param Fixup The pointer to the address to fix up.\r
197 @param FixupData The pointer to a buffer to log the fixups.\r
ebd04fc2 198 @param Adjust The offset to adjust the fixup.\r
199\r
200 @return Status code.\r
201\r
202**/\r
203RETURN_STATUS\r
204PeHotRelocateImageEx (\r
2f88bd3a
MK
205 IN UINT16 *Reloc,\r
206 IN OUT CHAR8 *Fixup,\r
207 IN OUT CHAR8 **FixupData,\r
208 IN UINT64 Adjust\r
ebd04fc2 209 )\r
210{\r
bcec20df 211 UINT16 *Fixup16;\r
212 UINT32 FixupVal;\r
213\r
214 Fixup16 = (UINT16 *)Fixup;\r
215\r
216 switch ((*Reloc) >> 12) {\r
2f88bd3a
MK
217 case EFI_IMAGE_REL_BASED_ARM_MOV32T:\r
218 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
219 if (*(UINT64 *)(*FixupData) == ReadUnaligned64 ((UINT64 *)Fixup16)) {\r
220 FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;\r
221 ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);\r
222 }\r
223\r
224 *FixupData = *FixupData + sizeof (UINT64);\r
225 break;\r
226\r
227 case EFI_IMAGE_REL_BASED_ARM_MOV32A:\r
228 ASSERT (FALSE);\r
bcec20df 229 // break omitted - ARM instruction encoding not implemented\r
2f88bd3a
MK
230 default:\r
231 DEBUG ((DEBUG_ERROR, "PeHotRelocateEx:unknown fixed type\n"));\r
232 return RETURN_UNSUPPORTED;\r
bcec20df 233 }\r
9095d37b 234\r
bcec20df 235 return RETURN_SUCCESS;\r
ebd04fc2 236}\r