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 <[email protected]>
---
 BaseTools/Source/Python/build/BuildReport.py | 53 +++++++++++++++++++++++++++-
 BaseTools/Source/Python/build/build.py       |  4 +--
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/BaseTools/Source/Python/build/BuildReport.py 
b/BaseTools/Source/Python/build/BuildReport.py
index aee50fb..27a5d97 100644
--- a/BaseTools/Source/Python/build/BuildReport.py
+++ b/BaseTools/Source/Python/build/BuildReport.py
@@ -22,19 +22,23 @@ import platform
 import textwrap
 import traceback
 import sys
 import time
 import struct
+import hashlib
+import subprocess
+import threading
 from datetime import datetime
 from StringIO import StringIO
 from Common import EdkLogger
 from Common.Misc import SaveFileOnChange
 from Common.Misc import GuidStructureByteArrayToGuidString
 from Common.Misc import GuidStructureStringToGuidString
 from Common.InfClassObject import gComponentType2ModuleType
 from Common.BuildToolError import FILE_WRITE_FAILURE
 from Common.BuildToolError import CODE_ERROR
+from Common.BuildToolError import COMMAND_FAILURE
 from Common.DataType import TAB_LINE_BREAK
 from Common.DataType import TAB_DEPEX
 from Common.DataType import TAB_SLASH
 from Common.DataType import TAB_SPACE_SPLIT
 from Common.DataType import TAB_BRG_PCD
@@ -526,10 +530,11 @@ class ModuleReport(object):
         self.ModuleName = M.Module.BaseName
         self.ModuleInfPath = M.MetaFile.File
         self.FileGuid = M.Guid
         self.Size = 0
         self.BuildTimeStamp = None
+        self.Hash = 0
         self.DriverType = ""
         if not M.IsLibrary:
             ModuleType = M.ModuleType
             if not ModuleType:
                 ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")
@@ -597,16 +602,50 @@ class ModuleReport(object):
                 if Match:
                     self.BuildTimeStamp = 
datetime.fromtimestamp(int(Match.group(1)))
             except IOError:
                 EdkLogger.warn(None, "Fail to read report file", 
FwReportFileName)
 
+        if "HASH" in ReportType:
+            OutputDir = os.path.join(self._BuildDir, "OUTPUT")
+            DefaultEFIfile = os.path.join(OutputDir, self.ModuleName + ".efi")
+            if os.path.isfile(DefaultEFIfile):
+                Tempfile = os.path.join(OutputDir, self.ModuleName + 
"_hash.tmp")
+                # rebase the efi image since its base address may not zero
+                cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, 
DefaultEFIfile]
+                try:
+                    PopenObject = subprocess.Popen(' '.join(cmd), 
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+                except Exception, X:
+                    EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: 
%s" % (str(X), cmd[0]))
+                EndOfProcedure = threading.Event()
+                EndOfProcedure.clear()
+                if PopenObject.stderr:
+                    StdErrThread = threading.Thread(target=ReadMessage, 
args=(PopenObject.stderr, EdkLogger.quiet, EndOfProcedure))
+                    StdErrThread.setName("STDERR-Redirector")
+                    StdErrThread.setDaemon(False)
+                    StdErrThread.start()
+                # waiting for program exit
+                PopenObject.wait()
+                if PopenObject.stderr:
+                    StdErrThread.join()
+                if PopenObject.returncode != 0:
+                    EdkLogger.error("GenFw", COMMAND_FAILURE, "Failed to 
generate firmware hash image for %s" % (DefaultEFIfile))
+                if os.path.isfile(Tempfile):
+                    self.Hash = hashlib.sha1()
+                    buf = open(Tempfile, 'rb').read()
+                    if self.Hash.update(buf):
+                        self.Hash = self.Hash.update(buf)
+                    self.Hash = self.Hash.hexdigest()
+                    os.remove(Tempfile)
+
         FileWrite(File, "Module Summary")
         FileWrite(File, "Module Name:          %s" % self.ModuleName)
         FileWrite(File, "Module INF Path:      %s" % self.ModuleInfPath)
         FileWrite(File, "File GUID:            %s" % self.FileGuid)
         if self.Size:
             FileWrite(File, "Size:                 0x%X (%.2fK)" % (self.Size, 
self.Size / 1024.0))
+        if self.Hash:
+            FileWrite(File, "SHA1 HASH:            %s *%s" % (self.Hash, 
self.ModuleName + ".efi"))
         if self.BuildTimeStamp:
             FileWrite(File, "Build Time Stamp:     %s" % self.BuildTimeStamp)
         if self.DriverType:
             FileWrite(File, "Driver Type:          %s" % self.DriverType)
         if self.UefiSpecVersion:
@@ -637,10 +676,22 @@ class ModuleReport(object):
         if "FIXED_ADDRESS" in ReportType and self.FileGuid:
             GlobalPredictionReport.GenerateReport(File, self.FileGuid)
 
         FileWrite(File, gSectionEnd)
 
+def ReadMessage(From, To, ExitFlag):
+    while True:
+        # read one line a time
+        Line = From.readline()
+        # empty string means "end"
+        if Line != None and Line != "":
+            To(Line.rstrip())
+        else:
+            break
+        if ExitFlag.isSet():
+            break
+
 ##
 # Reports platform and module PCD information
 #
 # This class reports the platform PCD section and module PCD subsection
 # in the build report file.
@@ -1665,11 +1716,11 @@ class BuildReport(object):
             if ReportType: 
                 for ReportTypeItem in ReportType:
                     if ReportTypeItem not in self.ReportType:
                         self.ReportType.append(ReportTypeItem)
             else:
-                self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", 
"FLASH", "FIXED_ADDRESS"]
+                self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", 
"HASH", "FLASH", "FIXED_ADDRESS"]
     ##
     # Adds platform report to the list
     #
     # This function adds a platform report to the final report list.
     #
diff --git a/BaseTools/Source/Python/build/build.py 
b/BaseTools/Source/Python/build/build.py
index 37afe52..37ce8e1 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -2103,12 +2103,12 @@ def MyOptionParser():
                                                                                
"and warning messages, etc.")
     Parser.add_option("-d", "--debug", action="store", type="int", 
help="Enable debug messages at specified level.")
     Parser.add_option("-D", "--define", action="append", type="string", 
dest="Macros", help="Macro: \"Name [= Value]\".")
 
     Parser.add_option("-y", "--report-file", action="store", 
dest="ReportFile", help="Create/overwrite the report to the specified 
filename.")
-    Parser.add_option("-Y", "--report-type", action="append", type="choice", 
choices=['PCD', 'LIBRARY', 'FLASH', 'DEPEX', 'BUILD_FLAGS', 'FIXED_ADDRESS', 
'EXECUTION_ORDER'], dest="ReportType", default=[],
-        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].  "\
+    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=[],
+        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].  "\
              "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]")
     Parser.add_option("-F", "--flag", action="store", type="string", 
dest="Flag",
         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. "\
              "This option can also be specified by setting *_*_*_BUILD_FLAGS 
in [BuildOptions] section of platform DSC. If they are both specified, this 
value "\
              "will override the setting in [BuildOptions] section of platform 
DSC.")
-- 
2.6.1.windows.1

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to