From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 403F4820A4 for ; Wed, 8 Feb 2017 19:57:46 -0800 (PST) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP; 08 Feb 2017 19:57:46 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,349,1484035200"; d="scan'208";a="931787124" Received: from fmsmsx103.amr.corp.intel.com ([10.18.124.201]) by orsmga003.jf.intel.com with ESMTP; 08 Feb 2017 19:57:45 -0800 Received: from fmsmsx122.amr.corp.intel.com (10.18.125.37) by FMSMSX103.amr.corp.intel.com (10.18.124.201) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 8 Feb 2017 19:57:45 -0800 Received: from shsmsx101.ccr.corp.intel.com (10.239.4.153) by fmsmsx122.amr.corp.intel.com (10.18.125.37) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 8 Feb 2017 19:57:45 -0800 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.88]) by SHSMSX101.ccr.corp.intel.com ([169.254.1.177]) with mapi id 14.03.0248.002; Thu, 9 Feb 2017 11:57:42 +0800 From: "Gao, Liming" To: "Yao, Jiewen" , "edk2-devel@lists.01.org" CC: "Zhu, Yonghong" , "Kinney, Michael D" , Laszlo Ersek Thread-Topic: [PATCH 10/12] BaseTool/Script: Add SmiHandleProfile OS tool to get symbol. Thread-Index: AQHSgijQzJdkSjiTqE2Lfe6kQVR2wKFgDABw Date: Thu, 9 Feb 2017 03:57:42 +0000 Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14D6D8ED9@shsmsx102.ccr.corp.intel.com> References: <1486571486-20420-1-git-send-email-jiewen.yao@intel.com> In-Reply-To: <1486571486-20420-1-git-send-email-jiewen.yao@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH 10/12] BaseTool/Script: Add SmiHandleProfile OS tool to get symbol. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Feb 2017 03:57:46 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Jiewen: For the commented code, if they are useless, could you clean up them?=20 =20 Besides, Guid Value and Name mapping is recorded into Build Output FV\Gui= d.xref. Could you enhance script to parse this file to get full guid lists?= =20 + #print "0 - " + match.group(0) + #print "1 - " + match.group(1) Thanks Liming >-----Original Message----- >From: Yao, Jiewen >Sent: Thursday, February 09, 2017 12:31 AM >To: edk2-devel@lists.01.org >Cc: Zhu, Yonghong ; Gao, Liming >; Kinney, Michael D ; >Laszlo Ersek >Subject: [PATCH 10/12] BaseTool/Script: Add SmiHandleProfile OS tool to ge= t >symbol. > >This tool accepts the input XML file generated by SmiHandlerProfile >application and convert the RVA address to be a user readable >symbol. >It also converts the GUID to be a user readable string. > >Cc: Yonghong Zhu >Cc: Liming Gao >Cc: Michael D Kinney >Cc: Laszlo Ersek >Contributed-under: TianoCore Contribution Agreement 1.0 >Signed-off-by: Jiewen Yao >--- > BaseTools/Scripts/SmiHandlerProfileSymbolGen.py | 351 >++++++++++++++++++++ > 1 file changed, 351 insertions(+) > >diff --git a/BaseTools/Scripts/SmiHandlerProfileSymbolGen.py >b/BaseTools/Scripts/SmiHandlerProfileSymbolGen.py >new file mode 100644 >index 0000000..28614fd >--- /dev/null >+++ b/BaseTools/Scripts/SmiHandlerProfileSymbolGen.py >@@ -0,0 +1,351 @@ >+## >+# Generate symbal for SMI handler profile info. >+# >+# This tool depends on DIA2Dump.exe (VS) or nm (gcc) to parse debug entry= . >+# >+# Copyright (c) 2017, Intel Corporation. All rights reserved.
>+# This program and the accompanying materials are licensed and made >available under >+# the terms and conditions of the BSD License that accompanies this >distribution. >+# The full text of the license may be found at >+# http://opensource.org/licenses/bsd-license.php. >+# >+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" >BASIS, >+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER >EXPRESS OR IMPLIED. >+# >+## >+ >+import os >+import re >+import sys >+from optparse import OptionParser >+ >+from xml.dom.minidom import parse >+import xml.dom.minidom >+ >+versionNumber =3D "1.1" >+__copyright__ =3D "Copyright (c) 2016, Intel Corporation. All rights rese= rved." >+ >+class Symbols: >+ def __init__(self): >+ self.listLineAddress =3D [] >+ self.pdbName =3D "" >+ # Cache for function >+ self.functionName =3D "" >+ # Cache for line >+ self.sourceName =3D "" >+ >+ >+ def getSymbol (self, rva): >+ index =3D 0 >+ lineName =3D 0 >+ sourceName =3D "??" >+ while index + 1 < self.lineCount : >+ if self.listLineAddress[index][0] <=3D rva and self.listLineA= ddress[index + >1][0] > rva : >+ offset =3D rva - self.listLineAddress[index][0] >+ functionName =3D self.listLineAddress[index][1] >+ lineName =3D self.listLineAddress[index][2] >+ sourceName =3D self.listLineAddress[index][3] >+ if lineName =3D=3D 0 : >+ return [functionName] >+ else : >+ return [functionName, sourceName, lineName] >+ index +=3D 1 >+ >+ return [] >+ >+ def parse_debug_file(self, driverName, pdbName): >+ if cmp (pdbName, "") =3D=3D 0 : >+ return >+ self.pdbName =3D pdbName; >+ >+ try: >+ nmCommand =3D "nm" >+ nmLineOption =3D "-l" >+ print "parsing (debug) - " + pdbName >+ os.system ('%s %s %s > nmDump.line.log' % (nmCommand, >nmLineOption, pdbName)) >+ except : >+ print 'ERROR: nm command not available. Please verify PATH' >+ return >+ >+ # >+ # parse line >+ # >+ linefile =3D open("nmDump.line.log") >+ reportLines =3D linefile.readlines() >+ linefile.close() >+ >+ # 000113ca T AllocatePool c:\home\edk- >ii\MdePkg\Library\UefiMemoryAllocationLib\MemoryAllocationLib.c:399 >+ patchLineFileMatchString =3D "([0-9a-fA- >F]*)\s+[T|D|t|d]\s+(\w+)\s*((?:[a-zA-Z]:)?[\w+\-./_a-zA-Z0-9\\\\]*):?([0- >9]*)" >+ >+ for reportLine in reportLines: >+ #print "check - " + reportLine >+ match =3D re.match(patchLineFileMatchString, reportLine) >+ if match is not None: >+ #print "match - " + reportLine[:-1] >+ #print "0 - " + match.group(0) >+ #print "1 - " + match.group(1) >+ #print "2 - " + match.group(2) >+ #print "3 - " + match.group(3) >+ #print "4 - " + match.group(4) >+ >+ rva =3D int (match.group(1), 16) >+ functionName =3D match.group(2) >+ sourceName =3D match.group(3) >+ if cmp (match.group(4), "") !=3D 0 : >+ lineName =3D int (match.group(4)) >+ else : >+ lineName =3D 0 >+ self.listLineAddress.append ([rva, functionName, lineName= , >sourceName]) >+ >+ self.lineCount =3D len (self.listLineAddress) >+ >+ self.listLineAddress =3D sorted(self.listLineAddress, key=3Dlambd= a >symbolAddress:symbolAddress[0]) >+ >+ #for key in self.listLineAddress : >+ #print "rva - " + "%x"%(key[0]) + ", func - " + key[1] + ", l= ine - " + >str(key[2]) + ", source - " + key[3] >+ >+ def parse_pdb_file(self, driverName, pdbName): >+ if cmp (pdbName, "") =3D=3D 0 : >+ return >+ self.pdbName =3D pdbName; >+ >+ try: >+ #DIA2DumpCommand =3D "\"C:\\Program Files (x86)\Microsoft Vis= ual >Studio 14.0\\DIA SDK\\Samples\\DIA2Dump\\x64\\Debug\\Dia2Dump.exe\"" >+ DIA2DumpCommand =3D "Dia2Dump.exe" >+ #DIA2SymbolOption =3D "-p" >+ DIA2LinesOption =3D "-l" >+ print "parsing (pdb) - " + pdbName >+ #os.system ('%s %s %s > DIA2Dump.symbol.log' % >(DIA2DumpCommand, DIA2SymbolOption, pdbName)) >+ os.system ('%s %s %s > DIA2Dump.line.log' % (DIA2DumpCommand, >DIA2LinesOption, pdbName)) >+ except : >+ print 'ERROR: DIA2Dump command not available. Please verify = PATH' >+ return >+ >+ # >+ # parse line >+ # >+ linefile =3D open("DIA2Dump.line.log") >+ reportLines =3D linefile.readlines() >+ linefile.close() >+ >+ # ** GetDebugPrintErrorLevel >+ # line 32 at [0000C790][0001:0000B790], len =3D 0x3 c:\home\edk- >ii\mdepkg\library\basedebugprinterrorlevellib\basedebugprinterrorlevellib.= c >(MD5: 687C0AE564079D35D56ED5D84A6164CC) >+ # line 36 at [0000C793][0001:0000B793], len =3D 0x5 >+ # line 37 at [0000C798][0001:0000B798], len =3D 0x2 >+ >+ patchLineFileMatchString =3D "\s+line ([0-9]+) at \[([0-9a-fA-F]{= 8})\]\[[0- >9a-fA-F]{4}\:[0-9a-fA-F]{8}\], len =3D 0x[0-9a-fA-F]+\s*([\w+\-\:./_a-zA-Z= 0- >9\\\\]*)\s*" >+ patchLineFileMatchStringFunc =3D "\*\*\s+(\w+)\s*" >+ >+ for reportLine in reportLines: >+ #print "check line - " + reportLine >+ match =3D re.match(patchLineFileMatchString, reportLine) >+ if match is not None: >+ #print "match - " + reportLine[:-1] >+ #print "0 - " + match.group(0) >+ #print "1 - " + match.group(1) >+ #print "2 - " + match.group(2) >+ if cmp (match.group(3), "") !=3D 0 : >+ self.sourceName =3D match.group(3) >+ sourceName =3D self.sourceName >+ functionName =3D self.functionName >+ >+ rva =3D int (match.group(2), 16) >+ lineName =3D int (match.group(1)) >+ self.listLineAddress.append ([rva, functionName, lineName= , >sourceName]) >+ else : >+ match =3D re.match(patchLineFileMatchStringFunc, reportLi= ne) >+ if match is not None: >+ self.functionName =3D match.group(1) >+ >+ self.lineCount =3D len (self.listLineAddress) >+ self.listLineAddress =3D sorted(self.listLineAddress, key=3Dlambd= a >symbolAddress:symbolAddress[0]) >+ >+ #for key in self.listLineAddress : >+ #print "rva - " + "%x"%(key[0]) + ", func - " + key[1] + ", l= ine - " + >str(key[2]) + ", source - " + key[3] >+ >+class SymbolsFile: >+ def __init__(self): >+ self.symbolsTable =3D {} >+ >+symbolsFile =3D "" >+ >+driverName =3D "" >+rvaName =3D "" >+symbolName =3D "" >+ >+def getSymbolName(driverName, rva): >+ global symbolsFile >+ >+ #print "driverName - " + driverName >+ >+ try : >+ symbolList =3D symbolsFile.symbolsTable[driverName] >+ if symbolList is not None: >+ return symbolList.getSymbol (rva) >+ else: >+ return [] >+ except Exception: >+ return [] >+ >+def myOptionParser(): >+ usage =3D "%prog [--version] [-h] [--help] [-i inputfile [-o outputfi= le] [-g >guidreffile]]" >+ Parser =3D OptionParser(usage=3Dusage, description=3D__copyright__, >version=3D"%prog " + str(versionNumber)) >+ Parser.add_option("-i", "--inputfile", dest=3D"inputfilename", type= =3D"string", >help=3D"The input memory profile info file output from MemoryProfileInfo >application in MdeModulePkg") >+ Parser.add_option("-o", "--outputfile", dest=3D"outputfilename", >type=3D"string", help=3D"The output memory profile info file with symbol, >MemoryProfileInfoSymbol.txt will be used if it is not specified") >+ Parser.add_option("-g", "--guidref", dest=3D"guidreffilename", >type=3D"string", help=3D"The input guid ref file output from build") >+ >+ (Options, args) =3D Parser.parse_args() >+ if Options.inputfilename is None: >+ Parser.error("no input file specified") >+ if Options.outputfilename is None: >+ Options.outputfilename =3D "SmiHandlerProfileInfoSymbol.xml" >+ return Options >+ >+dictGuid =3D { >+ '00000000-0000-0000-0000-000000000000':'gZeroGuid', >+ '2A571201-4966-47F6-8B86-F31E41F32F10':'gEfiEventLegacyBootGuid', >+ '27ABF055-B1B8-4C26-8048-748F37BAA2DF':'gEfiEventExitBootServicesGuid', >+ '7CE88FB3-4BD7-4679-87A8-A8D8DEE50D2B':'gEfiEventReadyToBootGuid', >+ '02CE967A-DD7E-4FFC-9EE7-810CF0470880':'gEfiEndOfDxeEventGroupGuid', >+ '60FF8964-E906-41D0-AFED- >F241E974E08E':'gEfiDxeSmmReadyToLockProtocolGuid', >+ '18A3C6DC-5EEA-48C8-A1C1- >B53389F98999':'gEfiSmmSwDispatch2ProtocolGuid', >+ '456D2859-A84B-4E47-A2EE- >3276D886997D':'gEfiSmmSxDispatch2ProtocolGuid', >+ '4CEC368E-8E8E-4D71-8BE1- >958C45FC8A53':'gEfiSmmPeriodicTimerDispatch2ProtocolGuid', >+ 'EE9B8D90-C5A6-40A2-BDE2- >52558D33CCA1':'gEfiSmmUsbDispatch2ProtocolGuid', >+ '25566B03-B577-4CBF-958C- >ED663EA24380':'gEfiSmmGpiDispatch2ProtocolGuid', >+ '7300C4A1-43F2-4017-A51B- >C81A7F40585B':'gEfiSmmStandbyButtonDispatch2ProtocolGuid', >+ '1B1183FA-1823-46A7-8872- >9C578755409D':'gEfiSmmPowerButtonDispatch2ProtocolGuid', >+ '58DC368D-7BFA-4E77-ABBC- >0E29418DF930':'gEfiSmmIoTrapDispatch2ProtocolGuid', >+ } >+ >+def genGuidString(guidreffile): >+ guidLines =3D guidreffile.readlines() >+ for guidLine in guidLines: >+ guidLineList =3D guidLine.split(" ") >+ if len(guidLineList) =3D=3D 2: >+ guid =3D guidLineList[0] >+ guidName =3D guidLineList[1] >+ #print "guid: " + guid >+ #print "name: " + guidName >+ if guid not in dictGuid.keys() : >+ dictGuid[guid] =3D guidName >+ >+def createSym(symbolName): >+ SymbolNode =3D xml.dom.minidom.Document().createElement("Symbol") >+ SymbolFunction =3D >xml.dom.minidom.Document().createElement("Function") >+ SymbolFunctionData =3D >xml.dom.minidom.Document().createTextNode(symbolName[0]) >+ SymbolFunction.appendChild(SymbolFunctionData) >+ SymbolNode.appendChild(SymbolFunction) >+ #print " append SymbolFunction: " + symbolName[0] >+ if (len(symbolName)) >=3D 2: >+ SymbolSourceFile =3D >xml.dom.minidom.Document().createElement("SourceFile") >+ SymbolSourceFileData =3D >xml.dom.minidom.Document().createTextNode(symbolName[1]) >+ SymbolSourceFile.appendChild(SymbolSourceFileData) >+ SymbolNode.appendChild(SymbolSourceFile) >+ #print " append SymbolSourceFile: " + symbolName[1] >+ if (len(symbolName)) >=3D 3: >+ SymbolLineNumber =3D >xml.dom.minidom.Document().createElement("LineNumber") >+ SymbolLineNumberData =3D >xml.dom.minidom.Document().createTextNode(str(symbolName[2])) >+ SymbolLineNumber.appendChild(SymbolLineNumberData) >+ SymbolNode.appendChild(SymbolLineNumber) >+ #print " append SymbolLineNumber: " + str(symbolName[2]) >+ return SymbolNode >+ >+def main(): >+ global symbolsFile >+ global Options >+ Options =3D myOptionParser() >+ >+ symbolsFile =3D SymbolsFile() >+ >+ try : >+ DOMTree =3D xml.dom.minidom.parse(Options.inputfilename) >+ except Exception: >+ print "fail to open input " + Options.inputfilename >+ return 1 >+ >+ if Options.guidreffilename is not None: >+ try : >+ guidreffile =3D open(Options.guidreffilename) >+ except Exception: >+ print "fail to open guidref" + Options.guidreffilename >+ return 1 >+ genGuidString(guidreffile) >+ guidreffile.close() >+ >+ SmiHandlerProfile =3D DOMTree.documentElement >+ >+ SmiHandlerDatabase =3D >SmiHandlerProfile.getElementsByTagName("SmiHandlerDatabase") >+ SmiHandlerCategory =3D >SmiHandlerDatabase[0].getElementsByTagName("SmiHandlerCategory") >+ for smiHandlerCategory in SmiHandlerCategory: >+ #print "*****SmiHandlerCategory*****" >+ #if smiHandlerCategory.hasAttribute("Name"): >+ # print "Name: %s" % smiHandlerCategory.getAttribute("Name") >+ SmiEntry =3D smiHandlerCategory.getElementsByTagName("SmiEntry") >+ for smiEntry in SmiEntry: >+ #print " *****SmiEntry*****" >+ if smiEntry.hasAttribute("HandlerType"): >+ #print " HandlerType: %s" % smiEntry.getAttribute("Handl= erType") >+ guidValue =3D smiEntry.getAttribute("HandlerType") >+ if guidValue in dictGuid.keys() : >+ smiEntry.setAttribute("HandlerType", dictGuid[guidVal= ue]) >+ SmiHandler =3D smiEntry.getElementsByTagName("SmiHandler") >+ for smiHandler in SmiHandler: >+ #print " *****SmiHandler*****" >+ #if smiHandler.hasAttribute("SwSmi"): >+ # print " SwSmi: %s" % smiHandler.getAttribute("SwS= mi") >+ Module =3D smiHandler.getElementsByTagName("Module") >+ #print " Module: %s" % Module[0].childNodes[0].data >+ Pdb =3D Module[0].getElementsByTagName("Pdb") >+ if (len(Pdb)) >=3D 1: >+ #print " Pdb: %s" % Pdb[0].childNodes[0].data >+ >+ driverName =3D Module[0].getAttribute("Name") >+ pdbName =3D Pdb[0].childNodes[0].data >+ >+ Module[0].removeChild(Pdb[0]) >+ >+ symbolsFile.symbolsTable[driverName] =3D Symbols() >+ >+ if cmp (pdbName[-3:], "pdb") =3D=3D 0 : >+ symbolsFile.symbolsTable[driverName].parse_pdb_fi= le >(driverName, pdbName) >+ else : >+ symbolsFile.symbolsTable[driverName].parse_debug_= file >(driverName, pdbName) >+ >+ Handler =3D smiHandler.getElementsByTagName("Handler"= ) >+ RVA =3D Handler[0].getElementsByTagName("RVA") >+ print " Handler RVA: %s" % RVA[0].childNodes[0].da= ta >+ >+ if (len(RVA)) >=3D 1: >+ rvaName =3D RVA[0].childNodes[0].data >+ symbolName =3D getSymbolName (driverName, int(rva= Name, 16)) >+ #print " symbolName: %s" % symbolName >+ >+ if (len(symbolName)) >=3D 1: >+ SymbolNode =3D createSym(symbolName) >+ Handler[0].appendChild(SymbolNode) >+ >+ Caller =3D smiHandler.getElementsByTagName("Caller") >+ RVA =3D Caller[0].getElementsByTagName("RVA") >+ print " Caller RVA: %s" % RVA[0].childNodes[0].dat= a >+ >+ if (len(RVA)) >=3D 1: >+ rvaName =3D RVA[0].childNodes[0].data >+ symbolName =3D getSymbolName (driverName, int(rva= Name, 16)) >+ #print " symbolName: %s" % symbolName >+ >+ if (len(symbolName)) >=3D 1: >+ SymbolNode =3D createSym(symbolName) >+ Caller[0].appendChild(SymbolNode) >+ >+ try : >+ newfile =3D open(Options.outputfilename, "w") >+ except Exception: >+ print "fail to open output" + Options.outputfilename >+ return 1 >+ >+ newfile.write(DOMTree.toprettyxml(indent =3D "\t", newl =3D "\n", enc= oding >=3D "utf-8")) >+ newfile.close() >+ >+if __name__ =3D=3D '__main__': >+ sys.exit(main()) >-- >2.7.4.windows.1