diff --git a/BaseTools/ImageTool/BinEmit.c b/BaseTools/ImageTool/BinEmit.c index 51fbb6f5a7..828c357a7a 100644 --- a/BaseTools/ImageTool/BinEmit.c +++ b/BaseTools/ImageTool/BinEmit.c @@ -5,6 +5,9 @@ #include "ImageTool.h" +#include +#include + static EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY * CreateEntry ( diff --git a/BaseTools/ImageTool/ElfScan.c b/BaseTools/ImageTool/ElfScan.c index ca2a1010b2..60fd9184b5 100644 --- a/BaseTools/ImageTool/ElfScan.c +++ b/BaseTools/ImageTool/ElfScan.c @@ -52,13 +52,6 @@ typedef struct { bool HasPieRelocs; } tool_elf_scan_context; -#if defined (_MSC_EXTENSIONS) -#define EFI_IMAGE_MACHINE_IA32 0x014C -#define EFI_IMAGE_MACHINE_X64 0x8664 -#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2 -#define EFI_IMAGE_MACHINE_AARCH64 0xAA64 -#endif - #define GetShrbyIndex ELF_SUFFIX(GetShrbyIndex) static @@ -687,17 +680,17 @@ ScanElf ( switch (Ehdr->e_machine) { #if ELF_ARCH == 64 case EM_X86_64: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_X64; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_X64; break; case EM_AARCH64: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_AARCH64; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_ARM64; break; #elif ELF_ARCH == 32 case EM_386: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_IA32; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_I386; break; case EM_ARM: - ImageInfo->HeaderInfo.Machine = EFI_IMAGE_MACHINE_ARMTHUMB_MIXED; + ImageInfo->HeaderInfo.Machine = IMAGE_FILE_MACHINE_ARMTHUMB_MIXED; break; #endif default: diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c deleted file mode 100644 index c38180af69..0000000000 --- a/BaseTools/Source/C/Common/BasePeCoff.c +++ /dev/null @@ -1,1417 +0,0 @@ -/** @file - - Functions to get info and load PE/COFF image. - -Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
-Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
-Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include "PeCoffLib.h" - -typedef union { - VOID *Header; - EFI_IMAGE_OPTIONAL_HEADER32 *Optional32; - EFI_IMAGE_OPTIONAL_HEADER64 *Optional64; -} EFI_IMAGE_OPTIONAL_HEADER_POINTER; - -STATIC -RETURN_STATUS -PeCoffLoaderGetPeHeader ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr, - OUT EFI_TE_IMAGE_HEADER **TeHdr - ); - -STATIC -RETURN_STATUS -PeCoffLoaderCheckImageType ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr, - IN EFI_TE_IMAGE_HEADER *TeHdr - ); - -STATIC -VOID * -PeCoffLoaderImageAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN UINTN Address - ); - -RETURN_STATUS -PeCoffLoaderRelocateIa32Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - - -RETURN_STATUS -PeCoffLoaderRelocateArmImage ( - IN UINT16 **Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - -RETURN_STATUS -PeCoffLoaderRelocateRiscVImage ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - -RETURN_STATUS -PeCoffLoaderRelocateLoongArch64Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ); - -/** - Retrieves the PE or TE Header from a PE/COFF or TE image - - @param ImageContext The context of the image being loaded - @param PeHdr The buffer in which to return the PE header - @param TeHdr The buffer in which to return the TE header - - @return RETURN_SUCCESS if the PE or TE Header is read, - Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function. -**/ -STATIC -RETURN_STATUS -PeCoffLoaderGetPeHeader ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - OUT EFI_IMAGE_OPTIONAL_HEADER_UNION **PeHdr, - OUT EFI_TE_IMAGE_HEADER **TeHdr - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_DOS_HEADER DosHdr; - UINTN Size; - - ImageContext->IsTeImage = FALSE; - // - // Read the DOS image headers - // - Size = sizeof (EFI_IMAGE_DOS_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &Size, - &DosHdr - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - ImageContext->PeCoffHeaderOffset = 0; - if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header - // - ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew; - } - // - // Get the PE/COFF Header pointer - // - *PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN)ImageContext->Handle + ImageContext->PeCoffHeaderOffset); - if ((*PeHdr)->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - // - // Check the PE/COFF Header Signature. If not, then try to get a TE header - // - *TeHdr = (EFI_TE_IMAGE_HEADER *)*PeHdr; - if ((*TeHdr)->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) { - return RETURN_UNSUPPORTED; - } - ImageContext->IsTeImage = TRUE; - } - - return RETURN_SUCCESS; -} - -/** - Checks the PE or TE header of a PE/COFF or TE image to determine if it supported - - @param ImageContext The context of the image being loaded - @param PeHdr The buffer in which to return the PE header - @param TeHdr The buffer in which to return the TE header - - @retval RETURN_SUCCESS if the PE/COFF or TE image is supported - @retval RETURN_UNSUPPORTED of the PE/COFF or TE image is not supported. - -**/ -STATIC -RETURN_STATUS -PeCoffLoaderCheckImageType ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr, - IN EFI_TE_IMAGE_HEADER *TeHdr - ) -{ - // - // See if the machine type is supported. - // We support a native machine type (IA-32/Itanium-based) - // - if (ImageContext->IsTeImage == FALSE) { - ImageContext->Machine = PeHdr->Pe32.FileHeader.Machine; - } else { - ImageContext->Machine = TeHdr->Machine; - } - - if (ImageContext->Machine != IMAGE_FILE_MACHINE_I386 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_X64 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_ARMTHUMB_MIXED && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_EBC && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_ARM64 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_RISCV64 && \ - ImageContext->Machine != IMAGE_FILE_MACHINE_LOONGARCH64) { - // - // unsupported PeImage machine type - // - return RETURN_UNSUPPORTED; - } - - // - // See if the image type is supported. We support EFI Applications, - // EFI Boot Service Drivers, EFI Runtime Drivers and EFI SAL Drivers. - // - if (ImageContext->IsTeImage == FALSE) { - ImageContext->ImageType = PeHdr->Pe32.OptionalHeader.Subsystem; - } else { - ImageContext->ImageType = (UINT16) (TeHdr->Subsystem); - } - - if (ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \ - ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER && \ - ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && \ - ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) { - // - // unsupported PeImage subsystem type - // - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} - -/** - Retrieves information on a PE/COFF image - - @param This Calling context - @param ImageContext The context of the image being loaded - - @retval RETURN_SUCCESS The information on the PE/COFF image was collected. - @retval RETURN_INVALID_PARAMETER ImageContext is NULL. - @retval RETURN_UNSUPPORTED The PE/COFF image is not supported. - @retval Otherwise The error status from reading the PE/COFF image using the - ImageContext->ImageRead() function - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderGetImageInfo ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry; - UINTN Size; - UINTN Index; - UINTN DebugDirectoryEntryRva; - UINTN DebugDirectoryEntryFileOffset; - UINTN SectionHeaderOffset; - EFI_IMAGE_SECTION_HEADER SectionHeader; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry; - EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader; - - PeHdr = NULL; - TeHdr = NULL; - DebugDirectoryEntry = NULL; - DebugDirectoryEntryRva = 0; - - if (NULL == ImageContext) { - return RETURN_INVALID_PARAMETER; - } - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - Status = PeCoffLoaderGetPeHeader (ImageContext, &PeHdr, &TeHdr); - if (RETURN_ERROR (Status)) { - return Status; - } - - // - // Verify machine type - // - Status = PeCoffLoaderCheckImageType (ImageContext, PeHdr, TeHdr); - if (RETURN_ERROR (Status)) { - return Status; - } - OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader); - - // - // Retrieve the base address of the image - // - if (!(ImageContext->IsTeImage)) { - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional32->ImageBase; - } else { - ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional64->ImageBase; - } - } else { - ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr->ImageBase + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); - } - // - // Initialize the alternate destination address to 0 indicating that it - // should not be used. - // - ImageContext->DestinationAddress = 0; - - // - // Initialize the codeview pointer. - // - ImageContext->CodeView = NULL; - ImageContext->PdbPointer = NULL; - - // - // Three cases with regards to relocations: - // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable - // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable - // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but - // has no base relocs to apply - // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid. - // - // Look at the file header to determine if relocations have been stripped, and - // save this info in the image context for later use. - // - if ((!(ImageContext->IsTeImage)) && ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) { - ImageContext->RelocationsStripped = TRUE; - } else if ((ImageContext->IsTeImage) && (TeHdr->DataDirectory[0].Size == 0) && (TeHdr->DataDirectory[0].VirtualAddress == 0)) { - ImageContext->RelocationsStripped = TRUE; - } else { - ImageContext->RelocationsStripped = FALSE; - } - - if (!(ImageContext->IsTeImage)) { - - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImageContext->ImageSize = (UINT64) OptionHeader.Optional32->SizeOfImage; - ImageContext->SectionAlignment = OptionHeader.Optional32->SectionAlignment; - ImageContext->SizeOfHeaders = OptionHeader.Optional32->SizeOfHeaders; - - // - // Modify ImageSize to contain .PDB file name if required and initialize - // PdbRVA field... - // - if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - } - } else { - ImageContext->ImageSize = (UINT64) OptionHeader.Optional64->SizeOfImage; - ImageContext->SectionAlignment = OptionHeader.Optional64->SectionAlignment; - ImageContext->SizeOfHeaders = OptionHeader.Optional64->SizeOfHeaders; - - // - // Modify ImageSize to contain .PDB file name if required and initialize - // PdbRVA field... - // - if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) { - DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - } - } - - if (DebugDirectoryEntryRva != 0) { - // - // Determine the file offset of the debug directory... This means we walk - // the sections to find which section contains the RVA of the debug - // directory - // - DebugDirectoryEntryFileOffset = 0; - - SectionHeaderOffset = (UINTN)( - ImageContext->PeCoffHeaderOffset + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - PeHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && - DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = - DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData; - break; - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (DebugDirectoryEntryFileOffset != 0) { - for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) { - // - // Read next debug directory entry - // - Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugDirectoryEntryFileOffset + Index, - &Size, - &DebugEntry - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index); - if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) { - ImageContext->ImageSize += DebugEntry.SizeOfData; - } - - return RETURN_SUCCESS; - } - } - } - } - } else { - ImageContext->ImageSize = 0; - ImageContext->SectionAlignment = 4096; - ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr->BaseOfCode - (UINTN) TeHdr->StrippedSize; - - DebugDirectoryEntry = &TeHdr->DataDirectory[1]; - DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress; - SectionHeaderOffset = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER)); - - DebugDirectoryEntryFileOffset = 0; - - for (Index = 0; Index < TeHdr->NumberOfSections;) { - // - // Read section header from file - // - Size = sizeof (EFI_IMAGE_SECTION_HEADER); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - SectionHeaderOffset, - &Size, - &SectionHeader - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress && - DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) { - DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - - SectionHeader.VirtualAddress + - SectionHeader.PointerToRawData + - sizeof (EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize; - - // - // File offset of the debug directory was found, if this is not the last - // section, then skip to the last section for calculating the image size. - // - if (Index < (UINTN) TeHdr->NumberOfSections - 1) { - SectionHeaderOffset += (TeHdr->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER); - Index = TeHdr->NumberOfSections - 1; - continue; - } - } - - // - // In Te image header there is not a field to describe the ImageSize. - // Actually, the ImageSize equals the RVA plus the VirtualSize of - // the last section mapped into memory (Must be rounded up to - // a multiple of Section Alignment). Per the PE/COFF specification, the - // section headers in the Section Table must appear in order of the RVA - // values for the corresponding sections. So the ImageSize can be determined - // by the RVA and the VirtualSize of the last section header in the - // Section Table. - // - if ((++Index) == (UINTN) TeHdr->NumberOfSections) { - ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize + - ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1); - } - - SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER); - } - - if (DebugDirectoryEntryFileOffset != 0) { - for (Index = 0; Index < DebugDirectoryEntry->Size; Index += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) { - // - // Read next debug directory entry - // - Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugDirectoryEntryFileOffset, - &Size, - &DebugEntry - ); - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - - if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) { - ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index); - return RETURN_SUCCESS; - } - } - } - } - - return RETURN_SUCCESS; -} - -/** - Converts an image address to the loaded address - - @param ImageContext The context of the image being loaded - @param Address The address to be converted to the loaded address - - @return NULL if the address can not be converted, otherwise, the converted address - ---*/ -STATIC -VOID * -PeCoffLoaderImageAddress ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, - IN UINTN Address - ) -{ - if (Address >= ImageContext->ImageSize) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; - return NULL; - } - - return (UINT8 *) ((UINTN) ImageContext->ImageAddress + Address); -} - -/** - Relocates a PE/COFF image in memory - - @param This Calling context - @param ImageContext Contains information on the loaded image to relocate - - @retval RETURN_SUCCESS if the PE/COFF image was relocated - @retval RETURN_LOAD_ERROR if the image is not a valid PE/COFF image - @retval RETURN_UNSUPPORTED not support - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderRelocateImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - EFI_IMAGE_DATA_DIRECTORY *RelocDir; - UINT64 Adjust; - EFI_IMAGE_BASE_RELOCATION *RelocBase; - EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd; - UINT16 *Reloc; - UINT16 *RelocEnd; - CHAR8 *Fixup; - CHAR8 *FixupBase; - UINT16 *F16; - UINT32 *F32; - UINT64 *F64; - CHAR8 *FixupData; - PHYSICAL_ADDRESS BaseAddress; - UINT16 MachineType; - EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader; - - PeHdr = NULL; - TeHdr = NULL; - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - // - // If there are no relocation entries, then we are done - // - if (ImageContext->RelocationsStripped) { - return RETURN_SUCCESS; - } - - // - // Use DestinationAddress field of ImageContext as the relocation address even if it is 0. - // - BaseAddress = ImageContext->DestinationAddress; - - if (!(ImageContext->IsTeImage)) { - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN)ImageContext->ImageAddress + - ImageContext->PeCoffHeaderOffset); - OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader); - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - Adjust = (UINT64) BaseAddress - OptionHeader.Optional32->ImageBase; - OptionHeader.Optional32->ImageBase = (UINT32) BaseAddress; - MachineType = ImageContext->Machine; - // - // Find the relocation block - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - RelocDir = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - if ((RelocDir != NULL) && (RelocDir->Size > 0)) { - RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress); - RelocBaseEnd = PeCoffLoaderImageAddress ( - ImageContext, - RelocDir->VirtualAddress + RelocDir->Size - 1 - ); - if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } else { - Adjust = (UINT64) BaseAddress - OptionHeader.Optional64->ImageBase; - OptionHeader.Optional64->ImageBase = BaseAddress; - MachineType = ImageContext->Machine; - // - // Find the relocation block - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - RelocDir = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - if ((RelocDir != NULL) && (RelocDir->Size > 0)) { - RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress); - RelocBaseEnd = PeCoffLoaderImageAddress ( - ImageContext, - RelocDir->VirtualAddress + RelocDir->Size - 1 - ); - if (RelocBase == NULL || RelocBaseEnd == NULL || RelocBaseEnd < RelocBase) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } else { - // - // Set base and end to bypass processing below. - // - RelocBase = RelocBaseEnd = 0; - } - } - } else { - TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); - Adjust = (UINT64) (BaseAddress - TeHdr->ImageBase); - TeHdr->ImageBase = (UINT64) (BaseAddress); - MachineType = TeHdr->Machine; - - // - // Find the relocation block - // - RelocDir = &TeHdr->DataDirectory[0]; - RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)( - ImageContext->ImageAddress + - RelocDir->VirtualAddress + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1); - } - - // - // Run the relocation information and apply the fixups - // - FixupData = ImageContext->FixupData; - while (RelocBase < RelocBaseEnd) { - - Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION)); - RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock); - if (!(ImageContext->IsTeImage)) { - FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress); - if (FixupBase == NULL) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_LOAD_ERROR; - } - } else { - FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress + - RelocBase->VirtualAddress + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - } - - if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) || - (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress + - (UINTN)ImageContext->ImageSize)) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_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 = (UINT16) (*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: - // - // Return the same EFI_UNSUPPORTED return code as - // PeCoffLoaderRelocateImageEx() returns if it does not recognize - // the relocation type. - // - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return RETURN_UNSUPPORTED; - - default: - switch (MachineType) { - case IMAGE_FILE_MACHINE_I386: - Status = PeCoffLoaderRelocateIa32Image (Reloc, Fixup, &FixupData, Adjust); - break; - case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED: - Status = PeCoffLoaderRelocateArmImage (&Reloc, Fixup, &FixupData, Adjust); - break; - case IMAGE_FILE_MACHINE_RISCV64: - Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust); - break; - case IMAGE_FILE_MACHINE_LOONGARCH64: - Status = PeCoffLoaderRelocateLoongArch64Image (Reloc, Fixup, &FixupData, Adjust); - break; - default: - Status = RETURN_UNSUPPORTED; - break; - } - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_FAILED_RELOCATION; - return Status; - } - } - - // - // Next relocation record - // - Reloc += 1; - } - - // - // Next reloc block - // - RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd; - } - - return RETURN_SUCCESS; -} - -/** - Loads a PE/COFF image into memory - - @param This Calling context - @param ImageContext Contains information on image to load into memory - - @retval RETURN_SUCCESS if the PE/COFF image was loaded - @retval RETURN_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer - @retval RETURN_LOAD_ERROR if the image is a runtime driver with no relocations - @retval RETURN_INVALID_PARAMETER if the image address is invalid - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderLoadImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -{ - RETURN_STATUS Status; - EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr; - EFI_TE_IMAGE_HEADER *TeHdr; - PE_COFF_LOADER_IMAGE_CONTEXT CheckContext; - EFI_IMAGE_SECTION_HEADER *FirstSection; - EFI_IMAGE_SECTION_HEADER *Section; - UINTN NumberOfSections; - UINTN Index; - CHAR8 *Base; - CHAR8 *End; - CHAR8 *MaxEnd; - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - UINTN Size; - UINT32 TempDebugEntryRva; - EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader; - - PeHdr = NULL; - TeHdr = NULL; - OptionHeader.Header = NULL; - // - // Assume success - // - ImageContext->ImageError = IMAGE_ERROR_SUCCESS; - - // - // Copy the provided context info into our local version, get what we - // can from the original image, and then use that to make sure everything - // is legit. - // - CopyMem (&CheckContext, ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT)); - - Status = PeCoffLoaderGetImageInfo (&CheckContext); - if (RETURN_ERROR (Status)) { - return Status; - } - - // - // Make sure there is enough allocated space for the image being loaded - // - if (ImageContext->ImageSize < CheckContext.ImageSize) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_SIZE; - return RETURN_BUFFER_TOO_SMALL; - } - - // - // If there's no relocations, then make sure it's not a runtime driver, - // and that it's being loaded at the linked address. - // - if (CheckContext.RelocationsStripped) { - // - // If the image does not contain relocations and it is a runtime driver - // then return an error. - // - if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_SUBSYSTEM; - return RETURN_LOAD_ERROR; - } - // - // If the image does not contain relocations, and the requested load address - // is not the linked address, then return an error. - // - if (CheckContext.ImageAddress != ImageContext->ImageAddress) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_IMAGE_ADDRESS; - return RETURN_INVALID_PARAMETER; - } - } - // - // Make sure the allocated space has the proper section alignment - // - if (!(ImageContext->IsTeImage)) { - if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) { - ImageContext->ImageError = IMAGE_ERROR_INVALID_SECTION_ALIGNMENT; - return RETURN_INVALID_PARAMETER; - } - } - // - // Read the entire PE/COFF or TE header into memory - // - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &ImageContext->SizeOfHeaders, - (VOID *) (UINTN) ImageContext->ImageAddress - ); - - PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) - ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset); - - OptionHeader.Header = (VOID *) &(PeHdr->Pe32.OptionalHeader); - - FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN)ImageContext->ImageAddress + - ImageContext->PeCoffHeaderOffset + - sizeof(UINT32) + - sizeof(EFI_IMAGE_FILE_HEADER) + - PeHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - NumberOfSections = (UINTN) (PeHdr->Pe32.FileHeader.NumberOfSections); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - 0, - &ImageContext->SizeOfHeaders, - (VOID *) (UINTN) ImageContext->ImageAddress - ); - - TeHdr = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress); - - FirstSection = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN)ImageContext->ImageAddress + - sizeof(EFI_TE_IMAGE_HEADER) - ); - NumberOfSections = (UINTN) (TeHdr->NumberOfSections); - - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - // - // Load each section of the image - // - Section = FirstSection; - for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) { - - // - // Compute sections address - // - Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress); - End = PeCoffLoaderImageAddress ( - ImageContext, - Section->VirtualAddress + Section->Misc.VirtualSize - 1 - ); - - // - // If the base start or end address resolved to 0, then fail. - // - if ((Base == NULL) || (End == NULL)) { - ImageContext->ImageError = IMAGE_ERROR_SECTION_NOT_LOADED; - return RETURN_LOAD_ERROR; - } - - - if (ImageContext->IsTeImage) { - Base = (CHAR8 *) ((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); - End = (CHAR8 *) ((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize); - } - - if (End > MaxEnd) { - MaxEnd = End; - } - - // - // Read the section - // - Size = (UINTN) Section->Misc.VirtualSize; - if ((Size == 0) || (Size > Section->SizeOfRawData)) { - Size = (UINTN) Section->SizeOfRawData; - } - - if (Section->SizeOfRawData) { - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - Section->PointerToRawData, - &Size, - Base - ); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN) TeHdr->StrippedSize, - &Size, - Base - ); - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return Status; - } - } - - // - // If raw size is less then virt size, zero fill the remaining - // - - if (Size < Section->Misc.VirtualSize) { - ZeroMem (Base + Size, Section->Misc.VirtualSize - Size); - } - - // - // Next Section - // - Section += 1; - } - - // - // Get image's entry point - // - if (!(ImageContext->IsTeImage)) { - ImageContext->EntryPoint = (PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress ( - ImageContext, - PeHdr->Pe32.OptionalHeader.AddressOfEntryPoint - ); - } else { - ImageContext->EntryPoint = (UINTN)ImageContext->ImageAddress + - (UINTN)TeHdr->AddressOfEntryPoint + - (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - - (UINTN) TeHdr->StrippedSize; - } - - // - // Determine the size of the fixup data - // - // Per the PE/COFF spec, you can't assume that a given data directory - // is present in the image. You have to check the NumberOfRvaAndSizes in - // the optional header to verify a desired directory entry is there. - // - if (!(ImageContext->IsTeImage)) { - if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) - &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } else { - ImageContext->FixupDataSize = 0; - } - } else { - if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) { - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) - &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } else { - ImageContext->FixupDataSize = 0; - } - } - } else { - DirectoryEntry = &TeHdr->DataDirectory[0]; - ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN); - } - // - // Consumer must allocate a buffer for the relocation fixup log. - // Only used for runtime drivers. - // - ImageContext->FixupData = NULL; - - // - // Load the Codeview info if present - // - if (ImageContext->DebugDirectoryEntryRva != 0) { - if (!(ImageContext->IsTeImage)) { - DebugEntry = PeCoffLoaderImageAddress ( - ImageContext, - ImageContext->DebugDirectoryEntryRva - ); - } else { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)( - ImageContext->ImageAddress + - ImageContext->DebugDirectoryEntryRva + - sizeof(EFI_TE_IMAGE_HEADER) - - TeHdr->StrippedSize - ); - } - - if (DebugEntry != NULL) { - TempDebugEntryRva = DebugEntry->RVA; - if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) { - Section--; - if ((UINTN) Section->SizeOfRawData < Section->Misc.VirtualSize) { - TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize; - } else { - TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData; - } - } - - if (TempDebugEntryRva != 0) { - if (!(ImageContext->IsTeImage)) { - ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva); - } else { - ImageContext->CodeView = (VOID *)( - (UINTN)ImageContext->ImageAddress + - (UINTN)TempDebugEntryRva + - (UINTN)sizeof(EFI_TE_IMAGE_HEADER) - - (UINTN) TeHdr->StrippedSize - ); - } - - if (ImageContext->CodeView == NULL) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - if (DebugEntry->RVA == 0) { - Size = DebugEntry->SizeOfData; - if (!(ImageContext->IsTeImage)) { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugEntry->FileOffset, - &Size, - ImageContext->CodeView - ); - } else { - Status = ImageContext->ImageRead ( - ImageContext->Handle, - DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - TeHdr->StrippedSize, - &Size, - ImageContext->CodeView - ); - // - // Should we apply fix up to this field according to the size difference between PE and TE? - // Because now we maintain TE header fields unfixed, this field will also remain as they are - // in original PE image. - // - } - - if (RETURN_ERROR (Status)) { - ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ; - return RETURN_LOAD_ERROR; - } - - DebugEntry->RVA = TempDebugEntryRva; - } - - switch (*(UINT32 *) ImageContext->CodeView) { - case CODEVIEW_SIGNATURE_NB10: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY); - break; - - case CODEVIEW_SIGNATURE_RSDS: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY); - break; - - case CODEVIEW_SIGNATURE_MTOC: - ImageContext->PdbPointer = (CHAR8 *) ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY); - - default: - break; - } - } - } - } - - return Status; -} - -/** - Returns a pointer to the PDB file name for a raw PE/COFF image that is not - loaded into system memory with the PE/COFF Loader Library functions. - - Returns the PDB file name for the PE/COFF image specified by Pe32Data. If - the PE/COFF image specified by Pe32Data is not a valid, then NULL is - returned. If the PE/COFF image specified by Pe32Data does not contain a - debug directory entry, then NULL is returned. If the debug directory entry - in the PE/COFF image specified by Pe32Data does not contain a PDB file name, - then NULL is returned. - If Pe32Data is NULL, then return NULL. - - @param Pe32Data Pointer to the PE/COFF image that is loaded in system - memory. - - @return The PDB file name for the PE/COFF image specified by Pe32Data or NULL - if it cannot be retrieved. - -**/ -VOID * -EFIAPI -PeCoffLoaderGetPdbPointer ( - IN VOID *Pe32Data - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry; - EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry; - UINTN DirCount; - VOID *CodeViewEntryPointer; - INTN TEImageAdjust; - UINT32 NumberOfRvaAndSizes; - UINT16 Magic; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - UINT32 Index, Index1; - - if (Pe32Data == NULL) { - return NULL; - } - - TEImageAdjust = 0; - DirectoryEntry = NULL; - DebugEntry = NULL; - NumberOfRvaAndSizes = 0; - Index = 0; - Index1 = 0; - SectionHeader = NULL; - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (EFI_IMAGE_DOS_SIGNATURE == DosHdr->e_magic) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - if (EFI_TE_IMAGE_HEADER_SIGNATURE == Hdr.Te->Signature) { - if (Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) { - DirectoryEntry = &Hdr.Te->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG]; - TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize; - - // - // Get the DebugEntry offset in the raw data image. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (Hdr.Te + 1); - Index = Hdr.Te->NumberOfSections; - for (Index1 = 0; Index1 < Index; Index1 ++) { - if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && - (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) Hdr.Te + - DirectoryEntry->VirtualAddress - - SectionHeader [Index1].VirtualAddress + - SectionHeader [Index1].PointerToRawData + - TEImageAdjust); - break; - } - } - } - } else if (EFI_IMAGE_NT_SIGNATURE == Hdr.Pe32->Signature) { - // - // NOTE: We use Machine field to identify PE32/PE32+, instead of Magic. - // It is due to backward-compatibility, for some system might - // generate PE32+ image with PE32 Magic. - // - switch (Hdr.Pe32->FileHeader.Machine) { - case IMAGE_FILE_MACHINE_I386: - case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED: - // - // Assume PE32 image with IA32 Machine field. - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC; - break; - case IMAGE_FILE_MACHINE_X64: - // - // Assume PE32+ image with X64 Machine field - // - Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC; - break; - default: - // - // For unknown Machine field, use Magic in optional Header - // - Magic = Hdr.Pe32->OptionalHeader.Magic; - } - - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINT8 *) Hdr.Pe32 + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - Hdr.Pe32->FileHeader.SizeOfOptionalHeader - ); - Index = Hdr.Pe32->FileHeader.NumberOfSections; - - if (EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC == Magic) { - // - // Use PE32 offset get Debug Directory Entry - // - NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - } else if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - // - // Use PE32+ offset get Debug Directory Entry - // - NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes; - DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]); - } - - if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_DEBUG || DirectoryEntry->VirtualAddress == 0) { - DirectoryEntry = NULL; - DebugEntry = NULL; - } else { - // - // Get the DebugEntry offset in the raw data image. - // - for (Index1 = 0; Index1 < Index; Index1 ++) { - if ((DirectoryEntry->VirtualAddress >= SectionHeader[Index1].VirtualAddress) && - (DirectoryEntry->VirtualAddress < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) { - DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ( - (UINTN) Pe32Data + - DirectoryEntry->VirtualAddress - - SectionHeader[Index1].VirtualAddress + - SectionHeader[Index1].PointerToRawData); - break; - } - } - } - } else { - return NULL; - } - - if (NULL == DebugEntry || NULL == DirectoryEntry) { - return NULL; - } - - // - // Scan the directory to find the debug entry. - // - for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY), DebugEntry++) { - if (EFI_IMAGE_DEBUG_TYPE_CODEVIEW == DebugEntry->Type) { - if (DebugEntry->SizeOfData > 0) { - // - // Get the DebugEntry offset in the raw data image. - // - CodeViewEntryPointer = NULL; - for (Index1 = 0; Index1 < Index; Index1 ++) { - if ((DebugEntry->RVA >= SectionHeader[Index1].VirtualAddress) && - (DebugEntry->RVA < (SectionHeader[Index1].VirtualAddress + SectionHeader[Index1].Misc.VirtualSize))) { - CodeViewEntryPointer = (VOID *) ( - ((UINTN)Pe32Data) + - (UINTN) DebugEntry->RVA - - SectionHeader[Index1].VirtualAddress + - SectionHeader[Index1].PointerToRawData + - (UINTN)TEImageAdjust); - break; - } - } - if (Index1 >= Index) { - // - // Can't find CodeViewEntryPointer in raw PE/COFF image. - // - continue; - } - switch (* (UINT32 *) CodeViewEntryPointer) { - case CODEVIEW_SIGNATURE_NB10: - return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)); - case CODEVIEW_SIGNATURE_RSDS: - return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY)); - case CODEVIEW_SIGNATURE_MTOC: - return (VOID *) ((CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY)); - default: - break; - } - } - } - } - - return NULL; -} - - -RETURN_STATUS -EFIAPI -PeCoffLoaderGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint, - OUT VOID **BaseOfImage - ) -{ - EFI_IMAGE_DOS_HEADER *DosHdr; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data; - if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { - // - // DOS image header is present, so read the PE header after the DOS image header. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); - } else { - // - // DOS image header is not present, so PE header is at the image base. - // - Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; - } - - // - // Calculate the entry point relative to the start of the image. - // AddressOfEntryPoint is common for PE32 & PE32+ - // - if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) { - *BaseOfImage = (VOID *)(UINTN)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER)); - *EntryPoint = (VOID *)((UINTN)*BaseOfImage + (Hdr.Te->AddressOfEntryPoint & 0x0ffffffff) + sizeof(EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize); - return RETURN_SUCCESS; - } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { - *EntryPoint = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint; - if (Hdr.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32->OptionalHeader.ImageBase; - } else { - *BaseOfImage = (VOID *)(UINTN)Hdr.Pe32Plus->OptionalHeader.ImageBase; - } - *EntryPoint = (VOID *)(UINTN)((UINTN)*EntryPoint + (UINTN)*BaseOfImage); - return RETURN_SUCCESS; - } - - return RETURN_UNSUPPORTED; -} diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index 80b62897ca..d5f845b568 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -14,12 +14,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #else #include +#include #endif #include "CommonLib.h" #include "EfiUtilityMsgs.h" +#include "FvLib.h" + +#include #include #include +#include GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultDataType = EfiBootServicesData; GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_MEMORY_TYPE gPhaseDefaultCodeType = EfiBootServicesCode; @@ -615,3 +620,64 @@ CpuDeadLoop ( { abort (); } + +EFI_STATUS +GetAlignmentFromFile ( + IN CHAR8 *InFile, + OUT UINT32 *Alignment + ) + /*++ + InFile is input file for getting alignment + return the alignment + --*/ +{ + FILE *InFileHandle; + UINT8 *ImageFileBuffer; + UINTN ImageFileSize; + UINT32 CurSecHdrSize; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + EFI_COMMON_SECTION_HEADER *CommonHeader; + EFI_STATUS Status; + + InFileHandle = NULL; + ImageFileBuffer = NULL; + *Alignment = 0; + + InFileHandle = fopen(LongFilePath(InFile), "rb"); + if (InFileHandle == NULL){ + Error (NULL, 0, 0001, "Error opening file", InFile); + return EFI_ABORTED; + } + ImageFileSize = _filelength (fileno(InFileHandle)); + ImageFileBuffer = (UINT8 *) malloc (ImageFileSize); + if (ImageFileBuffer == NULL) { + fclose (InFileHandle); + Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); + return EFI_OUT_OF_RESOURCES; + } + fread (ImageFileBuffer, sizeof (UINT8), ImageFileSize, InFileHandle); + fclose (InFileHandle); + + CommonHeader = (EFI_COMMON_SECTION_HEADER *) ImageFileBuffer; + CurSecHdrSize = GetSectionHeaderLength(CommonHeader); + + Status = UefiImageInitializeContext ( + &ImageContext, + ImageFileBuffer + CurSecHdrSize, + ImageFileSize, + UEFI_IMAGE_SOURCE_FV + ); + if (EFI_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and return status is %x", InFile, (int) Status); + return Status; + } + + *Alignment = UefiImageGetSegmentAlignment (&ImageContext); + // Free the allocated memory resource + if (ImageFileBuffer != NULL) { + free (ImageFileBuffer); + ImageFileBuffer = NULL; + } + + return EFI_SUCCESS; +} diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h index 6ac64897f1..02bb63e6ba 100644 --- a/BaseTools/Source/C/Common/CommonLib.h +++ b/BaseTools/Source/C/Common/CommonLib.h @@ -113,6 +113,12 @@ LongFilePath ( IN CHAR8 *FileName ); +EFI_STATUS +GetAlignmentFromFile ( + IN CHAR8 *InFile, + OUT UINT32 *Alignment + ); + /*++ Routine Description: diff --git a/BaseTools/Source/C/Common/GNUmakefile b/BaseTools/Source/C/Common/GNUmakefile index c5a49ffe2f..1396c3f578 100644 --- a/BaseTools/Source/C/Common/GNUmakefile +++ b/BaseTools/Source/C/Common/GNUmakefile @@ -11,7 +11,6 @@ MAKEROOT ?= .. LIBNAME = Common OBJECTS = \ - BasePeCoff.o \ BinderFuncs.o \ CommonLib.o \ Crc32.o \ @@ -25,13 +24,26 @@ OBJECTS = \ OsPath.o \ ParseGuidedSectionTools.o \ ParseInf.o \ - PeCoffLoaderEx.o \ SimpleFileParsing.o \ StringFuncs.o \ TianoCompress.o OBJECTS += AutoGen.o DebugLib.o +OBJECTS += \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ImageToolEmit.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/Image.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan32.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScan64.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/ElfScanCommon.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/UefiImageScan.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeScan.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit32.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmitCommon.o \ + $(EDK2_OBJPATH)/BaseTools/ImageTool/BinEmit.o \ + $(EDK2_OBJPATH)/OpenCorePkg/User/Library/UserFile.o + OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.o @@ -92,6 +104,30 @@ OBJECTS += \ $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLib.o \ $(EDK2_OBJPATH)/MdePkg/Library/BasePrintLib/PrintLibInternal.o +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseAlignment.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseBitOverflow.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseMath.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseNativeOverflow.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseOverflowLib/BaseTripleOverflow.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffDebug.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffHash.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffHii.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffInfo.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffInit.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffLoad.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BasePeCoffLib2/PeCoffRelocate.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/CommonSupport.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/PeCoffSupport.o \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageLib/UefiImageLibPeCoff.o + +OBJECTS += \ + $(EDK2_OBJPATH)/MdePkg/Library/BaseUefiImageExtraActionLibNull/UefiImageExtraActionLib.o + OBJECTS += \ $(EDK2_OBJPATH)/MdeModulePkg/Library/BaseMemoryProfileLibNull/BaseMemoryProfileLibNull.o diff --git a/BaseTools/Source/C/Common/Makefile b/BaseTools/Source/C/Common/Makefile index e4982cbff4..af704876dd 100644 --- a/BaseTools/Source/C/Common/Makefile +++ b/BaseTools/Source/C/Common/Makefile @@ -11,7 +11,6 @@ LIBNAME = Common OBJECTS = \ - BasePeCoff.obj \ BinderFuncs.obj \ CommonLib.obj \ Crc32.obj \ @@ -25,13 +24,26 @@ OBJECTS = \ OsPath.obj \ ParseGuidedSectionTools.obj \ ParseInf.obj \ - PeCoffLoaderEx.obj \ SimpleFileParsing.obj \ StringFuncs.obj \ TianoCompress.obj OBJECTS = $(OBJECTS) AutoGen.obj DebugLib.obj +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ImageToolEmit.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\Image.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan32.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScan64.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\ElfScanCommon.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\UefiImageScan.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeScan.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit32.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmitCommon.obj \ + $(EDK2_OBJPATH)\BaseTools\ImageTool\BinEmit.obj \ + $(EDK2_OBJPATH)\OpenCorePkg\User\Library\UserFile.obj + OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\BaseDebugPrintErrorLevelLib.obj @@ -91,6 +103,30 @@ OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLib.obj \ $(EDK2_OBJPATH)\MdePkg\Library\BasePrintLib\PrintLibInternal.obj +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseAlignment.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseBitOverflow.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseMath.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseNativeOverflow.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\BaseTripleOverflow.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffDebug.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffHash.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffHii.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffInfo.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffInit.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffLoad.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\PeCoffRelocate.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\CommonSupport.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\PeCoffSupport.obj \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\UefiImageLibPeCoff.obj + +OBJECTS = $(OBJECTS) \ + $(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\UefiImageExtraActionLib.obj + OBJECTS = $(OBJECTS) \ $(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\BaseMemoryProfileLibNull.obj diff --git a/BaseTools/Source/C/Common/PeCoffLib.h b/BaseTools/Source/C/Common/PeCoffLib.h deleted file mode 100644 index dd38f442f9..0000000000 --- a/BaseTools/Source/C/Common/PeCoffLib.h +++ /dev/null @@ -1,213 +0,0 @@ -/** @file - Function prototypes and defines on Memory Only PE COFF loader - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __BASE_PE_COFF_LIB_H__ -#define __BASE_PE_COFF_LIB_H__ - -// -// Return status codes from the PE/COFF Loader services -// BUGBUG: Find where used and see if can be replaced by RETURN_STATUS codes -// -#define IMAGE_ERROR_SUCCESS 0 -#define IMAGE_ERROR_IMAGE_READ 1 -#define IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2 -#define IMAGE_ERROR_INVALID_MACHINE_TYPE 3 -#define IMAGE_ERROR_INVALID_SUBSYSTEM 4 -#define IMAGE_ERROR_INVALID_IMAGE_ADDRESS 5 -#define IMAGE_ERROR_INVALID_IMAGE_SIZE 6 -#define IMAGE_ERROR_INVALID_SECTION_ALIGNMENT 7 -#define IMAGE_ERROR_SECTION_NOT_LOADED 8 -#define IMAGE_ERROR_FAILED_RELOCATION 9 -#define IMAGE_ERROR_FAILED_ICACHE_FLUSH 10 - -// -// Macro definitions for RISC-V architecture. -// -#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1)) -#define RISCV_IMM_BITS 12 -#define RISCV_IMM_REACH (1LL<ImageRead() function - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderGetImageInfo ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -/** - Relocates a PE/COFF image in memory - - @param ImageContext Contains information on the loaded image to relocate - - @retval EFI_SUCCESS if the PE/COFF image was relocated - @retval EFI_LOAD_ERROR if the image is not a valid PE/COFF image - @retval EFI_UNSUPPORTED not support - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderRelocateImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -/** - Loads a PE/COFF image into memory - - @param ImageContext Contains information on image to load into memory - - @retval EFI_SUCCESS if the PE/COFF image was loaded - @retval EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer - @retval EFI_LOAD_ERROR if the image is a runtime driver with no relocations - @retval EFI_INVALID_PARAMETER if the image address is invalid - -**/ -RETURN_STATUS -EFIAPI -PeCoffLoaderLoadImage ( - IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext - ) -; - -VOID * -EFIAPI -PeCoffLoaderGetPdbPointer ( - IN VOID *Pe32Data - ) -; - -RETURN_STATUS -EFIAPI -PeCoffLoaderGetEntryPoint ( - IN VOID *Pe32Data, - OUT VOID **EntryPoint, - OUT VOID **BaseOfImage - ) -; - -// -// These functions are used by the ARM PE/COFF relocation code and by -// the ELF to PE/COFF converter so that is why they are public -// - -/** - Pass in a pointer to an ARM MOVT or MOVW immediate instruction and - return the immediate data encoded in the instruction - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - - @return Immediate address encoded in the instruction - -**/ -UINT16 -EFIAPI -ThumbMovtImmediateAddress ( - IN UINT16 *Instruction - ); - -/** - Update an ARM MOVT or MOVW immediate instruction immediate data. - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - @param Address New address to patch into the instruction - -**/ -VOID -EFIAPI -ThumbMovtImmediatePatch ( - IN OUT UINT16 *Instruction, - IN UINT16 Address - ); - - -/** - Pass in a pointer to an ARM MOVW/MOVT instruction pair and - return the immediate data encoded in the two` instruction - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - - @return Immediate address encoded in the instructions - -**/ -UINT32 -EFIAPI -ThumbMovwMovtImmediateAddress ( - IN UINT16 *Instructions - ); - -/** - Update an ARM MOVW/MOVT immediate instruction instruction pair. - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - @param Address New address to patch into the instructions -**/ -VOID -EFIAPI -ThumbMovwMovtImmediatePatch ( - IN OUT UINT16 *Instructions, - IN UINT32 Address - ); - - - -#endif diff --git a/BaseTools/Source/C/Common/PeCoffLoaderEx.c b/BaseTools/Source/C/Common/PeCoffLoaderEx.c deleted file mode 100644 index 088e470d17..0000000000 --- a/BaseTools/Source/C/Common/PeCoffLoaderEx.c +++ /dev/null @@ -1,385 +0,0 @@ -/** @file -IA32 and X64 Specific relocation fixups - -Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
-Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
-Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
-Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
-SPDX-License-Identifier: BSD-2-Clause-Patent - ---*/ - -#include -#include -#include "PeCoffLib.h" -#include "CommonLib.h" -#include "EfiUtilityMsgs.h" - -#define IMM64_IMM7B_INST_WORD_X 3 -#define IMM64_IMM7B_SIZE_X 7 -#define IMM64_IMM7B_INST_WORD_POS_X 4 -#define IMM64_IMM7B_VAL_POS_X 0 - -#define IMM64_IMM9D_INST_WORD_X 3 -#define IMM64_IMM9D_SIZE_X 9 -#define IMM64_IMM9D_INST_WORD_POS_X 18 -#define IMM64_IMM9D_VAL_POS_X 7 - -#define IMM64_IMM5C_INST_WORD_X 3 -#define IMM64_IMM5C_SIZE_X 5 -#define IMM64_IMM5C_INST_WORD_POS_X 13 -#define IMM64_IMM5C_VAL_POS_X 16 - -#define IMM64_IC_INST_WORD_X 3 -#define IMM64_IC_SIZE_X 1 -#define IMM64_IC_INST_WORD_POS_X 12 -#define IMM64_IC_VAL_POS_X 21 - -#define IMM64_IMM41a_INST_WORD_X 1 -#define IMM64_IMM41a_SIZE_X 10 -#define IMM64_IMM41a_INST_WORD_POS_X 14 -#define IMM64_IMM41a_VAL_POS_X 22 - -#define IMM64_IMM41b_INST_WORD_X 1 -#define IMM64_IMM41b_SIZE_X 8 -#define IMM64_IMM41b_INST_WORD_POS_X 24 -#define IMM64_IMM41b_VAL_POS_X 32 - -#define IMM64_IMM41c_INST_WORD_X 2 -#define IMM64_IMM41c_SIZE_X 23 -#define IMM64_IMM41c_INST_WORD_POS_X 0 -#define IMM64_IMM41c_VAL_POS_X 40 - -#define IMM64_SIGN_INST_WORD_X 3 -#define IMM64_SIGN_SIZE_X 1 -#define IMM64_SIGN_INST_WORD_POS_X 27 -#define IMM64_SIGN_VAL_POS_X 63 - -UINT32 *RiscVHi20Fixup = NULL; - -/** - Performs an IA-32 specific relocation fixup - - @param Reloc Pointer to the relocation record - @param Fixup Pointer to the address to fix up - @param FixupData Pointer to a buffer to log the fixups - @param Adjust The offset to adjust the fixup - - @retval EFI_UNSUPPORTED - Unsupported now -**/ -RETURN_STATUS -PeCoffLoaderRelocateIa32Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - return RETURN_UNSUPPORTED; -} - -/** - Performs an RISC-V specific relocation fixup - - @param Reloc Pointer to the relocation record - @param Fixup Pointer to the address to fix up - @param FixupData Pointer to a buffer to log the fixups - @param Adjust The offset to adjust the fixup - - @return Status code -**/ -RETURN_STATUS -PeCoffLoaderRelocateRiscVImage ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - UINT32 Value; - UINT32 Value2; - - switch ((*Reloc) >> 12) { - case EFI_IMAGE_REL_BASED_RISCV_HI20: - RiscVHi20Fixup = (UINT32 *) Fixup; - break; - - case EFI_IMAGE_REL_BASED_RISCV_LOW12I: - if (RiscVHi20Fixup != NULL) { - Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12); - Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 20, 12)); - if (Value2 & (RISCV_IMM_REACH/2)) { - Value2 |= ~(RISCV_IMM_REACH-1); - } - Value += Value2; - Value += (UINT32)Adjust; - Value2 = RISCV_CONST_HIGH_PART (Value); - *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \ - (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12)); - *(UINT32 *)Fixup = (RV_X (Value, 0, 12) << 20) | \ - (RV_X (*(UINT32 *)Fixup, 0, 20)); - } - RiscVHi20Fixup = NULL; - break; - - case EFI_IMAGE_REL_BASED_RISCV_LOW12S: - if (RiscVHi20Fixup != NULL) { - Value = (UINT32)(RV_X(*RiscVHi20Fixup, 12, 20) << 12); - Value2 = (UINT32)(RV_X(*(UINT32 *)Fixup, 7, 5) | (RV_X(*(UINT32 *)Fixup, 25, 7) << 5)); - if (Value2 & (RISCV_IMM_REACH/2)) { - Value2 |= ~(RISCV_IMM_REACH-1); - } - Value += Value2; - Value += (UINT32)Adjust; - Value2 = RISCV_CONST_HIGH_PART (Value); - *(UINT32 *)RiscVHi20Fixup = (RV_X (Value2, 12, 20) << 12) | \ - (RV_X (*(UINT32 *)RiscVHi20Fixup, 0, 12)); - Value2 = *(UINT32 *)Fixup & 0x01fff07f; - Value &= RISCV_IMM_REACH - 1; - *(UINT32 *)Fixup = Value2 | (UINT32)(((RV_X(Value, 0, 5) << 7) | (RV_X(Value, 5, 7) << 25))); - } - RiscVHi20Fixup = NULL; - break; - - default: - return EFI_UNSUPPORTED; - - } - return RETURN_SUCCESS; -} - -/** - Pass in a pointer to an ARM MOVT or MOVW immediate instruction and - return the immediate data encoded in the instruction - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - - @return Immediate address encoded in the instruction - -**/ -UINT16 -EFIAPI -ThumbMovtImmediateAddress ( - IN UINT16 *Instruction - ) -{ - UINT32 Movt; - UINT16 Address; - - // Thumb2 is two 16-bit instructions working together. Not a single 32-bit instruction - // Example MOVT R0, #0 is 0x0000f2c0 or 0xf2c0 0x0000 - Movt = (*Instruction << 16) | (*(Instruction + 1)); - - // imm16 = imm4:i:imm3:imm8 - // imm4 -> Bit19:Bit16 - // i -> Bit26 - // imm3 -> Bit14:Bit12 - // imm8 -> Bit7:Bit0 - Address = (UINT16)(Movt & 0x000000ff); // imm8 - Address |= (UINT16)((Movt >> 4) & 0x0000f700); // imm4 imm3 - Address |= (((Movt & BIT26) != 0) ? BIT11 : 0); // i - return Address; -} - - -/** - Update an ARM MOVT or MOVW immediate instruction immediate data. - - @param Instruction Pointer to ARM MOVT or MOVW immediate instruction - @param Address New address to patch into the instruction -**/ -VOID -EFIAPI -ThumbMovtImmediatePatch ( - IN OUT UINT16 *Instruction, - IN UINT16 Address - ) -{ - UINT16 Patch; - - // First 16-bit chunk of instruction - Patch = ((Address >> 12) & 0x000f); // imm4 - Patch |= (((Address & BIT11) != 0) ? BIT10 : 0); // i - *Instruction = (*Instruction & ~0x040f) | Patch; - - // Second 16-bit chunk of instruction - Patch = Address & 0x000000ff; // imm8 - Patch |= ((Address << 4) & 0x00007000); // imm3 - Instruction++; - *Instruction = (*Instruction & ~0x70ff) | Patch; -} - -/** - Pass in a pointer to an ARM MOVW/MOVT instruction pair and - return the immediate data encoded in the two` instruction - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - - @return Immediate address encoded in the instructions - -**/ -UINT32 -EFIAPI -ThumbMovwMovtImmediateAddress ( - IN UINT16 *Instructions - ) -{ - UINT16 *Word; - UINT16 *Top; - - Word = Instructions; // MOVW - Top = Word + 2; // MOVT - - return (ThumbMovtImmediateAddress (Top) << 16) + ThumbMovtImmediateAddress (Word); -} - - -/** - Update an ARM MOVW/MOVT immediate instruction instruction pair. - - @param Instructions Pointer to ARM MOVW/MOVT instruction pair - @param Address New address to patch into the instructions -**/ -VOID -EFIAPI -ThumbMovwMovtImmediatePatch ( - IN OUT UINT16 *Instructions, - IN UINT32 Address - ) -{ - UINT16 *Word; - UINT16 *Top; - - Word = (UINT16 *)Instructions; // MOVW - Top = Word + 2; // MOVT - - ThumbMovtImmediatePatch (Word, (UINT16)(Address & 0xffff)); - ThumbMovtImmediatePatch (Top, (UINT16)(Address >> 16)); -} - - -/** - Performs an ARM-based specific relocation fixup and is a no-op on other - instruction sets. - - @param Reloc Pointer to the relocation record. - @param Fixup Pointer to the address to fix up. - @param FixupData Pointer to a buffer to log the fixups. - @param Adjust The offset to adjust the fixup. - - @return Status code. - -**/ -RETURN_STATUS -PeCoffLoaderRelocateArmImage ( - IN UINT16 **Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - UINT16 *Fixup16; - UINT32 FixupVal; - - Fixup16 = (UINT16 *) Fixup; - - switch ((**Reloc) >> 12) { - - case EFI_IMAGE_REL_BASED_ARM_MOV32T: - FixupVal = ThumbMovwMovtImmediateAddress (Fixup16) + (UINT32)Adjust; - ThumbMovwMovtImmediatePatch (Fixup16, FixupVal); - - - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64)); - CopyMem (*FixupData, Fixup16, sizeof (UINT64)); - *FixupData = *FixupData + sizeof(UINT64); - } - break; - - case EFI_IMAGE_REL_BASED_ARM_MOV32A: - // break omitted - ARM instruction encoding not implemented - default: - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} - -/** - Performs a LoongArch specific relocation fixup. - - @param[in] Reloc Pointer to the relocation record. - @param[in, out] Fixup Pointer to the address to fix up. - @param[in, out] FixupData Pointer to a buffer to log the fixups. - @param[in] Adjust The offset to adjust the fixup. - - @return Status code. -**/ -RETURN_STATUS -PeCoffLoaderRelocateLoongArch64Image ( - IN UINT16 *Reloc, - IN OUT CHAR8 *Fixup, - IN OUT CHAR8 **FixupData, - IN UINT64 Adjust - ) -{ - UINT8 RelocType; - UINT64 Value; - UINT64 Tmp1; - UINT64 Tmp2; - - RelocType = ((*Reloc) >> 12); - Value = 0; - Tmp1 = 0; - Tmp2 = 0; - - switch (RelocType) { - case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA: - // The next four instructions are used to load a 64 bit address, relocate all of them - Value = (*(UINT32 *)Fixup & 0x1ffffe0) << 7 | // lu12i.w 20bits from bit5 - (*((UINT32 *)Fixup + 1) & 0x3ffc00) >> 10; // ori 12bits from bit10 - Tmp1 = *((UINT32 *)Fixup + 2) & 0x1ffffe0; // lu32i.d 20bits from bit5 - Tmp2 = *((UINT32 *)Fixup + 3) & 0x3ffc00; // lu52i.d 12bits from bit10 - Value = Value | (Tmp1 << 27) | (Tmp2 << 42); - Value += Adjust; - - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - Fixup += sizeof (UINT32); - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | ((Value & 0xfff) << 10); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - Fixup += sizeof (UINT32); - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - Fixup += sizeof (UINT32); - *(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10); - if (*FixupData != NULL) { - *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32)); - *(UINT32 *)(*FixupData) = *(UINT32 *)Fixup; - *FixupData = *FixupData + sizeof (UINT32); - } - - break; - default: - Error (NULL, 0, 3000, "", "PeCoffLoaderRelocateLoongArch64Image: Fixup[0x%x] Adjust[0x%llx] *Reloc[0x%x], type[0x%x].", *(UINT32 *)Fixup, Adjust, *Reloc, RelocType); - return RETURN_UNSUPPORTED; - } - - return RETURN_SUCCESS; -} diff --git a/BaseTools/Source/C/EfiRom/EfiRom.c b/BaseTools/Source/C/EfiRom/EfiRom.c index fa7bf0e62e..9a41a34baf 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.c +++ b/BaseTools/Source/C/EfiRom/EfiRom.c @@ -1,5 +1,5 @@ /** @file -Utility program to create an EFI option ROM image from binary and EFI PE32 files. +Utility program to create an EFI option ROM image from binary and UEFI image files. Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -426,12 +426,12 @@ ProcessEfiFile ( Routine Description: - Process a PE32 EFI file. + Process an UEFI image file. Arguments: OutFptr - file pointer to output binary ROM image file we're creating - InFile - structure contains information on the PE32 file to process + InFile - structure contains information on the UEFI image file to process VendId - vendor ID as required in the option ROM header DevId - device ID as required in the option ROM header Size - pointer to where to return the size added to the output file @@ -471,22 +471,40 @@ Returns: // // Initialize our buffer pointers to null. // - Buffer = NULL; CompressedBuffer = NULL; - // - // Double-check the file to make sure it's what we expect it to be - // - Status = CheckPE32File (InFptr, &MachineType, &SubSystem); - if (Status != STATUS_SUCCESS) { - goto BailOut; - } // // Seek to the end of the input file and get the file size // fseek (InFptr, 0, SEEK_END); FileSize = ftell (InFptr); + // + // Allocate memory for the entire file (in case we have to compress), then + // seek back to the beginning of the file and read it into our buffer. + // + Buffer = (UINT8 *) malloc (FileSize); + if (Buffer == NULL) { + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); + Status = STATUS_ERROR; + goto BailOut; + } + + fseek (InFptr, 0, SEEK_SET); + if (fread (Buffer, FileSize, 1, InFptr) != 1) { + Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName); + Status = STATUS_ERROR; + goto BailOut; + } + + // + // Double-check the file to make sure it's what we expect it to be + // + Status = CheckUefiImageFile (Buffer, FileSize, &MachineType, &SubSystem); + if (Status != STATUS_SUCCESS) { + goto BailOut; + } + // // Get the size of the headers we're going to put in front of the image. The // EFI header must be aligned on a 4-byte boundary, so pad accordingly. @@ -519,23 +537,6 @@ Returns: VerboseMsg(" File size = 0x%X\n", (unsigned) FileSize); } // - // Allocate memory for the entire file (in case we have to compress), then - // seek back to the beginning of the file and read it into our buffer. - // - Buffer = (UINT8 *) malloc (FileSize); - if (Buffer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!"); - Status = STATUS_ERROR; - goto BailOut; - } - - fseek (InFptr, 0, SEEK_SET); - if (fread (Buffer, FileSize, 1, InFptr) != 1) { - Error (NULL, 0, 0004, "Error reading file", "File %s", InFile->FileName); - Status = STATUS_ERROR; - goto BailOut; - } - // // Now determine the size of the final output file. It's either the header size // plus the file's size, or the header size plus the compressed file size. // @@ -805,8 +806,9 @@ BailOut: static int -CheckPE32File ( - FILE *Fptr, +CheckUefiImageFile ( + VOID *FileBuffer, + UINT32 FileSize, UINT16 *MachineType, UINT16 *SubSystem ) @@ -814,13 +816,14 @@ CheckPE32File ( Routine Description: - Given a file pointer to a supposed PE32 image file, verify that it is indeed a - PE32 image file, and then return the machine type in the supplied pointer. + Given a file pointer to a supposed UEFI image file, verify that it is indeed a + UEFI image file, and then return the machine type in the supplied pointer. Arguments: - Fptr File pointer to the already-opened PE32 file - MachineType Location to stuff the machine type of the PE32 file. This is needed + FileBuffer File buffer of the UEFI image file + FileSize File size, in bytes, of FileBuffer + MachineType Location to stuff the machine type of the UEFI file. This is needed because the image may be Itanium-based, IA32, or EBC. Returns: @@ -830,67 +833,24 @@ Returns: --*/ { - EFI_IMAGE_DOS_HEADER DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr; + RETURN_STATUS Status; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context; - // - // Position to the start of the file - // - fseek (Fptr, 0, SEEK_SET); - - // - // Read the DOS header - // - if (fread (&DosHeader, sizeof (DosHeader), 1, Fptr) != 1) { - Error (NULL, 0, 0004, "Failed to read the DOS stub from the input file!", NULL); - return STATUS_ERROR; - } - // - // Check the magic number (0x5A4D) - // - if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (magic number)!"); - return STATUS_ERROR; - } - // - // Position into the file and check the PE signature - // - fseek (Fptr, (long) DosHeader.e_lfanew, SEEK_SET); - - // - // Read PE headers - // - if (fread (&PeHdr, sizeof (PeHdr), 1, Fptr) != 1) { - Error (NULL, 0, 0004, "Failed to read PE/COFF headers from input file!", NULL); + Status = UefiImageInitializeContext (&Context, FileBuffer, FileSize); + if (RETURN_ERROR (Status)) { + Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be an UEFI image - %llu!", Status); return STATUS_ERROR; } - - // - // Check the PE signature in the header "PE\0\0" - // - if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 2000, "Invalid parameter", "Input file does not appear to be a PE32 image (signature)!"); - return STATUS_ERROR; - } - - memcpy ((char *) MachineType, &PeHdr.Pe32.FileHeader.Machine, 2); - - if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - *SubSystem = PeHdr.Pe32.OptionalHeader.Subsystem; - } else if (PeHdr.Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - *SubSystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem; - } else { - Error (NULL, 0, 2000, "Invalid parameter", "Unable to find subsystem type!"); - return STATUS_ERROR; - } + *MachineType = UefiImageGetMachine (&Context); + *SubSystem = UefiImageGetSubsystem (&Context); if (mOptions.Verbose) { VerboseMsg(" Got subsystem = 0x%X from image\n", *SubSystem); } // - // File was successfully identified as a PE32 + // File was successfully identified as an UEFI image // return STATUS_SUCCESS; } @@ -1354,9 +1314,9 @@ Returns: fprintf (stdout, " -o FileName, --output FileName\n\ File will be created to store the output content.\n"); fprintf (stdout, " -e EfiFileName\n\ - EFI PE32 image files.\n"); + UEFI image files.\n"); fprintf (stdout, " -ec EfiFileName\n\ - EFI PE32 image files and will be compressed.\n"); + UEFI image files and will be compressed.\n"); fprintf (stdout, " -b BinFileName\n\ Legacy binary files.\n"); fprintf (stdout, " -l ClassCode\n\ diff --git a/BaseTools/Source/C/EfiRom/EfiRom.h b/BaseTools/Source/C/EfiRom/EfiRom.h index f05198713e..c51bebb0fe 100644 --- a/BaseTools/Source/C/EfiRom/EfiRom.h +++ b/BaseTools/Source/C/EfiRom/EfiRom.h @@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include // for PE32 structure definitions +#include // for PE32 structure definitions #include // for option ROM header structures #include @@ -22,6 +22,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "Compress.h" #include "CommonLib.h" +#include + // // Version of this utility // @@ -203,8 +205,9 @@ Returns: static int -CheckPE32File ( - FILE *Fptr, +CheckUefiImageFile ( + VOID *FileBuffer, + UINT32 FileSize, UINT16 *MachineType, UINT16 *SubSystem ) @@ -242,12 +245,12 @@ ProcessEfiFile ( Routine Description: - Process a PE32 EFI file. + Process a UEFI image file. Arguments: OutFptr - file pointer to output binary ROM image file we're creating - InFile - structure contains information on the PE32 file to process + InFile - structure contains information on the UEFI image file to process VendId - vendor ID as required in the option ROM header DevId - device ID as required in the option ROM header Size - pointer to where to return the size added to the output file diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c index 8b1f6a7bf9..dc4bd621f8 100644 --- a/BaseTools/Source/C/GenFfs/GenFfs.c +++ b/BaseTools/Source/C/GenFfs/GenFfs.c @@ -25,14 +25,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -#include #include #include "CommonLib.h" #include "ParseInf.h" #include "EfiUtilityMsgs.h" #include "FvLib.h" -#include "PeCoffLib.h" #define UTILITY_NAME "GenFfs" #define UTILITY_MAJOR_VERSION 0 @@ -451,104 +449,6 @@ Returns: } } -EFI_STATUS -EFIAPI -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) - /*++ - - Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - - Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - - Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - - --*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -GetAlignmentFromFile(char *InFile, UINT32 *Alignment) - /*++ - InFile is input file for getting alignment - return the alignment - --*/ -{ - FILE *InFileHandle; - UINT8 *PeFileBuffer; - UINTN PeFileSize; - UINT32 CurSecHdrSize; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - EFI_COMMON_SECTION_HEADER *CommonHeader; - EFI_STATUS Status; - - InFileHandle = NULL; - PeFileBuffer = NULL; - *Alignment = 0; - - memset (&ImageContext, 0, sizeof (ImageContext)); - - InFileHandle = fopen(LongFilePath(InFile), "rb"); - if (InFileHandle == NULL){ - Error (NULL, 0, 0001, "Error opening file", InFile); - return EFI_ABORTED; - } - PeFileSize = _filelength (fileno(InFileHandle)); - PeFileBuffer = (UINT8 *) malloc (PeFileSize); - if (PeFileBuffer == NULL) { - fclose (InFileHandle); - Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); - return EFI_OUT_OF_RESOURCES; - } - fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle); - fclose (InFileHandle); - CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer; - CurSecHdrSize = GetSectionHeaderLength(CommonHeader); - ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize); - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead; - Status = PeCoffLoaderGetImageInfo(&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status); - return Status; - } - *Alignment = ImageContext.SectionAlignment; - // Free the allocated memory resource - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; - } - return EFI_SUCCESS; -} - int main ( int argc, diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.c b/BaseTools/Source/C/GenFv/GenFvInternalLib.c index af87d6fa23..da60df8363 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.c +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.c @@ -22,12 +22,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #endif #include +#include #include #include "GenFvInternalLib.h" #include "FvLib.h" -#include "PeCoffLib.h" +#include +#include + +#include "../../../ImageTool/ImageToolEmit.h" #define ARM64_UNCONDITIONAL_JUMP_INSTRUCTION 0x14000000 @@ -718,24 +722,24 @@ Returns: EFI_STATUS WriteMapFile ( IN OUT FILE *FvMapFile, - IN CHAR8 *FileName, + IN CONST CHAR8 *FileName, IN EFI_FFS_FILE_HEADER *FfsFile, IN EFI_PHYSICAL_ADDRESS ImageBaseAddress, - IN PE_COFF_LOADER_IMAGE_CONTEXT *pImageContext + IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *pImageContext ) /*++ Routine Description: This function gets the basic debug information (entrypoint, baseaddress, .text, .data section base address) - from PE/COFF image and abstracts Pe Map file information and add them into FvMap file for Debug. + from UEFI image and abstracts UEFI image Map file information and add them into FvMap file for Debug. Arguments: FvMapFile A pointer to FvMap File FileName Ffs File PathName FfsFile A pointer to Ffs file image. - ImageBaseAddress PeImage Base Address. + ImageBaseAddress UefiImage Base Address. pImageContext Image Context Information. Returns: @@ -755,9 +759,8 @@ Returns: EFI_PHYSICAL_ADDRESS FunctionAddress; UINT32 FunctionType; CHAR8 FunctionTypeName [MAX_LINE_LEN]; + UINT8 Format; UINT32 AddressOfEntryPoint; - UINT32 Offset; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; long long TempLongAddress; EFI_PHYSICAL_ADDRESS LinkTimeBaseAddress; BOOLEAN IsUseClang; @@ -823,13 +826,9 @@ Returns: *Cptr2 = '.'; // - // AddressOfEntryPoint and Offset in Image + // AddressOfEntryPoint in Image // - assert (!pImageContext->IsTeImage); - - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINT8 *) pImageContext->Handle + pImageContext->PeCoffHeaderOffset); - AddressOfEntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; - Offset = 0; + AddressOfEntryPoint = UefiImageGetEntryPointAddress (pImageContext); // // module information output @@ -839,11 +838,18 @@ Returns: fprintf (FvMapFile, "BaseAddress=%010llx, ", (unsigned long long) ImageBaseAddress); } else { fprintf (FvMapFile, "%s (Fixed Flash Address, ", KeyWord); - fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) (ImageBaseAddress + Offset)); + fprintf (FvMapFile, "BaseAddress=0x%010llx, ", (unsigned long long) ImageBaseAddress); } + Format = UefiImageGetFormat (pImageContext); + fprintf (FvMapFile, "EntryPoint=0x%010llx, ", (unsigned long long) (ImageBaseAddress + AddressOfEntryPoint)); - fprintf (FvMapFile, "Type=PE"); + if (Format == UefiImageFormatPe) { + fprintf (FvMapFile, "Type=PE"); + } else { + assert (FALSE); + fprintf (FvMapFile, "Type=Unknown"); + } fprintf (FvMapFile, ")\n"); fprintf (FvMapFile, "(GUID=%s)\n\n", FileGuidName); @@ -1260,7 +1266,7 @@ Returns: return EFI_ABORTED; } // - // Rebase the PE image in FileBuffer of FFS file for XIP + // Rebase the UEFI image in FileBuffer of FFS file for XIP // Rebase for the debug genfvmap tool // Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) *VtfFileImage - (UINTN) FvImage->FileImage, FvMapFile); @@ -1312,7 +1318,7 @@ Returns: // if ((UINTN) (FvImage->CurrentFilePointer + FileSize) <= (UINTN) (*VtfFileImage)) { // - // Rebase the PE image in FileBuffer of FFS file for XIP. + // Rebase the UEFI image in FileBuffer of FFS file for XIP. // Rebase Bs and Rt drivers for the debug genfvmap tool. // Status = FfsRebase (FvInfo, FvInfo->FvFiles[Index], (EFI_FFS_FILE_HEADER **)&FileBuffer, &FileSize, (UINTN) FvImage->CurrentFilePointer - (UINTN) FvImage->FileImage, FvMapFile); @@ -1549,14 +1555,15 @@ Returns: } SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader); - Status = GetPe32Info ( + Status = GetUefiImageInfo ( (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize), + GetSectionFileLength (Pe32Section.CommonHeader) - SecHeaderSize, &EntryPoint, &MachineType ); if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the SEC core."); + Error (NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the SEC core."); return EFI_ABORTED; } @@ -1574,7 +1581,7 @@ Returns: } // - // Physical address is FV base + offset of PE32 + offset of the entry point + // Physical address is FV base + offset of UEFI image + offset of the entry point // SecCorePhysicalAddress = FvInfo->BaseAddress; SecCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage; @@ -1597,18 +1604,19 @@ Returns: } SecHeaderSize = GetSectionHeaderLength(Pe32Section.CommonHeader); - Status = GetPe32Info ( + Status = GetUefiImageInfo ( (VOID *) ((UINTN) Pe32Section.Pe32Section + SecHeaderSize), + GetSectionFileLength (Pe32Section.CommonHeader) - SecHeaderSize, &EntryPoint, &MachineType ); if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the PEI core."); + Error (NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the PEI core."); return EFI_ABORTED; } // - // Physical address is FV base + offset of PE32 + offset of the entry point + // Physical address is FV base + offset of UEFI image + offset of the entry point // PeiCorePhysicalAddress = FvInfo->BaseAddress; PeiCorePhysicalAddress += (UINTN) Pe32Section.Pe32Section + SecHeaderSize - (UINTN) FvImage->FileImage; @@ -1842,13 +1850,14 @@ Returns: return EFI_INVALID_PARAMETER; } - Status = GetPe32Info( + Status = GetUefiImageInfo( (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)), + GetSectionFileLength (Pe32Section.CommonHeader) - GetSectionHeaderLength(Pe32Section.CommonHeader), &EntryPoint, CoreMachineType ); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "could not get the PE32 machine type for the core."); + Error(NULL, 0, 3000, "Invalid", "could not get the UEFI image machine type for the core."); return EFI_ABORTED; } @@ -1872,7 +1881,7 @@ Arguments: FvImageBuffer Pointer to buffer containing FV data FvInfo Info for the parent FV - Pe32Section PE32 section data + Pe32Section UEFI image section data CoreEntryAddress The extracted core entry physical address Returns: @@ -1892,18 +1901,19 @@ Returns: return EFI_INVALID_PARAMETER; } - Status = GetPe32Info( + Status = GetUefiImageInfo( (VOID *)((UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader)), + GetSectionFileLength (Pe32Section.CommonHeader) - GetSectionHeaderLength(Pe32Section.CommonHeader), &EntryPoint, &MachineType ); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "could not get the PE32 entry point for the core."); + Error(NULL, 0, 3000, "Invalid", "could not get the UEFI image entry point for the core."); return EFI_ABORTED; } // - // Physical address is FV base + offset of PE32 + offset of the entry point + // Physical address is FV base + offset of UEFI image + offset of the entry point // EntryPhysicalAddress = FvInfo->BaseAddress; EntryPhysicalAddress += (UINTN)Pe32Section.Pe32Section + GetSectionHeaderLength(Pe32Section.CommonHeader) - (UINTN)FvImageBuffer; @@ -1989,13 +1999,13 @@ Returns: Status = GetCoreMachineType(SecPe32, &MachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC Core."); return EFI_ABORTED; } Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core."); return EFI_ABORTED; } @@ -2011,13 +2021,13 @@ Returns: Status = GetCoreMachineType(PeiPe32, &PeiMachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for PEI Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for PEI Core."); return EFI_ABORTED; } Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, PeiPe32, &PeiCoreEntryAddress); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for PEI Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for PEI Core."); return EFI_ABORTED; } @@ -2208,7 +2218,7 @@ Returns: Status = GetCoreMachineType(SecPe32, &MachineType); if(EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC core."); return EFI_ABORTED; } @@ -2219,7 +2229,7 @@ Returns: Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress); if(EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core."); return EFI_ABORTED; } @@ -2297,13 +2307,13 @@ Returns: Status = GetCoreMachineType(SecPe32, &MachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC Core."); return EFI_ABORTED; } Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image entry point address for SEC Core."); return EFI_ABORTED; } @@ -2340,8 +2350,9 @@ Returns: } EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, +GetUefiImageInfo ( + IN UINT8 *UefiImage, + IN UINT32 UefiImageSize, OUT UINT32 *EntryPoint, OUT UINT16 *MachineType ) @@ -2349,14 +2360,15 @@ GetPe32Info ( Routine Description: - Retrieves the PE32 entry point offset and machine type from PE image or TeImage. + Retrieves the UEFI image entry point offset and machine type from UEFI image. See EfiImage.h for machine types. The entry point offset is from the beginning - of the PE32 buffer passed in. + of the UEFI image buffer passed in. Arguments: - Pe32 Beginning of the PE32. - EntryPoint Offset from the beginning of the PE32 to the image entry point. + UefiImage Beginning of the UEFI image. + UefiImageSize The size, in bytes, of UefiImage. + EntryPoint Offset from the beginning of the UEFI image to the image entry point. MachineType Magic number for the machine type. Returns: @@ -2368,46 +2380,23 @@ Returns: --*/ { - EFI_IMAGE_DOS_HEADER *DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT Context; // // Verify input parameters // - if (Pe32 == NULL) { + if (UefiImage == NULL) { return EFI_INVALID_PARAMETER; } - // - // Check whether - // First is the DOS header - // - DosHeader = (EFI_IMAGE_DOS_HEADER *) Pe32; - - // - // Verify DOS header is expected - // - if (DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "Unknown magic number in the DOS header, 0x%04X.", DosHeader->e_magic); - return EFI_UNSUPPORTED; + RETURN_STATUS Status = UefiImageInitializeContext (&Context, UefiImage, UefiImageSize); + if (RETURN_ERROR (Status)) { + Error (NULL, 0, 3000, "Invalid", "Unrecognized UEFI image file."); + return Status; } - // - // Immediately following is the NT header. - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *) ((UINTN) Pe32 + DosHeader->e_lfanew); - // - // Verify NT header is expected - // - if (ImgHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) { - Error (NULL, 0, 3000, "Invalid", "Unrecognized image signature 0x%08X.", (unsigned) ImgHdr->Pe32.Signature); - return EFI_UNSUPPORTED; - } - // - // Get output - // - *EntryPoint = ImgHdr->Pe32.OptionalHeader.AddressOfEntryPoint; - *MachineType = ImgHdr->Pe32.FileHeader.Machine; + *EntryPoint = UefiImageGetEntryPointAddress (&Context); + *MachineType = UefiImageGetMachine (&Context); // // Verify machine type is supported @@ -2415,7 +2404,7 @@ Returns: if ((*MachineType != IMAGE_FILE_MACHINE_I386) && (*MachineType != IMAGE_FILE_MACHINE_X64) && (*MachineType != IMAGE_FILE_MACHINE_EBC) && (*MachineType != IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) && (*MachineType != IMAGE_FILE_MACHINE_ARM64) && (*MachineType != IMAGE_FILE_MACHINE_RISCV64) && (*MachineType != IMAGE_FILE_MACHINE_LOONGARCH64)) { - Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file."); + Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the UEFI image file."); return EFI_UNSUPPORTED; } @@ -3263,50 +3252,6 @@ Returns: return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - EFI_STATUS GetChildFvFromFfs ( IN FV_INFO *FvInfo, @@ -3360,7 +3305,7 @@ Returns: if (!EFI_ERROR(Status)) { Status = GetCoreMachineType(CorePe32, &MachineType); if (EFI_ERROR(Status)) { - Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC/PEI Core."); + Error(NULL, 0, 3000, "Invalid", "Could not get the UEFI image machine type for SEC/PEI Core."); return EFI_ABORTED; } @@ -3519,32 +3464,40 @@ Returns: --*/ { EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - PE_COFF_LOADER_IMAGE_CONTEXT OrigImageContext; + UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext; + UINT16 Machine; EFI_PHYSICAL_ADDRESS XipBase; - EFI_PHYSICAL_ADDRESS NewPe32BaseAddress; + EFI_PHYSICAL_ADDRESS NewBaseAddress; UINTN Index; EFI_FILE_SECTION_POINTER CurrentPe32Section; EFI_FFS_FILE_STATE SavedState; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - UINT8 *MemoryImagePointer; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - CHAR8 PeFileName [MAX_LONG_FILE_PATH]; + CHAR8 UefiImageFileName [MAX_LONG_FILE_PATH]; CHAR8 *Cptr; - FILE *PeFile; - UINT8 *PeFileBuffer; - UINT32 PeFileSize; - CHAR8 *PdbPointer; + FILE *UefiImageFile; + UINT8 *UefiImageFileBuffer; + UINT32 UefiImageFileSize; + BOOLEAN FreeUefiImageFile; + CONST CHAR8 *SymbolsPath; + UINT32 SymbolsPathSize; + CHAR8 *SymbolsPathCpy; UINT32 FfsHeaderSize; UINT32 CurSecHdrSize; + UINT32 SectPeSize; + UINT32 ImageSize; + UINT32 DestinationPages; + UINT32 DestinationSize; + UINT32 ImageAlignment; + VOID *Destination; + BOOLEAN Strip; + UINT8 ImageFormat; + UINT32 RebasedImageSize; + VOID *RebasedImage; - Index = 0; - MemoryImagePointer = NULL; - ImgHdr = NULL; - SectionHeader = NULL; - Cptr = NULL; - PeFile = NULL; - PeFileBuffer = NULL; + Index = 0; + Cptr = NULL; + UefiImageFile = NULL; + UefiImageFileBuffer = NULL; + FreeUefiImageFile = FALSE; // // Don't need to relocate image when BaseAddress is zero and no ForceRebase Flag specified. @@ -3562,6 +3515,8 @@ Returns: XipBase = FvInfo->BaseAddress + XipOffset; + Strip = FALSE; + // // We only process files potentially containing PE32 sections. // @@ -3596,7 +3551,7 @@ Returns: // // Init Value // - NewPe32BaseAddress = 0; + NewBaseAddress = 0; // // Find Pe Image @@ -3610,140 +3565,76 @@ Returns: // // Initialize context // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); + SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize; + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), + SectPeSize + ); if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status); + Error (NULL, 0, 3000, "Invalid UefiImage", "The input file is %s and the return status is %x", FileName, (int) Status); return Status; } - if ( (ImageContext.Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || - (ImageContext.Machine == IMAGE_FILE_MACHINE_ARM64) ) { + Machine = UefiImageGetMachine (&ImageContext); + + if ( (Machine == IMAGE_FILE_MACHINE_ARMTHUMB_MIXED) || + (Machine == IMAGE_FILE_MACHINE_AARCH64) ) { mArm = TRUE; } - if (ImageContext.Machine == IMAGE_FILE_MACHINE_RISCV64) { + if (Machine == IMAGE_FILE_MACHINE_RISCV64) { mRiscV = TRUE; } - if (ImageContext.Machine == IMAGE_FILE_MACHINE_LOONGARCH64) { + if (Machine == IMAGE_FILE_MACHINE_LOONGARCH64) { mLoongArch = TRUE; } + ImageFormat = UefiImageGetFormat (&ImageContext); + + ImageSize = UefiImageGetImageSize (&ImageContext); + DestinationPages = EFI_SIZE_TO_PAGES (ImageSize); + DestinationSize = EFI_PAGES_TO_SIZE (DestinationPages); + ImageAlignment = UefiImageGetSegmentAlignment (&ImageContext); + Destination = AllocateAlignedCodePages (DestinationPages, ImageAlignment); + if (Destination == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = UefiImageLoadImage (&ImageContext, Destination, DestinationSize); + if (EFI_ERROR (Status)) { + return Status; + } + + SymbolsPathCpy = NULL; // - // Keep Image Context for PE image in FV + // Get File SymbolsPath // - memcpy (&OrigImageContext, &ImageContext, sizeof (ImageContext)); + Status = UefiImageGetSymbolsPath (&ImageContext, &SymbolsPath, &SymbolsPathSize); + if (!RETURN_ERROR (Status)) { + SymbolsPathCpy = malloc (SymbolsPathSize); + if (SymbolsPathCpy == NULL) { + FreeAlignedPages (Destination, DestinationPages); + return EFI_OUT_OF_RESOURCES; + } + + memmove (SymbolsPathCpy, SymbolsPath, SymbolsPathSize); + } + + FreeAlignedPages (Destination, DestinationPages); // - // Get File PdbPointer - // - PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle); - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset); - - // - // Calculate the PE32 base address, based on file type + // Calculate the UEFI image base address, based on file type // switch ((*FfsFile)->Type) { case EFI_FV_FILETYPE_SECURITY_CORE: case EFI_FV_FILETYPE_PEI_CORE: case EFI_FV_FILETYPE_PEIM: case EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER: - // - // Check if section-alignment and file-alignment match or not - // - if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) { - // - // Xip module has the same section alignment and file alignment. - // - Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName); - return EFI_ABORTED; - } - // - // PeImage has no reloc section. It will try to get reloc data from the original EFI image. - // - if (ImageContext.RelocationsStripped) { - // - // Construct the original efi file Name - // - if (strlen (FileName) >= MAX_LONG_FILE_PATH) { - Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName); - return EFI_ABORTED; - } - strncpy (PeFileName, FileName, MAX_LONG_FILE_PATH - 1); - PeFileName[MAX_LONG_FILE_PATH - 1] = 0; - Cptr = PeFileName + strlen (PeFileName); - while (*Cptr != '.') { - Cptr --; - } - if (*Cptr != '.') { - Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); - return EFI_ABORTED; - } else { - *(Cptr + 1) = 'e'; - *(Cptr + 2) = 'f'; - *(Cptr + 3) = 'i'; - *(Cptr + 4) = '\0'; - } - PeFile = fopen (LongFilePath (PeFileName), "rb"); - if (PeFile == NULL) { - Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); - //return EFI_ABORTED; - break; - } - // - // Get the file size - // - PeFileSize = _filelength (fileno (PeFile)); - PeFileBuffer = (UINT8 *) malloc (PeFileSize); - if (PeFileBuffer == NULL) { - fclose (PeFile); - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - // - // Read Pe File - // - fread (PeFileBuffer, sizeof (UINT8), PeFileSize, PeFile); - // - // close file - // - fclose (PeFile); - // - // Handle pointer to the original efi image. - // - ImageContext.Handle = PeFileBuffer; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and the return status is %x", FileName, (int) Status); - return Status; - } - ImageContext.RelocationsStripped = FALSE; - } - - NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); - break; - case EFI_FV_FILETYPE_DRIVER: case EFI_FV_FILETYPE_DXE_CORE: - // - // Check if section-alignment and file-alignment match or not - // - if ((ImgHdr->Pe32.OptionalHeader.SectionAlignment != ImgHdr->Pe32.OptionalHeader.FileAlignment)) { - // - // Xip module has the same section alignment and file alignment. - // - Error (NULL, 0, 3000, "Invalid", "PE image Section-Alignment and File-Alignment do not match : %s.", FileName); - return EFI_ABORTED; - } - NewPe32BaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); + NewBaseAddress = XipBase + (UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize - (UINTN)(*FfsFile); break; default: @@ -3753,97 +3644,122 @@ Returns: return EFI_SUCCESS; } - // - // Relocation doesn't exist - // - if (ImageContext.RelocationsStripped) { - Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); - continue; - } + Strip = UefiImageGetRelocsStripped (&ImageContext); - // - // Relocation exist and rebase - // - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) calloc (1, (UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - ImageContext.ImageAddress = ALIGN_VALUE ((UINTN)MemoryImagePointer, ImageContext.SectionAlignment); - - if (!(IS_ALIGNED (NewPe32BaseAddress, ImageContext.SectionAlignment))) { - Status = AddPadSection (&NewPe32BaseAddress, ImageContext.SectionAlignment, FfsFile, FileSize, &CurrentPe32Section); + if (!(IS_ALIGNED (NewBaseAddress, ImageAlignment))) { + Status = AddPadSection (&NewBaseAddress, ImageAlignment, FfsFile, FileSize, &CurrentPe32Section); if (EFI_ERROR (Status)) { - free ((VOID *) MemoryImagePointer); return Status; } - CurSecHdrSize = GetSectionHeaderLength (CurrentPe32Section.CommonHeader); - ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); - PdbPointer = PeCoffLoaderGetPdbPointer (ImageContext.Handle); + CurSecHdrSize = GetSectionHeaderLength (CurrentPe32Section.CommonHeader); - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize + ImageContext.PeCoffHeaderOffset); + SectPeSize = GetSectionFileLength (CurrentPe32Section.CommonHeader) - CurSecHdrSize; } - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } + UefiImageFileBuffer = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize); + UefiImageFileSize = SectPeSize; + // + // UefiImage has no reloc section. It will try to get reloc data from the original UEFI image. + // + if (Strip) { + // + // Construct the original efi file Name + // + if (strlen (FileName) >= MAX_LONG_FILE_PATH) { + Error (NULL, 0, 2000, "Invalid", "The file name %s is too long.", FileName); + return EFI_ABORTED; + } + strncpy (UefiImageFileName, FileName, MAX_LONG_FILE_PATH - 1); + UefiImageFileName[MAX_LONG_FILE_PATH - 1] = 0; + Cptr = UefiImageFileName + strlen (UefiImageFileName); + while (*Cptr != '.') { + Cptr --; + } + if (*Cptr != '.') { + Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); + return EFI_ABORTED; + } else { + *(Cptr + 1) = 'e'; + *(Cptr + 2) = 'f'; + *(Cptr + 3) = 'i'; + *(Cptr + 4) = '\0'; + } + UefiImageFile = fopen (LongFilePath (UefiImageFileName), "rb"); + if (UefiImageFile == NULL) { + Warning (NULL, 0, 0, "Invalid", "The file %s has no .reloc section.", FileName); + //Error (NULL, 0, 3000, "Invalid", "The file %s has no .reloc section.", FileName); + //return EFI_ABORTED; + break; + } + // + // Get the file size + // + UefiImageFileSize = _filelength (fileno (UefiImageFile)); + UefiImageFileBuffer = (UINT8 *) malloc (UefiImageFileSize); + if (UefiImageFileBuffer == NULL) { + fclose (UefiImageFile); + Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); + return EFI_OUT_OF_RESOURCES; + } - ImageContext.DestinationAddress = NewPe32BaseAddress; - - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s Status=%d", FileName, Status); - free ((VOID *) MemoryImagePointer); - return Status; + FreeUefiImageFile = TRUE; + // + // Read Pe File + // + fread (UefiImageFileBuffer, sizeof (UINT8), UefiImageFileSize, UefiImageFile); + // + // close file + // + fclose (UefiImageFile); } // - // Copy Relocated data to raw image file. + // Load and Relocate Image Data // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); + RebasedImage = ToolImageEmit ( + &RebasedImageSize, + UefiImageFileBuffer, + UefiImageFileSize, + ImageFormat, + -1, + NULL, + 0, + true, + NewBaseAddress, + NULL, + Strip, + FALSE + ); - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - CopyMem ( - (UINT8 *) CurrentPe32Section.Pe32Section + CurSecHdrSize + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); + if (FreeUefiImageFile) { + free (UefiImageFileBuffer); } - free ((VOID *) MemoryImagePointer); - MemoryImagePointer = NULL; - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; + if (RebasedImage == NULL) { + Error (NULL, 0, 4001, "Invalid", "failed to rebase (%s)", FileName); + return EFI_UNSUPPORTED; } - // - // Update Image Base Address - // - if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress; - } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress; - } else { - Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s", - ImgHdr->Pe32.OptionalHeader.Magic, - FileName - ); - return EFI_ABORTED; + UefiImageFileBuffer = NULL; + UefiImageFileSize = 0; + + if (RebasedImageSize > SectPeSize) { + Error (NULL, 0, 4001, "Invalid", "rebased file is too large (%s)", FileName); + return EFI_UNSUPPORTED; } + memmove ( + (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize, + RebasedImage, + RebasedImageSize + ); + memset ( + (UINT8 *)CurrentPe32Section.Pe32Section + CurSecHdrSize + RebasedImageSize, + 0, + SectPeSize - RebasedImageSize + ); + // // Now update file checksum // @@ -3862,14 +3778,25 @@ Returns: // Get this module function address from ModulePeMapFile and add them into FvMap file // + Status = UefiImageInitializeContext ( + &ImageContext, + (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + CurSecHdrSize), + RebasedImageSize + ); + ASSERT_EFI_ERROR (Status); + // // Default use FileName as map file path // - if (PdbPointer == NULL) { - PdbPointer = FileName; - } + WriteMapFile ( + FvMapFile, + SymbolsPathCpy != NULL ? SymbolsPathCpy : FileName, + *FfsFile, + NewBaseAddress, + &ImageContext + ); - WriteMapFile (FvMapFile, PdbPointer, *FfsFile, NewPe32BaseAddress, &ImageContext); + free (SymbolsPathCpy); } return EFI_SUCCESS; diff --git a/BaseTools/Source/C/GenFv/GenFvInternalLib.h b/BaseTools/Source/C/GenFv/GenFvInternalLib.h index dc6b2aca91..ff668f385b 100644 --- a/BaseTools/Source/C/GenFv/GenFvInternalLib.h +++ b/BaseTools/Source/C/GenFv/GenFvInternalLib.h @@ -22,7 +22,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include "CommonLib.h" #include "ParseInf.h" @@ -304,8 +303,9 @@ Returns: ; EFI_STATUS -GetPe32Info ( - IN UINT8 *Pe32, +GetUefiImageInfo ( + IN UINT8 *UefiImage, + IN UINT32 UefiImageSize, OUT UINT32 *EntryPoint, OUT UINT16 *MachineType ); diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c index fab813902b..70f449183b 100644 --- a/BaseTools/Source/C/GenSec/GenSec.c +++ b/BaseTools/Source/C/GenSec/GenSec.c @@ -22,7 +22,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include "CommonLib.h" #include "Compress.h" @@ -30,7 +29,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "EfiUtilityMsgs.h" #include "ParseInf.h" #include "FvLib.h" -#include "PeCoffLib.h" // // GenSec Tool Information @@ -1125,104 +1123,6 @@ Returns: return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -FfsRebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) - /*++ - - Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - - Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - - Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - - --*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -STATIC -EFI_STATUS -GetAlignmentFromFile(char *InFile, UINT32 *Alignment) - /* - InFile is input file for getting alignment - return the alignment - */ -{ - FILE *InFileHandle; - UINT8 *PeFileBuffer; - UINTN PeFileSize; - UINT32 CurSecHdrSize; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - EFI_COMMON_SECTION_HEADER *CommonHeader; - EFI_STATUS Status; - - InFileHandle = NULL; - PeFileBuffer = NULL; - *Alignment = 0; - - memset (&ImageContext, 0, sizeof (ImageContext)); - - InFileHandle = fopen(LongFilePath(InFile), "rb"); - if (InFileHandle == NULL){ - Error (NULL, 0, 0001, "Error opening file", InFile); - return EFI_ABORTED; - } - PeFileSize = _filelength (fileno(InFileHandle)); - PeFileBuffer = (UINT8 *) malloc (PeFileSize); - if (PeFileBuffer == NULL) { - fclose (InFileHandle); - Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile); - return EFI_OUT_OF_RESOURCES; - } - fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle); - fclose (InFileHandle); - CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer; - CurSecHdrSize = GetSectionHeaderLength(CommonHeader); - ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize); - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead; - Status = PeCoffLoaderGetImageInfo(&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status); - return Status; - } - *Alignment = ImageContext.SectionAlignment; - // Free the allocated memory resource - if (PeFileBuffer != NULL) { - free (PeFileBuffer); - PeFileBuffer = NULL; - } - return EFI_SUCCESS; -} - int main ( int argc, diff --git a/BaseTools/Source/C/Include/Common/AutoGen.h b/BaseTools/Source/C/Include/Common/AutoGen.h index 150994a7e1..bf5bc9a063 100644 --- a/BaseTools/Source/C/Include/Common/AutoGen.h +++ b/BaseTools/Source/C/Include/Common/AutoGen.h @@ -1,101 +1,171 @@ -/** @file - AutoGen definitions for edk2 package code consumption in BaseTools. - - Copyright (c) 2023, Marvin Häuser. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef _BT_AUTOGENH -#define _BT_AUTOGENH - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -extern GUID gEfiCallerIdGuid; -extern GUID gEdkiiDscPlatformGuid; -extern CHAR8 *gEfiCallerBaseName; - -#define EFI_CALLER_ID_GUID \ - {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} -#define EDKII_DSC_PLATFORM_GUID \ - {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} - -// Definition of SkuId Array -extern UINT64 _gPcd_SkuId_Array[]; - -// Definition of PCDs used in this module - -#define _PCD_TOKEN_PcdMaximumAsciiStringLength 0U -#define _PCD_SIZE_PcdMaximumAsciiStringLength 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumAsciiStringLength _PCD_SIZE_PcdMaximumAsciiStringLength -#define _PCD_VALUE_PcdMaximumAsciiStringLength 0U -#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength _PCD_VALUE_PcdMaximumAsciiStringLength -//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdMaximumUnicodeStringLength 0U -#define _PCD_SIZE_PcdMaximumUnicodeStringLength 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumUnicodeStringLength _PCD_SIZE_PcdMaximumUnicodeStringLength -#define _PCD_VALUE_PcdMaximumUnicodeStringLength 0U -#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength _PCD_VALUE_PcdMaximumUnicodeStringLength -//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdMaximumLinkedListLength 0U -#define _PCD_SIZE_PcdMaximumLinkedListLength 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumLinkedListLength _PCD_SIZE_PcdMaximumLinkedListLength -#define _PCD_VALUE_PcdMaximumLinkedListLength 0U -#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength _PCD_VALUE_PcdMaximumLinkedListLength -//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdMaximumDevicePathNodeCount 0U -#define _PCD_SIZE_PcdMaximumDevicePathNodeCount 4 -#define _PCD_GET_MODE_SIZE_PcdMaximumDevicePathNodeCount _PCD_SIZE_PcdMaximumDevicePathNodeCount -#define _PCD_VALUE_PcdMaximumDevicePathNodeCount 0U -#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount _PCD_VALUE_PcdMaximumDevicePathNodeCount -//#define _PCD_SET_MODE_32_PcdMaximumDevicePathNodeCount ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdVerifyNodeInList 0U -#define _PCD_SIZE_PcdVerifyNodeInList 1 -#define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList _PCD_SIZE_PcdVerifyNodeInList -#define _PCD_VALUE_PcdVerifyNodeInList 1U -#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList _PCD_VALUE_PcdVerifyNodeInList -//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdFixedDebugPrintErrorLevel 0U -#define _PCD_SIZE_PcdFixedDebugPrintErrorLevel 4 -#define _PCD_GET_MODE_SIZE_PcdFixedDebugPrintErrorLevel _PCD_SIZE_PcdFixedDebugPrintErrorLevel -#define _PCD_VALUE_PcdFixedDebugPrintErrorLevel 0xFFFFFFFFU -#define _PCD_GET_MODE_32_PcdFixedDebugPrintErrorLevel _PCD_VALUE_PcdFixedDebugPrintErrorLevel -//#define _PCD_SET_MODE_32_PcdFixedDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdDebugPropertyMask 0U -#define _PCD_SIZE_PcdDebugPropertyMask 1 -#define _PCD_GET_MODE_SIZE_PcdDebugPropertyMask _PCD_SIZE_PcdDebugPropertyMask -#define _PCD_VALUE_PcdDebugPropertyMask 0xFFU -#define _PCD_GET_MODE_8_PcdDebugPropertyMask _PCD_VALUE_PcdDebugPropertyMask -//#define _PCD_SET_MODE_8_PcdDebugPropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdDebugClearMemoryValue 0U -#define _PCD_SIZE_PcdDebugClearMemoryValue 1 -#define _PCD_GET_MODE_SIZE_PcdDebugClearMemoryValue _PCD_SIZE_PcdDebugClearMemoryValue -#define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU -#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue _PCD_VALUE_PcdDebugClearMemoryValue -//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - -#define _PCD_TOKEN_PcdDebugPrintErrorLevel 0U -#define _PCD_SIZE_PcdDebugPrintErrorLevel 4 -#define _PCD_GET_MODE_SIZE_PcdDebugPrintErrorLevel _PCD_SIZE_PcdDebugPrintErrorLevel -#define _PCD_VALUE_PcdDebugPrintErrorLevel 0x8000004F -#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel _PCD_VALUE_PcdDebugPrintErrorLevel -//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD - - -#ifdef __cplusplus -} -#endif - -#endif +/** @file + AutoGen definitions for edk2 package code consumption in BaseTools. + + Copyright (c) 2023, Marvin Häuser. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _BT_AUTOGENH +#define _BT_AUTOGENH + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern GUID gEfiCallerIdGuid; +extern GUID gEdkiiDscPlatformGuid; +extern CHAR8 *gEfiCallerBaseName; + +#define EFI_CALLER_ID_GUID \ + {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} +#define EDKII_DSC_PLATFORM_GUID \ + {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} + +// Definition of SkuId Array +extern UINT64 _gPcd_SkuId_Array[]; + +// Definition of PCDs used in this module + +#define _PCD_TOKEN_PcdMaximumAsciiStringLength 0U +#define _PCD_SIZE_PcdMaximumAsciiStringLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumAsciiStringLength _PCD_SIZE_PcdMaximumAsciiStringLength +#define _PCD_VALUE_PcdMaximumAsciiStringLength 0U +#define _PCD_GET_MODE_32_PcdMaximumAsciiStringLength _PCD_VALUE_PcdMaximumAsciiStringLength +//#define _PCD_SET_MODE_32_PcdMaximumAsciiStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumUnicodeStringLength 0U +#define _PCD_SIZE_PcdMaximumUnicodeStringLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumUnicodeStringLength _PCD_SIZE_PcdMaximumUnicodeStringLength +#define _PCD_VALUE_PcdMaximumUnicodeStringLength 0U +#define _PCD_GET_MODE_32_PcdMaximumUnicodeStringLength _PCD_VALUE_PcdMaximumUnicodeStringLength +//#define _PCD_SET_MODE_32_PcdMaximumUnicodeStringLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumLinkedListLength 0U +#define _PCD_SIZE_PcdMaximumLinkedListLength 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumLinkedListLength _PCD_SIZE_PcdMaximumLinkedListLength +#define _PCD_VALUE_PcdMaximumLinkedListLength 0U +#define _PCD_GET_MODE_32_PcdMaximumLinkedListLength _PCD_VALUE_PcdMaximumLinkedListLength +//#define _PCD_SET_MODE_32_PcdMaximumLinkedListLength ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdMaximumDevicePathNodeCount 0U +#define _PCD_SIZE_PcdMaximumDevicePathNodeCount 4 +#define _PCD_GET_MODE_SIZE_PcdMaximumDevicePathNodeCount _PCD_SIZE_PcdMaximumDevicePathNodeCount +#define _PCD_VALUE_PcdMaximumDevicePathNodeCount 0U +#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount _PCD_VALUE_PcdMaximumDevicePathNodeCount +//#define _PCD_SET_MODE_32_PcdMaximumDevicePathNodeCount ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdVerifyNodeInList 0U +#define _PCD_SIZE_PcdVerifyNodeInList 1 +#define _PCD_GET_MODE_SIZE_PcdVerifyNodeInList _PCD_SIZE_PcdVerifyNodeInList +#define _PCD_VALUE_PcdVerifyNodeInList 1U +#define _PCD_GET_MODE_BOOL_PcdVerifyNodeInList _PCD_VALUE_PcdVerifyNodeInList +//#define _PCD_SET_MODE_BOOL_PcdVerifyNodeInList ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdFixedDebugPrintErrorLevel 0U +#define _PCD_SIZE_PcdFixedDebugPrintErrorLevel 4 +#define _PCD_GET_MODE_SIZE_PcdFixedDebugPrintErrorLevel _PCD_SIZE_PcdFixedDebugPrintErrorLevel +#define _PCD_VALUE_PcdFixedDebugPrintErrorLevel 0xFFFFFFFFU +#define _PCD_GET_MODE_32_PcdFixedDebugPrintErrorLevel _PCD_VALUE_PcdFixedDebugPrintErrorLevel +//#define _PCD_SET_MODE_32_PcdFixedDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugPropertyMask 0U +#define _PCD_SIZE_PcdDebugPropertyMask 1 +#define _PCD_GET_MODE_SIZE_PcdDebugPropertyMask _PCD_SIZE_PcdDebugPropertyMask +#define _PCD_VALUE_PcdDebugPropertyMask 0xFFU +#define _PCD_GET_MODE_8_PcdDebugPropertyMask _PCD_VALUE_PcdDebugPropertyMask +//#define _PCD_SET_MODE_8_PcdDebugPropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugClearMemoryValue 0U +#define _PCD_SIZE_PcdDebugClearMemoryValue 1 +#define _PCD_GET_MODE_SIZE_PcdDebugClearMemoryValue _PCD_SIZE_PcdDebugClearMemoryValue +#define _PCD_VALUE_PcdDebugClearMemoryValue 0xAFU +#define _PCD_GET_MODE_8_PcdDebugClearMemoryValue _PCD_VALUE_PcdDebugClearMemoryValue +//#define _PCD_SET_MODE_8_PcdDebugClearMemoryValue ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugPrintErrorLevel 0U +#define _PCD_SIZE_PcdDebugPrintErrorLevel 4 +#define _PCD_GET_MODE_SIZE_PcdDebugPrintErrorLevel _PCD_SIZE_PcdDebugPrintErrorLevel +#define _PCD_VALUE_PcdDebugPrintErrorLevel 0x8000004F +#define _PCD_GET_MODE_32_PcdDebugPrintErrorLevel _PCD_VALUE_PcdDebugPrintErrorLevel +//#define _PCD_SET_MODE_32_PcdDebugPrintErrorLevel ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderDebugSupport 0U +#define _PCD_SIZE_PcdImageLoaderDebugSupport 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderDebugSupport _PCD_SIZE_PcdImageLoaderDebugSupport +#define _PCD_VALUE_PcdImageLoaderDebugSupport TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderDebugSupport _PCD_VALUE_PcdImageLoaderDebugSupport +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderDebugSupport ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderHashProhibitOverlap 0U +#define _PCD_SIZE_PcdImageLoaderHashProhibitOverlap 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderHashProhibitOverlap _PCD_SIZE_PcdImageLoaderHashProhibitOverlap +#define _PCD_VALUE_PcdImageLoaderHashProhibitOverlap FALSE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderHashProhibitOverlap _PCD_VALUE_PcdImageLoaderHashProhibitOverlap +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderHashProhibitOverlap ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderAllowMisalignedOffset 0U +#define _PCD_SIZE_PcdImageLoaderAllowMisalignedOffset 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderAllowMisalignedOffset _PCD_SIZE_PcdImageLoaderAllowMisalignedOffset +#define _PCD_VALUE_PcdImageLoaderAllowMisalignedOffset FALSE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderAllowMisalignedOffset _PCD_VALUE_PcdImageLoaderAllowMisalignedOffset +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderAllowMisalignedOffset ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderRemoveXForWX 0U +#define _PCD_SIZE_PcdImageLoaderRemoveXForWX 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderRemoveXForWX _PCD_SIZE_PcdImageLoaderRemoveXForWX +#define _PCD_VALUE_PcdImageLoaderRemoveXForWX FALSE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderRemoveXForWX _PCD_VALUE_PcdImageLoaderRemoveXForWX +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderRemoveXForWX ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderWXorX 0U +#define _PCD_SIZE_PcdImageLoaderWXorX 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderWXorX _PCD_SIZE_PcdImageLoaderWXorX +#define _PCD_VALUE_PcdImageLoaderWXorX TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderWXorX _PCD_VALUE_PcdImageLoaderWXorX +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderWXorX ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderLoadHeader 0U +#define _PCD_SIZE_PcdImageLoaderLoadHeader 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderLoadHeader _PCD_SIZE_PcdImageLoaderLoadHeader +#define _PCD_VALUE_PcdImageLoaderLoadHeader TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderLoadHeader _PCD_VALUE_PcdImageLoaderLoadHeader +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderLoadHeader ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderRtRelocAllowTargetMismatch 0U +#define _PCD_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch 1 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch _PCD_SIZE_PcdImageLoaderRtRelocAllowTargetMismatch +#define _PCD_VALUE_PcdImageLoaderRtRelocAllowTargetMismatch TRUE +#define _PCD_GET_MODE_BOOL_PcdImageLoaderRtRelocAllowTargetMismatch _PCD_VALUE_PcdImageLoaderRtRelocAllowTargetMismatch +//#define _PCD_SET_MODE_BOOL_PcdImageLoaderRtRelocAllowTargetMismatch ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderAlignmentPolicy 0U +#define _PCD_SIZE_PcdImageLoaderAlignmentPolicy 4 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderAlignmentPolicy _PCD_SIZE_PcdImageLoaderAlignmentPolicy +#define _PCD_VALUE_PcdImageLoaderAlignmentPolicy 0U +#define _PCD_GET_MODE_32_PcdImageLoaderAlignmentPolicy _PCD_VALUE_PcdImageLoaderAlignmentPolicy +//#define _PCD_SET_MODE_32_PcdImageLoaderAlignmentPolicy ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdImageLoaderRelocTypePolicy 0U +#define _PCD_SIZE_PcdImageLoaderRelocTypePolicy 4 +#define _PCD_GET_MODE_SIZE_PcdImageLoaderRelocTypePolicy _PCD_SIZE_PcdImageLoaderRelocTypePolicy +#define _PCD_VALUE_PcdImageLoaderRelocTypePolicy 0U +#define _PCD_GET_MODE_32_PcdImageLoaderRelocTypePolicy _PCD_VALUE_PcdImageLoaderRelocTypePolicy +//#define _PCD_SET_MODE_32_PcdImageLoaderRelocTypePolicy ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + +#define _PCD_TOKEN_PcdDebugRaisePropertyMask 0U +#define _PCD_SIZE_PcdDebugRaisePropertyMask 1 +#define _PCD_GET_MODE_SIZE_PcdDebugRaisePropertyMask _PCD_SIZE_PcdDebugRaisePropertyMask +#define _PCD_VALUE_PcdDebugRaisePropertyMask 0xFFU +#define _PCD_GET_MODE_8_PcdDebugRaisePropertyMask _PCD_VALUE_PcdDebugRaisePropertyMask +//#define _PCD_SET_MODE_8_PcdDebugRaisePropertyMask ASSERT(FALSE) // It is not allowed to set value for a FIXED_AT_BUILD PCD + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/BaseTools/Source/C/Include/Common/PeImageEx.h b/BaseTools/Source/C/Include/Common/PeImageEx.h deleted file mode 100644 index 3e4e129778..0000000000 --- a/BaseTools/Source/C/Include/Common/PeImageEx.h +++ /dev/null @@ -1,59 +0,0 @@ -/** @file - EFI image format for PE32+. Please note some data structures are different - for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64 - - @bug Fix text - doc as defined in MSFT EFI specification. - - Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
- Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
- Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.
- Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __BT_PE_IMAGE_H__ -#define __BT_PE_IMAGE_H__ - -#include - -// -// PE32+ Machine type for EFI images -// -#define IMAGE_FILE_MACHINE_ARM 0x01c0 -#define IMAGE_FILE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMTHUMB_MIXED - -// -// Support old names for backward compatible -// -#define EFI_IMAGE_MACHINE_ARMT EFI_IMAGE_MACHINE_ARMTHUMB_MIXED - -#define EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // Supports addresses > 2-GB - -// -// Based export types. -// -#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1 -#define EFI_IMAGE_EXPORT_ADDR_SIZE 4 -#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2 - -// -// .pdata entries for X64 -// -typedef struct { - UINT32 FunctionStartAddress; - UINT32 FunctionEndAddress; - UINT32 UnwindInfoAddress; -} RUNTIME_FUNCTION; - -typedef struct { - UINT8 Version:3; - UINT8 Flags:5; - UINT8 SizeOfProlog; - UINT8 CountOfUnwindCodes; - UINT8 FrameRegister:4; - UINT8 FrameRegisterOffset:4; -} UNWIND_INFO; - -#endif diff --git a/BaseTools/Source/C/Makefiles/header.makefile b/BaseTools/Source/C/Makefiles/header.makefile index 12d4e720f6..f8e0b59d91 100644 --- a/BaseTools/Source/C/Makefiles/header.makefile +++ b/BaseTools/Source/C/Makefiles/header.makefile @@ -86,7 +86,7 @@ endif INCLUDE = $(TOOL_INCLUDE) -I $(MAKEROOT) -I $(MAKEROOT)/Include/Common -I $(MAKEROOT)/Include/ -I $(MAKEROOT)/Include/IndustryStandard -I $(MAKEROOT)/Common/ -I .. -I . $(ARCH_INCLUDE) -INCLUDE += -I $(EDK2_PATH)/MdePkg/Include/ -I $(EDK2_PATH)/MdeModulePkg/Include/ +INCLUDE += -I $(EDK2_PATH)/MdePkg/Include/ -I $(EDK2_PATH)/MdeModulePkg/Include/ -I $(EDK2_PATH)/OpenCorePkg/User/Include EDK2_INCLUDE = -include $(MAKEROOT)/Include/Common/AutoGen.h diff --git a/BaseTools/Source/C/Makefiles/ms.common b/BaseTools/Source/C/Makefiles/ms.common index 769da7db79..c40629e4bd 100644 --- a/BaseTools/Source/C/Makefiles/ms.common +++ b/BaseTools/Source/C/Makefiles/ms.common @@ -69,7 +69,7 @@ LINKER = $(LD) INC = $(INC) -I . -I $(SOURCE_PATH)\Include -I $(ARCH_INCLUDE) -I $(SOURCE_PATH)\Common INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -I $(EDK2_PATH)\MdeModulePkg\Include +INC = $(INC) -I $(EDK2_PATH)\MdePkg\Include -I $(EDK2_PATH)\MdeModulePkg\Include -I $(EDK2_PATH)/OpenCorePkg/User/Include EDK2_INC = $(INC) /FI..\Include\Common\AutoGen.h diff --git a/BaseTools/Source/C/Makefiles/ms.rule b/BaseTools/Source/C/Makefiles/ms.rule index 97f43126ad..c00df83714 100644 --- a/BaseTools/Source/C/Makefiles/ms.rule +++ b/BaseTools/Source/C/Makefiles/ms.rule @@ -7,6 +7,10 @@ #DEPFILES = $(OBJECTS:%.o=%.d) +{$(EDK2_PATH)\BaseTools\ImageTool\}.c{$(EDK2_OBJPATH)\BaseTools\ImageTool\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + {$(EDK2_PATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseDebugPrintErrorLevelLib\}.obj : -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ @@ -27,6 +31,22 @@ -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ +{$(EDK2_PATH)\MdePkg\Library\BaseOverflowLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseOverflowLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BasePeCoffLib2\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BasePeCoffLib2\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BaseUefiImageLib\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageLib\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + +{$(EDK2_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.c{$(EDK2_OBJPATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + {$(EDK2_PATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.c{$(EDK2_OBJPATH)\MdeModulePkg\Library\BaseMemoryProfileLibNull\}.obj : -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ @@ -35,6 +55,10 @@ -@if not exist $(@D)\ mkdir $(@D) $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ +{$(EDK2_PATH)\OpenCorePkg\User\Library\}.c{$(EDK2_OBJPATH)\OpenCorePkg\User\Library\}.obj : + -@if not exist $(@D)\ mkdir $(@D) + $(CC) -c $(CFLAGS) $(EDK2_INC) $< -Fo$@ + .c.obj : $(CC) -c $(CFLAGS) $(INC) $< -Fo$@ diff --git a/BaseTools/Source/C/VolInfo/VolInfo.c b/BaseTools/Source/C/VolInfo/VolInfo.c index 5fe962729f..c16d07ca11 100644 --- a/BaseTools/Source/C/VolInfo/VolInfo.c +++ b/BaseTools/Source/C/VolInfo/VolInfo.c @@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include +#include #include #include #include @@ -24,7 +25,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include #include #include "Compress.h" @@ -37,7 +37,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include "ParseGuidedSectionTools.h" #include "StringFuncs.h" #include "ParseInf.h" -#include "PeCoffLib.h" + +#include "../../../ImageTool/ImageToolEmit.h" // // Utility global variables @@ -1417,249 +1418,63 @@ Returns: return EFI_SUCCESS; } -EFI_STATUS -EFIAPI -RebaseImageRead ( - IN VOID *FileHandle, - IN UINTN FileOffset, - IN OUT UINT32 *ReadSize, - OUT VOID *Buffer - ) -/*++ - -Routine Description: - - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - -Arguments: - - FileHandle - The handle to the PE/COFF file - - FileOffset - The offset, in bytes, into the file to read - - ReadSize - The number of bytes to read from the file starting at FileOffset - - Buffer - A pointer to the buffer to read the data into. - -Returns: - - EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset - ---*/ -{ - CHAR8 *Destination8; - CHAR8 *Source8; - UINT32 Length; - - Destination8 = Buffer; - Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); - Length = *ReadSize; - while (Length--) { - *(Destination8++) = *(Source8++); - } - - return EFI_SUCCESS; -} - -EFI_STATUS -SetAddressToSectionHeader ( - IN CHAR8 *FileName, - IN OUT UINT8 *FileBuffer, - IN UINT64 NewPe32BaseAddress - ) -/*++ - -Routine Description: - - Set new base address into the section header of PeImage - -Arguments: - - FileName - Name of file - FileBuffer - Pointer to PeImage. - NewPe32BaseAddress - New Base Address for PE image. - -Returns: - - EFI_SUCCESS Set new base address into this image successfully. - ---*/ -{ - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - EFI_IMAGE_SECTION_HEADER *SectionHeader; - - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); - return Status; - } - - if (ImageContext.RelocationsStripped) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); - return Status; - } - - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); - - // - // Get section header list - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - // - // Set base address into the first section header that doesn't point to code section. - // - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) { - *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress; - break; - } - } - - // - // BaseAddress is set to section header. - // - return EFI_SUCCESS; -} - EFI_STATUS RebaseImage ( IN CHAR8 *FileName, IN OUT UINT8 *FileBuffer, - IN UINT64 NewPe32BaseAddress + IN UINT32 FileBufferSize, + IN UINT64 NewBaseAddress ) /*++ Routine Description: - Set new base address into PeImage, and fix up PeImage based on new address. + Set new base address into UefiImage, and fix up UefiImage based on new address. Arguments: FileName - Name of file - FileBuffer - Pointer to PeImage. - NewPe32BaseAddress - New Base Address for PE image. + FileBuffer - Pointer to UefiImage. + NewBaseAddress - New Base Address for UEFI image. Returns: EFI_INVALID_PARAMETER - BaseAddress is not valid. - EFI_SUCCESS - Update PeImage is correctly. + EFI_SUCCESS - Update UefiImage is correctly. --*/ { - EFI_STATUS Status; - PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; - UINTN Index; - EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr; - UINT8 *MemoryImagePointer; - EFI_IMAGE_SECTION_HEADER *SectionHeader; + UINT32 RebasedSize; + VOID *RebasedBuffer; - // - // Initialize context - // - memset (&ImageContext, 0, sizeof (ImageContext)); - ImageContext.Handle = (VOID *) FileBuffer; - ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead; - Status = PeCoffLoaderGetImageInfo (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName); - return Status; + RebasedBuffer = ToolImageEmit ( + &RebasedSize, + FileBuffer, + FileBufferSize, + -1, + -1, + NULL, + 0, + true, + NewBaseAddress, + NULL, + FALSE, + TRUE + ); + if (RebasedBuffer == NULL) { + Error (NULL, 0, 3000, "Invalid", "The input UefiImage %s is not valid", FileName); + return EFI_UNSUPPORTED; } - if (ImageContext.RelocationsStripped) { - Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName); - return Status; + if (RebasedSize > FileBufferSize) { + Error (NULL, 0, 3000, "Invalid", "Rebased %s too large: %u vs %u", FileName, RebasedSize, FileBufferSize); + return EFI_UNSUPPORTED; } - // - // Get PeHeader pointer - // - ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset); + memmove (FileBuffer, RebasedBuffer, RebasedSize); + memset (FileBuffer + RebasedSize, 0, FileBufferSize - RebasedSize); - // - // Load and Relocate Image Data - // - MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - if (MemoryImagePointer == NULL) { - Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName); - return EFI_OUT_OF_RESOURCES; - } - memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment); - ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1)); - - Status = PeCoffLoaderLoadImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - ImageContext.DestinationAddress = NewPe32BaseAddress; - Status = PeCoffLoaderRelocateImage (&ImageContext); - if (EFI_ERROR (Status)) { - Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName); - free ((VOID *) MemoryImagePointer); - return Status; - } - - // - // Copy Relocated data to raw image file. - // - SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ( - (UINTN) ImgHdr + - sizeof (UINT32) + - sizeof (EFI_IMAGE_FILE_HEADER) + - ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader - ); - - for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) { - CopyMem ( - FileBuffer + SectionHeader->PointerToRawData, - (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), - SectionHeader->SizeOfRawData - ); - } - - free ((VOID *) MemoryImagePointer); - - // - // Update Image Base Address - // - if (ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress; - } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress; - } else { - Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s", - ImgHdr->Pe32.OptionalHeader.Magic, - FileName - ); - return EFI_ABORTED; - } - - // - // Set new base address into section header - // - Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress); - - return Status; + return EFI_SUCCESS; } EFI_STATUS @@ -1795,7 +1610,7 @@ Returns: if (EnableHash) { ToolInputFileName = "edk2Temp_InputEfi.tmp"; ToolOutputFileName = "edk2Temp_OutputHash.tmp"; - RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, 0); + RebaseImage(ToolInputFileName, (UINT8*)Ptr + SectionHeaderLen, SectionLength - SectionHeaderLen, 0); PutFileImage ( ToolInputFileName, (CHAR8*)Ptr + SectionHeaderLen, @@ -1830,7 +1645,7 @@ Returns: CHAR8 *NewStr; UINT32 nFileLen; if((fp = fopen(ToolOutputFileName,"r")) == NULL) { - Error (NULL, 0, 0004, "Hash the PE32 image failed.", NULL); + Error (NULL, 0, 0004, "Hash the UEFI image failed.", NULL); } else { fseek(fp,0,SEEK_SET); @@ -2517,7 +2332,7 @@ Returns: The offset from the start of the input file to start \n\ processing an FV\n"); fprintf (stdout, " --hash\n\ - Generate HASH value of the entire PE image\n"); + Generate HASH value of the entire UEFI image\n"); fprintf (stdout, " --sfo\n\ Reserved for future use\n"); }