peloader.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 594 行 · 第 1/2 页
C
594 行
//
// If raw size is less then virt size, zero fill the remaining
//
if (Section->SizeOfRawData < Section->Misc.VirtualSize) {
EfiCommonLibZeroMem (
Base + Section->SizeOfRawData,
Section->Misc.VirtualSize - Section->SizeOfRawData
);
}
//
// Next Section
//
Section += 1;
}
//
// Copy in CodeView information if it exists
//
if (CodeViewSize != 0) {
Status = EfiLdrPeCoffImageRead (FHand, CodeViewFileOffset, CodeViewSize, Image->ImageBase + CodeViewOffset);
DebugEntry->RVA = (UINT32) (CodeViewOffset);
}
//
// Apply relocations only if needed
//
if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
ImageBase = (UINT64)PeHdr.Pe32.OptionalHeader.ImageBase;
} else {
ImageBase = PeHdr.Pe32Plus.OptionalHeader.ImageBase;
}
if ((UINTN)(Image->ImageBase) != (UINTN) (ImageBase)) {
Status = EfiLdrPeCoffLoadPeRelocate (
Image,
&DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC],
(UINTN) Image->ImageBase - (UINTN)ImageBase,
NumberOfMemoryMapEntries,
EfiMemoryDescriptor
);
if (EFI_ERROR(Status)) {
PrintHeader ('N');
return Status;
}
}
//
// Use exported EFI specific interface if present, else use the image's entry point
//
Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)
(EfiLdrPeCoffImageAddress(
Image,
PeHdr.Pe32.OptionalHeader.AddressOfEntryPoint
));
return Status;
}
STATIC
EFI_STATUS
EfiLdrPeCoffLoadPeRelocate (
IN EFILDR_LOADED_IMAGE *Image,
IN EFI_IMAGE_DATA_DIRECTORY *RelocDir,
IN UINTN Adjust,
IN UINTN *NumberOfMemoryMapEntries,
IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor
)
{
EFI_IMAGE_BASE_RELOCATION *RelocBase;
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
UINT16 *Reloc;
UINT16 *RelocEnd;
UINT8 *Fixup;
UINT8 *FixupBase;
UINT16 *F16;
UINT32 *F32;
UINT64 *F64;
UINT8 *FixupData;
UINTN NoFixupPages;
//
// Find the relocation block
//
RelocBase = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress);
RelocBaseEnd = EfiLdrPeCoffImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);
if (!RelocBase || !RelocBaseEnd) {
PrintHeader ('O');
return EFI_LOAD_ERROR;
}
NoFixupPages = EFI_SIZE_TO_PAGES(RelocDir->Size / sizeof(UINT16) * sizeof(UINTN));
Image->FixupData = (UINT8*) FindSpace (NoFixupPages, NumberOfMemoryMapEntries, EfiMemoryDescriptor, EfiRuntimeServicesData, EFI_MEMORY_WB);
if (Image->FixupData == 0) {
return EFI_OUT_OF_RESOURCES;
}
//
// Run the whole relocation block
//
FixupData = Image->FixupData;
while (RelocBase < RelocBaseEnd) {
Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof(EFI_IMAGE_BASE_RELOCATION));
RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);
FixupBase = EfiLdrPeCoffImageAddress (Image, RelocBase->VirtualAddress);
if ((UINT8 *) RelocEnd < Image->ImageBase || (UINT8 *) RelocEnd > Image->ImageEof) {
PrintHeader ('P');
return EFI_LOAD_ERROR;
}
//
// Run this relocation record
//
while (Reloc < RelocEnd) {
Fixup = FixupBase + (*Reloc & 0xFFF);
switch ((*Reloc) >> 12) {
case EFI_IMAGE_REL_BASED_ABSOLUTE:
break;
case EFI_IMAGE_REL_BASED_HIGH:
F16 = (UINT16 *) Fixup;
*F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16));
if (FixupData != NULL) {
*(UINT16 *) FixupData = *F16;
FixupData = FixupData + sizeof(UINT16);
}
break;
case EFI_IMAGE_REL_BASED_LOW:
F16 = (UINT16 *) Fixup;
*F16 = *F16 + (UINT16) Adjust;
if (FixupData != NULL) {
*(UINT16 *) FixupData = *F16;
FixupData = FixupData + sizeof(UINT16);
}
break;
case EFI_IMAGE_REL_BASED_HIGHLOW:
F32 = (UINT32 *) Fixup;
*F32 = *F32 + (UINT32) Adjust;
if (FixupData != NULL) {
FixupData = ALIGN_POINTER(FixupData, sizeof(UINT32));
*(UINT32 *) FixupData = *F32;
FixupData = FixupData + sizeof(UINT32);
}
break;
case EFI_IMAGE_REL_BASED_DIR64:
F64 = (UINT64 *) Fixup;
*F64 = *F64 + (UINT64) Adjust;
if (FixupData != NULL) {
FixupData = ALIGN_POINTER(FixupData, sizeof(UINT64));
*(UINT64 *) FixupData = *F64;
FixupData = FixupData + sizeof(UINT64);
}
break;
case EFI_IMAGE_REL_BASED_HIGHADJ:
EFI_DEADLOOP(); // BUGBUG: not done
break;
default:
// DEBUG((D_LOAD|D_ERROR, "PeRelocate: unknown fixed type\n"));
PrintHeader ('Q');
EFI_DEADLOOP();
return EFI_LOAD_ERROR;
}
// Next reloc record
Reloc += 1;
}
// next reloc block
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
EfiLdrPeCoffImageRead (
IN VOID *FHand,
IN UINTN Offset,
IN OUT UINTN ReadSize,
OUT VOID *Buffer
)
{
EfiCommonLibCopyMem (Buffer, (VOID *)((UINTN)FHand + Offset), ReadSize);
return EFI_SUCCESS;
}
STATIC
VOID *
EfiLdrPeCoffImageAddress (
IN EFILDR_LOADED_IMAGE *Image,
IN UINTN Address
)
{
UINT8 *FixedAddress;
FixedAddress = Image->ImageAdjust + Address;
if ((FixedAddress < Image->ImageBase) || (FixedAddress > Image->ImageEof)) {
// DEBUG((D_LOAD|D_ERROR, "PeCoffImageAddress: pointer is outside of image\n"));
FixedAddress = NULL;
}
// DEBUG((
// D_LOAD,
// "PeCoffImageAddress: ImageBase %x, ImageEof %x, Address %x, FixedAddress %x\n",
// Image->ImageBase,
// Image->ImageEof,
// Address,
// FixedAddress
// ));
return FixedAddress;
}
EFI_STATUS
EfiLdrPeCoffSetImageType (
IN OUT EFILDR_LOADED_IMAGE *Image,
IN UINTN ImageType
)
{
EFI_MEMORY_TYPE CodeType;
EFI_MEMORY_TYPE DataType;
switch (ImageType) {
case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
CodeType = EfiLoaderCode;
DataType = EfiLoaderData;
break;
case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
CodeType = EfiBootServicesCode;
DataType = EfiBootServicesData;
break;
case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
CodeType = EfiRuntimeServicesCode;
DataType = EfiRuntimeServicesData;
break;
default:
return EFI_INVALID_PARAMETER;
}
Image->Type = ImageType;
Image->Info.ImageCodeType = CodeType;
Image->Info.ImageDataType = DataType;
return EFI_SUCCESS;
}
EFI_STATUS
EfiLdrPeCoffCheckImageMachineType (
IN UINT16 MachineType
)
{
EFI_STATUS Status;
Status = EFI_UNSUPPORTED;
#if EFI32
if (MachineType == EFI_IMAGE_MACHINE_IA32) {
Status = EFI_SUCCESS;
}
#endif
#if EFIX64
if (MachineType == EFI_IMAGE_MACHINE_X64) {
Status = EFI_SUCCESS;
}
#endif
#if EFI64
if (MachineType == EFI_IMAGE_MACHINE_IA64) {
Status = EFI_SUCCESS;
}
#endif
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?