BaseTools: generate hash value in build report for each output EFI image
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>
This commit is contained in:
@ -24,6 +24,9 @@ import traceback
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import struct
|
import struct
|
||||||
|
import hashlib
|
||||||
|
import subprocess
|
||||||
|
import threading
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
from Common import EdkLogger
|
from Common import EdkLogger
|
||||||
@ -33,6 +36,7 @@ from Common.Misc import GuidStructureStringToGuidString
|
|||||||
from Common.InfClassObject import gComponentType2ModuleType
|
from Common.InfClassObject import gComponentType2ModuleType
|
||||||
from Common.BuildToolError import FILE_WRITE_FAILURE
|
from Common.BuildToolError import FILE_WRITE_FAILURE
|
||||||
from Common.BuildToolError import CODE_ERROR
|
from Common.BuildToolError import CODE_ERROR
|
||||||
|
from Common.BuildToolError import COMMAND_FAILURE
|
||||||
from Common.DataType import TAB_LINE_BREAK
|
from Common.DataType import TAB_LINE_BREAK
|
||||||
from Common.DataType import TAB_DEPEX
|
from Common.DataType import TAB_DEPEX
|
||||||
from Common.DataType import TAB_SLASH
|
from Common.DataType import TAB_SLASH
|
||||||
@ -528,6 +532,7 @@ class ModuleReport(object):
|
|||||||
self.FileGuid = M.Guid
|
self.FileGuid = M.Guid
|
||||||
self.Size = 0
|
self.Size = 0
|
||||||
self.BuildTimeStamp = None
|
self.BuildTimeStamp = None
|
||||||
|
self.Hash = 0
|
||||||
self.DriverType = ""
|
self.DriverType = ""
|
||||||
if not M.IsLibrary:
|
if not M.IsLibrary:
|
||||||
ModuleType = M.ModuleType
|
ModuleType = M.ModuleType
|
||||||
@ -599,12 +604,46 @@ class ModuleReport(object):
|
|||||||
except IOError:
|
except IOError:
|
||||||
EdkLogger.warn(None, "Fail to read report file", FwReportFileName)
|
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 Summary")
|
||||||
FileWrite(File, "Module Name: %s" % self.ModuleName)
|
FileWrite(File, "Module Name: %s" % self.ModuleName)
|
||||||
FileWrite(File, "Module INF Path: %s" % self.ModuleInfPath)
|
FileWrite(File, "Module INF Path: %s" % self.ModuleInfPath)
|
||||||
FileWrite(File, "File GUID: %s" % self.FileGuid)
|
FileWrite(File, "File GUID: %s" % self.FileGuid)
|
||||||
if self.Size:
|
if self.Size:
|
||||||
FileWrite(File, "Size: 0x%X (%.2fK)" % (self.Size, self.Size / 1024.0))
|
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:
|
if self.BuildTimeStamp:
|
||||||
FileWrite(File, "Build Time Stamp: %s" % self.BuildTimeStamp)
|
FileWrite(File, "Build Time Stamp: %s" % self.BuildTimeStamp)
|
||||||
if self.DriverType:
|
if self.DriverType:
|
||||||
@ -639,6 +678,18 @@ class ModuleReport(object):
|
|||||||
|
|
||||||
FileWrite(File, gSectionEnd)
|
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
|
# Reports platform and module PCD information
|
||||||
#
|
#
|
||||||
@ -1667,7 +1718,7 @@ class BuildReport(object):
|
|||||||
if ReportTypeItem not in self.ReportType:
|
if ReportTypeItem not in self.ReportType:
|
||||||
self.ReportType.append(ReportTypeItem)
|
self.ReportType.append(ReportTypeItem)
|
||||||
else:
|
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
|
# Adds platform report to the list
|
||||||
#
|
#
|
||||||
|
@ -2105,8 +2105,8 @@ def MyOptionParser():
|
|||||||
Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
|
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-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=[],
|
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, EXECUTION_ORDER]. "\
|
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]")
|
"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",
|
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. "\
|
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. "\
|
||||||
|
Reference in New Issue
Block a user