]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
Removed CommonHeader.h generated file from the MdePkg.
[mirror_edk2.git] / MdePkg / Library / BasePeCoffLib / Ipf / PeCoffLoaderEx.c
CommitLineData
d071fb19 1/** @file\r
2 Fixes Intel Itanium(TM) specific relocation types.\r
3\r
4 Copyright (c) 2006, Intel Corporation\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13 Module Name: PeCoffLoaderEx.c\r
14\r
15**/\r
16\r
d071fb19 17#include "BasePeCoffLibInternals.h"\r
18\r
19\r
20\r
21#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \\r
22 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)\r
23\r
24#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \\r
25 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \\r
26 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)\r
27\r
28#define IMM64_IMM7B_INST_WORD_X 3\r
29#define IMM64_IMM7B_SIZE_X 7\r
30#define IMM64_IMM7B_INST_WORD_POS_X 4\r
31#define IMM64_IMM7B_VAL_POS_X 0\r
32\r
33#define IMM64_IMM9D_INST_WORD_X 3\r
34#define IMM64_IMM9D_SIZE_X 9\r
35#define IMM64_IMM9D_INST_WORD_POS_X 18\r
36#define IMM64_IMM9D_VAL_POS_X 7\r
37\r
38#define IMM64_IMM5C_INST_WORD_X 3\r
39#define IMM64_IMM5C_SIZE_X 5\r
40#define IMM64_IMM5C_INST_WORD_POS_X 13\r
41#define IMM64_IMM5C_VAL_POS_X 16\r
42\r
43#define IMM64_IC_INST_WORD_X 3\r
44#define IMM64_IC_SIZE_X 1\r
45#define IMM64_IC_INST_WORD_POS_X 12\r
46#define IMM64_IC_VAL_POS_X 21\r
47\r
48#define IMM64_IMM41a_INST_WORD_X 1\r
49#define IMM64_IMM41a_SIZE_X 10\r
50#define IMM64_IMM41a_INST_WORD_POS_X 14\r
51#define IMM64_IMM41a_VAL_POS_X 22\r
52\r
53#define IMM64_IMM41b_INST_WORD_X 1\r
54#define IMM64_IMM41b_SIZE_X 8\r
55#define IMM64_IMM41b_INST_WORD_POS_X 24\r
56#define IMM64_IMM41b_VAL_POS_X 32\r
57\r
58#define IMM64_IMM41c_INST_WORD_X 2\r
59#define IMM64_IMM41c_SIZE_X 23\r
60#define IMM64_IMM41c_INST_WORD_POS_X 0\r
61#define IMM64_IMM41c_VAL_POS_X 40\r
62\r
63#define IMM64_SIGN_INST_WORD_X 3\r
64#define IMM64_SIGN_SIZE_X 1\r
65#define IMM64_SIGN_INST_WORD_POS_X 27\r
66#define IMM64_SIGN_VAL_POS_X 63\r
67\r
68/**\r
69 Performs an Itanium-based specific relocation fixup.\r
70\r
71 @param Reloc Pointer to the relocation record.\r
72 @param Fixup Pointer to the address to fix up.\r
73 @param FixupData Pointer to a buffer to log the fixups.\r
74 @param Adjust The offset to adjust the fixup.\r
75\r
76 @return Status code.\r
77\r
78**/\r
79RETURN_STATUS\r
80PeCoffLoaderRelocateImageEx (\r
81 IN UINT16 *Reloc,\r
82 IN OUT CHAR8 *Fixup,\r
83 IN OUT CHAR8 **FixupData,\r
84 IN UINT64 Adjust\r
85 )\r
86{\r
87 UINT64 *F64;\r
88 UINT64 FixupVal;\r
89\r
90 switch ((*Reloc) >> 12) {\r
91 case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
92\r
93 //\r
94 // Align it to bundle address before fixing up the\r
95 // 64-bit immediate value of the movl instruction.\r
96 //\r
97\r
98 Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));\r
99 FixupVal = (UINT64)0;\r
100\r
101 //\r
102 // Extract the lower 32 bits of IMM64 from bundle\r
103 //\r
104 EXT_IMM64(FixupVal,\r
105 (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,\r
106 IMM64_IMM7B_SIZE_X,\r
107 IMM64_IMM7B_INST_WORD_POS_X,\r
108 IMM64_IMM7B_VAL_POS_X\r
109 );\r
110\r
111 EXT_IMM64(FixupVal,\r
112 (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,\r
113 IMM64_IMM9D_SIZE_X,\r
114 IMM64_IMM9D_INST_WORD_POS_X,\r
115 IMM64_IMM9D_VAL_POS_X\r
116 );\r
117\r
118 EXT_IMM64(FixupVal,\r
119 (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,\r
120 IMM64_IMM5C_SIZE_X,\r
121 IMM64_IMM5C_INST_WORD_POS_X,\r
122 IMM64_IMM5C_VAL_POS_X\r
123 );\r
124\r
125 EXT_IMM64(FixupVal,\r
126 (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,\r
127 IMM64_IC_SIZE_X,\r
128 IMM64_IC_INST_WORD_POS_X,\r
129 IMM64_IC_VAL_POS_X\r
130 );\r
131\r
132 EXT_IMM64(FixupVal,\r
133 (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,\r
134 IMM64_IMM41a_SIZE_X,\r
135 IMM64_IMM41a_INST_WORD_POS_X,\r
136 IMM64_IMM41a_VAL_POS_X\r
137 );\r
138\r
139 //\r
140 // Update 64-bit address\r
141 //\r
142 FixupVal += Adjust;\r
143\r
144 //\r
145 // Insert IMM64 into bundle\r
146 //\r
147 INS_IMM64(FixupVal,\r
148 ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),\r
149 IMM64_IMM7B_SIZE_X,\r
150 IMM64_IMM7B_INST_WORD_POS_X,\r
151 IMM64_IMM7B_VAL_POS_X\r
152 );\r
153\r
154 INS_IMM64(FixupVal,\r
155 ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),\r
156 IMM64_IMM9D_SIZE_X,\r
157 IMM64_IMM9D_INST_WORD_POS_X,\r
158 IMM64_IMM9D_VAL_POS_X\r
159 );\r
160\r
161 INS_IMM64(FixupVal,\r
162 ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),\r
163 IMM64_IMM5C_SIZE_X,\r
164 IMM64_IMM5C_INST_WORD_POS_X,\r
165 IMM64_IMM5C_VAL_POS_X\r
166 );\r
167\r
168 INS_IMM64(FixupVal,\r
169 ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),\r
170 IMM64_IC_SIZE_X,\r
171 IMM64_IC_INST_WORD_POS_X,\r
172 IMM64_IC_VAL_POS_X\r
173 );\r
174\r
175 INS_IMM64(FixupVal,\r
176 ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),\r
177 IMM64_IMM41a_SIZE_X,\r
178 IMM64_IMM41a_INST_WORD_POS_X,\r
179 IMM64_IMM41a_VAL_POS_X\r
180 );\r
181\r
182 INS_IMM64(FixupVal,\r
183 ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),\r
184 IMM64_IMM41b_SIZE_X,\r
185 IMM64_IMM41b_INST_WORD_POS_X,\r
186 IMM64_IMM41b_VAL_POS_X\r
187 );\r
188\r
189 INS_IMM64(FixupVal,\r
190 ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),\r
191 IMM64_IMM41c_SIZE_X,\r
192 IMM64_IMM41c_INST_WORD_POS_X,\r
193 IMM64_IMM41c_VAL_POS_X\r
194 );\r
195\r
196 INS_IMM64(FixupVal,\r
197 ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),\r
198 IMM64_SIGN_SIZE_X,\r
199 IMM64_SIGN_INST_WORD_POS_X,\r
200 IMM64_SIGN_VAL_POS_X\r
201 );\r
202\r
203 F64 = (UINT64 *) Fixup;\r
204 if (*FixupData != NULL) {\r
205 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
206 *(UINT64 *)(*FixupData) = *F64;\r
207 *FixupData = *FixupData + sizeof(UINT64);\r
208 }\r
209 break;\r
210\r
211 default:\r
212 return RETURN_UNSUPPORTED;\r
213 }\r
214\r
215 return RETURN_SUCCESS;\r
216}\r
217\r
218/**\r
219 Returns TRUE if the machine type of PE/COFF image is supported. Supported\r
220 does not mean the image can be executed it means the PE/COFF loader supports\r
221 loading and relocating of the image type. It's up to the caller to support\r
222 the entry point.\r
223\r
224 This function implies the basic PE/COFF loader/relocator supports IA32, EBC,\r
225 & X64 images. Calling the entry point in a correct mannor is up to the\r
226 consumer of this library. This version also supports the special relocations\r
227 for Itanium.\r
228\r
229 @param Machine Machine type from the PE Header.\r
230\r
231 @return TRUE if this PE/COFF loader can load the image\r
232\r
233**/\r
234BOOLEAN\r
235PeCoffLoaderImageFormatSupported (\r
236 IN UINT16 Machine\r
237 )\r
238{\r
239 if ((Machine == EFI_IMAGE_MACHINE_IPF) || (Machine == EFI_IMAGE_MACHINE_IA32) ||\r
240 (Machine == EFI_IMAGE_MACHINE_EBC) || (Machine == EFI_IMAGE_MACHINE_X64)) {\r
241 return TRUE;\r
242 }\r
243\r
244 return FALSE;\r
245}\r
246\r
247\r
248/**\r
249 ImageRead function that operates on a memory buffer whos base is passed into\r
250 FileHandle.\r
251\r
252 @param Reloc Ponter to baes of the input stream\r
253 @param Fixup Offset to the start of the buffer\r
254 @param FixupData Number of bytes to copy into the buffer\r
255 @param Adjust Location to place results of read\r
256\r
257 @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into\r
258 the buffer.\r
259**/\r
260RETURN_STATUS\r
261PeHotRelocateImageEx (\r
262 IN UINT16 *Reloc,\r
263 IN OUT CHAR8 *Fixup,\r
264 IN OUT CHAR8 **FixupData,\r
265 IN UINT64 Adjust\r
266 )\r
267{\r
268 UINT64 *F64;\r
269 UINT64 FixupVal;\r
270\r
271 switch ((*Reloc) >> 12) {\r
272 case EFI_IMAGE_REL_BASED_DIR64:\r
273 F64 = (UINT64 *) Fixup;\r
274 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
275 if (*(UINT64 *) (*FixupData) == *F64) {\r
276 *F64 = *F64 + (UINT64) Adjust;\r
277 }\r
278\r
279 *FixupData = *FixupData + sizeof (UINT64);\r
280 break;\r
281\r
282 case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
283 F64 = (UINT64 *) Fixup;\r
284 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
285 if (*(UINT64 *) (*FixupData) == *F64) {\r
286 //\r
287 // Align it to bundle address before fixing up the\r
288 // 64-bit immediate value of the movl instruction.\r
289 //\r
290 //\r
291 Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));\r
292 FixupVal = (UINT64) 0;\r
293\r
294 //\r
295 // Extract the lower 32 bits of IMM64 from bundle\r
296 //\r
297 EXT_IMM64 (\r
298 FixupVal,\r
299 (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,\r
300 IMM64_IMM7B_SIZE_X,\r
301 IMM64_IMM7B_INST_WORD_POS_X,\r
302 IMM64_IMM7B_VAL_POS_X\r
303 );\r
304\r
305 EXT_IMM64 (\r
306 FixupVal,\r
307 (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,\r
308 IMM64_IMM9D_SIZE_X,\r
309 IMM64_IMM9D_INST_WORD_POS_X,\r
310 IMM64_IMM9D_VAL_POS_X\r
311 );\r
312\r
313 EXT_IMM64 (\r
314 FixupVal,\r
315 (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,\r
316 IMM64_IMM5C_SIZE_X,\r
317 IMM64_IMM5C_INST_WORD_POS_X,\r
318 IMM64_IMM5C_VAL_POS_X\r
319 );\r
320\r
321 EXT_IMM64 (\r
322 FixupVal,\r
323 (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,\r
324 IMM64_IC_SIZE_X,\r
325 IMM64_IC_INST_WORD_POS_X,\r
326 IMM64_IC_VAL_POS_X\r
327 );\r
328\r
329 EXT_IMM64 (\r
330 FixupVal,\r
331 (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,\r
332 IMM64_IMM41a_SIZE_X,\r
333 IMM64_IMM41a_INST_WORD_POS_X,\r
334 IMM64_IMM41a_VAL_POS_X\r
335 );\r
336\r
337 //\r
338 // Update 64-bit address\r
339 //\r
340 FixupVal += Adjust;\r
341\r
342 //\r
343 // Insert IMM64 into bundle\r
344 //\r
345 INS_IMM64 (\r
346 FixupVal,\r
347 ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),\r
348 IMM64_IMM7B_SIZE_X,\r
349 IMM64_IMM7B_INST_WORD_POS_X,\r
350 IMM64_IMM7B_VAL_POS_X\r
351 );\r
352\r
353 INS_IMM64 (\r
354 FixupVal,\r
355 ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),\r
356 IMM64_IMM9D_SIZE_X,\r
357 IMM64_IMM9D_INST_WORD_POS_X,\r
358 IMM64_IMM9D_VAL_POS_X\r
359 );\r
360\r
361 INS_IMM64 (\r
362 FixupVal,\r
363 ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),\r
364 IMM64_IMM5C_SIZE_X,\r
365 IMM64_IMM5C_INST_WORD_POS_X,\r
366 IMM64_IMM5C_VAL_POS_X\r
367 );\r
368\r
369 INS_IMM64 (\r
370 FixupVal,\r
371 ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),\r
372 IMM64_IC_SIZE_X,\r
373 IMM64_IC_INST_WORD_POS_X,\r
374 IMM64_IC_VAL_POS_X\r
375 );\r
376\r
377 INS_IMM64 (\r
378 FixupVal,\r
379 ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),\r
380 IMM64_IMM41a_SIZE_X,\r
381 IMM64_IMM41a_INST_WORD_POS_X,\r
382 IMM64_IMM41a_VAL_POS_X\r
383 );\r
384\r
385 INS_IMM64 (\r
386 FixupVal,\r
387 ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),\r
388 IMM64_IMM41b_SIZE_X,\r
389 IMM64_IMM41b_INST_WORD_POS_X,\r
390 IMM64_IMM41b_VAL_POS_X\r
391 );\r
392\r
393 INS_IMM64 (\r
394 FixupVal,\r
395 ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),\r
396 IMM64_IMM41c_SIZE_X,\r
397 IMM64_IMM41c_INST_WORD_POS_X,\r
398 IMM64_IMM41c_VAL_POS_X\r
399 );\r
400\r
401 INS_IMM64 (\r
402 FixupVal,\r
403 ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),\r
404 IMM64_SIGN_SIZE_X,\r
405 IMM64_SIGN_INST_WORD_POS_X,\r
406 IMM64_SIGN_VAL_POS_X\r
407 );\r
408\r
409 *(UINT64 *) (*FixupData) = *F64;\r
410 }\r
411\r
412 *FixupData = *FixupData + sizeof (UINT64);\r
413 break;\r
414\r
415 default:\r
416 DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));\r
417 return RETURN_UNSUPPORTED;\r
418 }\r
419\r
420 return RETURN_SUCCESS;\r
421}\r
422\r
423\r
424\r