]> git.proxmox.com Git - mirror_edk2.git/blobdiff - InOsEmuPkg/Unix/Sec/SecMain.c
InOsEmuPkg: Make build dir different for IA-32. Fix PCD XIP issues.
[mirror_edk2.git] / InOsEmuPkg / Unix / Sec / SecMain.c
index ff5eff0c07fe8e437e033ffbb7a2ecd885e21930..bf594892fb6c25a90a65d328bf2f46a466dec7c7 100644 (file)
@@ -57,7 +57,7 @@ EMU_SYSTEM_MEMORY  *gSystemMemory;
 UINTN                        mImageContextModHandleArraySize = 0;
 IMAGE_CONTEXT_TO_MOD_HANDLE  *mImageContextModHandleArray = NULL;
 
-
+EFI_PEI_PPI_DESCRIPTOR  *gPpiList;
 
 /*++
 
@@ -117,8 +117,7 @@ main (
   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
@@ -127,7 +126,6 @@ main (
 
   // EmuSecLibConstructor ();
   
-  
   gPpiList = GetThunkPpiList (); 
 
 
@@ -212,14 +210,24 @@ main (
     }
     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);
@@ -290,10 +298,11 @@ main (
 
 EFI_PHYSICAL_ADDRESS *
 MapMemory (
-  INTN fd,
-  UINT64 length,
-  INTN   prot,
-  INTN   flags)
+  IN INTN   fd,
+  IN UINT64 length,
+  IN INTN   prot,
+  IN INTN   flags
+  )
 {
   STATIC UINTN base  = 0x40000000;
   CONST UINTN  align = (1 << 24);
@@ -350,31 +359,126 @@ MapFile (
   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 *)(UINTN)(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;  
+}
 
 
 /*++
@@ -565,18 +669,30 @@ SecPeCoffGetEntryPoint (
     return Status;
   }
 
-  //
-  // Relocate image to match the address where it resides
-  //
-  ImageContext.ImageAddress = (UINTN)Pe32Data;
-  Status = PeCoffLoaderLoadImage (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
+  if (ImageContext.ImageAddress != (UINTN)Pe32Data) {
+    //
+    // Relocate image to match the address where it resides
+    //
+    ImageContext.ImageAddress = (UINTN)Pe32Data;
+    Status = PeCoffLoaderLoadImage (&ImageContext);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
 
-  Status = PeCoffLoaderRelocateImage (&ImageContext);
-  if (EFI_ERROR (Status)) {
-    return Status;
+    Status = PeCoffLoaderRelocateImage (&ImageContext);
+    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
@@ -671,7 +787,6 @@ CountSeperatorsInString (
 
 
 EFI_STATUS
-EFIAPI
 SecImageRead (
   IN     VOID    *FileHandle,
   IN     UINTN   FileOffset,