DuetPkg: Removing ipf which is no longer supported from edk2.
[mirror_edk2.git] / DuetPkg / EfiLdr / PeLoader.c
CommitLineData
9071550e 1/*++\r
2\r
3ea9a5c7 3Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
b1f700a8 4This program and the accompanying materials \r
9071550e 5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13 PeLoader.c\r
14\r
15Abstract:\r
16\r
17Revision History:\r
18\r
19--*/\r
20#include "EfiLdr.h"\r
21#include "Debug.h"\r
22#include "Support.h"\r
23\r
9071550e 24EFI_STATUS\r
25EfiLdrPeCoffLoadPeRelocate (\r
26 IN EFILDR_LOADED_IMAGE *Image,\r
27 IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,\r
28 IN UINTN Adjust,\r
29 IN UINTN *NumberOfMemoryMapEntries,\r
30 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor\r
31 );\r
32\r
9071550e 33EFI_STATUS\r
34EfiLdrPeCoffImageRead (\r
35 IN VOID *FHand,\r
36 IN UINTN Offset,\r
37 IN OUT UINTN ReadSize,\r
38 OUT VOID *Buffer\r
39 );\r
40\r
9071550e 41VOID *\r
42EfiLdrPeCoffImageAddress (\r
43 IN EFILDR_LOADED_IMAGE *Image,\r
44 IN UINTN Address\r
45 );\r
46\r
47\r
48EFI_STATUS\r
49EfiLdrPeCoffSetImageType (\r
50 IN OUT EFILDR_LOADED_IMAGE *Image,\r
51 IN UINTN ImageType\r
52 );\r
53\r
54EFI_STATUS\r
55EfiLdrPeCoffCheckImageMachineType (\r
56 IN UINT16 MachineType\r
57 );\r
58\r
59EFI_STATUS\r
60EfiLdrGetPeImageInfo (\r
61 IN VOID *FHand,\r
62 OUT UINT64 *ImageBase,\r
63 OUT UINT32 *ImageSize\r
64 )\r
65{\r
66 EFI_STATUS Status;\r
67 EFI_IMAGE_DOS_HEADER DosHdr;\r
68 EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;\r
69\r
70 ZeroMem (&DosHdr, sizeof(DosHdr));\r
71 ZeroMem (&PeHdr, sizeof(PeHdr));\r
72\r
73 //\r
74 // Read image headers\r
75 //\r
76\r
77 EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr);\r
78 if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
79 return EFI_UNSUPPORTED;\r
80 }\r
81\r
82 EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr);\r
83\r
84 if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
85 return EFI_UNSUPPORTED;\r
86 }\r
87 \r
88 //\r
89 // Verify machine type\r
90 //\r
91\r
92 Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine);\r
93 if (EFI_ERROR(Status)) {\r
94 return Status;\r
95 }\r
96\r
97 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
98 *ImageBase = (UINT32)PeHdr.Pe32.OptionalHeader.ImageBase;\r
99 } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
100 *ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;\r
101 } else {\r
102 return EFI_UNSUPPORTED;\r
103 }\r
104 \r
105 *ImageSize = PeHdr.Pe32.OptionalHeader.SizeOfImage;\r
106\r
107 return EFI_SUCCESS;\r
108}\r
109\r
110EFI_STATUS\r
111EfiLdrPeCoffLoadPeImage (\r
112 IN VOID *FHand,\r
113 IN EFILDR_LOADED_IMAGE *Image,\r
114 IN UINTN *NumberOfMemoryMapEntries,\r
115 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor\r
116 )\r
117{\r
118 EFI_IMAGE_DOS_HEADER DosHdr;\r
119 EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;\r
120 EFI_IMAGE_SECTION_HEADER *FirstSection;\r
121 EFI_IMAGE_SECTION_HEADER *Section;\r
122 UINTN Index;\r
123 EFI_STATUS Status;\r
124 UINT8 *Base;\r
125 UINT8 *End;\r
126 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
127 UINTN DirCount;\r
128 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY TempDebugEntry;\r
129 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
130 UINTN CodeViewSize;\r
131 UINTN CodeViewOffset;\r
132 UINTN CodeViewFileOffset;\r
133 UINTN OptionalHeaderSize;\r
134 UINTN PeHeaderSize;\r
135 UINT32 NumberOfRvaAndSizes;\r
136 EFI_IMAGE_DATA_DIRECTORY *DataDirectory;\r
137 UINT64 ImageBase;\r
3da85e63 138 CHAR8 PrintBuffer[256];\r
9071550e 139\r
140 ZeroMem (&DosHdr, sizeof(DosHdr));\r
141 ZeroMem (&PeHdr, sizeof(PeHdr));\r
142\r
143 //\r
144 // Read image headers\r
145 //\r
146\r
147 EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr);\r
148 if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
3da85e63 149 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Dos header signature not found\n");\r
150 PrintString (PrintBuffer);\r
151 PrintHeader ('F');\r
9071550e 152 return EFI_UNSUPPORTED;\r
153 }\r
154\r
155 EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr);\r
156\r
157 if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
3da85e63 158 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: PE image header signature not found\n");\r
159 PrintString (PrintBuffer);\r
160 PrintHeader ('G');\r
9071550e 161 return EFI_UNSUPPORTED;\r
162 }\r
163 \r
164 //\r
165 // Set the image subsystem type\r
166 //\r
167\r
168 Status = EfiLdrPeCoffSetImageType (Image, PeHdr.Pe32.OptionalHeader.Subsystem);\r
169 if (EFI_ERROR(Status)) {\r
3da85e63 170 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Subsystem type not known\n");\r
171 PrintString (PrintBuffer);\r
172 PrintHeader ('H');\r
9071550e 173 return Status;\r
174 }\r
175\r
176 //\r
177 // Verify machine type\r
178 //\r
179\r
180 Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine);\r
181 if (EFI_ERROR(Status)) {\r
3da85e63 182 AsciiSPrint (PrintBuffer, 256, "PeCoffLoadPeImage: Incorrect machine type\n");\r
183 PrintString (PrintBuffer);\r
184 PrintHeader ('I');\r
9071550e 185 return Status;\r
186 }\r
187\r
188 //\r
189 // Compute the amount of memory needed to load the image and \r
190 // allocate it. This will include all sections plus the codeview debug info.\r
191 // Since the codeview info is actually outside of the image, we calculate\r
192 // its size seperately and add it to the total.\r
193 //\r
194 // Memory starts off as data\r
195 //\r
196\r
197 CodeViewSize = 0;\r
198 CodeViewFileOffset = 0;\r
199 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
200 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
201 } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
202 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
203 } else {\r
204 return EFI_UNSUPPORTED;\r
205 }\r
206 for (DirCount = 0; \r
207 (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && (CodeViewSize == 0);\r
208 DirCount++) {\r
209 Status = EfiLdrPeCoffImageRead (\r
210 FHand, \r
211 DirectoryEntry->VirtualAddress + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),\r
212 sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),\r
213 &TempDebugEntry\r
214 );\r
215 if (!EFI_ERROR (Status)) {\r
216 if (TempDebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
217 CodeViewSize = TempDebugEntry.SizeOfData;\r
218 CodeViewFileOffset = TempDebugEntry.FileOffset;\r
219 }\r
220 }\r
221 }\r
222 \r
223 CodeViewOffset = PeHdr.Pe32.OptionalHeader.SizeOfImage + PeHdr.Pe32.OptionalHeader.SectionAlignment;\r
224 Image->NoPages = EFI_SIZE_TO_PAGES (CodeViewOffset + CodeViewSize);\r
225\r
226 //\r
227 // Compute the amount of memory needed to load the image and \r
228 // allocate it. Memory starts off as data\r
229 //\r
230\r
231 Image->ImageBasePage = (EFI_PHYSICAL_ADDRESS)FindSpace (Image->NoPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesCode, EFI_MEMORY_WB);\r
232 if (Image->ImageBasePage == 0) {\r
233 return EFI_OUT_OF_RESOURCES;\r
234 }\r
235\r
236 if (EFI_ERROR(Status)) {\r
3da85e63 237 PrintHeader ('J');\r
9071550e 238 return Status;\r
239 }\r
240\r
3da85e63 241 AsciiSPrint (PrintBuffer, 256, "LoadPe: new image base %lx\n", Image->ImageBasePage);\r
242 PrintString (PrintBuffer);\r
9071550e 243 Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageBasePage;\r
244 Image->Info.ImageSize = (Image->NoPages << EFI_PAGE_SHIFT) - 1;\r
245 Image->ImageBase = (UINT8 *)(UINTN)Image->ImageBasePage;\r
246 Image->ImageEof = Image->ImageBase + Image->Info.ImageSize;\r
247 Image->ImageAdjust = Image->ImageBase;\r
248\r
249 //\r
250 // Copy the Image header to the base location\r
251 //\r
252 Status = EfiLdrPeCoffImageRead (\r
253 FHand, \r
254 0, \r
255 PeHdr.Pe32.OptionalHeader.SizeOfHeaders, \r
256 Image->ImageBase\r
257 );\r
258\r
259 if (EFI_ERROR(Status)) {\r
3da85e63 260 PrintHeader ('K');\r
9071550e 261 return Status;\r
262 }\r
263\r
264 //\r
265 // Load each directory of the image into memory... \r
266 // Save the address of the Debug directory for later\r
267 //\r
268 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
269 NumberOfRvaAndSizes = PeHdr.Pe32.OptionalHeader.NumberOfRvaAndSizes;\r
270 DataDirectory = PeHdr.Pe32.OptionalHeader.DataDirectory;\r
271 } else {\r
272 NumberOfRvaAndSizes = PeHdr.Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;\r
273 DataDirectory = PeHdr.Pe32Plus.OptionalHeader.DataDirectory;\r
274 }\r
275 DebugEntry = NULL;\r
276 for (Index = 0; Index < NumberOfRvaAndSizes; Index++) {\r
277 if ((DataDirectory[Index].VirtualAddress != 0) && (DataDirectory[Index].Size != 0)) {\r
278 Status = EfiLdrPeCoffImageRead (\r
279 FHand,\r
280 DataDirectory[Index].VirtualAddress,\r
281 DataDirectory[Index].Size,\r
282 Image->ImageBase + DataDirectory[Index].VirtualAddress\r
283 );\r
284 if (EFI_ERROR(Status)) {\r
285 return Status;\r
286 }\r
287 if (Index == EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
288 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (Image->ImageBase + DataDirectory[Index].VirtualAddress);\r
289 }\r
290 }\r
291 }\r
292\r
293 //\r
294 // Load each section of the image\r
295 //\r
296\r
297 // BUGBUG: change this to use the in memory copy\r
298 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
299 OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32);\r
300 PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS32);\r
301 } else {\r
302 OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64);\r
303 PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS64);\r
304 }\r
305 FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
306 Image->ImageBase +\r
307 DosHdr.e_lfanew + \r
308 PeHeaderSize + \r
309 PeHdr.Pe32.FileHeader.SizeOfOptionalHeader - \r
310 OptionalHeaderSize\r
311 );\r
312\r
313 Section = FirstSection;\r
314 for (Index=0; Index < PeHdr.Pe32.FileHeader.NumberOfSections; Index += 1) {\r
315\r
316 //\r
317 // Compute sections address\r
318 //\r
319\r
320 Base = EfiLdrPeCoffImageAddress (Image, (UINTN)Section->VirtualAddress);\r
321 End = EfiLdrPeCoffImageAddress (Image, (UINTN)(Section->VirtualAddress + Section->Misc.VirtualSize));\r
322 \r
323 if (EFI_ERROR(Status) || !Base || !End) {\r
324// DEBUG((D_LOAD|D_ERROR, "LoadPe: Section %d was not loaded\n", Index));\r
3da85e63 325 PrintHeader ('L');\r
9071550e 326 return EFI_LOAD_ERROR;\r
327 }\r
328\r
329// DEBUG((D_LOAD, "LoadPe: Section %d, loaded at %x\n", Index, Base));\r
330\r
331 //\r
332 // Read the section\r
333 //\r
334 \r
335 if (Section->SizeOfRawData) {\r
336 Status = EfiLdrPeCoffImageRead (FHand, Section->PointerToRawData, Section->SizeOfRawData, Base);\r
337 if (EFI_ERROR(Status)) {\r
338PrintHeader ('M');\r
339 return Status;\r
340 }\r
341 }\r
342\r
343 //\r
344 // If raw size is less then virt size, zero fill the remaining\r
345 //\r
346\r
347 if (Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
348 ZeroMem (\r
349 Base + Section->SizeOfRawData, \r
350 Section->Misc.VirtualSize - Section->SizeOfRawData\r
351 );\r
352 }\r
353\r
354 //\r
355 // Next Section\r
356 //\r
357\r
358 Section += 1;\r
359 }\r
360\r
361 //\r
362 // Copy in CodeView information if it exists\r
363 //\r
364 if (CodeViewSize != 0) {\r
365 Status = EfiLdrPeCoffImageRead (FHand, CodeViewFileOffset, CodeViewSize, Image->ImageBase + CodeViewOffset);\r
366 DebugEntry->RVA = (UINT32) (CodeViewOffset);\r
367 }\r
368\r
369 //\r
370 // Apply relocations only if needed\r
371 //\r
372 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
373 ImageBase = (UINT64)PeHdr.Pe32.OptionalHeader.ImageBase;\r
374 } else {\r
375 ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;\r
376 }\r
377 if ((UINTN)(Image->ImageBase) != (UINTN) (ImageBase)) {\r
378 Status = EfiLdrPeCoffLoadPeRelocate (\r
379 Image,\r
380 &DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC],\r
381 (UINTN) Image->ImageBase - (UINTN)ImageBase,\r
382 NumberOfMemoryMapEntries,\r
383 EfiMemoryDescriptor\r
384 );\r
385\r
386 if (EFI_ERROR(Status)) {\r
3da85e63 387 PrintHeader ('N');\r
9071550e 388 return Status;\r
389 }\r
390 }\r
391\r
392 //\r
393 // Use exported EFI specific interface if present, else use the image's entry point\r
394 //\r
395 Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)\r
396 (EfiLdrPeCoffImageAddress(\r
397 Image, \r
398 PeHdr.Pe32.OptionalHeader.AddressOfEntryPoint\r
399 ));\r
400\r
401 return Status;\r
402}\r
403\r
9071550e 404EFI_STATUS\r
405EfiLdrPeCoffLoadPeRelocate (\r
406 IN EFILDR_LOADED_IMAGE *Image,\r
407 IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,\r
408 IN UINTN Adjust,\r
409 IN UINTN *NumberOfMemoryMapEntries,\r
410 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor\r
411 )\r
412{\r
413 EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
414 EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
415 UINT16 *Reloc;\r
416 UINT16 *RelocEnd;\r
417 UINT8 *Fixup;\r
418 UINT8 *FixupBase;\r
419 UINT16 *F16;\r
420 UINT32 *F32;\r
421 UINT64 *F64;\r
422 UINT8 *FixupData;\r
423 UINTN NoFixupPages;\r
424\r
425 //\r
426 // Find the relocation block\r
427 //\r
428\r
429 RelocBase = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress);\r
430 RelocBaseEnd = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);\r
431 if (!RelocBase || !RelocBaseEnd) {\r
432PrintHeader ('O');\r
433 return EFI_LOAD_ERROR;\r
434 }\r
435\r
436 NoFixupPages = EFI_SIZE_TO_PAGES(RelocDir->Size / sizeof(UINT16) * sizeof(UINTN));\r
437 Image->FixupData = (UINT8*) FindSpace (NoFixupPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);\r
438 if (Image->FixupData == 0) {\r
439 return EFI_OUT_OF_RESOURCES;\r
440 }\r
441\r
442 //\r
443 // Run the whole relocation block\r
444 //\r
445\r
446 FixupData = Image->FixupData;\r
447 while (RelocBase < RelocBaseEnd) {\r
448 \r
449 Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));\r
450 RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);\r
451 FixupBase = EfiLdrPeCoffImageAddress (Image, RelocBase->VirtualAddress);\r
452 if ((UINT8 *) RelocEnd < Image->ImageBase || (UINT8 *) RelocEnd > Image->ImageEof) {\r
453PrintHeader ('P');\r
454 return EFI_LOAD_ERROR;\r
455 }\r
456\r
457 //\r
458 // Run this relocation record\r
459 //\r
460\r
461 while (Reloc < RelocEnd) {\r
462\r
463 Fixup = FixupBase + (*Reloc & 0xFFF);\r
464 switch ((*Reloc) >> 12) {\r
465\r
466 case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
467 break;\r
468\r
469 case EFI_IMAGE_REL_BASED_HIGH:\r
470 F16 = (UINT16 *) Fixup;\r
471 *F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16));\r
472 if (FixupData != NULL) {\r
473 *(UINT16 *) FixupData = *F16;\r
474 FixupData = FixupData + sizeof(UINT16);\r
475 }\r
476 break;\r
477\r
478 case EFI_IMAGE_REL_BASED_LOW:\r
479 F16 = (UINT16 *) Fixup;\r
e188a609 480 *F16 = (UINT16) (*F16 + (UINT16) Adjust);\r
9071550e 481 if (FixupData != NULL) {\r
482 *(UINT16 *) FixupData = *F16;\r
483 FixupData = FixupData + sizeof(UINT16);\r
484 }\r
485 break;\r
486\r
487 case EFI_IMAGE_REL_BASED_HIGHLOW:\r
488 F32 = (UINT32 *) Fixup;\r
489 *F32 = *F32 + (UINT32) Adjust;\r
490 if (FixupData != NULL) {\r
491 FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));\r
492 *(UINT32 *) FixupData = *F32;\r
493 FixupData = FixupData + sizeof(UINT32);\r
494 }\r
495 break;\r
496\r
497 case EFI_IMAGE_REL_BASED_DIR64:\r
498 F64 = (UINT64 *) Fixup;\r
499 *F64 = *F64 + (UINT64) Adjust;\r
500 if (FixupData != NULL) {\r
501 FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64));\r
502 *(UINT64 *) FixupData = *F64;\r
503 FixupData = FixupData + sizeof(UINT64);\r
504 }\r
505 break;\r
506\r
507 case EFI_IMAGE_REL_BASED_HIGHADJ:\r
508 CpuDeadLoop(); // BUGBUG: not done\r
509 break;\r
510\r
511 default:\r
512// DEBUG((D_LOAD|D_ERROR, "PeRelocate: unknown fixed type\n"));\r
513PrintHeader ('Q');\r
514 CpuDeadLoop();\r
515 return EFI_LOAD_ERROR;\r
516 }\r
517\r
518 // Next reloc record\r
519 Reloc += 1;\r
520 }\r
521\r
522 // next reloc block\r
523 RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
524 }\r
525\r
526 //\r
527 // Add Fixup data to whole Image (assume Fixup data just below the image), so that there is no hole in the descriptor.\r
528 // Because only NoPages or ImageBasePage will be used in EfiLoader(), we update these 2 fields.\r
529 //\r
530 Image->NoPages += NoFixupPages;\r
531 Image->ImageBasePage -= (NoFixupPages << EFI_PAGE_SHIFT);\r
532\r
533 return EFI_SUCCESS;\r
534}\r
535\r
9071550e 536EFI_STATUS\r
537EfiLdrPeCoffImageRead (\r
538 IN VOID *FHand,\r
539 IN UINTN Offset,\r
540 IN OUT UINTN ReadSize,\r
541 OUT VOID *Buffer\r
542 )\r
543{\r
544 CopyMem (Buffer, (VOID *)((UINTN)FHand + Offset), ReadSize);\r
545\r
546 return EFI_SUCCESS;\r
547}\r
548\r
9071550e 549VOID *\r
550EfiLdrPeCoffImageAddress (\r
551 IN EFILDR_LOADED_IMAGE *Image,\r
552 IN UINTN Address\r
553 )\r
554{\r
555 UINT8 *FixedAddress;\r
556\r
557 FixedAddress = Image->ImageAdjust + Address;\r
558\r
559 if ((FixedAddress < Image->ImageBase) || (FixedAddress > Image->ImageEof)) {\r
560// DEBUG((D_LOAD|D_ERROR, "PeCoffImageAddress: pointer is outside of image\n"));\r
561 FixedAddress = NULL;\r
562 }\r
563\r
564// DEBUG((\r
565// D_LOAD,\r
566// "PeCoffImageAddress: ImageBase %x, ImageEof %x, Address %x, FixedAddress %x\n", \r
567// Image->ImageBase,\r
568// Image->ImageEof,\r
569// Address,\r
570// FixedAddress\r
571// ));\r
572 return FixedAddress;\r
573}\r
574\r
575\r
576EFI_STATUS\r
577EfiLdrPeCoffSetImageType (\r
578 IN OUT EFILDR_LOADED_IMAGE *Image,\r
579 IN UINTN ImageType\r
580 )\r
581{\r
582 EFI_MEMORY_TYPE CodeType;\r
583 EFI_MEMORY_TYPE DataType;\r
584\r
585 switch (ImageType) {\r
586 case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:\r
587 CodeType = EfiLoaderCode;\r
588 DataType = EfiLoaderData;\r
589 break;\r
590\r
591 case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:\r
592 CodeType = EfiBootServicesCode;\r
593 DataType = EfiBootServicesData;\r
594 break;\r
595\r
596 case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
597 CodeType = EfiRuntimeServicesCode;\r
598 DataType = EfiRuntimeServicesData;\r
599 break;\r
600\r
601 default:\r
602 return EFI_INVALID_PARAMETER;\r
603 }\r
604\r
605 Image->Type = ImageType;\r
606 Image->Info.ImageCodeType = CodeType; \r
607 Image->Info.ImageDataType = DataType;\r
608\r
609 return EFI_SUCCESS;\r
610}\r
611\r
612EFI_STATUS\r
613EfiLdrPeCoffCheckImageMachineType (\r
614 IN UINT16 MachineType\r
615 )\r
616{\r
617 EFI_STATUS Status;\r
618\r
619 Status = EFI_UNSUPPORTED;\r
620\r
72be1c7a 621#ifdef MDE_CPU_IA32\r
9071550e 622 if (MachineType == EFI_IMAGE_MACHINE_IA32) {\r
623 Status = EFI_SUCCESS;\r
624 }\r
625#endif\r
626\r
72be1c7a 627#ifdef MDE_CPU_X64\r
9071550e 628 if (MachineType == EFI_IMAGE_MACHINE_X64) {\r
629 Status = EFI_SUCCESS;\r
630 }\r
631#endif\r
632\r
9071550e 633 return Status;\r
634}\r
635\r