]> git.proxmox.com Git - mirror_edk2.git/blame - DuetPkg/EfiLdr/PeLoader.c
Add missing module for duet package.
[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
141\r
142 ZeroMem (&DosHdr, sizeof(DosHdr));\r
143 ZeroMem (&PeHdr, sizeof(PeHdr));\r
144\r
145 //\r
146 // Read image headers\r
147 //\r
148\r
149 EfiLdrPeCoffImageRead (FHand, 0, sizeof(DosHdr), &DosHdr);\r
150 if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
151// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Dos header signature not found\n"));\r
152PrintHeader ('F');\r
153 return EFI_UNSUPPORTED;\r
154 }\r
155\r
156 EfiLdrPeCoffImageRead (FHand, DosHdr.e_lfanew, sizeof(PeHdr), &PeHdr);\r
157\r
158 if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
159// DEBUG ((D_LOAD, "PeCoffLoadPeImage: PE image header signature not found\n"));\r
160PrintHeader ('G');\r
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
170// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Subsystem type not known\n"));\r
171PrintHeader ('H');\r
172 return Status;\r
173 }\r
174\r
175 //\r
176 // Verify machine type\r
177 //\r
178\r
179 Status = EfiLdrPeCoffCheckImageMachineType (PeHdr.Pe32.FileHeader.Machine);\r
180 if (EFI_ERROR(Status)) {\r
181// DEBUG ((D_LOAD, "PeCoffLoadPeImage: Incorrect machine type\n"));\r
182PrintHeader ('I');\r
183 return Status;\r
184 }\r
185\r
186 //\r
187 // Compute the amount of memory needed to load the image and \r
188 // allocate it. This will include all sections plus the codeview debug info.\r
189 // Since the codeview info is actually outside of the image, we calculate\r
190 // its size seperately and add it to the total.\r
191 //\r
192 // Memory starts off as data\r
193 //\r
194\r
195 CodeViewSize = 0;\r
196 CodeViewFileOffset = 0;\r
197 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
198 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
199 } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
200 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(PeHdr.Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
201 } else {\r
202 return EFI_UNSUPPORTED;\r
203 }\r
204 for (DirCount = 0; \r
205 (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && (CodeViewSize == 0);\r
206 DirCount++) {\r
207 Status = EfiLdrPeCoffImageRead (\r
208 FHand, \r
209 DirectoryEntry->VirtualAddress + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),\r
210 sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY),\r
211 &TempDebugEntry\r
212 );\r
213 if (!EFI_ERROR (Status)) {\r
214 if (TempDebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
215 CodeViewSize = TempDebugEntry.SizeOfData;\r
216 CodeViewFileOffset = TempDebugEntry.FileOffset;\r
217 }\r
218 }\r
219 }\r
220 \r
221 CodeViewOffset = PeHdr.Pe32.OptionalHeader.SizeOfImage + PeHdr.Pe32.OptionalHeader.SectionAlignment;\r
222 Image->NoPages = EFI_SIZE_TO_PAGES (CodeViewOffset + CodeViewSize);\r
223\r
224 //\r
225 // Compute the amount of memory needed to load the image and \r
226 // allocate it. Memory starts off as data\r
227 //\r
228\r
229 Image->ImageBasePage = (EFI_PHYSICAL_ADDRESS)FindSpace (Image->NoPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesCode, EFI_MEMORY_WB);\r
230 if (Image->ImageBasePage == 0) {\r
231 return EFI_OUT_OF_RESOURCES;\r
232 }\r
233\r
234 if (EFI_ERROR(Status)) {\r
235PrintHeader ('J');\r
236 return Status;\r
237 }\r
238\r
239// DEBUG((D_LOAD, "LoadPe: new image base %lx\n", Image->ImageBasePage));\r
240 Image->Info.ImageBase = (VOID *)(UINTN)Image->ImageBasePage;\r
241 Image->Info.ImageSize = (Image->NoPages << EFI_PAGE_SHIFT) - 1;\r
242 Image->ImageBase = (UINT8 *)(UINTN)Image->ImageBasePage;\r
243 Image->ImageEof = Image->ImageBase + Image->Info.ImageSize;\r
244 Image->ImageAdjust = Image->ImageBase;\r
245\r
246 //\r
247 // Copy the Image header to the base location\r
248 //\r
249 Status = EfiLdrPeCoffImageRead (\r
250 FHand, \r
251 0, \r
252 PeHdr.Pe32.OptionalHeader.SizeOfHeaders, \r
253 Image->ImageBase\r
254 );\r
255\r
256 if (EFI_ERROR(Status)) {\r
257PrintHeader ('K');\r
258 return Status;\r
259 }\r
260\r
261 //\r
262 // Load each directory of the image into memory... \r
263 // Save the address of the Debug directory for later\r
264 //\r
265 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
266 NumberOfRvaAndSizes = PeHdr.Pe32.OptionalHeader.NumberOfRvaAndSizes;\r
267 DataDirectory = PeHdr.Pe32.OptionalHeader.DataDirectory;\r
268 } else {\r
269 NumberOfRvaAndSizes = PeHdr.Pe32Plus.OptionalHeader.NumberOfRvaAndSizes;\r
270 DataDirectory = PeHdr.Pe32Plus.OptionalHeader.DataDirectory;\r
271 }\r
272 DebugEntry = NULL;\r
273 for (Index = 0; Index < NumberOfRvaAndSizes; Index++) {\r
274 if ((DataDirectory[Index].VirtualAddress != 0) && (DataDirectory[Index].Size != 0)) {\r
275 Status = EfiLdrPeCoffImageRead (\r
276 FHand,\r
277 DataDirectory[Index].VirtualAddress,\r
278 DataDirectory[Index].Size,\r
279 Image->ImageBase + DataDirectory[Index].VirtualAddress\r
280 );\r
281 if (EFI_ERROR(Status)) {\r
282 return Status;\r
283 }\r
284 if (Index == EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
285 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (Image->ImageBase + DataDirectory[Index].VirtualAddress);\r
286 }\r
287 }\r
288 }\r
289\r
290 //\r
291 // Load each section of the image\r
292 //\r
293\r
294 // BUGBUG: change this to use the in memory copy\r
295 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
296 OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER32);\r
297 PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS32);\r
298 } else {\r
299 OptionalHeaderSize = sizeof(EFI_IMAGE_OPTIONAL_HEADER64);\r
300 PeHeaderSize = sizeof(EFI_IMAGE_NT_HEADERS64);\r
301 }\r
302 FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
303 Image->ImageBase +\r
304 DosHdr.e_lfanew + \r
305 PeHeaderSize + \r
306 PeHdr.Pe32.FileHeader.SizeOfOptionalHeader - \r
307 OptionalHeaderSize\r
308 );\r
309\r
310 Section = FirstSection;\r
311 for (Index=0; Index < PeHdr.Pe32.FileHeader.NumberOfSections; Index += 1) {\r
312\r
313 //\r
314 // Compute sections address\r
315 //\r
316\r
317 Base = EfiLdrPeCoffImageAddress (Image, (UINTN)Section->VirtualAddress);\r
318 End = EfiLdrPeCoffImageAddress (Image, (UINTN)(Section->VirtualAddress + Section->Misc.VirtualSize));\r
319 \r
320 if (EFI_ERROR(Status) || !Base || !End) {\r
321// DEBUG((D_LOAD|D_ERROR, "LoadPe: Section %d was not loaded\n", Index));\r
322PrintHeader ('L');\r
323 return EFI_LOAD_ERROR;\r
324 }\r
325\r
326// DEBUG((D_LOAD, "LoadPe: Section %d, loaded at %x\n", Index, Base));\r
327\r
328 //\r
329 // Read the section\r
330 //\r
331 \r
332 if (Section->SizeOfRawData) {\r
333 Status = EfiLdrPeCoffImageRead (FHand, Section->PointerToRawData, Section->SizeOfRawData, Base);\r
334 if (EFI_ERROR(Status)) {\r
335PrintHeader ('M');\r
336 return Status;\r
337 }\r
338 }\r
339\r
340 //\r
341 // If raw size is less then virt size, zero fill the remaining\r
342 //\r
343\r
344 if (Section->SizeOfRawData < Section->Misc.VirtualSize) {\r
345 ZeroMem (\r
346 Base + Section->SizeOfRawData, \r
347 Section->Misc.VirtualSize - Section->SizeOfRawData\r
348 );\r
349 }\r
350\r
351 //\r
352 // Next Section\r
353 //\r
354\r
355 Section += 1;\r
356 }\r
357\r
358 //\r
359 // Copy in CodeView information if it exists\r
360 //\r
361 if (CodeViewSize != 0) {\r
362 Status = EfiLdrPeCoffImageRead (FHand, CodeViewFileOffset, CodeViewSize, Image->ImageBase + CodeViewOffset);\r
363 DebugEntry->RVA = (UINT32) (CodeViewOffset);\r
364 }\r
365\r
366 //\r
367 // Apply relocations only if needed\r
368 //\r
369 if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
370 ImageBase = (UINT64)PeHdr.Pe32.OptionalHeader.ImageBase;\r
371 } else {\r
372 ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;\r
373 }\r
374 if ((UINTN)(Image->ImageBase) != (UINTN) (ImageBase)) {\r
375 Status = EfiLdrPeCoffLoadPeRelocate (\r
376 Image,\r
377 &DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC],\r
378 (UINTN) Image->ImageBase - (UINTN)ImageBase,\r
379 NumberOfMemoryMapEntries,\r
380 EfiMemoryDescriptor\r
381 );\r
382\r
383 if (EFI_ERROR(Status)) {\r
384PrintHeader ('N');\r
385 return Status;\r
386 }\r
387 }\r
388\r
389 //\r
390 // Use exported EFI specific interface if present, else use the image's entry point\r
391 //\r
392 Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)\r
393 (EfiLdrPeCoffImageAddress(\r
394 Image, \r
395 PeHdr.Pe32.OptionalHeader.AddressOfEntryPoint\r
396 ));\r
397\r
398 return Status;\r
399}\r
400\r
401STATIC\r
402EFI_STATUS\r
403EfiLdrPeCoffLoadPeRelocate (\r
404 IN EFILDR_LOADED_IMAGE *Image,\r
405 IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,\r
406 IN UINTN Adjust,\r
407 IN UINTN *NumberOfMemoryMapEntries,\r
408 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor\r
409 )\r
410{\r
411 EFI_IMAGE_BASE_RELOCATION *RelocBase;\r
412 EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;\r
413 UINT16 *Reloc;\r
414 UINT16 *RelocEnd;\r
415 UINT8 *Fixup;\r
416 UINT8 *FixupBase;\r
417 UINT16 *F16;\r
418 UINT32 *F32;\r
419 UINT64 *F64;\r
420 UINT8 *FixupData;\r
421 UINTN NoFixupPages;\r
422\r
423 //\r
424 // Find the relocation block\r
425 //\r
426\r
427 RelocBase = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress);\r
428 RelocBaseEnd = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);\r
429 if (!RelocBase || !RelocBaseEnd) {\r
430PrintHeader ('O');\r
431 return EFI_LOAD_ERROR;\r
432 }\r
433\r
434 NoFixupPages = EFI_SIZE_TO_PAGES(RelocDir->Size / sizeof(UINT16) * sizeof(UINTN));\r
435 Image->FixupData = (UINT8*) FindSpace (NoFixupPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);\r
436 if (Image->FixupData == 0) {\r
437 return EFI_OUT_OF_RESOURCES;\r
438 }\r
439\r
440 //\r
441 // Run the whole relocation block\r
442 //\r
443\r
444 FixupData = Image->FixupData;\r
445 while (RelocBase < RelocBaseEnd) {\r
446 \r
447 Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));\r
448 RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);\r
449 FixupBase = EfiLdrPeCoffImageAddress (Image, RelocBase->VirtualAddress);\r
450 if ((UINT8 *) RelocEnd < Image->ImageBase || (UINT8 *) RelocEnd > Image->ImageEof) {\r
451PrintHeader ('P');\r
452 return EFI_LOAD_ERROR;\r
453 }\r
454\r
455 //\r
456 // Run this relocation record\r
457 //\r
458\r
459 while (Reloc < RelocEnd) {\r
460\r
461 Fixup = FixupBase + (*Reloc & 0xFFF);\r
462 switch ((*Reloc) >> 12) {\r
463\r
464 case EFI_IMAGE_REL_BASED_ABSOLUTE:\r
465 break;\r
466\r
467 case EFI_IMAGE_REL_BASED_HIGH:\r
468 F16 = (UINT16 *) Fixup;\r
469 *F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16));\r
470 if (FixupData != NULL) {\r
471 *(UINT16 *) FixupData = *F16;\r
472 FixupData = FixupData + sizeof(UINT16);\r
473 }\r
474 break;\r
475\r
476 case EFI_IMAGE_REL_BASED_LOW:\r
477 F16 = (UINT16 *) Fixup;\r
478 *F16 = *F16 + (UINT16) Adjust;\r
479 if (FixupData != NULL) {\r
480 *(UINT16 *) FixupData = *F16;\r
481 FixupData = FixupData + sizeof(UINT16);\r
482 }\r
483 break;\r
484\r
485 case EFI_IMAGE_REL_BASED_HIGHLOW:\r
486 F32 = (UINT32 *) Fixup;\r
487 *F32 = *F32 + (UINT32) Adjust;\r
488 if (FixupData != NULL) {\r
489 FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));\r
490 *(UINT32 *) FixupData = *F32;\r
491 FixupData = FixupData + sizeof(UINT32);\r
492 }\r
493 break;\r
494\r
495 case EFI_IMAGE_REL_BASED_DIR64:\r
496 F64 = (UINT64 *) Fixup;\r
497 *F64 = *F64 + (UINT64) Adjust;\r
498 if (FixupData != NULL) {\r
499 FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64));\r
500 *(UINT64 *) FixupData = *F64;\r
501 FixupData = FixupData + sizeof(UINT64);\r
502 }\r
503 break;\r
504\r
505 case EFI_IMAGE_REL_BASED_HIGHADJ:\r
506 CpuDeadLoop(); // BUGBUG: not done\r
507 break;\r
508\r
509 default:\r
510// DEBUG((D_LOAD|D_ERROR, "PeRelocate: unknown fixed type\n"));\r
511PrintHeader ('Q');\r
512 CpuDeadLoop();\r
513 return EFI_LOAD_ERROR;\r
514 }\r
515\r
516 // Next reloc record\r
517 Reloc += 1;\r
518 }\r
519\r
520 // next reloc block\r
521 RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;\r
522 }\r
523\r
524 //\r
525 // Add Fixup data to whole Image (assume Fixup data just below the image), so that there is no hole in the descriptor.\r
526 // Because only NoPages or ImageBasePage will be used in EfiLoader(), we update these 2 fields.\r
527 //\r
528 Image->NoPages += NoFixupPages;\r
529 Image->ImageBasePage -= (NoFixupPages << EFI_PAGE_SHIFT);\r
530\r
531 return EFI_SUCCESS;\r
532}\r
533\r
534STATIC\r
535EFI_STATUS\r
536EfiLdrPeCoffImageRead (\r
537 IN VOID *FHand,\r
538 IN UINTN Offset,\r
539 IN OUT UINTN ReadSize,\r
540 OUT VOID *Buffer\r
541 )\r
542{\r
543 CopyMem (Buffer, (VOID *)((UINTN)FHand + Offset), ReadSize);\r
544\r
545 return EFI_SUCCESS;\r
546}\r
547\r
548STATIC\r
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
621#if EFI32\r
622 if (MachineType == EFI_IMAGE_MACHINE_IA32) {\r
623 Status = EFI_SUCCESS;\r
624 }\r
625#endif\r
626\r
627#if EFIX64\r
628 if (MachineType == EFI_IMAGE_MACHINE_X64) {\r
629 Status = EFI_SUCCESS;\r
630 }\r
631#endif\r
632\r
633#if EFI64\r
634 if (MachineType == EFI_IMAGE_MACHINE_IA64) {\r
635 Status = EFI_SUCCESS;\r
636 }\r
637#endif\r
638\r
639 return Status;\r
640}\r
641\r