Update GenSec tool based on the GUID attributes defined in New FDF spec, and Update...
authorlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 26 Jun 2007 09:16:11 +0000 (09:16 +0000)
committerlgao4 <lgao4@7335b38e-4728-0410-8992-fb3ffe349368>
Tue, 26 Jun 2007 09:16:11 +0000 (09:16 +0000)
git-svn-id: https://buildtools.tianocore.org/svn/buildtools/trunk/BaseTools@201 7335b38e-4728-0410-8992-fb3ffe349368

Source/C/GenFfs/GenFfs.c
Source/C/GenFv/GenFvInternalLib.c
Source/C/GenFv/GenFvInternalLib.h
Source/C/GenFw/GenFw.c
Source/C/GenSec/GenSec.c
Source/C/Makefile
Source/C/PeCoffLoader/BasePeCoff.c

index 4f30ca1..2706d75 100644 (file)
@@ -257,7 +257,7 @@ Returns:
     }\r
     \r
     //\r
-    // make sure section data meet its alignment requirement.\r
+    // make sure section data meet its alignment requirement by adding one raw pad section.\r
     // But the different sections have the different section header. Necessary or not?\r
     // Based on section type to adjust offset? Todo\r
     //\r
@@ -354,7 +354,7 @@ Returns:
   Index          = 0;\r
   FfsAttrib      = 0;  \r
   FfsAlign       = 0;\r
-  FfsFiletype    = 0;\r
+  FfsFiletype    = EFI_FV_FILETYPE_ALL;\r
   OutputFileName = NULL;\r
   InputFileNum   = 0;\r
   InputFileName  = NULL;\r
@@ -391,10 +391,6 @@ Returns:
   while (argc > 0) {\r
     if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--filetype") == 0)) {\r
       FfsFiletype = StringToType (argv[1]);\r
-      if (FfsFiletype == EFI_FV_FILETYPE_ALL) {\r
-        Error (NULL, 0, 0, NULL, "ERROR: %s is one invalid fv file type", argv[1]);\r
-        goto Finish;      \r
-      }\r
       argc -= 2;\r
       argv += 2;\r
       continue; \r
@@ -530,6 +526,14 @@ Returns:
     Error (NULL, 0, 0, NULL, "%s is invaild paramter!", argv[0]);\r
     goto Finish;\r
   }\r
