UINTN mImageContextModHandleArraySize = 0;
IMAGE_CONTEXT_TO_MOD_HANDLE *mImageContextModHandleArray = NULL;
-
+EFI_PEI_PPI_DESCRIPTOR *gPpiList;
/*++
AddThunkProtocol (&gX11ThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE);
AddThunkProtocol (&gPosixFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE);
AddThunkProtocol (&gBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE);
-
-
+ AddThunkProtocol (&gSnpThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuNetworkInterface), TRUE);
//
// Emulator other Thunks
// EmuSecLibConstructor ();
-
gPpiList = GetThunkPpiList ();
}
FileName[Index1] = '\0';
- //
- // Open the FD and remmeber where it got mapped into our processes address space
- //
- Status = MapFile (
- FileName,
- &gFdInfo[Index].Address,
- &gFdInfo[Index].Size
- );
+ if (Index == 0) {
+ // Map FV Recovery Read Only and other areas Read/Write
+ Status = MapFd0 (
+ FileName,
+ &gFdInfo[0].Address,
+ &gFdInfo[0].Size
+ );
+ } else {
+ //
+ // Open the FD and remmeber where it got mapped into our processes address space
+ // Maps Read Only
+ //
+ Status = MapFile (
+ FileName,
+ &gFdInfo[Index].Address,
+ &gFdInfo[Index].Size
+ );
+ }
if (EFI_ERROR (Status)) {
printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName, (unsigned int)Status);
exit (1);
OUT UINT64 *Length
)
{
- int fd;
+ int fd;
VOID *res;
UINTN FileSize;
- fd = open (FileName, O_RDONLY);
+ fd = open (FileName, O_RDWR);
if (fd < 0) {
return EFI_NOT_FOUND;
}
FileSize = lseek (fd, 0, SEEK_END);
- res = MapMemory (fd, FileSize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
+ res = MapMemory (fd, FileSize, PROT_READ | PROT_EXEC, MAP_PRIVATE);
close (fd);
- if (res == MAP_FAILED) {
+ if (res == NULL) {
+ perror ("MapFile() Failed");
return EFI_DEVICE_ERROR;
}
-
+
*Length = (UINT64) FileSize;
*BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res;
return EFI_SUCCESS;
}
+EFI_STATUS
+MapFd0 (
+ IN CHAR8 *FileName,
+ IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT UINT64 *Length
+ )
+{
+ int fd;
+ void *res, *res2, *res3;
+ UINTN FileSize;
+ UINTN FvSize;
+ void *EmuMagicPage;
+
+ fd = open (FileName, O_RDWR);
+ if (fd < 0) {
+ return EFI_NOT_FOUND;
+ }
+ FileSize = lseek (fd, 0, SEEK_END);
+
+ FvSize = FixedPcdGet64 (PcdEmuFlashFvRecoverySize);
+
+ // Assume start of FD is Recovery FV, and make it write protected
+ res = mmap (
+ (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase),
+ FvSize,
+ PROT_READ | PROT_EXEC,
+ MAP_PRIVATE,
+ fd,
+ 0
+ );
+ if (res == MAP_FAILED) {
+ perror ("MapFd0() Failed res =");
+ close (fd);
+ return EFI_DEVICE_ERROR;
+ } else if (res != (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase)) {
+ // We could not load at the build address, so we need to allow writes
+ munmap (res, FvSize);
+ res = mmap (
+ (void *)(UINTN)FixedPcdGet64 (PcdEmuFlashFvRecoveryBase),
+ FvSize,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE,
+ fd,
+ 0
+ );
+ if (res == MAP_FAILED) {
+ perror ("MapFd0() Failed res =");
+ close (fd);
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ // Map the rest of the FD as read/write
+ res2 = mmap (
+ (void *)(FixedPcdGet64 (PcdEmuFlashFvRecoveryBase) + FvSize),
+ FileSize - FvSize,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_SHARED,
+ fd,
+ FvSize
+ );
+ close (fd);
+ if (res2 == MAP_FAILED) {
+ perror ("MapFd0() Failed res2 =");
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // If enabled use the magic page to communicate between modules
+ // This replaces the PI PeiServicesTable pointer mechanism that
+ // deos not work in the emulator. It also allows the removal of
+ // writable globals from SEC, PEI_CORE (libraries), PEIMs
+ //
+ EmuMagicPage = (void *)(UINTN)FixedPcdGet64 (PcdPeiServicesTablePage);
+ if (EmuMagicPage != NULL) {
+ res3 = mmap (
+ (void *)EmuMagicPage,
+ 4096,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ 0,
+ 0
+ );
+ if (res3 != EmuMagicPage) {
+ printf ("MapFd0(): Could not allocate PeiServicesTablePage @ %lx\n", (long unsigned int)EmuMagicPage);
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ *Length = (UINT64) FileSize;
+ *BaseAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) res;
+
+ return EFI_SUCCESS;
+}
/*++
return Status;
}
+ if (ImageContext.ImageAddress != (UINTN)Pe32Data) {
//
// Relocate image to match the address where it resides
//
if (EFI_ERROR (Status)) {
return Status;
}
+ } else {
+ //
+ // Or just return image entry point
+ //
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer (Pe32Data);
+ Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ImageContext.EntryPoint = (UINTN)*EntryPoint;
+ }
// On Unix a dlopen is done that will change the entry point
SecPeCoffRelocateImageExtraAction (&ImageContext);