BaseTools/C: Consume UefiImageLib and ImageToolEmit

This commit is contained in:
Mikhail Krichanov 2023-12-15 15:07:47 +03:00
parent f69039282f
commit c57cc69793
21 changed files with 697 additions and 3032 deletions

View File

@ -5,6 +5,9 @@
#include "ImageTool.h"
#include <Uefi/UefiBaseType.h>
#include <Uefi/UefiSpec.h>
static
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *
CreateEntry (

View File

@ -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:

File diff suppressed because it is too large Load Diff

View File

@ -14,12 +14,17 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <unistd.h>
#else
#include <direct.h>
#include <io.h>
#endif
#include "CommonLib.h"
#include "EfiUtilityMsgs.h"
#include "FvLib.h"
#include <Common/PiFirmwareFile.h>
#include <Uefi/UefiSpec.h>
#include <Library/PhaseMemoryAllocationLib.h>
#include <Library/UefiImageLib.h>
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;
}

View File

@ -113,6 +113,12 @@ LongFilePath (
IN CHAR8 *FileName
);
EFI_STATUS
GetAlignmentFromFile (
IN CHAR8 *InFile,
OUT UINT32 *Alignment
);
/*++
Routine Description:

View File

@ -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

View File

@ -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

View File

@ -1,213 +0,0 @@
/** @file
Function prototypes and defines on Memory Only PE COFF loader
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
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<<RISCV_IMM_BITS)
#define RISCV_CONST_HIGH_PART(VALUE) \
(((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
//
// PE/COFF Loader Read Function passed in by caller
//
typedef
RETURN_STATUS
(EFIAPI *PE_COFF_LOADER_READ_FILE) (
IN VOID *FileHandle,
IN UINTN FileOffset,
IN OUT UINTN *ReadSize,
OUT VOID *Buffer
);
//
// Context structure used while PE/COFF image is being loaded and relocated
//
typedef struct {
PHYSICAL_ADDRESS ImageAddress;
UINT64 ImageSize;
PHYSICAL_ADDRESS DestinationAddress;
PHYSICAL_ADDRESS EntryPoint;
PE_COFF_LOADER_READ_FILE ImageRead;
VOID *Handle;
VOID *FixupData;
UINT32 SectionAlignment;
UINT32 PeCoffHeaderOffset;
UINT32 DebugDirectoryEntryRva;
VOID *CodeView;
CHAR8 *PdbPointer;
UINTN SizeOfHeaders;
UINT32 ImageCodeMemoryType;
UINT32 ImageDataMemoryType;
UINT32 ImageError;
UINTN FixupDataSize;
UINT16 Machine;
UINT16 ImageType;
BOOLEAN RelocationsStripped;
BOOLEAN IsTeImage;
} PE_COFF_LOADER_IMAGE_CONTEXT;
/**
Retrieves information on a PE/COFF image
@param ImageContext The context of the image being loaded
@retval EFI_SUCCESS The information on the PE/COFF image was collected.
@retval EFI_INVALID_PARAMETER ImageContext is NULL.
@retval EFI_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
)
;
/**
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

View File

@ -1,385 +0,0 @@
/** @file
IA32 and X64 Specific relocation fixups
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
--*/
#include <Common/UefiBaseTypes.h>
#include <Common/PeImageEx.h>
#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;
}

View File

@ -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.<BR>
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\

View File

@ -14,7 +14,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <stdlib.h>
#include <Common/UefiBaseTypes.h>
#include <Common/PeImageEx.h> // for PE32 structure definitions
#include <IndustryStandard/PeImage2.h> // for PE32 structure definitions
#include <IndustryStandard/Pci22.h> // for option ROM header structures
#include <IndustryStandard/Pci30.h>
@ -22,6 +22,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "Compress.h"
#include "CommonLib.h"
#include <Library/UefiImageLib.h>
//
// 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

View File

@ -25,14 +25,12 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Common/UefiBaseTypes.h>
#include <Common/PiFirmwareFile.h>
#include <Common/PeImageEx.h>
#include <Guid/FfsSectionAlignmentPadding.h>
#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,

View File

@ -22,12 +22,16 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <io.h>
#endif
#include <assert.h>
#include <stdbool.h>
#include <Guid/FfsSectionAlignmentPadding.h>
#include "GenFvInternalLib.h"
#include "FvLib.h"
#include "PeCoffLib.h"
#include <Library/PeCoffLib2.h>
#include <Library/UefiImageLib.h>
#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;

View File

@ -22,7 +22,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Common/PiFirmwareVolume.h>
#include <Guid/FirmwareFileSystem2.h>
#include <Guid/FirmwareFileSystem3.h>
#include <Common/PeImageEx.h>
#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
);

View File

@ -22,7 +22,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Common/UefiBaseTypes.h>
#include <Common/PiFirmwareFile.h>
#include <Common/GuidedSectionExtractionEx.h>
#include <Common/PeImageEx.h>
#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,

View File

@ -1,101 +1,171 @@
/** @file
AutoGen definitions for edk2 package code consumption in BaseTools.
Copyright (c) 2023, Marvin Häuser. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _BT_AUTOGENH
#define _BT_AUTOGENH
#ifdef __cplusplus
extern "C" {
#endif
#include <Base.h>
#include <Library/PcdLib.h>
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.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef _BT_AUTOGENH
#define _BT_AUTOGENH
#ifdef __cplusplus
extern "C" {
#endif
#include <Base.h>
#include <Library/PcdLib.h>
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

View File

@ -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.<BR>
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __BT_PE_IMAGE_H__
#define __BT_PE_IMAGE_H__
#include <IndustryStandard/PeImage.h>
//
// 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

View File

@ -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

View File

@ -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

View File

@ -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$@

View File

@ -9,6 +9,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
@ -24,7 +25,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Common/PiFirmwareFile.h>
#include <Common/PiFirmwareVolume.h>
#include <Guid/FirmwareFileSystem2.h>
#include <Common/PeImageEx.h>
#include <Common/GuidedSectionExtractionEx.h>
#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");
}