+  \r
+  //\r
+  // Check the complete input paramters.\r
+  //\r
+  if (FfsFiletype == EFI_FV_FILETYPE_ALL) {\r
+    Error (NULL, 0, 0, NULL, "ERROR: File Type is not specified or File Type is not one valid type");\r
+    goto Finish;      \r
+  }\r
 \r
   if (CompareGuid (&FileGuid, &mZeroGuid) == 0) {\r
     Error (NULL, 0, 0, NULL, "File Guid value is not specified");\r
index a71134d..58eefc2 100644 (file)
@@ -1,5 +1,4 @@
 /*++\r
-i\r
 \r
 Copyright (c) 2004, Intel Corporation                                                         \r
 All rights reserved. This program and the accompanying materials                          \r
@@ -816,7 +815,6 @@ Returns:
   if (CurrentFileAlignment > MaxFfsAlignment) {\r
     MaxFfsAlignment = CurrentFileAlignment;\r
   }\r
-  _asm int 3;\r
   //\r
   // If we have a VTF file, add it at the top.\r
   //\r
@@ -1894,10 +1892,23 @@ Returns:
   UINTN                                 Index;\r
   EFI_FILE_SECTION_POINTER              CurrentPe32Section;\r
   EFI_FFS_FILE_STATE                    SavedState;\r
-  EFI_IMAGE_NT_HEADERS32                *PeHdr;\r
+  EFI_IMAGE_NT_HEADERS                  *PeHdr;\r
+  EFI_IMAGE_OPTIONAL_HEADER32           *Optional32;\r
+  EFI_IMAGE_OPTIONAL_HEADER64           *Optional64;\r
   EFI_TE_IMAGE_HEADER                   *TEImageHeader;\r
   UINT8                                 Flags;\r
-  \r
+  UINT8                                 *MemoryImagePointer;\r
+  EFI_IMAGE_SECTION_HEADER              *SectionHeader;\r
+\r
+  Index              = 0;  \r
+  MemoryImagePointer = NULL;\r
+  BaseToUpdate       = NULL;\r
+  TEImageHeader      = NULL;\r
+  PeHdr              = NULL;\r
+  Optional32         = NULL;\r
+  Optional64         = NULL;\r
+  MemoryImagePointer = NULL;\r
+  SectionHeader      = NULL;\r
   //\r
   // Check XipAddress, BootAddress and RuntimeAddress\r
   //\r
@@ -1962,19 +1973,9 @@ Returns:
     ImageContext.ImageAddress = (UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION);\r
 \r
     //\r
-    // Check if section-alignment and file-alignment match or not\r
+    // Get PeHeader pointer\r
     //\r
     PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);\r
-    if ((PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment)) {\r
-      //\r
-      // Nor XIP module can be ignored. Todo\r
-      //\r
-      if ((Flags & REBASE_XIP_FILE) == 0) {\r
-        continue;\r
-      }\r
-      Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileName);\r
-      return EFI_ABORTED;\r
-    }\r
 \r
     //\r
     // Calculate the PE32 base address, based on file type\r
@@ -1990,6 +1991,17 @@ Returns:
           //\r
           return EFI_SUCCESS;\r
         }\r
+        \r
+        //\r
+        // Check if section-alignment and file-alignment match or not\r
+        //\r
+        if ((PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment)) {\r
+          //\r
+          // Xip module has the same section alignment and file alignment.\r
+          //\r
+          Error (NULL, 0, 0, "Section-Alignment and File-Alignment does not match", FileName);\r
+          return EFI_ABORTED;\r
+        }\r
 \r
         NewPe32BaseAddress =\r
           XipBase + (UINTN)ImageContext.ImageAddress - (UINTN)FfsFile;\r
@@ -1997,7 +2009,6 @@ Returns:
         break;\r
 \r
       case EFI_FV_FILETYPE_DRIVER:\r
-        PeHdr = (EFI_IMAGE_NT_HEADERS32*)(ImageContext.ImageAddress + ImageContext.PeCoffHeaderOffset);\r
         switch (PeHdr->OptionalHeader.Subsystem) {\r
           case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:\r
             if ((Flags & REBASE_RUNTIME_FILE) == 0) {\r
@@ -2047,13 +2058,74 @@ Returns:
         return EFI_SUCCESS;\r
     }\r
 \r
+    //\r
+    // Load and Relocate Image Data\r
+    //\r
+    MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+    if (MemoryImagePointer == NULL) {\r
+      Error (NULL, 0, 0, "Can't allocate enough memory on rebase", FileName);\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
+    ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~(ImageContext.SectionAlignment - 1));\r
+    \r
+    Status =  PeCoffLoaderLoadImage (&ImageContext);\r
+    if (EFI_ERROR (Status)) {\r
+      Error (NULL, 0, 0, "LocateImage() call failed on rebase", FileName);\r
+      free ((VOID *) MemoryImagePointer);\r
+      return Status;\r
+    }\r
+         \r
     ImageContext.DestinationAddress = NewPe32BaseAddress;\r
     Status                          = PeCoffLoaderRelocateImage (&ImageContext);\r
     if (EFI_ERROR (Status)) {\r
       Error (NULL, 0, 0, "RelocateImage() call failed on rebase", FileName);\r
+      free ((VOID *) MemoryImagePointer);\r
       return Status;\r
     }\r
 \r
+    //\r
+    // Copy Relocated data to raw image file.\r
+    //\r
+    if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
+      Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *) &(PeHdr->OptionalHeader);\r
+      Optional32->ImageBase     = (UINT32) NewPe32BaseAddress;\r
+    } else if (PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64 || \r
+               PeHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
+      Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *) &(PeHdr->OptionalHeader);\r
+      Optional64->ImageBase     = NewPe32BaseAddress;\r
+    } else {\r
+      Error (\r
+        NULL,\r
+        0,\r
+        0,\r
+        "unknown machine type in PE32 image",\r
+        "machine type=0x%X, file=%s",\r
+        (UINT32) PeHdr->FileHeader.Machine,\r
+        FileName\r
+        );\r
+      free ((VOID *) MemoryImagePointer);\r
+      return EFI_ABORTED;\r
+    }\r
+\r
+    SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
+                       (UINTN) ImageContext.ImageAddress +\r
+                       ImageContext.PeCoffHeaderOffset +\r
+                       sizeof (UINT32) + \r
+                       sizeof (EFI_IMAGE_FILE_HEADER) +  \r
+                       PeHdr->FileHeader.SizeOfOptionalHeader\r
+                       );\r
+    \r
+    for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
+      CopyMem (\r
+        (UINT8 *) ImageContext.Handle + SectionHeader->PointerToRawData, \r
+        (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
+        SectionHeader->SizeOfRawData\r
+        );\r
+    }\r
+\r
+    free ((VOID *) MemoryImagePointer);\r
+\r
     //\r
     // Update BASE address\r
     //\r
index 842db76..606e147 100644 (file)
@@ -66,7 +66,6 @@ Abstract:
 // The maximum number of files in the FV supported by the library\r
 //\r
 #define MAX_NUMBER_OF_FILES_IN_FV       1000\r
-#define MAX_NUMBER_OF_COMPONENTS_IN_FV  10\r
 #define EFI_FFS_FILE_HEADER_ALIGNMENT   8\r
 \r
 //\r
@@ -75,14 +74,12 @@ Abstract:
 #define OPTIONS_SECTION_STRING            "[options]"\r
 #define ATTRIBUTES_SECTION_STRING         "[attributes]"\r
 #define FILES_SECTION_STRING              "[files]"\r
-#define COMPONENT_SECTION_STRING          "[components]"\r
 \r
 //\r
 // Options section\r
 //\r
 #define EFI_FV_BASE_ADDRESS_STRING        "EFI_BASE_ADDRESS"\r
 #define EFI_FV_FILE_NAME_STRING           "EFI_FILE_NAME"\r
-#define EFI_SYM_FILE_NAME_STRING          "EFI_SYM_FILE_NAME"\r
 #define EFI_NUM_BLOCKS_STRING             "EFI_NUM_BLOCKS"\r
 #define EFI_BLOCK_SIZE_STRING             "EFI_BLOCK_SIZE"\r
 #define EFI_FV_GUID_STRING                "EFI_FV_GUID"\r
@@ -143,14 +140,6 @@ Abstract:
 #define EFI_FVB2_ALIGNMENT_1G_STRING      "EFI_FVB2_ALIGNMENT_1G"  \r
 #define EFI_FVB2_ALIGNMENT_2G_STRING      "EFI_FVB2_ALIGNMENT_2G"  \r
 \r
-//\r
-// Component sections\r
-//\r
-#define EFI_NV_VARIABLE_STRING    "EFI_NV_VARIABLE"\r
-#define EFI_NV_EVENT_LOG_STRING   "EFI_NV_EVENT_LOG"\r
-#define EFI_NV_FTW_WORKING_STRING "EFI_NV_FTW_WORKING"\r
-#define EFI_NV_FTW_SPARE_STRING   "EFI_NV_FTW_SPARE"\r
-\r
 //\r
 // File sections\r
 //\r
index e0735e8..a474010 100644 (file)
@@ -939,6 +939,8 @@ Returns:
   Type              = 0;\r
   Status            = STATUS_SUCCESS;\r
   FileBuffer        = NULL;\r
+  fpIn              = NULL;\r
+  fpOut             = NULL;\r
 \r
   if (argc == 1) {\r
     Usage();\r
@@ -1001,42 +1003,6 @@ Returns:
     return STATUS_ERROR;    \r
   }\r
 \r
-  //\r
-  // get InImageName from stdin\r
-  //\r
-  if (InImageName == NULL) {\r
-    fscanf (stdin, "%s", FileName);\r
-    InImageName = (UINT8 *) FileName;\r
-  }\r
-\r
-  //\r
-  // Open input file\r
-  //\r
-  fpIn = fopen (InImageName, "rb");\r
-  if (!fpIn) {\r
-    Error (NULL, 0, 0, InImageName, "failed to open input file for reading");\r
-    return STATUS_ERROR;\r
-  }\r
-\r
-  FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength);\r
-  fclose (fpIn);\r
-\r
-  //\r
-  // Open output file and Write image into the output file.\r
-  // if OutImageName == NULL, output data to stdout.\r
-  //\r
-  if (OutImageName == NULL) {\r
-    fpOut = stdout; // binary stream can't be output to string strem stdout\r
-                    // because 0x0A can be auto converted to 0x0D 0x0A.\r
-  } else {\r
-    fpOut = fopen (OutImageName, "w+b");\r
-  }\r
-  if (!fpOut) {\r
-    Error (NULL, 0, 0, OutImageName, "could not open output file for writing");\r
-    Status = STATUS_ERROR;\r
-    goto Finish;\r
-  }\r
-\r
   //\r
   // Following code to convert dll to efi image or te image.\r
   // Get new image type\r
@@ -1045,7 +1011,6 @@ Returns:
     if (ModuleType == NULL) {\r
       Error (NULL, 0, 0, NULL, "No ModuleType specified, such as PEIM, DXE_DRIVER\n");\r
       Usage ();\r
-      Status = STATUS_ERROR;\r
       goto Finish;\r
     }\r
     \r
@@ -1079,9 +1044,43 @@ Returns:
     } else {\r
       Error (NULL, 0, 0, ModuleType, "%s is not one valid Module type.\n");\r
       Usage ();\r
-      Status = STATUS_ERROR;\r
       goto Finish;\r
     }\r
+  }\r
+\r
+  //\r
+  // get InImageName from stdin\r
+  //\r
+  if (InImageName == NULL) {\r
+    fscanf (stdin, "%s", FileName);\r
+    InImageName = (UINT8 *) FileName;\r
+  }\r
+\r
+  //\r
+  // Open input file\r
+  //\r
+  fpIn = fopen (InImageName, "rb");\r
+  if (!fpIn) {\r
+    Error (NULL, 0, 0, InImageName, "failed to open input file for reading");\r
+    goto Finish;\r
+  }\r
+\r
+  FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength);\r
+  fclose (fpIn);\r
+\r
+  //\r
+  // Open output file and Write image into the output file.\r
+  // if OutImageName == NULL, output data to stdout.\r
+  //\r
+  if (OutImageName == NULL) {\r
+    fpOut = stdout; // binary stream can't be output to string strem stdout\r
+                    // because 0x0A can be auto converted to 0x0D 0x0A.\r
+  } else {\r
+    fpOut = fopen (OutImageName, "w+b");\r
+  }\r
+  if (!fpOut) {\r
+    Error (NULL, 0, 0, OutImageName, "could not open output file for writing");\r
+    goto Finish;\r
   }
 \r
   //\r
@@ -1099,14 +1098,12 @@ Returns:
   DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;\r
   if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
     Error (NULL, 0, 0, InImageName, "DOS header signature not found in source image");\r
-    Status = STATUS_ERROR;\r
     goto Finish;\r
   }\r
 \r
   PeHdr = (EFI_IMAGE_NT_HEADERS *)(FileBuffer + DosHdr->e_lfanew);\r
   if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
     Error (NULL, 0, 0, InImageName, "PE header signature not found in source image");\r
-    Status = STATUS_ERROR;\r
     goto Finish;\r
   }\r
   \r
@@ -1125,7 +1122,6 @@ Returns:
 \r
         if (CheckAcpiTable (FileBuffer + SectionHeader->PointerToRawData, FileLength) != STATUS_SUCCESS) {\r
           Error (NULL, 0, 0, InImageName, "failed to check ACPI table");\r
-          Status = STATUS_ERROR;\r
           goto Finish;\r
         }\r
         \r
@@ -1139,7 +1135,6 @@ Returns:
       }\r
     }\r
     Error (NULL, 0, 0, InImageName, "failed to get ACPI table");\r
-    Status = STATUS_ERROR;\r
     goto Finish;\r
   }\r
   //\r
@@ -1342,7 +1337,14 @@ Returns:
       // Pack the subsystem and NumberOfSections into 1 byte. Make sure they fit both.\r
       //\r
       Error (NULL, 0, 0, InImageName, "image subsystem or NumberOfSections cannot be packed into 1 byte");\r
-      Status = STATUS_ERROR;\r
+      goto Finish;\r
+    }\r
+\r
+    if ((PeHdr->OptionalHeader.SectionAlignment != PeHdr->OptionalHeader.FileAlignment)) {\r
+      //\r
+      // TeImage has the same section alignment and file alignment.\r
+      //\r
+      Error (NULL, 0, 0, InImageName, "Section-Alignment and File-Alignment does not match for TeImage");\r
       goto Finish;\r
     }\r
 \r
@@ -1369,5 +1371,5 @@ Finish:
     fclose (fpOut);\r
   }\r
   \r
-  return Status;\r
+  return GetUtilityStatus ();\r
 }\r
index 33ba81f..92b4bd9 100644 (file)
@@ -74,7 +74,7 @@ CHAR8      *SectionTypeName[] = {
 };\r
 \r
 CHAR8      *CompressionTypeName[]    = { "PI_NONE", "PI_STD" };\r
-CHAR8      *GUIDedSectionAttribue[]  = { NULL, "PROCESSING", "AUTHENTIC", "BOTH" };\r
+CHAR8      *GUIDedSectionAttribue[]  = { NULL, "PROCESSING_REQUIRED", "AUTH_STATUS_VALID"};\r
 \r
 //\r
 // Crc32 GUID section related definitions.\r
@@ -137,7 +137,7 @@ Usage (
                           EFI_SECTION_PEI_DEPEX>\n\\r
         -c, --compress <PI_NONE|PI_STD>\n\\r
         -g, --vendorguid [GuidValue (########-####-####-####-############)]\n\\r
-        -r, --attributes <PROCESSING|AUTHENTIC|BOTH>\n\\r
+        -r, --attributes <PROCESSING_REQUIRED|AUTH_STATUS_VALID>\n\\r
         -n, --name \"string\"\n\\r
         -j, --buildnumber #### (0000~9999)\n\\r
         -h, --help\n\\r
@@ -623,6 +623,9 @@ Returns:
   // Now data is in FileBuffer\r
   //\r
   if (CompareGuid (VendorGuid, &gEfiCrc32SectionGuid) == 0) {\r
+    //\r
+    // Default Guid section is CRC32.\r
+    //\r
     Crc32Checksum = 0;\r
     CalculateCrc32 (FileBuffer, InputLength, &Crc32Checksum);\r
 \r
@@ -698,7 +701,6 @@ Returns:
   CHAR8                     *OutputFileName;\r
   CHAR8                     *SectionName;\r
   CHAR8                     *CompressionName;\r
-  CHAR8                     *VendorGuidDataAttribute;\r
   CHAR8                     *StringBuffer;\r
   EFI_GUID                  VendorGuid = gZeroGuid;\r
   INT32                     VersionNumber;\r
@@ -715,7 +717,6 @@ Returns:
   OutputFileName        = NULL;\r
   SectionName           = NULL;\r
   CompressionName       = NULL;\r
-  VendorGuidDataAttribute = NULL;\r
   StringBuffer          = "";\r
 \r
   InFile                = NULL;\r
@@ -783,8 +784,16 @@ Returns:
       continue;\r
     }\r
 \r
-    if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attribute") == 0)) {\r
-      VendorGuidDataAttribute = argv[1];\r
+    if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--attributes") == 0)) {\r
+      if (stricmp (argv[1], GUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0) {\r
+        SectGuidAttribute |= EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
+      } else if (stricmp (argv[1], GUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
+        SectGuidAttribute |= EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+      } else {\r
+        Error (NULL, 0, 0, argv[1], "unknown Guid Section Attribute");\r
+        Usage ();\r
+        goto Finish;\r
+      }\r
       argc -= 2;\r
       argv += 2;\r
       continue;\r
@@ -878,20 +887,10 @@ Returns:
     if (CompareGuid (&VendorGuid, &gZeroGuid) == 0) {\r
       memcpy (&VendorGuid, &gEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
     }\r
-\r
-    if ((VendorGuidDataAttribute == NULL) || \\r
-        ((stricmp (VendorGuidDataAttribute, GUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED]) == 0))) {\r
+    \r
+    if (SectGuidAttribute == 0) {\r
       SectGuidAttribute = EFI_GUIDED_SECTION_PROCESSING_REQUIRED;\r
-    } else if (stricmp (VendorGuidDataAttribute, GUIDedSectionAttribue[EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
-      SectGuidAttribute = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
-    } else if (stricmp (VendorGuidDataAttribute, GUIDedSectionAttribue[EFI_GUIDED_SECTION_PROCESSING_REQUIRED|EFI_GUIDED_SECTION_AUTH_STATUS_VALID]) == 0) {\r
-      SectGuidAttribute = EFI_GUIDED_SECTION_PROCESSING_REQUIRED | EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
-    } else {\r
-      Error (NULL, 0, 0, VendorGuidDataAttribute, "unknown Guid Section Attribute");\r
-      Usage ();\r
-      goto Finish;\r
     }\r
-\r
   } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PE32]) == 0) {\r
     SectType = EFI_SECTION_PE32;\r
   } else if (stricmp (SectionName, SectionTypeName[EFI_SECTION_PIC]) == 0) {\r
index a8e597e..86bb4c5 100644 (file)
@@ -28,8 +28,8 @@ install: $(LIB_PATH) $(BIN_PATH)
        @echo ######################
        @echo # Install to $(SYS_LIB_PATH)
        @echo ######################
-       @xcopy $(LIB_PATH) $(SYS_LIB_PATH) /I /D /E /F /Y
-       @xcopy $(BIN_PATH) $(SYS_BIN_PATH) /I /D /E /F /Y
+       @xcopy $(LIB_PATH)\*.lib $(SYS_LIB_PATH) /I /D /E /F /Y
+       @xcopy $(BIN_PATH)\*.exe $(SYS_BIN_PATH) /I /D /E /F /Y
 
 .PHONY: clean
 clean:
index 3174486..5ddd837 100644 (file)
@@ -21,17 +21,22 @@ Revision History
 \r
 --*/\r
 \r
-\r
 #include <Common/UefiBaseTypes.h>\r
 #include <Common/EfiImage.h>\r
 #include <Library/PeCoffLib.h>\r
 \r
+typedef union {\r
+  VOID                         *Header; \r
+  EFI_IMAGE_OPTIONAL_HEADER32  *Optional32;\r
+  EFI_IMAGE_OPTIONAL_HEADER64  *Optional64;\r
+} EFI_IMAGE_OPTIONAL_HEADER_POINTER;\r
+\r
 STATIC\r
 RETURN_STATUS\r
 PeCoffLoaderGetPeHeader (\r
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,\r
-  OUT    EFI_IMAGE_NT_HEADERS          *PeHdr,\r
-  OUT    EFI_TE_IMAGE_HEADER           *TeHdr\r
+  OUT    EFI_IMAGE_NT_HEADERS          **PeHdr,\r
+  OUT    EFI_TE_IMAGE_HEADER           **TeHdr\r
   );\r
 \r
 STATIC\r
@@ -43,7 +48,7 @@ PeCoffLoaderCheckImageType (
   );\r
 \r
 STATIC\r
-VOID                            *\r
+void *\r
 PeCoffLoaderImageAddress (\r
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,\r
   IN     UINTN                         Address\r
@@ -77,8 +82,8 @@ STATIC
 RETURN_STATUS\r
 PeCoffLoaderGetPeHeader (\r
   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext,\r
-  OUT    EFI_IMAGE_NT_HEADERS          *PeHdr,\r
-  OUT    EFI_TE_IMAGE_HEADER           *TeHdr\r
+  OUT    EFI_IMAGE_NT_HEADERS          **PeHdr,\r
+  OUT    EFI_TE_IMAGE_HEADER           **TeHdr\r
   )\r
 /*++\r
 \r
@@ -101,7 +106,7 @@ Returns:
 \r
 --*/\r
 {\r
-  RETURN_STATUS            Status;\r
+  RETURN_STATUS         Status;\r
   EFI_IMAGE_DOS_HEADER  DosHdr;\r
   UINTN                 Size;\r
 \r
@@ -129,34 +134,17 @@ Returns:
     ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;\r
   }\r
   //\r
-  // Read the PE/COFF Header\r
+  // Get the PE/COFF Header pointer\r
   //\r
-  Size = sizeof (EFI_IMAGE_NT_HEADERS);\r
-  Status = ImageContext->ImageRead (\r
-                          ImageContext->Handle,\r
-                          ImageContext->PeCoffHeaderOffset,\r
-                          &Size,\r
-                          PeHdr\r
-                          );\r
-  if (RETURN_ERROR (Status)) {\r
-    ImageContext->ImageError = IMAGE_ERROR_IMAGE_READ;\r
-    return Status;\r
-  }\r
-  //\r
-  // Check the PE/COFF Header Signature. If not, then try to read a TE header\r
-  //\r
-  if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
-    Size = sizeof (EFI_TE_IMAGE_HEADER);\r
-    Status = ImageContext->ImageRead (\r
-                            ImageContext->Handle,\r
-                            0,\r
-                            &Size,\r
-                            TeHdr\r
-                            );\r
-    if (TeHdr->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+  *PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);\r
+  if ((*PeHdr)->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+    //\r
+    // Check the PE/COFF Header Signature. If not, then try to get a TE header\r
+    //\r
+    *TeHdr = (EFI_TE_IMAGE_HEADER *)*PeHdr; \r
+    if ((*TeHdr)->Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
       return RETURN_UNSUPPORTED;\r
     }\r
-\r
     ImageContext->IsTeImage = TRUE;\r
   }\r
 \r
@@ -192,25 +180,27 @@ Returns:
 --*/\r
 {\r
   //\r
-  // See if the machine type is supported.  We support a native machine type (IA-32/Itanium-based)\r
-  // and the machine type for the Virtual Machine.\r
+  // See if the machine type is supported. \r
+  // We support a native machine type (IA-32/Itanium-based)\r
   //\r
   if (ImageContext->IsTeImage == FALSE) {\r
     ImageContext->Machine = PeHdr->FileHeader.Machine;\r
   } else {\r
     ImageContext->Machine = TeHdr->Machine;\r
   }\r
-\r
-  /*\r
-  if (!(EFI_IMAGE_MACHINE_TYPE_SUPPORTED (ImageContext->Machine))) {\r
-    ImageContext->ImageError = IMAGE_ERROR_INVALID_MACHINE_TYPE;\r
+  \r
+  if (ImageContext->Machine != EFI_IMAGE_MACHINE_IA32 && \\r
+      ImageContext->Machine != EFI_IMAGE_MACHINE_IA64 && \\r
+      ImageContext->Machine != EFI_IMAGE_MACHINE_X64) {\r
+    //\r
+    // upsupported PeImage machine type \r
+    // \r
     return RETURN_UNSUPPORTED;\r
   }\r
-  */\r
 \r
   //\r
   // See if the image type is supported.  We support EFI Applications,\r
-  // EFI Boot Service Drivers, and EFI Runtime Drivers.\r
+  // EFI Boot Service Drivers, EFI Runtime Drivers and EFI SAL Drivers.\r
   //\r
   if (ImageContext->IsTeImage == FALSE) {\r
     ImageContext->ImageType = PeHdr->OptionalHeader.Subsystem;\r
@@ -218,6 +208,15 @@ Returns:
     ImageContext->ImageType = (UINT16) (TeHdr->Subsystem);\r
   }\r
 \r
+  if (ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \\r
+      ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER && \\r
+      ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && \\r
+      ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) {\r
+    //\r
+    // upsupported PeImage subsystem type \r
+    // \r
+    return RETURN_UNSUPPORTED;\r
+  }\r
 \r
   return RETURN_SUCCESS;\r
 }\r
@@ -249,8 +248,8 @@ Returns:
 --*/\r
 {\r
   RETURN_STATUS                   Status;\r
-  EFI_IMAGE_NT_HEADERS            PeHdr;\r
-  EFI_TE_IMAGE_HEADER             TeHdr;\r
+  EFI_IMAGE_NT_HEADERS            *PeHdr;\r
+  EFI_TE_IMAGE_HEADER             *TeHdr;\r
   EFI_IMAGE_DATA_DIRECTORY        *DebugDirectoryEntry;\r
   UINTN                           Size;\r
   UINTN                           Index;\r
@@ -259,6 +258,11 @@ Returns:
   UINTN                           SectionHeaderOffset;\r
   EFI_IMAGE_SECTION_HEADER        SectionHeader;\r
   EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;\r
+  EFI_IMAGE_OPTIONAL_HEADER_POINTER OptionHeader;\r
+\r
+  PeHdr = NULL;\r
+  TeHdr = NULL;\r
+  DebugDirectoryEntryRva = 0;\r
 \r
   if (NULL == ImageContext) {\r
     return RETURN_INVALID_PARAMETER;\r
@@ -272,20 +276,27 @@ Returns:
   if (RETURN_ERROR (Status)) {\r
     return Status;\r
   }\r
+\r
   //\r
   // Verify machine type\r
   //\r
-  Status = PeCoffLoaderCheckImageType (ImageContext, &PeHdr, &TeHdr);\r
+  Status = PeCoffLoaderCheckImageType (ImageContext, PeHdr, TeHdr);\r
   if (RETURN_ERROR (Status)) {\r
     return Status;\r
   }\r
+  OptionHeader.Header = (VOID *) &(PeHdr->OptionalHeader);\r
+\r
   //\r
   // Retrieve the base address of the image\r
   //\r
   if (!(ImageContext->IsTeImage)) {\r
-    ImageContext->ImageAddress = PeHdr.OptionalHeader.ImageBase;\r
+    if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+      ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional32->ImageBase;\r
+    } else {\r
+      ImageContext->ImageAddress = (PHYSICAL_ADDRESS) OptionHeader.Optional64->ImageBase;\r
+    }\r
   } else {\r
-    ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr.ImageBase + TeHdr.StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
+    ImageContext->ImageAddress = (PHYSICAL_ADDRESS) (TeHdr->ImageBase + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));\r
   }\r
   //\r
   // Initialize the alternate destination address to 0 indicating that it\r
@@ -310,26 +321,43 @@ Returns:
   // Look at the file header to determine if relocations have been stripped, and\r
   // save this info in the image context for later use.\r
   //\r
-  if ((!(ImageContext->IsTeImage)) && ((PeHdr.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
+  if ((!(ImageContext->IsTeImage)) && ((PeHdr->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {\r
     ImageContext->RelocationsStripped = TRUE;\r
   } else {\r
     ImageContext->RelocationsStripped = FALSE;\r
   }\r
 \r
   if (!(ImageContext->IsTeImage)) {\r
-    ImageContext->ImageSize         = (UINT64) PeHdr.OptionalHeader.SizeOfImage;\r
-    ImageContext->SectionAlignment  = PeHdr.OptionalHeader.SectionAlignment;\r
-    ImageContext->SizeOfHeaders     = PeHdr.OptionalHeader.SizeOfHeaders;\r
-\r
-    //\r
-    // Modify ImageSize to contain .PDB file name if required and initialize\r
-    // PdbRVA field...\r
-    //\r
-    if (PeHdr.OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
-      DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
-\r
-      DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
 \r
+    if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+      ImageContext->ImageSize         = (UINT64) OptionHeader.Optional32->SizeOfImage;\r
+      ImageContext->SectionAlignment  = OptionHeader.Optional32->SectionAlignment;\r
+      ImageContext->SizeOfHeaders     = OptionHeader.Optional32->SizeOfHeaders;\r
+  \r
+      //\r
+      // Modify ImageSize to contain .PDB file name if required and initialize\r
+      // PdbRVA field...\r
+      //\r
+      if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+        DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+        DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
+      }\r
+    } else {\r
+      ImageContext->ImageSize         = (UINT64) OptionHeader.Optional64->SizeOfImage;\r
+      ImageContext->SectionAlignment  = OptionHeader.Optional64->SectionAlignment;\r
+      ImageContext->SizeOfHeaders     = OptionHeader.Optional64->SizeOfHeaders;\r
+  \r
+      //\r
+      // Modify ImageSize to contain .PDB file name if required and initialize\r
+      // PdbRVA field...\r
+      //\r
+      if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
+        DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
+        DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;\r
+      }\r
+    }\r
+    \r
+    if (DebugDirectoryEntryRva != 0) {\r
       //\r
       // Determine the file offset of the debug directory...  This means we walk\r
       // the sections to find which section contains the RVA of the debug\r
@@ -341,10 +369,10 @@ Returns:
                                ImageContext->PeCoffHeaderOffset +\r
                                sizeof (UINT32) + \r
                                sizeof (EFI_IMAGE_FILE_HEADER) + \r
-                               PeHdr.FileHeader.SizeOfOptionalHeader\r
+                               PeHdr->FileHeader.SizeOfOptionalHeader\r
                                );\r
 \r
-      for (Index = 0; Index < PeHdr.FileHeader.NumberOfSections; Index++) {\r
+      for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++) {\r
         //\r
         // Read section header from file\r
         //\r
@@ -401,15 +429,15 @@ Returns:
   } else {\r
     ImageContext->ImageSize         = 0;\r
     ImageContext->SectionAlignment  = 4096;\r
-    ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr.BaseOfCode - (UINTN) TeHdr.StrippedSize;\r
+    ImageContext->SizeOfHeaders     = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) TeHdr->BaseOfCode - (UINTN) TeHdr->StrippedSize;\r
 \r
-    DebugDirectoryEntry             = &TeHdr.DataDirectory[1];\r
+    DebugDirectoryEntry             = &TeHdr->DataDirectory[1];\r
     DebugDirectoryEntryRva          = DebugDirectoryEntry->VirtualAddress;\r
     SectionHeaderOffset             = (UINTN) (sizeof (EFI_TE_IMAGE_HEADER));\r
 \r
     DebugDirectoryEntryFileOffset   = 0;\r
 \r
-    for (Index = 0; Index < TeHdr.NumberOfSections;) {\r
+    for (Index = 0; Index < TeHdr->NumberOfSections;) {\r
       //\r
       // Read section header from file\r
       //\r
@@ -431,15 +459,15 @@ Returns:
           SectionHeader.VirtualAddress +\r
           SectionHeader.PointerToRawData +\r
           sizeof (EFI_TE_IMAGE_HEADER) -\r
-          TeHdr.StrippedSize;\r
+          TeHdr->StrippedSize;\r
 \r
         //\r
         // File offset of the debug directory was found, if this is not the last\r
         // section, then skip to the last section for calculating the image size.\r
         //\r
-        if (Index < (UINTN) TeHdr.NumberOfSections - 1) {\r
-          SectionHeaderOffset += (TeHdr.NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);\r
-          Index = TeHdr.NumberOfSections - 1;\r
+        if (Index < (UINTN) TeHdr->NumberOfSections - 1) {\r
+          SectionHeaderOffset += (TeHdr->NumberOfSections - 1 - Index) * sizeof (EFI_IMAGE_SECTION_HEADER);\r
+          Index = TeHdr->NumberOfSections - 1;\r
           continue;\r
         }\r
       }\r
@@ -454,7 +482,7 @@ Returns:
       // by the RVA and the VirtualSize of the last section header in the\r
       // Section Table.\r
       //\r
-      if ((++Index) == (UINTN) TeHdr.NumberOfSections) {\r
+      if ((++Index) == (UINTN) TeHdr->NumberOfSections) {\r
         ImageContext->ImageSize = (SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize +\r
                                    ImageContext->SectionAlignment - 1) & ~(ImageContext->SectionAlignment - 1);\r
       }\r
@@ -519,7 +547,7 @@ Returns:
     return NULL;\r
   }\r
 \r
-  return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address);\r
+  return (UINT8 *) ((UINTN) ImageContext->ImageAddress + Address);\r
 }\r
 \r
 RETURN_STATUS\r
@@ -563,6 +591,7 @@ Returns:
   CHAR8                     *FixupData;\r
   PHYSICAL_ADDRESS          BaseAddress;\r
   UINT16                    MachineType;\r
+  EFI_IMAGE_OPTIONAL_HEADER_POINTER     OptionHeader;\r
 \r
   PeHdr = NULL;\r
   TeHdr = NULL;\r
@@ -591,28 +620,55 @@ Returns:
   if (!(ImageContext->IsTeImage)) {\r
     PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN)ImageContext->ImageAddress + \r
                                             ImageContext->PeCoffHeaderOffset);\r
-    Adjust = (UINT64) BaseAddress - PeHdr->OptionalHeader.ImageBase;\r
-    PeHdr->OptionalHeader.ImageBase = (UINTN) BaseAddress;\r
-    MachineType = PeHdr->FileHeader.Machine;\r
-    //\r
-    // Find the relocation block\r
-    //\r
-    // Per the PE/COFF spec, you can't assume that a given data directory\r
-    // is present in the image. You have to check the NumberOfRvaAndSizes in\r
-    // the optional header to verify a desired directory entry is there.\r
-    //\r
-    if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
-      RelocDir  = &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
-      RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
-      RelocBaseEnd = PeCoffLoaderImageAddress (\r
-                      ImageContext,\r
-                      RelocDir->VirtualAddress + RelocDir->Size - 1\r
-                      );\r
+    OptionHeader.Header = (VOID *) &(PeHdr->OptionalHeader);\r
+    if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+      Adjust = (UINT64) BaseAddress - OptionHeader.Optional32->ImageBase;\r
+      OptionHeader.Optional32->ImageBase = (UINT32) BaseAddress;\r
+      MachineType = ImageContext->Machine;\r
+      //\r
+      // Find the relocation block\r
+      //\r
+      // Per the PE/COFF spec, you can't assume that a given data directory\r
+      // is present in the image. You have to check the NumberOfRvaAndSizes in\r
+      // the optional header to verify a desired directory entry is there.\r
+      //\r
+      if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+        RelocDir  = &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+        RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+        RelocBaseEnd = PeCoffLoaderImageAddress (\r
+                        ImageContext,\r
+                        RelocDir->VirtualAddress + RelocDir->Size - 1\r
+                        );\r
+      } else {\r
+        //\r
+        // Set base and end to bypass processing below.\r
+        //\r
+        RelocBase = RelocBaseEnd = 0;\r
+      }\r
     } else {\r
+      Adjust = (UINT64) BaseAddress - OptionHeader.Optional64->ImageBase;\r
+      OptionHeader.Optional64->ImageBase = BaseAddress;\r
+      MachineType = ImageContext->Machine;\r
       //\r
-      // Set base and end to bypass processing below.\r
+      // Find the relocation block\r
       //\r
-      RelocBase = RelocBaseEnd = 0;\r
+      // Per the PE/COFF spec, you can't assume that a given data directory\r
+      // is present in the image. You have to check the NumberOfRvaAndSizes in\r
+      // the optional header to verify a desired directory entry is there.\r
+      //\r
+      if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+        RelocDir  = &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+        RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);\r
+        RelocBaseEnd = PeCoffLoaderImageAddress (\r
+                        ImageContext,\r
+                        RelocDir->VirtualAddress + RelocDir->Size - 1\r
+                        );\r
+      } else {\r
+        //\r
+        // Set base and end to bypass processing below.\r
+        //\r
+        RelocBase = RelocBaseEnd = 0;\r
+      }\r
     }\r
   } else {\r
     TeHdr             = (EFI_TE_IMAGE_HEADER *) (UINTN) (ImageContext->ImageAddress);\r
@@ -767,10 +823,10 @@ Returns:
 \r
 --*/\r
 {\r
-  RETURN_STATUS                            Status;\r
+  RETURN_STATUS                         Status;\r
   EFI_IMAGE_NT_HEADERS                  *PeHdr;\r
   EFI_TE_IMAGE_HEADER                   *TeHdr;\r
-  PE_COFF_LOADER_IMAGE_CONTEXT  CheckContext;\r
+  PE_COFF_LOADER_IMAGE_CONTEXT          CheckContext;\r
   EFI_IMAGE_SECTION_HEADER              *FirstSection;\r
   EFI_IMAGE_SECTION_HEADER              *Section;\r
   UINTN                                 NumberOfSections;\r
@@ -782,6 +838,7 @@ Returns:
   EFI_IMAGE_DEBUG_DIRECTORY_ENTRY       *DebugEntry;\r
   UINTN                                 Size;\r
   UINT32                                TempDebugEntryRva;\r
+  EFI_IMAGE_OPTIONAL_HEADER_POINTER     OptionHeader;\r
 \r
   PeHdr = NULL;\r
   TeHdr = NULL;\r
@@ -855,6 +912,8 @@ Returns:
     PeHdr = (EFI_IMAGE_NT_HEADERS *)\r
       ((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);\r
 \r
+    OptionHeader.Header = (VOID *) &(PeHdr->OptionalHeader);\r
+    \r
     FirstSection = (EFI_IMAGE_SECTION_HEADER *) (\r
                       (UINTN)ImageContext->ImageAddress +\r
                       ImageContext->PeCoffHeaderOffset +\r
@@ -986,12 +1045,22 @@ Returns:
   // the optional header to verify a desired directory entry is there.\r
   //\r
   if (!(ImageContext->IsTeImage)) {\r
-    if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
-      DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
-        &PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
-      ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+    if (ImageContext->Machine == EFI_IMAGE_MACHINE_IA32) {\r
+      if (OptionHeader.Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
+          &OptionHeader.Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+        ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+      } else {\r
+        ImageContext->FixupDataSize = 0;\r
+      }\r
     } else {\r
-      ImageContext->FixupDataSize = 0;\r
+      if (OptionHeader.Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
+        DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)\r
+          &OptionHeader.Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
+        ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);\r
+      } else {\r
+        ImageContext->FixupDataSize = 0;\r
+      }\r
     }\r
   } else {\r
     DirectoryEntry              = &TeHdr->DataDirectory[0];\r