]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/C/Common/PeCoffLoaderEx.c
BaseTools: Remove unused logic from C tools
[mirror_edk2.git] / BaseTools / Source / C / Common / PeCoffLoaderEx.c
... / ...
CommitLineData
1/** @file\r
2IA32 and X64 Specific relocation fixups\r
3\r
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
5Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
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
13\r
14--*/\r
15\r
16#include <Common/UefiBaseTypes.h>\r
17#include <IndustryStandard/PeImage.h>\r
18#include "PeCoffLib.h"\r
19#include "CommonLib.h"\r
20#include "EfiUtilityMsgs.h"\r
21\r
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
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
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
102\r
103/**\r
104 Pass in a pointer to an ARM MOVT or MOVW immediate instruciton and\r
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
122 Movt = (*Instruction << 16) | (*(Instruction + 1));\r
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
151 Patch = ((Address >> 12) & 0x000f); // imm4\r
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
162/**\r
163 Pass in a pointer to an ARM MOVW/MOVT instruciton pair and\r
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
179\r
180 Word = Instructions; // MOVW\r
181 Top = Word + 2; // MOVT\r
182\r
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
202\r
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
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
232 UINT32 FixupVal;\r
233\r
234 Fixup16 = (UINT16 *) Fixup;\r
235\r
236 switch ((**Reloc) >> 12) {\r
237\r
238 case EFI_IMAGE_REL_BASED_ARM_MOV32T:\r
239 FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust;\r
240 ThumbMovwMovtImmediatePatch (Fixup16, FixupVal);\r
241\r
242\r
243 if (*FixupData != NULL) {\r
244 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
245 CopyMem (*FixupData, Fixup16, sizeof (UINT64));\r
246 *FixupData = *FixupData + sizeof(UINT64);\r
247 }\r
248 break;\r
249\r
250 case EFI_IMAGE_REL_BASED_ARM_MOV32A:\r
251 // break omitted - ARM instruction encoding not implemented\r
252 default:\r
253 return RETURN_UNSUPPORTED;\r
254 }\r
255\r
256 return RETURN_SUCCESS;\r
257}\r