Removed cross references from PciCf8Lib and PciExpressLib class to PciLib class.
Added PeCoffLoaderGetMachineType to the PeCoffGetEntryPointLibrary Class. Document to be updated. Added the PeCoffLoaderImageReadFromMemory() and PeCoffLoaderRelocateImageForRuntime () to the PcCoffLib. Updated EfiImage.h and removed EFI_IMAGE_OPTIONAL_HEADER and EFI_IMAGE_NT_HEADERS as they were replaced with checking the MachineType. PeCoffLib – Added checks for MachineType so the PeCoff lib can load any PE32 or PE32+ image. The relocations are still limited to IA32, X64, IPF, and EBC. I also added a re-relocator function to remove PeLoader Code from Runtime Lib. Even though there is only one instance of the re-relocator I wanted to get all the PeCoff loader code together. Replaced DEBUG_CODE() macro with DEBUG_CODE_START() and DEBUG_CODE_END() so you can debug through the DEBUG_CODE() macros. Also removed PE/COFF code and replaced with library usage. I also updated the IO Instrinsic lib to use _ReadWriteBarrior() to help with sync problems git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1103 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -51,166 +51,3 @@ Returns:
|
||||
return (CHAR8 *) ((UINTN) Image->ImageBase + Address);
|
||||
}
|
||||
|
||||
VOID
|
||||
RelocatePeImageForRuntime (
|
||||
RUNTIME_IMAGE_RELOCATION_DATA *Image
|
||||
)
|
||||
{
|
||||
CHAR8 *OldBase;
|
||||
CHAR8 *NewBase;
|
||||
EFI_IMAGE_DOS_HEADER *DosHdr;
|
||||
EFI_IMAGE_NT_HEADERS *PeHdr;
|
||||
UINT32 NumberOfRvaAndSizes;
|
||||
EFI_IMAGE_DATA_DIRECTORY *DataDirectory;
|
||||
EFI_IMAGE_DATA_DIRECTORY *RelocDir;
|
||||
EFI_IMAGE_BASE_RELOCATION *RelocBase;
|
||||
EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
|
||||
UINT16 *Reloc;
|
||||
UINT16 *RelocEnd;
|
||||
CHAR8 *Fixup;
|
||||
CHAR8 *FixupBase;
|
||||
UINT16 *F16;
|
||||
UINT32 *F32;
|
||||
CHAR8 *FixupData;
|
||||
UINTN Adjust;
|
||||
EFI_STATUS Status;
|
||||
|
||||
OldBase = (CHAR8 *) ((UINTN) Image->ImageBase);
|
||||
NewBase = (CHAR8 *) ((UINTN) Image->ImageBase);
|
||||
|
||||
Status = RuntimeDriverConvertPointer (0, (VOID **) &NewBase);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Adjust = (UINTN) NewBase - (UINTN) OldBase;
|
||||
|
||||
//
|
||||
// Find the image's relocate dir info
|
||||
//
|
||||
DosHdr = (EFI_IMAGE_DOS_HEADER *) OldBase;
|
||||
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
|
||||
//
|
||||
// Valid DOS header so get address of PE header
|
||||
//
|
||||
PeHdr = (EFI_IMAGE_NT_HEADERS *) (((CHAR8 *) DosHdr) + DosHdr->e_lfanew);
|
||||
} else {
|
||||
//
|
||||
// No Dos header so assume image starts with PE header.
|
||||
//
|
||||
PeHdr = (EFI_IMAGE_NT_HEADERS *) OldBase;
|
||||
}
|
||||
|
||||
if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {
|
||||
//
|
||||
// Not a valid PE image so Exit
|
||||
//
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Get some data from the PE type dependent data
|
||||
//
|
||||
NumberOfRvaAndSizes = PeHdr->OptionalHeader.NumberOfRvaAndSizes;
|
||||
DataDirectory = &PeHdr->OptionalHeader.DataDirectory[0];
|
||||
|
||||
//
|
||||
// Find the relocation block
|
||||
//
|
||||
// Per the PE/COFF spec, you can't assume that a given data directory
|
||||
// is present in the image. You have to check the NumberOfRvaAndSizes in
|
||||
// the optional header to verify a desired directory entry is there.
|
||||
//
|
||||
if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
|
||||
RelocDir = DataDirectory + EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC;
|
||||
RelocBase = RuntimePeImageAddress (Image, RelocDir->VirtualAddress);
|
||||
RelocBaseEnd = RuntimePeImageAddress (Image, RelocDir->VirtualAddress + RelocDir->Size);
|
||||
} else {
|
||||
//
|
||||
// Cannot find relocations, cannot continue
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
return ;
|
||||
}
|
||||
|
||||
ASSERT (RelocBase != NULL && RelocBaseEnd != NULL);
|
||||
|
||||
//
|
||||
// Run the whole relocation block. And re-fixup data that has not been
|
||||
// modified. The FixupData is used to see if the image has been modified
|
||||
// since it was relocated. This is so data sections that have been updated
|
||||
// by code will not be fixed up, since that would set them back to
|
||||
// defaults.
|
||||
//
|
||||
FixupData = Image->RelocationData;
|
||||
while (RelocBase < RelocBaseEnd) {
|
||||
|
||||
Reloc = (UINT16 *) ((UINT8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
|
||||
RelocEnd = (UINT16 *) ((UINT8 *) RelocBase + RelocBase->SizeOfBlock);
|
||||
FixupBase = (CHAR8 *) ((UINTN) Image->ImageBase) + RelocBase->VirtualAddress;
|
||||
|
||||
//
|
||||
// Run this relocation record
|
||||
//
|
||||
while (Reloc < RelocEnd) {
|
||||
|
||||
Fixup = FixupBase + (*Reloc & 0xFFF);
|
||||
switch ((*Reloc) >> 12) {
|
||||
|
||||
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_REL_BASED_HIGH:
|
||||
F16 = (UINT16 *) Fixup;
|
||||
if (*(UINT16 *) FixupData == *F16) {
|
||||
*F16 = (UINT16) ((*F16 << 16) + ((UINT16) Adjust & 0xffff));
|
||||
}
|
||||
|
||||
FixupData = FixupData + sizeof (UINT16);
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_REL_BASED_LOW:
|
||||
F16 = (UINT16 *) Fixup;
|
||||
if (*(UINT16 *) FixupData == *F16) {
|
||||
*F16 = (UINT16) (*F16 + ((UINT16) Adjust & 0xffff));
|
||||
}
|
||||
|
||||
FixupData = FixupData + sizeof (UINT16);
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
||||
F32 = (UINT32 *) Fixup;
|
||||
FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));
|
||||
if (*(UINT32 *) FixupData == *F32) {
|
||||
*F32 = *F32 + (UINT32) Adjust;
|
||||
}
|
||||
|
||||
FixupData = FixupData + sizeof (UINT32);
|
||||
break;
|
||||
|
||||
case EFI_IMAGE_REL_BASED_HIGHADJ:
|
||||
//
|
||||
// Not implemented, but not used in EFI 1.0
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Only Itanium requires ConvertPeImage_Ex
|
||||
//
|
||||
Status = PeHotRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return ;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Next relocation record
|
||||
//
|
||||
Reloc += 1;
|
||||
}
|
||||
//
|
||||
// next reloc block
|
||||
//
|
||||
RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
|
||||
}
|
||||
|
||||
FlushCpuCache (Image->ImageBase, (UINT64) Image->ImageSize);
|
||||
}
|
||||
|
Reference in New Issue
Block a user