]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools: generate hash value in build report for each output EFI image
authorYonghong Zhu <yonghong.zhu@intel.com>
Thu, 7 Apr 2016 05:57:14 +0000 (13:57 +0800)
committerYonghong Zhu <yonghong.zhu@intel.com>
Tue, 12 Apr 2016 05:16:06 +0000 (13:16 +0800)
Build report add new report type 'HASH' to include the hash value for
each output EFI image.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
BaseTools/Source/Python/build/BuildReport.py
BaseTools/Source/Python/build/build.py

index aee50fb3a2940da050676103ceaef647756eb097..27a5d9736efa32d5f1b7645adb38f5facb356ade 100644 (file)
@@ -24,6 +24,9 @@ import traceback
 import sys\r
 import time\r
 import struct\r
+import hashlib\r
+import subprocess\r
+import threading\r
 from datetime import datetime\r
 from StringIO import StringIO\r
 from Common import EdkLogger\r
@@ -33,6 +36,7 @@ from Common.Misc import GuidStructureStringToGuidString
 from Common.InfClassObject import gComponentType2ModuleType\r
 from Common.BuildToolError import FILE_WRITE_FAILURE\r
 from Common.BuildToolError import CODE_ERROR\r
+from Common.BuildToolError import COMMAND_FAILURE\r
 from Common.DataType import TAB_LINE_BREAK\r
 from Common.DataType import TAB_DEPEX\r
 from Common.DataType import TAB_SLASH\r
@@ -528,6 +532,7 @@ class ModuleReport(object):
         self.FileGuid = M.Guid\r
         self.Size = 0\r
         self.BuildTimeStamp = None\r
+        self.Hash = 0\r
         self.DriverType = ""\r
         if not M.IsLibrary:\r
             ModuleType = M.ModuleType\r
@@ -599,12 +604,46 @@ class ModuleReport(object):
             except IOError:\r
                 EdkLogger.warn(None, "Fail to read report file", FwReportFileName)\r
 \r
+        if "HASH" in ReportType:\r
+            OutputDir = os.path.join(self._BuildDir, "OUTPUT")\r
+            DefaultEFIfile = os.path.join(OutputDir, self.ModuleName + ".efi")\r
+            if os.path.isfile(DefaultEFIfile):\r
+                Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp")\r
+                # rebase the efi image since its base address may not zero\r
+                cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, DefaultEFIfile]\r
+                try:\r
+                    PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)\r
+                except Exception, X:\r
+                    EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))\r
+                EndOfProcedure = threading.Event()\r
+                EndOfProcedure.clear()\r
+                if PopenObject.stderr:\r
+                    StdErrThread = threading.Thread(target=ReadMessage, args=(PopenObject.stderr, EdkLogger.quiet, EndOfProcedure))\r
+                    StdErrThread.setName("STDERR-Redirector")\r
+                    StdErrThread.setDaemon(False)\r
+                    StdErrThread.start()\r
+                # waiting for program exit\r
+                PopenObject.wait()\r
+                if PopenObject.stderr:\r
+                    StdErrThread.join()\r
+                if PopenObject.returncode != 0:\r
+                    EdkLogger.error("GenFw", COMMAND_FAILURE, "Failed to generate firmware hash image for %s" % (DefaultEFIfile))\r
+                if os.path.isfile(Tempfile):\r
+                    self.Hash = hashlib.sha1()\r
+                    buf = open(Tempfile, 'rb').read()\r
+                    if self.Hash.update(buf):\r
+                        self.Hash = self.Hash.update(buf)\r
+                    self.Hash = self.Hash.hexdigest()\r
+                    os.remove(Tempfile)\r
+\r
         FileWrite(File, "Module Summary")\r
         FileWrite(File, "Module Name:          %s" % self.ModuleName)\r
         FileWrite(File, "Module INF Path:      %s" % self.ModuleInfPath)\r
         FileWrite(File, "File GUID:            %s" % self.FileGuid)\r
         if self.Size:\r
             FileWrite(File, "Size:                 0x%X (%.2fK)" % (self.Size, self.Size / 1024.0))\r
+        if self.Hash:\r
+            FileWrite(File, "SHA1 HASH:            %s *%s" % (self.Hash, self.ModuleName + ".efi"))\r
         if self.BuildTimeStamp:\r
             FileWrite(File, "Build Time Stamp:     %s" % self.BuildTimeStamp)\r
         if self.DriverType:\r
@@ -639,6 +678,18 @@ class ModuleReport(object):
 \r
         FileWrite(File, gSectionEnd)\r
 \r
+def ReadMessage(From, To, ExitFlag):\r
+    while True:\r
+        # read one line a time\r
+        Line = From.readline()\r
+        # empty string means "end"\r
+        if Line != None and Line != "":\r
+            To(Line.rstrip())\r
+        else:\r
+            break\r
+        if ExitFlag.isSet():\r
+            break\r
+\r
 ##\r
 # Reports platform and module PCD information\r
 #\r
@@ -1667,7 +1718,7 @@ class BuildReport(object):
                     if ReportTypeItem not in self.ReportType:\r
                         self.ReportType.append(ReportTypeItem)\r
             else:\r
-                self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", "FLASH", "FIXED_ADDRESS"]\r
+                self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", "HASH", "FLASH", "FIXED_ADDRESS"]\r
     ##\r
     # Adds platform report to the list\r
     #\r
index 37afe52ac298858627170c545b77fcba28242c80..37ce8e16aa9d5aa24857a5a3db7f01315aeddab7 100644 (file)
@@ -2105,8 +2105,8 @@ def MyOptionParser():
     Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
 \r
     Parser.add_option("-y", "--report-file", action="store", dest="ReportFile", help="Create/overwrite the report to the specified filename.")\r
-    Parser.add_option("-Y", "--report-type", action="append", type="choice", choices=['PCD', 'LIBRARY', 'FLASH', 'DEPEX', 'BUILD_FLAGS', 'FIXED_ADDRESS', 'EXECUTION_ORDER'], dest="ReportType", default=[],\r
-        help="Flags that control the type of build report to generate.  Must be one of: [PCD, LIBRARY, FLASH, DEPEX, BUILD_FLAGS, FIXED_ADDRESS, EXECUTION_ORDER].  "\\r
+    Parser.add_option("-Y", "--report-type", action="append", type="choice", choices=['PCD','LIBRARY','FLASH','DEPEX','BUILD_FLAGS','FIXED_ADDRESS','HASH','EXECUTION_ORDER'], dest="ReportType", default=[],\r
+        help="Flags that control the type of build report to generate.  Must be one of: [PCD, LIBRARY, FLASH, DEPEX, BUILD_FLAGS, FIXED_ADDRESS, HASH, EXECUTION_ORDER].  "\\r
              "To specify more than one flag, repeat this option on the command line and the default flag set is [PCD, LIBRARY, FLASH, DEPEX, BUILD_FLAGS, FIXED_ADDRESS]")\r
     Parser.add_option("-F", "--flag", action="store", type="string", dest="Flag",\r
         help="Specify the specific option to parse EDK UNI file. Must be one of: [-c, -s]. -c is for EDK framework UNI file, and -s is for EDK UEFI UNI file. "\\r