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
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
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
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
\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
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
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