diff options
Diffstat (limited to 'src/scripts/genXplatEventing.py')
-rw-r--r-- | src/scripts/genXplatEventing.py | 133 |
1 files changed, 68 insertions, 65 deletions
diff --git a/src/scripts/genXplatEventing.py b/src/scripts/genXplatEventing.py index 1d01b60a6c..2d44904693 100644 --- a/src/scripts/genXplatEventing.py +++ b/src/scripts/genXplatEventing.py @@ -1,4 +1,4 @@ -## +# ## Copyright (c) Microsoft. All rights reserved. ## Licensed under the MIT license. See LICENSE file in the project root for full license information. ## @@ -8,7 +8,7 @@ #Look at the Code in <root>/src/inc/genXplatLttng.py for using subroutines in this file # -import os +import os import xml.dom.minidom as DOM stdprolog=""" @@ -59,22 +59,21 @@ palDataTypeMapping ={ "win:Binary" :"const BYTE" } # A Template represents an ETW template can contain 1 or more AbstractTemplates -# The AbstractTemplate contains FunctionSignature +# The AbstractTemplate contains FunctionSignature # FunctionSignature consist of FunctionParameter representing each parameter in it's signature class AbstractTemplate: def __init__(self,abstractTemplateName,abstractFnFrame): self.abstractTemplateName = abstractTemplateName self.AbstractFnFrame = abstractFnFrame - class Template: def __init__(self,templateName): self.template = templateName - self.allAbstractTemplateTypes = [] # list of AbstractTemplateNames - self.allAbstractTemplateLUT = {} #dictionary of AbstractTemplate - + self.allAbstractTemplateTypes = [] # list of AbstractTemplateNames + self.allAbstractTemplateLUT = {} #dictionary of AbstractTemplate + def append(self,abstractTemplateName,abstractFnFrame): self.allAbstractTemplateTypes.append(abstractTemplateName) self.allAbstractTemplateLUT[abstractTemplateName] = AbstractTemplate(abstractTemplateName,abstractFnFrame) @@ -90,12 +89,12 @@ class Template: frame = self.getFnFrame(subtemplate) if frame.getParam(name): return frame.getParam(name) - return None + return None class FunctionSignature: def __init__(self): - self.LUT = {} # dictionary of FunctionParameter + self.LUT = {} # dictionary of FunctionParameter self.paramlist = [] # list of parameters to maintain their order in signature def append(self,variable,fnparam): @@ -114,7 +113,7 @@ class FunctionParameter: self.winType = winType #ETW type as given in the manifest self.name = name #parameter name as given in the manifest self.prop = prop #any special property as determined by the manifest and developer - #self.count #indicates if the parameter is a pointer + #self.count #indicates if the parameter is a pointer if count == "win:null": self.count = "win:null" elif count or winType == "win:GUID" or count == "win:count": @@ -123,7 +122,6 @@ class FunctionParameter: else: self.count = "win:null" - def getTopLevelElementsByTagName(Node,tag): dataNodes = [] @@ -134,7 +132,7 @@ def getTopLevelElementsByTagName(Node,tag): return dataNodes def bucketizeAbstractTemplates(template,fnPrototypes,var_Dependecies): - # At this point we have the complete argument list, now break them into chunks of 10 + # At this point we have the complete argument list, now break them into chunks of 10 # As Abstract Template supports a maximum of 10 arguments abstractTemplateName = template; subevent_cnt = 1; @@ -147,7 +145,7 @@ def bucketizeAbstractTemplates(template,fnPrototypes,var_Dependecies): abstractFnFrame.append(dependency,fnPrototypes.getParam(dependency)) frameCount = abstractFnFrame.getLength() - if frameCount == 10: + if frameCount == 10: templateProp.append(abstractTemplateName,abstractFnFrame) abstractTemplateName = template + "_" + str(subevent_cnt) @@ -167,10 +165,9 @@ def bucketizeAbstractTemplates(template,fnPrototypes,var_Dependecies): # 2. Check if the frame has enough space, if there is continue adding missing dependencies # 3. Else Save the current Frame and start a new frame and follow step 1 and 2 # 4. Add the current parameter and proceed - - #create a new fn frame - abstractFnFrame = FunctionSignature() + #create a new fn frame + abstractFnFrame = FunctionSignature() #subevent_cnt == 1 represents argumentless templates if abstractFnFrame.getLength() > 0 or subevent_cnt == 1: @@ -200,11 +197,11 @@ def parseTemplateNodes(templateNodes): attrib_name = attrib.name if attrib_name not in ignoredXmlTemplateAttribes and attrib_name not in usedXmlTemplateAttribes: raise ValueError('unknown attribute: '+ attrib_name + ' in template:'+ template) - + for dataNode in dataNodes: variable = dataNode.getAttribute('name') wintype = dataNode.getAttribute('inType') - + #count and length are the same wincount = dataNode.getAttribute('count') winlength = dataNode.getAttribute('length'); @@ -213,36 +210,35 @@ def parseTemplateNodes(templateNodes): var_dependency = [variable] if winlength: if wincount: - raise Exception("both count and length property found on: " + variable + "in template: " + template) + raise Exception("both count and length property found on: " + variable + "in template: " + template) wincount = winlength if (wincount.isdigit() and int(wincount) ==1): wincount = '' - + if wincount: if (wincount.isdigit()): var_Props = wincount - elif fnPrototypes.getParam(wincount): + elif fnPrototypes.getParam(wincount): var_Props = wincount var_dependency.insert(0,wincount) - + #construct the function signature - if wintype == "win:GUID": var_Props = "sizeof(GUID)/sizeof(int)" - + var_Dependecies[variable] = var_dependency fnparam = FunctionParameter(wintype,variable,wincount,var_Props) fnPrototypes.append(variable,fnparam) structNodes = getTopLevelElementsByTagName(templateNode,'struct') - + count = 0; for structToBeMarshalled in structNodes: struct_len = "Arg"+ str(count) + "_Struct_Len_" struct_pointer = "Arg"+ str(count) + "_Struct_Pointer_" - count += 1 + count += 1 #populate the Property- used in codegen structname = structToBeMarshalled.getAttribute('name') @@ -250,19 +246,19 @@ def parseTemplateNodes(templateNodes): if not countVarName: raise ValueError('Struct '+ structname+ ' in template:'+ template + 'does not have an attribute count') - + var_Props = countVarName + "*" + struct_len + "/sizeof(int)" var_Dependecies[struct_len] = [struct_len] var_Dependecies[struct_pointer] = [countVarName,struct_len,struct_pointer] - + fnparam_len = FunctionParameter("win:ULong",struct_len,"win:null",None) fnparam_pointer = FunctionParameter("win:Struct",struct_pointer,"win:count",var_Props) - + fnPrototypes.append(struct_len,fnparam_len) fnPrototypes.append(struct_pointer,fnparam_pointer) allTemplates[template] = bucketizeAbstractTemplates(template,fnPrototypes,var_Dependecies) - + return allTemplates def generateClrallEvents(eventNodes,allTemplates): @@ -317,7 +313,7 @@ def generateClrallEvents(eventNodes,allTemplates): del line[-1] if len(fnptypeline) > 0: del fnptypeline[-1] - + fnptype.extend(fnptypeline) fnptype.append("\n)\n{\n") fnbody.append(lindent) @@ -327,10 +323,10 @@ def generateClrallEvents(eventNodes,allTemplates): fnbody.extend(line) fnbody.append(");\n") fnbody.append("}\n\n") - + clrallEvents.extend(fnptype) clrallEvents.extend(fnbody) - + return ''.join(clrallEvents) def generateClrXplatEvents(eventNodes, allTemplates): @@ -370,11 +366,11 @@ def generateClrXplatEvents(eventNodes, allTemplates): #remove trailing commas if len(fnptypeline) > 0: del fnptypeline[-1] - + fnptype.extend(fnptypeline) fnptype.append("\n);\n") clrallEvents.extend(fnptype) - + return ''.join(clrallEvents) #generates the dummy header file which is used by the VM as entry point to the logging Functions @@ -385,7 +381,7 @@ def generateclrEtwDummy(eventNodes,allTemplates): templateName = eventNode.getAttribute('template') fnptype = [] - #generate FireEtw functions + #generate FireEtw functions fnptype.append("#define FireEtw") fnptype.append(eventName) fnptype.append("("); @@ -398,11 +394,11 @@ def generateclrEtwDummy(eventNodes,allTemplates): fnparam = fnSig.getParam(params) line.append(fnparam.name) line.append(", ") - + #remove trailing commas if len(line) > 0: del line[-1] - + fnptype.extend(line) fnptype.append(") 0\n") clretmEvents.extend(fnptype) @@ -423,7 +419,6 @@ def generateClralltestEvents(sClrEtwAllMan): clrtestEvents.append(" EventXplatEnabled" + eventName + "();\n") clrtestEvents.append("Error |= FireEtXplat" + eventName + "(\n") - line =[] if templateName : for subTemplate in allTemplates[templateName].allAbstractTemplateTypes: @@ -453,7 +448,7 @@ def generateClralltestEvents(sClrEtwAllMan): line.append(argline) line.append(",\n") - + #remove trailing commas if len(line) > 0: del line[-1] @@ -463,20 +458,22 @@ def generateClralltestEvents(sClrEtwAllMan): return ''.join(clrtestEvents) +def generateSanityTest(sClrEtwAllMan,testDir): + if not testDir: + return + print('Generting Event Logging Tests') - -def generateSanityTest(sClrEtwAllMan,testDir): if not os.path.exists(testDir): os.makedirs(testDir) cmake_file = testDir + "/CMakeLists.txt" - test_cpp = testDir + "/clralltestevents.cpp" + test_cpp = "clralltestevents.cpp" testinfo = testDir + "/testinfo.dat" Cmake_file = open(cmake_file,'w') - Test_cpp = open(test_cpp,'w') + Test_cpp = open(testDir + "/" + test_cpp,'w') Testinfo = open(testinfo,'w') - + #CMake File: print >>Cmake_file, stdprolog_cmake print >>Cmake_file, """ @@ -487,7 +484,7 @@ def generateSanityTest(sClrEtwAllMan,testDir): print >>Cmake_file, test_cpp print >>Cmake_file, """ ) - include_directories($ENV{__GeneratedIntermediatesDir}/inc) + include_directories(${GENERATED_INCLUDE_DIR}) include_directories(${COREPAL_SOURCE_DIR}/inc/rt) add_executable(eventprovidertest @@ -562,7 +559,7 @@ unsigned int win_UInt32 = 4; unsigned short win_UInt16 = 12; unsigned char win_UInt8 = 9; int win_Int32 = 12; -BYTE* win_Binary =(BYTE*)var21 ; +BYTE* win_Binary =(BYTE*)var21 ; int __cdecl main(int argc, char **argv) { @@ -601,11 +598,17 @@ int __cdecl main(int argc, char **argv) Testinfo.close() def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy): + + if not clretwdummy: + return + + print(' Generting Dummy Event Headers') tree = DOM.parse(sClrEtwAllMan) incDir = os.path.dirname(os.path.realpath(clretwdummy)) if not os.path.exists(incDir): os.makedirs(incDir) + Clretwdummy = open(clretwdummy,'w') Clretwdummy.write(stdprolog + "\n") @@ -615,16 +618,21 @@ def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy): eventNodes = providerNode.getElementsByTagName('event') #pal: create etmdummy.h Clretwdummy.write(generateclrEtwDummy(eventNodes, allTemplates) + "\n") - + Clretwdummy.close() -def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile, testDir): +def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile): + + generateEtmDummyHeader(sClrEtwAllMan,etmDummyFile) tree = DOM.parse(sClrEtwAllMan) + + if not incDir: + return + + print(' Generting Event Headers') if not os.path.exists(incDir): os.makedirs(incDir) - generateSanityTest(sClrEtwAllMan,testDir) - generateEtmDummyHeader(sClrEtwAllMan,etmDummyFile) clrallevents = incDir + "/clretwallmain.h" clrxplatevents = incDir + "/clrxplatevents.h" @@ -640,13 +648,12 @@ def generatePlformIndependentFiles(sClrEtwAllMan,incDir,etmDummyFile, testDir): templateNodes = providerNode.getElementsByTagName('template') allTemplates = parseTemplateNodes(templateNodes) eventNodes = providerNode.getElementsByTagName('event') - #vm header: + #vm header: Clrallevents.write(generateClrallEvents(eventNodes, allTemplates) + "\n") #pal: create clrallevents.h Clrxplatevents.write(generateClrXplatEvents(eventNodes, allTemplates) + "\n") - Clrxplatevents.close() Clrallevents.close() @@ -662,7 +669,7 @@ def parseExclusionList(exclusionListFile): for line in ExclusionFile: line = line.strip() - + #remove comments if not line or line.startswith('#'): continue @@ -703,7 +710,7 @@ def getStackWalkBit(eventProvider, taskName, eventSymbol, stackSet): if len(tokens) != 3: raise Exception("Error, possible error in the script which introduced the enrty "+ entry) - + eventCond = tokens[0] == eventProvider or tokens[0] == "*" taskCond = tokens[1] == taskName or tokens[1] == "*" symbolCond = tokens[2] == eventSymbol or tokens[2] == "*" @@ -740,7 +747,6 @@ def checkConsistency(sClrEtwAllMan,exclusionListFile): if not(fnParam and fnParam.winType == sLookupFieldType): raise Exception(exclusionListFile + ":No " + sLookupFieldName + " field of type " + sLookupFieldType + " for event symbol " + eventSymbol) - # If some versions of an event are on the nostack/stack lists, # and some versions are not on either the nostack or stack list, # then developer likely forgot to specify one of the versions @@ -754,7 +760,7 @@ def checkConsistency(sClrEtwAllMan,exclusionListFile): if ( not eventStackBitFromNoStackList) or ( not eventStackBitFromExplicitStackList): stackSupportSpecified[eventValue] = True else: - stackSupportSpecified[eventValue] = False + stackSupportSpecified[eventValue] = False else: # We've checked this event before. if stackSupportSpecified[eventValue]: @@ -778,11 +784,11 @@ def main(argv): help='full path to manifest containig the description of events') required.add_argument('--exc', type=str, required=True, help='full path to exclusion list') - required.add_argument('--inc', type=str, required=True, + required.add_argument('--inc', type=str, default=None, help='full path to directory where the header files will be generated') - required.add_argument('--dummy', type=str, required=True, + required.add_argument('--dummy', type=str,default=None, help='full path to file that will have dummy definitions of FireEtw functions') - required.add_argument('--testdir', type=str, required=True, + required.add_argument('--testdir', type=str, default=None, help='full path to directory where the test assets will be deployed' ) args, unknown = parser.parse_known_args(argv) if unknown: @@ -796,11 +802,8 @@ def main(argv): testDir = args.testdir checkConsistency(sClrEtwAllMan, exclusionListFile) - generatePlformIndependentFiles(sClrEtwAllMan,incdir,etmDummyFile,testDir) - + generatePlformIndependentFiles(sClrEtwAllMan,incdir,etmDummyFile) + generateSanityTest(sClrEtwAllMan,testDir) if __name__ == '__main__': return_code = main(sys.argv[1:]) sys.exit(return_code) - - - |