]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/Common/PeCoffLoaderEx.c
BaseTools: Remove unused logic from C tools
[mirror_edk2.git] / BaseTools / Source / C / Common / PeCoffLoaderEx.c
CommitLineData
30fdf114 1/** @file\r
8daa4278 2IA32 and X64 Specific relocation fixups\r
30fdf114 3\r
f7496d71 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
4afd3d04 5Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
f7496d71
LG
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
30fdf114 13\r
30fdf114
LG
14--*/\r
15\r
16#include <Common/UefiBaseTypes.h>\r
17#include <IndustryStandard/PeImage.h>\r
18#include "PeCoffLib.h"\r
da92f276 19#include "CommonLib.h"\r
4afd3d04 20#include "EfiUtilityMsgs.h"\r
da92f276 21\r
30fdf114
LG
22\r
23#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \\r
24 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)\r
25\r
26#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \\r
27 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \\r
28 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)\r
29\r
f7496d71
LG
30#define IMM64_IMM7B_INST_WORD_X 3\r
31#define IMM64_IMM7B_SIZE_X 7\r
32#define IMM64_IMM7B_INST_WORD_POS_X 4\r
33#define IMM64_IMM7B_VAL_POS_X 0\r
34\r
35#define IMM64_IMM9D_INST_WORD_X 3\r
36#define IMM64_IMM9D_SIZE_X 9\r
37#define IMM64_IMM9D_INST_WORD_POS_X 18\r
38#define IMM64_IMM9D_VAL_POS_X 7\r
39\r
40#define IMM64_IMM5C_INST_WORD_X 3\r
41#define IMM64_IMM5C_SIZE_X 5\r
42#define IMM64_IMM5C_INST_WORD_POS_X 13\r
43#define IMM64_IMM5C_VAL_POS_X 16\r
44\r
45#define IMM64_IC_INST_WORD_X 3\r
46#define IMM64_IC_SIZE_X 1\r
47#define IMM64_IC_INST_WORD_POS_X 12\r
48#define IMM64_IC_VAL_POS_X 21\r
49\r
50#define IMM64_IMM41a_INST_WORD_X 1\r
51#define IMM64_IMM41a_SIZE_X 10\r
52#define IMM64_IMM41a_INST_WORD_POS_X 14\r
53#define IMM64_IMM41a_VAL_POS_X 22\r
54\r
55#define IMM64_IMM41b_INST_WORD_X 1\r
56#define IMM64_IMM41b_SIZE_X 8\r
57#define IMM64_IMM41b_INST_WORD_POS_X 24\r
58#define IMM64_IMM41b_VAL_POS_X 32\r
59\r
60#define IMM64_IMM41c_INST_WORD_X 2\r
61#define IMM64_IMM41c_SIZE_X 23\r
62#define IMM64_IMM41c_INST_WORD_POS_X 0\r
63#define IMM64_IMM41c_VAL_POS_X 40\r
64\r
65#define IMM64_SIGN_INST_WORD_X 3\r
66#define IMM64_SIGN_SIZE_X 1\r
67#define IMM64_SIGN_INST_WORD_POS_X 27\r
68#define IMM64_SIGN_VAL_POS_X 63\r
30fdf114
LG
69\r
70RETURN_STATUS\r
71PeCoffLoaderRelocateIa32Image (\r
72 IN UINT16 *Reloc,\r
73 IN OUT CHAR8 *Fixup,\r
74 IN OUT CHAR8 **FixupData,\r
75 IN UINT64 Adjust\r
76 )\r
77/*++\r
78\r
79Routine Description:\r
80\r
81 Performs an IA-32 specific relocation fixup\r
82\r
83Arguments:\r
84\r
85 Reloc - Pointer to the relocation record\r
86\r
87 Fixup - Pointer to the address to fix up\r
88\r
89 FixupData - Pointer to a buffer to log the fixups\r
90\r
91 Adjust - The offset to adjust the fixup\r
92\r
93Returns:\r
94\r
95 EFI_UNSUPPORTED - Unsupported now\r
96\r
97--*/\r
98{\r
99 return RETURN_UNSUPPORTED;\r
100}\r
101\r
30fdf114 102\r
40d841f6 103/**\r
f7496d71 104 Pass in a pointer to an ARM MOVT or MOVW immediate instruciton and\r
40d841f6
LG
105 return the immediate data encoded in the instruction\r
106\r
107 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction\r
108\r
109 @return Immediate address encoded in the instruction\r
110\r
111**/\r
112UINT16\r
113ThumbMovtImmediateAddress (\r
114 IN UINT16 *Instruction\r
115 )\r
116{\r
117 UINT32 Movt;\r
118 UINT16 Address;\r
119\r
120 // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction\r
121 // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000\r
f7496d71 122 Movt = (*Instruction << 16) | (*(Instruction + 1));\r
40d841f6
LG
123\r
124 // imm16 = imm4:i:imm3:imm8\r
125 // imm4 -> Bit19:Bit16\r
126 // i -> Bit26\r
127 // imm3 -> Bit14:Bit12\r
128 // imm8 -> Bit7:Bit0\r
129 Address = (UINT16)(Movt & 0x000000ff); // imm8\r
130 Address |= (UINT16)((Movt >> 4) & 0x0000f700); // imm4 imm3\r
131 Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i\r
132 return Address;\r
133}\r
134\r
135\r
136/**\r
137 Update an ARM MOVT or MOVW immediate instruction immediate data.\r
138\r
139 @param Instruction Pointer to ARM MOVT or MOVW immediate instruction\r
140 @param Address New addres to patch into the instruction\r
141**/\r
142VOID\r
143ThumbMovtImmediatePatch (\r
144 IN OUT UINT16 *Instruction,\r
145 IN UINT16 Address\r
146 )\r
147{\r
148 UINT16 Patch;\r
149\r
150 // First 16-bit chunk of instruciton\r
f7496d71 151 Patch = ((Address >> 12) & 0x000f); // imm4\r
40d841f6
LG
152 Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i\r
153 *Instruction = (*Instruction & ~0x040f) | Patch;\r
154\r
155 // Second 16-bit chunk of instruction\r
156 Patch = Address & 0x000000ff; // imm8\r
157 Patch |= ((Address << 4) & 0x00007000); // imm3\r
158 Instruction++;\r
159 *Instruction = (*Instruction & ~0x70ff) | Patch;\r
160}\r
161\r
da92f276 162/**\r
f7496d71 163 Pass in a pointer to an ARM MOVW/MOVT instruciton pair and\r
da92f276
LG
164 return the immediate data encoded in the two` instruction\r
165\r
166 @param Instructions Pointer to ARM MOVW/MOVT insturction pair\r
167\r
168 @return Immediate address encoded in the instructions\r
169\r
170**/\r
171UINT32\r
172EFIAPI\r
173ThumbMovwMovtImmediateAddress (\r
174 IN UINT16 *Instructions\r
175 )\r
176{\r
177 UINT16 *Word;\r
178 UINT16 *Top;\r
f7496d71 179\r
da92f276
LG
180 Word = Instructions; // MOVW\r
181 Top = Word + 2; // MOVT\r
f7496d71 182\r
da92f276
LG
183 return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word);\r
184}\r
185\r
186\r
187/**\r
188 Update an ARM MOVW/MOVT immediate instruction instruction pair.\r
189\r
190 @param Instructions Pointer to ARM MOVW/MOVT instruction pair\r
191 @param Address New addres to patch into the instructions\r
192**/\r
193VOID\r
194EFIAPI\r
195ThumbMovwMovtImmediatePatch (\r
196 IN OUT UINT16 *Instructions,\r
197 IN UINT32 Address\r
198 )\r
199{\r
200 UINT16 *Word;\r
201 UINT16 *Top;\r
f7496d71 202\r
da92f276
LG
203 Word = (UINT16 *)Instructions; // MOVW\r
204 Top = Word + 2; // MOVT\r
205\r
206 ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff));\r
207 ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16));\r
208}\r
209\r
210\r
40d841f6
LG
211/**\r
212 Performs an ARM-based specific relocation fixup and is a no-op on other\r
213 instruction sets.\r
214\r
215 @param Reloc Pointer to the relocation record.\r
216 @param Fixup Pointer to the address to fix up.\r
217 @param FixupData Pointer to a buffer to log the fixups.\r
218 @param Adjust The offset to adjust the fixup.\r
219\r
220 @return Status code.\r
221\r
222**/\r
223RETURN_STATUS\r
224PeCoffLoaderRelocateArmImage (\r
225 IN UINT16 **Reloc,\r
226 IN OUT CHAR8 *Fixup,\r
227 IN OUT CHAR8 **FixupData,\r
228 IN UINT64 Adjust\r
229 )\r
230{\r
231 UINT16 *Fixup16;\r
da92f276 232 UINT32 FixupVal;\r
40d841f6 233\r
da92f276 234 Fixup16 = (UINT16 *) Fixup;\r
40d841f6
LG
235\r
236 switch ((**Reloc) >> 12) {\r
f7496d71 237\r
da92f276
LG
238 case EFI_IMAGE_REL_BASED_ARM_MOV32T:\r
239 FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;\r
240 ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);\r
f7496d71
LG
241\r
242\r
40d841f6 243 if (*FixupData != NULL) {\r
da92f276 244 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
da92f276 245 CopyMem (*FixupData, Fixup16, sizeof (UINT64));\r
94762dde 246 *FixupData = *FixupData + sizeof(UINT64);\r
40d841f6
LG
247 }\r
248 break;\r
f7496d71 249\r
da92f276
LG
250 case EFI_IMAGE_REL_BASED_ARM_MOV32A:\r
251 // break omitted - ARM instruction encoding not implemented\r
40d841f6
LG
252 default:\r
253 return RETURN_UNSUPPORTED;\r
254 }\r
255\r
256 return RETURN_SUCCESS;\r
257}\r