summaryrefslogtreecommitdiff
path: root/src/scripts/genEventing.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts/genEventing.py')
-rw-r--r--src/scripts/genEventing.py808
1 files changed, 808 insertions, 0 deletions
diff --git a/src/scripts/genEventing.py b/src/scripts/genEventing.py
new file mode 100644
index 0000000000..d6d6afbb90
--- /dev/null
+++ b/src/scripts/genEventing.py
@@ -0,0 +1,808 @@
+#
+## Licensed to the .NET Foundation under one or more agreements.
+## The .NET Foundation licenses this file to you under the MIT license.
+## See the LICENSE file in the project root for more information.
+#
+#
+#USAGE:
+#Add Events: modify <root>src/vm/ClrEtwAll.man
+#Look at the Code in <root>/src/scripts/genLttngProvider.py for using subroutines in this file
+#
+
+# Python 2 compatibility
+from __future__ import print_function
+
+import os
+import xml.dom.minidom as DOM
+from utilities import open_for_update
+
+stdprolog="""
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/******************************************************************
+
+DO NOT MODIFY. AUTOGENERATED FILE.
+This file is generated using the logic from <root>/src/scripts/genEventing.py
+
+******************************************************************/
+"""
+
+stdprolog_cmake="""
+#
+#
+#******************************************************************
+
+#DO NOT MODIFY. AUTOGENERATED FILE.
+#This file is generated using the logic from <root>/src/scripts/genEventing.py
+
+#******************************************************************
+"""
+
+lindent = " ";
+palDataTypeMapping ={
+ #constructed types
+ "win:null" :" ",
+ "win:Int64" :"const __int64",
+ "win:ULong" :"const ULONG",
+ "win:count" :"*",
+ "win:Struct" :"const void",
+ #actual spec
+ "win:GUID" :"const GUID",
+ "win:AnsiString" :"LPCSTR",
+ "win:UnicodeString" :"PCWSTR",
+ "win:Double" :"const double",
+ "win:Int32" :"const signed int",
+ "win:Boolean" :"const BOOL",
+ "win:UInt64" :"const unsigned __int64",
+ "win:UInt32" :"const unsigned int",
+ "win:UInt16" :"const unsigned short",
+ "win:UInt8" :"const unsigned char",
+ "win:Pointer" :"const void*",
+ "win:Binary" :"const BYTE"
+ }
+# A Template represents an ETW template can contain 1 or more AbstractTemplates
+# The AbstractTemplate contains FunctionSignature
+# FunctionSignature consist of FunctionParameter representing each parameter in it's signature
+
+def getParamSequenceSize(paramSequence, estimate):
+ total = 0
+ pointers = 0
+ for param in paramSequence:
+ if param == "win:Int64":
+ total += 8
+ elif param == "win:ULong":
+ total += 4
+ elif param == "GUID":
+ total += 16
+ elif param == "win:Double":
+ total += 8
+ elif param == "win:Int32":
+ total += 4
+ elif param == "win:Boolean":
+ total += 4
+ elif param == "win:UInt64":
+ total += 8
+ elif param == "win:UInt32":
+ total += 4
+ elif param == "win:UInt16":
+ total += 2
+ elif param == "win:UInt8":
+ total += 1
+ elif param == "win:Pointer":
+ if estimate:
+ total += 8
+ else:
+ pointers += 1
+ elif param == "win:Binary":
+ total += 1
+ elif estimate:
+ if param == "win:AnsiString":
+ total += 32
+ elif param == "win:UnicodeString":
+ total += 64
+ elif param == "win:Struct":
+ total += 32
+ else:
+ raise Exception("Don't know size for " + param)
+
+ if estimate:
+ return total
+
+ return total, pointers
+
+
+class Template:
+ def __repr__(self):
+ return "<Template " + self.name + ">"
+
+ def __init__(self, templateName, fnPrototypes, dependencies, structSizes, arrays):
+ self.name = templateName
+ self.signature = FunctionSignature()
+ self.structs = structSizes
+ self.arrays = arrays
+
+ for variable in fnPrototypes.paramlist:
+ for dependency in dependencies[variable]:
+ if not self.signature.getParam(dependency):
+ self.signature.append(dependency, fnPrototypes.getParam(dependency))
+
+ def getFnParam(self, name):
+ return self.signature.getParam(name)
+
+ @property
+ def num_params(self):
+ return len(self.signature.paramlist)
+
+ @property
+ def estimated_size(self):
+ total = getParamSequenceSize((self.getFnParam(paramName).winType for paramName in self.signature.paramlist), True)
+
+ if total < 32:
+ total = 32
+ elif total > 1024:
+ total = 1024
+
+ return total
+
+
+
+class FunctionSignature:
+ def __repr__(self):
+ return ", ".join(self.paramlist)
+
+ def __init__(self):
+ self.LUT = {} # dictionary of FunctionParameter
+ self.paramlist = [] # list of parameters to maintain their order in signature
+
+ def append(self,variable,fnparam):
+ self.LUT[variable] = fnparam
+ self.paramlist.append(variable)
+
+ def getParam(self,variable):
+ return self.LUT.get(variable)
+
+ def getLength(self):
+ return len(self.paramlist)
+
+class FunctionParameter:
+ def __repr__(self):
+ return self.name
+
+ def __init__(self,winType,name,count,prop):
+ 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
+ if count == "win:null":
+ self.count = "win:null"
+ elif count or winType == "win:GUID" or count == "win:count":
+ #special case for GUIDS, consider them as structs
+ self.count = "win:count"
+ else:
+ self.count = "win:null"
+
+
+def getTopLevelElementsByTagName(node,tag):
+ dataNodes = []
+ for element in node.getElementsByTagName(tag):
+ if element.parentNode == node:
+ dataNodes.append(element)
+
+ return dataNodes
+
+ignoredXmlTemplateAttribes = frozenset(["map","outType"])
+usedXmlTemplateAttribes = frozenset(["name","inType","count", "length"])
+
+def parseTemplateNodes(templateNodes):
+
+ #return values
+ allTemplates = {}
+
+ for templateNode in templateNodes:
+ structCounts = {}
+ arrays = {}
+ templateName = templateNode.getAttribute('tid')
+ var_Dependecies = {}
+ fnPrototypes = FunctionSignature()
+ dataNodes = getTopLevelElementsByTagName(templateNode,'data')
+
+ # Validate that no new attributes has been added to manifest
+ for dataNode in dataNodes:
+ nodeMap = dataNode.attributes
+ for attrib in nodeMap.values():
+ attrib_name = attrib.name
+ if attrib_name not in ignoredXmlTemplateAttribes and attrib_name not in usedXmlTemplateAttribes:
+ raise ValueError('unknown attribute: '+ attrib_name + ' in template:'+ templateName)
+
+ 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');
+
+ var_Props = None
+ var_dependency = [variable]
+ if winlength:
+ if wincount:
+ raise Exception("both count and length property found on: " + variable + "in template: " + templateName)
+ wincount = winlength
+
+ if (wincount.isdigit() and int(wincount) ==1):
+ wincount = ''
+
+ if wincount:
+ if (wincount.isdigit()):
+ var_Props = wincount
+ elif fnPrototypes.getParam(wincount):
+ var_Props = wincount
+ var_dependency.insert(0, wincount)
+ arrays[variable] = 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')
+
+ for structToBeMarshalled in structNodes:
+ structName = structToBeMarshalled.getAttribute('name')
+ countVarName = structToBeMarshalled.getAttribute('count')
+
+ assert(countVarName == "Count")
+ assert(countVarName in fnPrototypes.paramlist)
+ if not countVarName:
+ raise ValueError("Struct '%s' in template '%s' does not have an attribute count." % (structName, templateName))
+
+ names = [x.attributes['name'].value for x in structToBeMarshalled.getElementsByTagName("data")]
+ types = [x.attributes['inType'].value for x in structToBeMarshalled.getElementsByTagName("data")]
+
+ structCounts[structName] = countVarName
+ var_Dependecies[structName] = [countVarName, structName]
+ fnparam_pointer = FunctionParameter("win:Struct", structName, "win:count", countVarName)
+ fnPrototypes.append(structName, fnparam_pointer)
+
+ allTemplates[templateName] = Template(templateName, fnPrototypes, var_Dependecies, structCounts, arrays)
+
+ return allTemplates
+
+def generateClrallEvents(eventNodes,allTemplates):
+ clrallEvents = []
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+
+ #generate EventEnabled
+ clrallEvents.append("inline BOOL EventEnabled")
+ clrallEvents.append(eventName)
+ clrallEvents.append("() {return ")
+ clrallEvents.append("EventPipeEventEnabled" + eventName + "() || ")
+ clrallEvents.append("EventXplatEnabled" + eventName + "();}\n\n")
+ #generate FireEtw functions
+ fnptype = []
+ fnbody = []
+ fnptype.append("inline ULONG FireEtw")
+ fnptype.append(eventName)
+ fnptype.append("(\n")
+
+ line = []
+ fnptypeline = []
+
+ if templateName:
+ template = allTemplates[templateName]
+ fnSig = template.signature
+
+ for params in fnSig.paramlist:
+ fnparam = fnSig.getParam(params)
+ wintypeName = fnparam.winType
+ typewName = palDataTypeMapping[wintypeName]
+ winCount = fnparam.count
+ countw = palDataTypeMapping[winCount]
+
+
+ if params in template.structs:
+ fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params))
+
+ fnptypeline.append(lindent)
+ fnptypeline.append(typewName)
+ fnptypeline.append(countw)
+ fnptypeline.append(" ")
+ fnptypeline.append(fnparam.name)
+ fnptypeline.append(",\n")
+
+ #fnsignature
+ for params in fnSig.paramlist:
+ fnparam = fnSig.getParam(params)
+
+ if params in template.structs:
+ line.append(fnparam.name + "_ElementSize")
+ line.append(", ")
+
+ line.append(fnparam.name)
+ line.append(",")
+
+ #remove trailing commas
+ if len(line) > 0:
+ del line[-1]
+ if len(fnptypeline) > 0:
+ del fnptypeline[-1]
+
+ fnptype.extend(fnptypeline)
+ fnptype.append("\n)\n{\n")
+ fnbody.append(lindent)
+ fnbody.append("ULONG status = EventPipeWriteEvent" + eventName + "(" + ''.join(line) + ");\n")
+ fnbody.append(lindent)
+ fnbody.append("status &= FireEtXplat" + eventName + "(" + ''.join(line) + ");\n")
+ fnbody.append(lindent)
+ fnbody.append("return status;\n")
+ fnbody.append("}\n\n")
+
+ clrallEvents.extend(fnptype)
+ clrallEvents.extend(fnbody)
+
+ return ''.join(clrallEvents)
+
+def generateClrXplatEvents(eventNodes, allTemplates, extern):
+ clrallEvents = []
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+
+ #generate EventEnabled
+ if extern: clrallEvents.append('extern "C" ')
+ clrallEvents.append("BOOL EventXplatEnabled")
+ clrallEvents.append(eventName)
+ clrallEvents.append("();\n")
+
+ #generate FireEtw functions
+ fnptype = []
+ fnptypeline = []
+ if extern: fnptype.append('extern "C" ')
+ fnptype.append("ULONG FireEtXplat")
+ fnptype.append(eventName)
+ fnptype.append("(\n")
+
+ if templateName:
+ template = allTemplates[templateName]
+ fnSig = template.signature
+
+ for params in fnSig.paramlist:
+ fnparam = fnSig.getParam(params)
+ wintypeName = fnparam.winType
+ typewName = palDataTypeMapping[wintypeName]
+ winCount = fnparam.count
+ countw = palDataTypeMapping[winCount]
+
+
+ if params in template.structs:
+ fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params))
+
+ fnptypeline.append(lindent)
+ fnptypeline.append(typewName)
+ fnptypeline.append(countw)
+ fnptypeline.append(" ")
+ fnptypeline.append(fnparam.name)
+ fnptypeline.append(",\n")
+
+ #remove trailing commas
+ if len(fnptypeline) > 0:
+ del fnptypeline[-1]
+
+ fnptype.extend(fnptypeline)
+ fnptype.append("\n);\n")
+ clrallEvents.extend(fnptype)
+
+ return ''.join(clrallEvents)
+
+def generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern):
+ clrallEvents = []
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+
+ #generate EventPipeEventEnabled and EventPipeWriteEvent functions
+ eventenabled = []
+ writeevent = []
+ fnptypeline = []
+
+ if extern:eventenabled.append('extern "C" ')
+ eventenabled.append("BOOL EventPipeEventEnabled")
+ eventenabled.append(eventName)
+ eventenabled.append("();\n")
+
+ if extern: writeevent.append('extern "C" ')
+ writeevent.append("ULONG EventPipeWriteEvent")
+ writeevent.append(eventName)
+ writeevent.append("(\n")
+
+ if templateName:
+ template = allTemplates[templateName]
+ fnSig = template.signature
+
+ for params in fnSig.paramlist:
+ fnparam = fnSig.getParam(params)
+ wintypeName = fnparam.winType
+ typewName = palDataTypeMapping[wintypeName]
+ winCount = fnparam.count
+ countw = palDataTypeMapping[winCount]
+
+ if params in template.structs:
+ fnptypeline.append("%sint %s_ElementSize,\n" % (lindent, params))
+
+ fnptypeline.append(lindent)
+ fnptypeline.append(typewName)
+ fnptypeline.append(countw)
+ fnptypeline.append(" ")
+ fnptypeline.append(fnparam.name)
+ fnptypeline.append(",\n")
+
+ #remove trailing commas
+ if len(fnptypeline) > 0:
+ del fnptypeline[-1]
+
+ writeevent.extend(fnptypeline)
+ writeevent.append("\n);\n")
+ clrallEvents.extend(eventenabled)
+ clrallEvents.extend(writeevent)
+
+ return ''.join(clrallEvents)
+
+#generates the dummy header file which is used by the VM as entry point to the logging Functions
+def generateclrEtwDummy(eventNodes,allTemplates):
+ clretmEvents = []
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+
+ fnptype = []
+ #generate FireEtw functions
+ fnptype.append("#define FireEtw")
+ fnptype.append(eventName)
+ fnptype.append("(");
+ line = []
+ if templateName:
+ template = allTemplates[templateName]
+ fnSig = template.signature
+
+ for params in fnSig.paramlist:
+ fnparam = fnSig.getParam(params)
+
+ if params in template.structs:
+ line.append(fnparam.name + "_ElementSize")
+ line.append(", ")
+
+ 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)
+
+ return ''.join(clretmEvents)
+
+def generateClralltestEvents(sClrEtwAllMan):
+ tree = DOM.parse(sClrEtwAllMan)
+
+ clrtestEvents = []
+ for providerNode in tree.getElementsByTagName('provider'):
+ templateNodes = providerNode.getElementsByTagName('template')
+ allTemplates = parseTemplateNodes(templateNodes)
+ eventNodes = providerNode.getElementsByTagName('event')
+ for eventNode in eventNodes:
+ eventName = eventNode.getAttribute('symbol')
+ templateName = eventNode.getAttribute('template')
+ clrtestEvents.append(" EventXplatEnabled" + eventName + "();\n")
+ clrtestEvents.append("Error |= FireEtXplat" + eventName + "(\n")
+
+ line =[]
+ if templateName:
+ template = allTemplates[templateName]
+ fnSig = template.signature
+
+ for params in fnSig.paramlist:
+ if params in template.structs:
+ line.append("sizeof(Struct1),\n")
+
+ argline =''
+ fnparam = fnSig.getParam(params)
+ if fnparam.name.lower() == 'count':
+ argline = '2'
+ else:
+ if fnparam.winType == "win:Binary":
+ argline = 'win_Binary'
+ elif fnparam.winType == "win:Pointer" and fnparam.count == "win:count":
+ argline = "(const void**)&var11"
+ elif fnparam.winType == "win:Pointer" :
+ argline = "(const void*)var11"
+ elif fnparam.winType =="win:AnsiString":
+ argline = '" Testing AniString "'
+ elif fnparam.winType =="win:UnicodeString":
+ argline = 'W(" Testing UnicodeString ")'
+ else:
+ if fnparam.count == "win:count":
+ line.append("&")
+
+ argline = fnparam.winType.replace(":","_")
+
+ line.append(argline)
+ line.append(",\n")
+
+ #remove trailing commas
+ if len(line) > 0:
+ del line[-1]
+ line.append("\n")
+ line.append(");\n")
+ clrtestEvents.extend(line)
+
+ return ''.join(clrtestEvents)
+
+def generateSanityTest(sClrEtwAllMan,testDir):
+
+ if not testDir:
+ return
+ print('Generating Event Logging Tests')
+
+ if not os.path.exists(testDir):
+ os.makedirs(testDir)
+
+ cmake_file = testDir + "/CMakeLists.txt"
+ test_cpp = "clralltestevents.cpp"
+ testinfo = testDir + "/testinfo.dat"
+
+ #CMake File:
+ with open_for_update(cmake_file) as Cmake_file:
+ Cmake_file.write(stdprolog_cmake)
+ Cmake_file.write("""
+cmake_minimum_required(VERSION 2.8.12.2)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(SOURCES
+""")
+ Cmake_file.write(test_cpp)
+ Cmake_file.write("""
+ )
+include_directories(${GENERATED_INCLUDE_DIR})
+
+if(FEATURE_PAL)
+ include_directories(${COREPAL_SOURCE_DIR}/inc/rt)
+endif(FEATURE_PAL)
+
+add_executable(eventprovidertest
+ ${SOURCES}
+ )
+set(EVENT_PROVIDER_DEPENDENCIES "")
+set(EVENT_PROVIDER_LINKER_OTPTIONS "")
+if(FEATURE_EVENT_TRACE)
+ add_definitions(-DFEATURE_EVENT_TRACE=1)
+ list(APPEND EVENT_PROVIDER_DEPENDENCIES
+ eventprovider
+ )
+ if(CLR_CMAKE_PLATFORM_LINUX)
+ list(APPEND EVENT_PROVIDER_DEPENDENCIES
+ coreclrtraceptprovider
+ )
+ endif(CLR_CMAKE_PLATFORM_LINUX)
+ list(APPEND EVENT_PROVIDER_LINKER_OTPTIONS
+ ${EVENT_PROVIDER_DEPENDENCIES}
+ )
+endif(FEATURE_EVENT_TRACE)
+
+add_dependencies(eventprovidertest ${EVENT_PROVIDER_DEPENDENCIES} coreclrpal)
+target_link_libraries(eventprovidertest
+ coreclrpal
+ ${EVENT_PROVIDER_LINKER_OTPTIONS}
+ )
+""")
+
+
+ with open_for_update(testinfo) as Testinfo:
+ Testinfo.write("""
+Copyright (c) Microsoft Corporation. All rights reserved.
+#
+
+Version = 1.0
+Section = EventProvider
+Function = EventProvider
+Name = PAL test for FireEtW* and EventEnabled* functions
+TYPE = DEFAULT
+EXE1 = eventprovidertest
+Description = This is a sanity test to check that there are no crashes in Xplat eventing
+""")
+
+ #Test.cpp
+ with open_for_update(testDir + "/" + test_cpp) as Test_cpp:
+ Test_cpp.write(stdprolog)
+ Test_cpp.write("""
+/*=====================================================================
+**
+** Source: clralltestevents.cpp
+**
+** Purpose: Ensure Correctness of Eventing code
+**
+**
+**===================================================================*/
+#if FEATURE_PAL
+#include <palsuite.h>
+#endif //FEATURE_PAL
+#include <clrxplatevents.h>
+
+typedef struct _Struct1 {
+ ULONG Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} Struct1;
+
+Struct1 var21[2] = { { 245, 13, 14, "deadbea" }, { 542, 0, 14, "deadflu" } };
+
+Struct1* var11 = var21;
+Struct1* win_Struct = var21;
+
+GUID win_GUID ={ 245, 13, 14, "deadbea" };
+double win_Double =34.04;
+ULONG win_ULong = 34;
+BOOL win_Boolean = FALSE;
+unsigned __int64 win_UInt64 = 114;
+unsigned int win_UInt32 = 4;
+unsigned short win_UInt16 = 12;
+unsigned char win_UInt8 = 9;
+int win_Int32 = 12;
+BYTE* win_Binary =(BYTE*)var21 ;
+int __cdecl main(int argc, char **argv)
+{
+#if defined(FEATURE_PAL)
+ /* Initialize the PAL.
+ */
+
+ if(0 != PAL_Initialize(argc, argv))
+ {
+ return FAIL;
+ }
+#endif
+
+ ULONG Error = ERROR_SUCCESS;
+#if defined(FEATURE_EVENT_TRACE)
+ Trace("\\n Starting functional eventing APIs tests \\n");
+""")
+
+ Test_cpp.write(generateClralltestEvents(sClrEtwAllMan))
+ Test_cpp.write("""
+
+ if (Error != ERROR_SUCCESS)
+ {
+ Fail("One or more eventing Apis failed\\n ");
+ return FAIL;
+ }
+ Trace("\\n All eventing APIs were fired succesfully \\n");
+#endif //defined(FEATURE_EVENT_TRACE)
+#if defined(FEATURE_PAL)
+
+/* Shutdown the PAL.
+*/
+
+ PAL_Terminate();
+#endif
+ return PASS;
+ }
+
+""")
+ Testinfo.close()
+
+def generateEtmDummyHeader(sClrEtwAllMan,clretwdummy):
+
+ if not clretwdummy:
+ return
+
+ print(' Generating Dummy Event Headers')
+ tree = DOM.parse(sClrEtwAllMan)
+
+ incDir = os.path.dirname(os.path.realpath(clretwdummy))
+ if not os.path.exists(incDir):
+ os.makedirs(incDir)
+
+ with open_for_update(clretwdummy) as Clretwdummy:
+ Clretwdummy.write(stdprolog + "\n")
+
+ for providerNode in tree.getElementsByTagName('provider'):
+ templateNodes = providerNode.getElementsByTagName('template')
+ allTemplates = parseTemplateNodes(templateNodes)
+ eventNodes = providerNode.getElementsByTagName('event')
+ #pal: create etmdummy.h
+ Clretwdummy.write(generateclrEtwDummy(eventNodes, allTemplates) + "\n")
+
+def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern):
+
+ generateEtmDummyHeader(sClrEtwAllMan,etmDummyFile)
+ tree = DOM.parse(sClrEtwAllMan)
+
+ if not incDir:
+ return
+
+ print(' Generating Event Headers')
+ if not os.path.exists(incDir):
+ os.makedirs(incDir)
+
+ # Write the main header for FireETW* functions
+ clrallevents = os.path.join(incDir, "clretwallmain.h")
+ with open_for_update(clrallevents) as Clrallevents:
+ Clrallevents.write(stdprolog)
+ Clrallevents.write("""
+#include "clrxplatevents.h"
+#include "clreventpipewriteevents.h"
+
+""")
+ for providerNode in tree.getElementsByTagName('provider'):
+ templateNodes = providerNode.getElementsByTagName('template')
+ allTemplates = parseTemplateNodes(templateNodes)
+ eventNodes = providerNode.getElementsByTagName('event')
+
+ #vm header:
+ Clrallevents.write(generateClrallEvents(eventNodes, allTemplates) + "\n")
+
+
+ # Write secondary headers for FireEtXplat* and EventPipe* functions
+ clrxplatevents = os.path.join(incDir, "clrxplatevents.h")
+ clreventpipewriteevents = os.path.join(incDir, "clreventpipewriteevents.h")
+ with open_for_update(clrxplatevents) as Clrxplatevents:
+ with open_for_update(clreventpipewriteevents) as Clreventpipewriteevents:
+ Clrxplatevents.write(stdprolog + "\n")
+ Clreventpipewriteevents.write(stdprolog + "\n")
+
+ for providerNode in tree.getElementsByTagName('provider'):
+ templateNodes = providerNode.getElementsByTagName('template')
+ allTemplates = parseTemplateNodes(templateNodes)
+ eventNodes = providerNode.getElementsByTagName('event')
+
+ #pal: create clrallevents.h
+ Clrxplatevents.write(generateClrXplatEvents(eventNodes, allTemplates, extern) + "\n")
+
+ #eventpipe: create clreventpipewriteevents.h
+ Clreventpipewriteevents.write(generateClrEventPipeWriteEvents(eventNodes, allTemplates, extern) + "\n")
+
+import argparse
+import sys
+
+def main(argv):
+
+ #parse the command line
+ parser = argparse.ArgumentParser(description="Generates the Code required to instrument LTTtng logging mechanism")
+
+ required = parser.add_argument_group('required arguments')
+ required.add_argument('--man', type=str, required=True,
+ help='full path to manifest containig the description of events')
+ 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,default=None,
+ help='full path to file that will have dummy definitions of FireEtw functions')
+ required.add_argument('--testdir', type=str, default=None,
+ help='full path to directory where the test assets will be deployed' )
+ required.add_argument('--nonextern', action='store_true',
+ help='if specified, will not generated extern function stub headers' )
+ args, unknown = parser.parse_known_args(argv)
+ if unknown:
+ print('Unknown argument(s): ', ', '.join(unknown))
+ return 1
+
+ sClrEtwAllMan = args.man
+ incdir = args.inc
+ etmDummyFile = args.dummy
+ testDir = args.testdir
+ extern = not args.nonextern
+
+ generatePlatformIndependentFiles(sClrEtwAllMan, incdir, etmDummyFile, extern)
+ generateSanityTest(sClrEtwAllMan, testDir)
+
+if __name__ == '__main__':
+ return_code = main(sys.argv[1:])
+ sys.exit(return_code) \ No newline at end of file