]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BasePeCoffLib/Ipf/PeCoffLoaderEx.c
Minor grammatical work--mostly adding periods. Items with ONLY period added did...
[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
acf57dec
HT
4 Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
d071fb19 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
2fc59a00 8 http://opensource.org/licenses/bsd-license.php.\r
d071fb19 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
2fc59a00 69 @param Reloc The pointer to the relocation record.\r
70 @param Fixup The pointer to the address to fix up.\r
71 @param FixupData The pointer to a buffer to log the fixups.\r
d071fb19 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
981b0f90
LG
221 the entry point. \r
222 \r
223 The itanium version PE/COFF loader/relocater supports itanium and EBC image.\r
d071fb19 224\r
225 @param Machine Machine type from the PE Header.\r
226\r
227 @return TRUE if this PE/COFF loader can load the image\r
f80b0830 228 @return FALSE unrecoganized machine type of image.\r
d071fb19 229\r
230**/\r
231BOOLEAN\r
232PeCoffLoaderImageFormatSupported (\r
233 IN UINT16 Machine\r
234 )\r
235{\r
821b0906 236 if ((Machine == IMAGE_FILE_MACHINE_IA64) || (Machine == IMAGE_FILE_MACHINE_EBC)) {\r
d071fb19 237 return TRUE;\r
238 }\r
239\r
240 return FALSE;\r
241}\r
242\r
243\r
244/**\r
245 ImageRead function that operates on a memory buffer whos base is passed into\r
246 FileHandle.\r
247\r
248 @param Reloc Ponter to baes of the input stream\r
249 @param Fixup Offset to the start of the buffer\r
2fc59a00 250 @param FixupData The number of bytes to copy into the buffer\r
d071fb19 251 @param Adjust Location to place results of read\r
252\r
253 @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into\r
254 the buffer.\r
f80b0830 255 @retval RETURN_UNSUPPORTED Un-recoganized relocation entry\r
256 type.\r
d071fb19 257**/\r
258RETURN_STATUS\r
259PeHotRelocateImageEx (\r
260 IN UINT16 *Reloc,\r
261 IN OUT CHAR8 *Fixup,\r
262 IN OUT CHAR8 **FixupData,\r
263 IN UINT64 Adjust\r
264 )\r
265{\r
1fa524e9 266 UINT64 *Fixup64;\r
d071fb19 267 UINT64 FixupVal;\r
268\r
269 switch ((*Reloc) >> 12) {\r
270 case EFI_IMAGE_REL_BASED_DIR64:\r
1fa524e9 271 Fixup64 = (UINT64 *) Fixup;\r
d071fb19 272 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
1fa524e9 273 if (*(UINT64 *) (*FixupData) == *Fixup64) {\r
274 *Fixup64 = *Fixup64 + (UINT64) Adjust;\r
d071fb19 275 }\r
276\r
277 *FixupData = *FixupData + sizeof (UINT64);\r
278 break;\r
279\r
280 case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
1fa524e9 281 Fixup64 = (UINT64 *) Fixup;\r
d071fb19 282 *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
1fa524e9 283 if (*(UINT64 *) (*FixupData) == *Fixup64) {\r
d071fb19 284 //\r
285 // Align it to bundle address before fixing up the\r
286 // 64-bit immediate value of the movl instruction.\r
287 //\r
288 //\r
289 Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));\r
290 FixupVal = (UINT64) 0;\r
291\r
292 //\r
293 // Extract the lower 32 bits of IMM64 from bundle\r
294 //\r
295 EXT_IMM64 (\r
296 FixupVal,\r
297 (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,\r
298 IMM64_IMM7B_SIZE_X,\r
299 IMM64_IMM7B_INST_WORD_POS_X,\r
300 IMM64_IMM7B_VAL_POS_X\r
301 );\r
302\r
303 EXT_IMM64 (\r
304 FixupVal,\r
305 (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,\r
306 IMM64_IMM9D_SIZE_X,\r
307 IMM64_IMM9D_INST_WORD_POS_X,\r
308 IMM64_IMM9D_VAL_POS_X\r
309 );\r
310\r
311 EXT_IMM64 (\r
312 FixupVal,\r
313 (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,\r
314 IMM64_IMM5C_SIZE_X,\r
315 IMM64_IMM5C_INST_WORD_POS_X,\r
316 IMM64_IMM5C_VAL_POS_X\r
317 );\r
318\r
319 EXT_IMM64 (\r
320 FixupVal,\r
321 (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,\r
322 IMM64_IC_SIZE_X,\r
323 IMM64_IC_INST_WORD_POS_X,\r
324 IMM64_IC_VAL_POS_X\r
325 );\r
326\r
327 EXT_IMM64 (\r
328 FixupVal,\r
1fa524e9 329 (UINT32 *) Fixup + IMM64_IMM41A_INST_WORD_X,\r
330 IMM64_IMM41A_SIZE_X,\r
331 IMM64_IMM41A_INST_WORD_POS_X,\r
332 IMM64_IMM41A_VAL_POS_X\r
d071fb19 333 );\r
334\r
335 //\r
336 // Update 64-bit address\r
337 //\r
338 FixupVal += Adjust;\r
339\r
340 //\r
341 // Insert IMM64 into bundle\r
342 //\r
343 INS_IMM64 (\r
344 FixupVal,\r
345 ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),\r
346 IMM64_IMM7B_SIZE_X,\r
347 IMM64_IMM7B_INST_WORD_POS_X,\r
348 IMM64_IMM7B_VAL_POS_X\r
349 );\r
350\r
351 INS_IMM64 (\r
352 FixupVal,\r
353 ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),\r
354 IMM64_IMM9D_SIZE_X,\r
355 IMM64_IMM9D_INST_WORD_POS_X,\r
356 IMM64_IMM9D_VAL_POS_X\r
357 );\r
358\r
359 INS_IMM64 (\r
360 FixupVal,\r
361 ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),\r
362 IMM64_IMM5C_SIZE_X,\r
363 IMM64_IMM5C_INST_WORD_POS_X,\r
364 IMM64_IMM5C_VAL_POS_X\r
365 );\r
366\r
367 INS_IMM64 (\r
368 FixupVal,\r
369 ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),\r
370 IMM64_IC_SIZE_X,\r
371 IMM64_IC_INST_WORD_POS_X,\r
372 IMM64_IC_VAL_POS_X\r
373 );\r
374\r
375 INS_IMM64 (\r
376 FixupVal,\r
1fa524e9 377 ((UINT32 *) Fixup + IMM64_IMM41A_INST_WORD_X),\r
378 IMM64_IMM41A_SIZE_X,\r
379 IMM64_IMM41A_INST_WORD_POS_X,\r
380 IMM64_IMM41A_VAL_POS_X\r
d071fb19 381 );\r
382\r
383 INS_IMM64 (\r
384 FixupVal,\r
1fa524e9 385 ((UINT32 *) Fixup + IMM64_IMM41B_INST_WORD_X),\r
386 IMM64_IMM41B_SIZE_X,\r
387 IMM64_IMM41B_INST_WORD_POS_X,\r
388 IMM64_IMM41B_VAL_POS_X\r
d071fb19 389 );\r
390\r
391 INS_IMM64 (\r
392 FixupVal,\r
1fa524e9 393 ((UINT32 *) Fixup + IMM64_IMM41C_INST_WORD_X),\r
394 IMM64_IMM41C_SIZE_X,\r
395 IMM64_IMM41C_INST_WORD_POS_X,\r
396 IMM64_IMM41C_VAL_POS_X\r
d071fb19 397 );\r
398\r
399 INS_IMM64 (\r
400 FixupVal,\r
401 ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),\r
402 IMM64_SIGN_SIZE_X,\r
403 IMM64_SIGN_INST_WORD_POS_X,\r
404 IMM64_SIGN_VAL_POS_X\r
405 );\r
406\r
1fa524e9 407 *(UINT64 *) (*FixupData) = *Fixup64;\r
d071fb19 408 }\r
409\r
410 *FixupData = *FixupData + sizeof (UINT64);\r
411 break;\r
412\r
413 default:\r
414 DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));\r
415 return RETURN_UNSUPPORTED;\r
416 }\r
417\r
418 return RETURN_SUCCESS;\r
419}\r
420\r
421\r
422\r