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