]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
1) Remove UEFI specific defines from IndustryStandard/PeImage.h
[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
373ade0e 4 Copyright (c) 2006 - 2008, Intel Corporation\r
d071fb19 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
d071fb19 13**/\r
14\r
d071fb19 15#include "BasePeCoffLibInternals.h"\r
16\r
17\r
18\r
19#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \\r
20 Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)\r
21\r
22#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \\r
23 *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \\r
24 ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)\r
25\r
26#define IMM64_IMM7B_INST_WORD_X 3\r
27#define IMM64_IMM7B_SIZE_X 7\r
28#define IMM64_IMM7B_INST_WORD_POS_X 4\r
29#define IMM64_IMM7B_VAL_POS_X 0\r
30\r
31#define IMM64_IMM9D_INST_WORD_X 3\r
32#define IMM64_IMM9D_SIZE_X 9\r
33#define IMM64_IMM9D_INST_WORD_POS_X 18\r
34#define IMM64_IMM9D_VAL_POS_X 7\r
35\r
36#define IMM64_IMM5C_INST_WORD_X 3\r
37#define IMM64_IMM5C_SIZE_X 5\r
38#define IMM64_IMM5C_INST_WORD_POS_X 13\r
39#define IMM64_IMM5C_VAL_POS_X 16\r
40\r
41#define IMM64_IC_INST_WORD_X 3\r
42#define IMM64_IC_SIZE_X 1\r
43#define IMM64_IC_INST_WORD_POS_X 12\r
44#define IMM64_IC_VAL_POS_X 21\r
45\r
1fa524e9 46#define IMM64_IMM41A_INST_WORD_X 1\r
47#define IMM64_IMM41A_SIZE_X 10\r
48#define IMM64_IMM41A_INST_WORD_POS_X 14\r
49#define IMM64_IMM41A_VAL_POS_X 22\r
d071fb19 50\r
1fa524e9 51#define IMM64_IMM41B_INST_WORD_X 1\r
52#define IMM64_IMM41B_SIZE_X 8\r
53#define IMM64_IMM41B_INST_WORD_POS_X 24\r
54#define IMM64_IMM41B_VAL_POS_X 32\r
d071fb19 55\r
1fa524e9 56#define IMM64_IMM41C_INST_WORD_X 2\r
57#define IMM64_IMM41C_SIZE_X 23\r
58#define IMM64_IMM41C_INST_WORD_POS_X 0\r
59#define IMM64_IMM41C_VAL_POS_X 40\r
d071fb19 60\r
61#define IMM64_SIGN_INST_WORD_X 3\r
62#define IMM64_SIGN_SIZE_X 1\r
63#define IMM64_SIGN_INST_WORD_POS_X 27\r
64#define IMM64_SIGN_VAL_POS_X 63\r
65\r
66/**\r
67 Performs an Itanium-based specific relocation fixup.\r
68\r
69 @param Reloc Pointer to the relocation record.\r
70 @param Fixup Pointer to the address to fix up.\r
71 @param FixupData Pointer to a buffer to log the fixups.\r
72 @param Adjust The offset to adjust the fixup.\r
73\r
f80b0830 74 @retval RETURN_SUCCESS Succeed to fix the relocation entry.\r
75 @retval RETURN_UNSUPPOTED Unrecoganized relocation entry.\r
d071fb19 76\r
77**/\r
78RETURN_STATUS\r
79PeCoffLoaderRelocateImageEx (\r
80 IN UINT16 *Reloc,\r
81 IN OUT CHAR8 *Fixup,\r
82 IN OUT CHAR8 **FixupData,\r
83 IN UINT64 Adjust\r
84 )\r
85{\r
1fa524e9 86 UINT64 *Fixup64;\r
d071fb19 87 UINT64 FixupVal;\r
88\r
89 switch ((*Reloc) >> 12) {\r
90 case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
91\r
92 //\r
93 // Align it to bundle address before fixing up the\r
94 // 64-bit immediate value of the movl instruction.\r
95 //\r
96\r
97 Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));\r
98 FixupVal = (UINT64)0;\r
99\r
100 //\r
101 // Extract the lower 32 bits of IMM64 from bundle\r
102 //\r
103 EXT_IMM64(FixupVal,\r
104 (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,\r
105 IMM64_IMM7B_SIZE_X,\r
106 IMM64_IMM7B_INST_WORD_POS_X,\r
107 IMM64_IMM7B_VAL_POS_X\r
108 );\r
109\r
110 EXT_IMM64(FixupVal,\r
111 (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,\r
112 IMM64_IMM9D_SIZE_X,\r
113 IMM64_IMM9D_INST_WORD_POS_X,\r
114 IMM64_IMM9D_VAL_POS_X\r
115 );\r
116\r
117 EXT_IMM64(FixupVal,\r
118 (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,\r
119 IMM64_IMM5C_SIZE_X,\r
120 IMM64_IMM5C_INST_WORD_POS_X,\r
121 IMM64_IMM5C_VAL_POS_X\r
122 );\r
123\r
124 EXT_IMM64(FixupVal,\r
125 (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,\r
126 IMM64_IC_SIZE_X,\r
127 IMM64_IC_INST_WORD_POS_X,\r
128 IMM64_IC_VAL_POS_X\r
129 );\r
130\r
131 EXT_IMM64(FixupVal,\r
1fa524e9 132 (UINT32 *)Fixup + IMM64_IMM41A_INST_WORD_X,\r
133 IMM64_IMM41A_SIZE_X,\r
134 IMM64_IMM41A_INST_WORD_POS_X,\r
135 IMM64_IMM41A_VAL_POS_X\r
d071fb19 136 );\r
137\r
138 //\r
139 // Update 64-bit address\r
140 //\r
141 FixupVal += Adjust;\r
142\r
143 //\r
144 // Insert IMM64 into bundle\r
145 //\r
146 INS_IMM64(FixupVal,\r
147 ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),\r
148 IMM64_IMM7B_SIZE_X,\r
149 IMM64_IMM7B_INST_WORD_POS_X,\r
150 IMM64_IMM7B_VAL_POS_X\r
151 );\r
152\r
153 INS_IMM64(FixupVal,\r
154 ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),\r
155 IMM64_IMM9D_SIZE_X,\r
156 IMM64_IMM9D_INST_WORD_POS_X,\r
157 IMM64_IMM9D_VAL_POS_X\r
158 );\r
159\r
160 INS_IMM64(FixupVal,\r
161 ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),\r
162 IMM64_IMM5C_SIZE_X,\r
163 IMM64_IMM5C_INST_WORD_POS_X,\r
164 IMM64_IMM5C_VAL_POS_X\r
165 );\r
166\r
167 INS_IMM64(FixupVal,\r
168 ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),\r
169 IMM64_IC_SIZE_X,\r
170 IMM64_IC_INST_WORD_POS_X,\r
171 IMM64_IC_VAL_POS_X\r
172 );\r
173\r
174 INS_IMM64(FixupVal,\r
1fa524e9 175 ((UINT32 *)Fixup + IMM64_IMM41A_INST_WORD_X),\r
176 IMM64_IMM41A_SIZE_X,\r
177 IMM64_IMM41A_INST_WORD_POS_X,\r
178 IMM64_IMM41A_VAL_POS_X\r
d071fb19 179 );\r
180\r
181 INS_IMM64(FixupVal,\r
1fa524e9 182 ((UINT32 *)Fixup + IMM64_IMM41B_INST_WORD_X),\r
183 IMM64_IMM41B_SIZE_X,\r
184 IMM64_IMM41B_INST_WORD_POS_X,\r
185 IMM64_IMM41B_VAL_POS_X\r
d071fb19 186 );\r
187\r
188 INS_IMM64(FixupVal,\r
1fa524e9 189 ((UINT32 *)Fixup + IMM64_IMM41C_INST_WORD_X),\r
190 IMM64_IMM41C_SIZE_X,\r
191 IMM64_IMM41C_INST_WORD_POS_X,\r
192 IMM64_IMM41C_VAL_POS_X\r
d071fb19 193 );\r
194\r
195 INS_IMM64(FixupVal,\r
196 ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),\r
197 IMM64_SIGN_SIZE_X,\r
198 IMM64_SIGN_INST_WORD_POS_X,\r
199 IMM64_SIGN_VAL_POS_X\r
200 );\r
201\r
1fa524e9 202 Fixup64 = (UINT64 *) Fixup;\r
d071fb19 203 if (*FixupData != NULL) {\r
204 *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
1fa524e9 205 *(UINT64 *)(*FixupData) = *Fixup64;\r
d071fb19 206 *FixupData = *FixupData + sizeof(UINT64);\r
207 }\r
208 break;\r
209\r
210 default:\r
211 return RETURN_UNSUPPORTED;\r
212 }\r
213\r
214 return RETURN_SUCCESS;\r
215}\r
216\r
217/**\r
218 Returns TRUE if the machine type of PE/COFF image is supported. Supported\r
219 does not mean the image can be executed it means the PE/COFF loader supports\r
220 loading and relocating of the image type. It's up to the caller to support\r
221 the entry point.\r
222\r
223 This function implies the basic PE/COFF loader/relocator supports IA32, EBC,\r
030cd1a2 224 & x64 images. Calling the entry point in a correct mannor is up to the\r
d071fb19 225 consumer of this library. This version also supports the special relocations\r
226 for Itanium.\r
227\r
228 @param Machine Machine type from the PE Header.\r
229\r
230 @return TRUE if this PE/COFF loader can load the image\r
f80b0830 231 @return FALSE unrecoganized machine type of image.\r
d071fb19 232\r
233**/\r
234BOOLEAN\r
235PeCoffLoaderImageFormatSupported (\r
236 IN UINT16 Machine\r
237 )\r
238{\r
4ab0dff3 239 if ((Machine == IMAGE_FILE_MACHINE_IA64) || (Machine == IMAGE_FILE_MACHINE_I386) ||\r
240 (Machine == IMAGE_FILE_MACHINE_EBC) || (Machine == IMAGE_FILE_MACHINE_X64)) {\r
d071fb19 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
f80b0830 259 @retval RETURN_UNSUPPORTED Un-recoganized relocation entry\r
260 type.\r
d071fb19 261**/\r
262RETURN_STATUS\r
263PeHotRelocateImageEx (\r
264 IN UINT16 *Reloc,\r
265 IN OUT CHAR8 *Fixup,\r
266 IN OUT CHAR8 **FixupData,\r
267 IN UINT64 Adjust\r
268 )\r
269{\r
1fa524e9 270 UINT64 *Fixup64;\r
d071fb19 271 UINT64 FixupVal;\r
272\r
273 switch ((*Reloc) >> 12) {\r
274 case EFI_IMAGE_REL_BASED_DIR64:\r
1fa524e9 275 Fixup64 = (UINT64 *) Fixup;\r
d071fb19 276 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
1fa524e9 277 if (*(UINT64 *) (*FixupData) == *Fixup64) {\r
278 *Fixup64 = *Fixup64 + (UINT64) Adjust;\r
d071fb19 279 }\r
280\r
281 *FixupData = *FixupData + sizeof (UINT64);\r
282 break;\r
283\r
284 case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
1fa524e9 285 Fixup64 = (UINT64 *) Fixup;\r
d071fb19 286 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
1fa524e9 287 if (*(UINT64 *) (*FixupData) == *Fixup64) {\r
d071fb19 288 //\r
289 // Align it to bundle address before fixing up the\r
290 // 64-bit immediate value of the movl instruction.\r
291 //\r
292 //\r
293 Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));\r
294 FixupVal = (UINT64) 0;\r
295\r
296 //\r
297 // Extract the lower 32 bits of IMM64 from bundle\r
298 //\r
299 EXT_IMM64 (\r
300 FixupVal,\r
301 (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,\r
302 IMM64_IMM7B_SIZE_X,\r
303 IMM64_IMM7B_INST_WORD_POS_X,\r
304 IMM64_IMM7B_VAL_POS_X\r
305 );\r
306\r
307 EXT_IMM64 (\r
308 FixupVal,\r
309 (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,\r
310 IMM64_IMM9D_SIZE_X,\r
311 IMM64_IMM9D_INST_WORD_POS_X,\r
312 IMM64_IMM9D_VAL_POS_X\r
313 );\r
314\r
315 EXT_IMM64 (\r
316 FixupVal,\r
317 (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,\r
318 IMM64_IMM5C_SIZE_X,\r
319 IMM64_IMM5C_INST_WORD_POS_X,\r
320 IMM64_IMM5C_VAL_POS_X\r
321 );\r
322\r
323 EXT_IMM64 (\r
324 FixupVal,\r
325 (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,\r
326 IMM64_IC_SIZE_X,\r
327 IMM64_IC_INST_WORD_POS_X,\r
328 IMM64_IC_VAL_POS_X\r
329 );\r
330\r
331 EXT_IMM64 (\r
332 FixupVal,\r
1fa524e9 333 (UINT32 *) Fixup + IMM64_IMM41A_INST_WORD_X,\r
334 IMM64_IMM41A_SIZE_X,\r
335 IMM64_IMM41A_INST_WORD_POS_X,\r
336 IMM64_IMM41A_VAL_POS_X\r
d071fb19 337 );\r
338\r
339 //\r
340 // Update 64-bit address\r
341 //\r
342 FixupVal += Adjust;\r
343\r
344 //\r
345 // Insert IMM64 into bundle\r
346 //\r
347 INS_IMM64 (\r
348 FixupVal,\r
349 ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),\r
350 IMM64_IMM7B_SIZE_X,\r
351 IMM64_IMM7B_INST_WORD_POS_X,\r
352 IMM64_IMM7B_VAL_POS_X\r
353 );\r
354\r
355 INS_IMM64 (\r
356 FixupVal,\r
357 ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),\r
358 IMM64_IMM9D_SIZE_X,\r
359 IMM64_IMM9D_INST_WORD_POS_X,\r
360 IMM64_IMM9D_VAL_POS_X\r
361 );\r
362\r
363 INS_IMM64 (\r
364 FixupVal,\r
365 ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),\r
366 IMM64_IMM5C_SIZE_X,\r
367 IMM64_IMM5C_INST_WORD_POS_X,\r
368 IMM64_IMM5C_VAL_POS_X\r
369 );\r
370\r
371 INS_IMM64 (\r
372 FixupVal,\r
373 ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),\r
374 IMM64_IC_SIZE_X,\r
375 IMM64_IC_INST_WORD_POS_X,\r
376 IMM64_IC_VAL_POS_X\r
377 );\r
378\r
379 INS_IMM64 (\r
380 FixupVal,\r
1fa524e9 381 ((UINT32 *) Fixup + IMM64_IMM41A_INST_WORD_X),\r
382 IMM64_IMM41A_SIZE_X,\r
383 IMM64_IMM41A_INST_WORD_POS_X,\r
384 IMM64_IMM41A_VAL_POS_X\r
d071fb19 385 );\r
386\r
387 INS_IMM64 (\r
388 FixupVal,\r
1fa524e9 389 ((UINT32 *) Fixup + IMM64_IMM41B_INST_WORD_X),\r
390 IMM64_IMM41B_SIZE_X,\r
391 IMM64_IMM41B_INST_WORD_POS_X,\r
392 IMM64_IMM41B_VAL_POS_X\r
d071fb19 393 );\r
394\r
395 INS_IMM64 (\r
396 FixupVal,\r
1fa524e9 397 ((UINT32 *) Fixup + IMM64_IMM41C_INST_WORD_X),\r
398 IMM64_IMM41C_SIZE_X,\r
399 IMM64_IMM41C_INST_WORD_POS_X,\r
400 IMM64_IMM41C_VAL_POS_X\r
d071fb19 401 );\r
402\r
403 INS_IMM64 (\r
404 FixupVal,\r
405 ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),\r
406 IMM64_SIGN_SIZE_X,\r
407 IMM64_SIGN_INST_WORD_POS_X,\r
408 IMM64_SIGN_VAL_POS_X\r
409 );\r
410\r
1fa524e9 411 *(UINT64 *) (*FixupData) = *Fixup64;\r
d071fb19 412 }\r
413\r
414 *FixupData = *FixupData + sizeof (UINT64);\r
415 break;\r
416\r
417 default:\r
418 DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));\r
419 return RETURN_UNSUPPORTED;\r
420 }\r
421\r
422 return RETURN_SUCCESS;\r
423}\r
424\r
425\r
426\r