IntelFsp2Pkg: SplitFspBin.py to support x64 drivers
authorChasel, Chiu <chasel.chiu@intel.com>
Fri, 22 Jun 2018 10:22:47 +0000 (18:22 +0800)
committerChasel, Chiu <chasel.chiu@intel.com>
Mon, 25 Jun 2018 00:11:30 +0000 (08:11 +0800)
FSP binary potentially can include X64 drivers to
simplify implementation or support new features so
update SplitFspBin.py to support x64 image headers.

Cc: Jiewen Yao <Jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>
IntelFsp2Pkg/Tools/SplitFspBin.py

index e4c3aa6..9b18720 100644 (file)
@@ -1,6 +1,6 @@
 ## @ FspTool.py\r
 #\r
-# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials are licensed and made available under\r
 # the terms and conditions of the BSD License that accompanies this distribution.\r
 # The full text of the license may be found at\r
@@ -234,11 +234,51 @@ class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
         ('DataDirectory',                 ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))\r
         ]\r
 \r
+class EFI_IMAGE_OPTIONAL_HEADER32_PLUS(Structure):\r
+    _fields_ = [\r
+        ('Magic',                         c_uint16),\r
+        ('MajorLinkerVersion',            c_uint8),\r
+        ('MinorLinkerVersion',            c_uint8),\r
+        ('SizeOfCode',                    c_uint32),\r
+        ('SizeOfInitializedData',         c_uint32),\r
+        ('SizeOfUninitializedData',       c_uint32),\r
+        ('AddressOfEntryPoint',           c_uint32),\r
+        ('BaseOfCode',                    c_uint32),\r
+        ('ImageBase',                     c_uint64),\r
+        ('SectionAlignment',              c_uint32),\r
+        ('FileAlignment',                 c_uint32),\r
+        ('MajorOperatingSystemVersion',   c_uint16),\r
+        ('MinorOperatingSystemVersion',   c_uint16),\r
+        ('MajorImageVersion',             c_uint16),\r
+        ('MinorImageVersion',             c_uint16),\r
+        ('MajorSubsystemVersion',         c_uint16),\r
+        ('MinorSubsystemVersion',         c_uint16),\r
+        ('Win32VersionValue',             c_uint32),\r
+        ('SizeOfImage',                   c_uint32),\r
+        ('SizeOfHeaders',                 c_uint32),\r
+        ('CheckSum'     ,                 c_uint32),\r
+        ('Subsystem',                     c_uint16),\r
+        ('DllCharacteristics',            c_uint16),\r
+        ('SizeOfStackReserve',            c_uint64),\r
+        ('SizeOfStackCommit' ,            c_uint64),\r
+        ('SizeOfHeapReserve',             c_uint64),\r
+        ('SizeOfHeapCommit' ,             c_uint64),\r
+        ('LoaderFlags'     ,              c_uint32),\r
+        ('NumberOfRvaAndSizes',           c_uint32),\r
+        ('DataDirectory',                 ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))\r
+        ]\r
+\r
+class EFI_IMAGE_OPTIONAL_HEADER(Union):\r
+    _fields_ = [\r
+        ('PeOptHdr',             EFI_IMAGE_OPTIONAL_HEADER32),\r
+        ('PePlusOptHdr',         EFI_IMAGE_OPTIONAL_HEADER32_PLUS)\r
+        ]\r
+\r
 class EFI_IMAGE_NT_HEADERS32(Structure):\r
     _fields_ = [\r
         ('Signature',            c_uint32),\r
         ('FileHeader',           EFI_IMAGE_FILE_HEADER),\r
-        ('OptionalHeader',       EFI_IMAGE_OPTIONAL_HEADER32)\r
+        ('OptionalHeader',       EFI_IMAGE_OPTIONAL_HEADER)\r
         ]\r
 \r
 \r
@@ -527,16 +567,24 @@ class PeTeImage:
         tehdr          = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)\r
         if   tehdr.Signature == 'VZ': # TE image\r
             self.TeHdr   = tehdr\r
-        elif tehdr.Signature == 'MZ': # PE32 image\r
+        elif tehdr.Signature == 'MZ': # PE image\r
             self.TeHdr   = None\r
             self.DosHdr  = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0)\r
             self.PeHdr   = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew)\r
             if self.PeHdr.Signature != 0x4550:\r
                 raise Exception("ERROR: Invalid PE32 header !")\r
-            if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:\r
-                raise Exception("ERROR: Unsupported PE32 image !")\r
-            if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:\r
-                raise Exception("ERROR: No relocation information available !")\r
+            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image\r
+                if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:\r
+                    raise Exception("ERROR: Unsupported PE32 image !")\r
+                if self.PeHdr.OptionalHeader.PeOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:\r
+                    raise Exception("ERROR: No relocation information available !")\r
+            elif self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image\r
+                if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32_PLUS.DataDirectory.offset:\r
+                    raise Exception("ERROR: Unsupported PE32+ image !")\r
+                if self.PeHdr.OptionalHeader.PePlusOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:\r
+                    raise Exception("ERROR: No relocation information available !")\r
+            else:\r
+                raise Exception("ERROR: Invalid PE32 optional header !")\r
         self.Offset    = offset\r
         self.Data      = data\r
         self.RelocList = []\r
@@ -549,8 +597,12 @@ class PeTeImage:
             rsize   = self.TeHdr.DataDirectoryBaseReloc.Size\r
             roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress\r
         else:\r
-            rsize   = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size\r
-            roffset = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress\r
+            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image\r
+                rsize   = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size\r
+                roffset = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress\r
+            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image\r
+                rsize   = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size\r
+                roffset = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress\r
 \r
         alignment = 4\r
         offset = roffset\r
@@ -565,9 +617,9 @@ class PeTeImage:
             for each in rdata:\r
                 roff  = each & 0xfff\r
                 rtype = each >> 12\r
-                if rtype == 0: # IMAGE_REL_BASED.ABSOLUTE:\r
+                if rtype == 0: # IMAGE_REL_BASED_ABSOLUTE:\r
                     continue\r
-                if rtype != 3: # IMAGE_REL_BASED_HIGHLOW\r
+                if ((rtype != 3) and (rtype != 10)): # IMAGE_REL_BASED_HIGHLOW and IMAGE_REL_BASED_DIR64\r
                     raise Exception("ERROR: Unsupported relocation type %d!" % rtype)\r
                 # Calculate the offset of the relocation\r
                 aoff  = blkhdr.PageRVA + roff\r
@@ -582,12 +634,18 @@ class PeTeImage:
             return count\r
 \r
         for (rtype, roff) in self.RelocList:\r
-            if rtype == 0x03: # HIGHLOW\r
+            if rtype == 3: # IMAGE_REL_BASED_HIGHLOW\r
                 offset = roff + self.Offset\r
                 value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])\r
                 value += delta\r
                 fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))\r
                 count += 1\r
+            elif rtype == 10: # IMAGE_REL_BASED_DIR64\r
+                offset = roff + self.Offset\r
+                value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint64)])\r
+                value += delta\r
+                fdbin[offset:offset+sizeof(c_uint64)] = Val2Bytes(value, sizeof(c_uint64))\r
+                count += 1\r
             else:\r
                 raise Exception('ERROR: Unknown relocation type %d !' % rtype)\r
 \r