| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755 |
- #-------------------------------------------------------------------------------------------------------
- # Copyright (C) Microsoft. All rights reserved.
- # Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- #-------------------------------------------------------------------------------------------------------
- import xml.dom.minidom as DOM
- lttngDataTypeMapping = {
- "win:null" :" ",
- "win:Int64" :"const __int64",
- "win:ULong" :"const unsigned long",
- "win:count" :"*",
- "win:Struct" :"const char *",
- "win:GUID" :"const int",
- "win:AnsiString" :"const char*",
- "win:UnicodeString" :"const char*",
- "win:Double" :"const double",
- "win:Int32" :"const signed int",
- "win:HexInt32" :"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:Int8" :"const char",
- "win:Pointer" :"const uintptr_t",
- "win:Binary" :"const char"
- }
- ctfDataTypeMapping = {
- "win:Int64" :"ctf_integer",
- "win:HexInt64" :"ctf_integer_hex",
- "win:ULong" :"ctf_integer",
- "win:count" :"ctf_sequence",
- "win:Struct" :"ctf_sequence",
- "win:GUID" :"ctf_sequence",
- "win:AnsiString" :"ctf_string",
- "win:UnicodeString" :"ctf_string",
- "win:Double" :"ctf_float",
- "win:Int32" :"ctf_integer",
- "win:HexInt32" :"ctf_integer_hex",
- "win:Boolean" :"ctf_integer",
- "win:UInt64" :"ctf_integer",
- "win:UInt32" :"ctf_integer",
- "win:UInt16" :"ctf_integer",
- "win:HexInt16" :"ctf_integer_hex",
- "win:UInt8" :"ctf_integer", #actually a character
- "win:Int8" :"ctf_integer", #actually a character
- "win:Pointer" :"ctf_integer",
- "win:Binary" :"ctf_sequence",
- "xs:string" :"ctf_string",
- "xs:unsignedLong" :"ctf_integer",
- "xs:unsignedInt" :"ctf_integer"
- }
- palDataTypeMapping ={
- "win:null" :" ",
- "win:Int64" :"const __int64",
- "win:ULong" :"const unsigned long",
- "win:count" :"*",
- "win:Struct" :"const void",
- "win:GUID" :"const GUID",
- "win:AnsiString" :"LPCSTR",
- "win:UnicodeString" :"PCWSTR",
- "win:Double" :"const double",
- "win:Int32" :"const signed int",
- "win:HexInt32" :"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:Int8" :"const char",
- "win:Pointer" :"const void*",
- "win:Binary" :"const char"
- }
- MAX_LTTNG_ARGS = 10
- def getParamSequenceSize(paramSequence, estimate):
- total = 0
- pointers =0
- for param in paramSequence:
- if param in ["win:Int64", "win:UInt64", "win:Double"]:
- total += 8
- elif param in ["win:ULong", "win:Int32", "win:Boolean",]:
- total += 4
- elif param == "GUID":
- total += 16
- elif param in ["win:UInt16"]:
- total += 2
- elif param in ["win:Uint8", "win:Binary"]:
- total += 1
- elif param == "win:Pointer":
- if estimate:
- total += 8
- else:
- pointers += 1
- elif estimate:
- if param in ["win:AnsiString", "win:Struct"]:
- total += 32
- elif param in ["win:UnicodeString"]:
- total += 64
- else:
- raise Exception ("Don't know size of " + param)
- if estimate:
- return total
- return total, pointers
- class Template:
- def __repr__(self):
- return "<Template " + self.name + " />"
-
- def __init__(self, name, prototypes, dependencies, structCounts, arrayCounts):
- self.name = name
- self.signature = FunctionSignature()
- self.structCounts = structCounts
- self.arrayCounts = arrayCounts
- for variable in prototypes.paramList:
- for dependency in dependencies[variable]:
- if not self.signature.getParam(dependency):
- self.signature.append(dependency, prototypes.getParam(dependency))
- @property
- def num_params(self):
- return len(self.signature.paramList)
- def getParam(self, name):
- return self.signature.getParam(name)
- @property
- def estimatedSize(self):
- total = getParamSequenceSize((self.getParam(paramName).winType for paramName in self.signature.paramList), True)
- if total < 32:
- return 32
- elif total > 1024:
- return 1024
- return total
- class FunctionSignature:
- def __repr__(self):
- return ', '.join(self.paramList)
-
- def __init__(self):
- self.LUT = {}
- self.paramList = []
- def append(self, variable, param):
- self.LUT[variable] = param
- 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, outType, length):
- self.winType = winType
- self.outType = outType
- self.name = name
- self.length = length
- self.count = "win:null"
- if winType == "win:GUID" or count == "win:count":
- self.count = "win:count"
- ignoredXmlAttributes = frozenset(["map"])
- usedXmlAttributes = frozenset(["name", "inType", "count", "length", "outType"])
- knownXmlAttributes = ignoredXmlAttributes | usedXmlAttributes
-
- def checkKnownAttributes(nodes, templateName):
- for node in nodes:
- nodeMap = node.attributes
- for attribute in nodeMap.values():
- if attribute.name not in knownXmlAttributes:
- raise ValueError('Unknown attribute: ' + attribute.name + ' in template ' + templateName)
- def getTopLevelElementsByTagName(node, tag):
- return [e for e in node.getElementsByTagName(tag) if e.parentNode == node]
-
- def parseTemplateNodes(templateNodes):
- templates = {}
- for templateNode in templateNodes:
- templateName = templateNode.getAttribute('tid')
- dataNodes = getTopLevelElementsByTagName(templateNode, 'data')
- checkKnownAttributes(dataNodes, templateName)
- functionPrototypes = FunctionSignature()
-
- arrayCounts = {}
- structCounts = {}
- var_Dependencies = {}
- for dataNode in dataNodes:
- variable = dataNode.getAttribute('name')
- wintype = dataNode.getAttribute('inType')
- outType = dataNode.getAttribute('outType')
- wincount = dataNode.getAttribute('count')
- winLength = dataNode.getAttribute('length')
- var_dependency = [variable]
- if winLength:
- if wincount:
- raise Exception("Both count and length properties found on " + variable + " in template " + templateName)
- if wincount.isdigit() and int(wincount) == 1:
- wincount = ''
- if wincount:
- if wincount.isdigit():
- raise Exception("Expect constant count to be length")
- elif functionPrototypes.getParam(wincount):
- var_dependency.insert(0, wincount)
- arrayCounts[variable] = wincount
- var_Dependencies[variable] = var_dependency
- functionParameter = FunctionParameter(wintype, variable, wincount, outType, winLength)
- functionPrototypes.append(variable, functionParameter)
- structNodes = getTopLevelElementsByTagName(templateNode, 'struct')
- for structNode in structNodes:
- structName = structNode.getAttribute('name')
- countName = structNode.getAttribute('count')
- assert(countName in functionPrototypes.paramList)
- #childData = structNode.getElementsByTagName("data")
- #names = [x.attributes['name'].value for x in childData]
- #types = [x.attributes['inType'].value for x in childData]
- structCounts[structName] = countName
- var_Dependencies[structName] = [countName, structName]
- functionParameterPointer = FunctionParameter("win:Struct", structName, "win:count", None, None)
- functionPrototypes.append(structName, functionParameterPointer)
- templates[templateName] = Template(templateName, functionPrototypes, var_Dependencies, structCounts, arrayCounts)
- return templates
-
- def shouldPackTemplate(template):
- return template.num_params > MAX_LTTNG_ARGS or len(template.structCounts) > 0 or len(template.arrayCounts) > 0
- def generateArgList(template):
- # Construct a TP_ARGS macro call, as defined in another macro, e.g.
- #
- # TP_ARGS( \
- # int, my_integer_arg, \
- # char*, my_string_arg \
- # )
- header = "TP_ARGS( \\\n"
- footer = "\\\n)"
- args = []
- if shouldPackTemplate(template):
- args.append(" const unsigned int, length")
- args.append(" const char *, __data__")
- else:
- signature = template.signature
- for param in signature.paramList:
- functionParam = signature.getParam(param)
- wintypeName = functionParam.winType
- mappedType = lttngDataTypeMapping[wintypeName]
- winCount = functionParam.count
- mappedCount = lttngDataTypeMapping[winCount]
- arg = " " + mappedType
- if mappedCount != " ":
- arg += mappedCount
- elif functionParam.length:
- arg += "*"
- arg += ", " + functionParam.name
-
- args.append(arg)
-
- return header + ", \\\n".join(args) + footer
- def generateFieldList(template):
- # Construct a TP_FIELDS macro call, e.g.
- # TP_FIELDS(
- # ctf_string(my_string_field, my_string_arg)
- # ctf_integer(int, my_integer_field, my_integer_arg)
- # )
- header = " " + " TP_FIELDS(\n"
- footer = "\n )"
- fieldList = []
-
- if shouldPackTemplate(template):
- fieldList.append(" ctf_integer(unsigned long, length, length)")
- fieldList.append(" ctf_sequence(char, __data__, __data__, unsigned long, length)")
- else:
- signature = template.signature
- for param in signature.paramList:
- functionParam = signature.getParam(param)
- wintypeName = functionParam.winType
- winCount = functionParam.count
- mappedCount = lttngDataTypeMapping[winCount]
- mappedType = lttngDataTypeMapping[wintypeName].replace("const ", "")
- if functionParam.outType:
- wintypeName = functionParam.outType
- ctf_type = None
- field_body = None
- varname = functionParam.name
- if param in template.structCounts or param in template.arrayCounts:
- # This is a struct, treat as a sequence
- countVar = template.structCounts.get(param, template.arrayCounts.get(param))
- ctf_type = "ctf_sequence"
- field_body = ", ".join((mappedType, varname, varname, "size_t", functionParam.prop))
- elif functionParam.length:
- ctf_type = "ctf_sequence"
- field_body = ", ".join((mappedType, varname, varname, "size_t", functionParam.length))
- else:
- ctf_type = ctfDataTypeMapping[wintypeName]
- if ctf_type == "ctf_string":
- field_body = ", ".join((varname, varname))
- elif ctf_type == "ctf_integer" or ctf_type == "ctf_integer_hex" or ctf_type == "ctf_float":
- field_body = ", ".join((mappedType, varname, varname))
- elif ctf_type == "ctf_sequence":
- raise Exception("ctf_sequence needs special handling: " + template.name + " " + param)
- else:
- raise Exception("Unhandled ctf intrinsic: " + ctf_type)
- # fieldList.append("// " + wintypeName)
- fieldList.append(" %s(%s)" % (ctf_type, field_body))
-
- return header + "\n".join(fieldList) + footer
- def generateLttngHeader(providerName, lttngEventHeaderShortName, templates, events):
- headerLines = []
- headerLines.append("")
- headerLines.append("#ifdef __int64")
- headerLines.append("#if TARGET_64")
- headerLines.append("#undef __int64")
- headerLines.append("#else")
- headerLines.append("#error \"Linux and OSX builds only support 64bit platforms\"")
- headerLines.append("#endif // TARGET_64")
- headerLines.append("#endif // __int64")
- headerLines.append("#undef TRACEPOINT_PROVIDER")
- headerLines.append("#undef TRACEPOINT_INCLUDE")
- headerLines.append("")
- headerLines.append("#define TRACEPOINT_PROVIDER " + providerName + "\n")
- headerLines.append("#define TRACEPOINT_INCLUDE \"./" + lttngEventHeaderShortName + "\"\n\n")
- headerLines.append("#if !defined(LTTNG_CHAKRA_H" + providerName + ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n\n")
- headerLines.append("#define LTTNG_CHAKRA_H" + providerName +"\n")
- headerLines.append("\n#include <lttng/tracepoint.h>\n\n")
-
- for templateName in templates:
- template = templates[templateName]
- functionSignature = template.signature
- headerLines.append("")
- headerLines.append("#define " + templateName + "_TRACEPOINT_ARGS \\")
- tracepointArgs = generateArgList(template)
- headerLines.append(tracepointArgs)
- headerLines.append("TRACEPOINT_EVENT_CLASS(")
- headerLines.append(" " + providerName + ",")
- headerLines.append(" " + templateName + ",")
- headerLines.append(" " + templateName + "_TRACEPOINT_ARGS,")
- tracepointFields = generateFieldList(template)
- headerLines.append(tracepointFields)
- headerLines.append(")")
-
- headerLines.append("#define " + templateName + "T_TRACEPOINT_INSTANCE(name) \\")
- headerLines.append("TRACEPOINT_EVENT_INSTANCE(\\")
- headerLines.append(" " + providerName + ",\\")
- headerLines.append(" " + templateName + ",\\")
- headerLines.append(" name,\\")
- headerLines.append(" " + templateName + "_TRACEPOINT_ARGS \\")
- headerLines.append(")")
- headerLines.append("")
- headerLines.append("")
- headerLines.append("TRACEPOINT_EVENT_CLASS(")
- headerLines.append(" " + providerName + ",")
- headerLines.append(" emptyTemplate,")
- headerLines.append(" TP_ARGS(),")
- headerLines.append(" TP_FIELDS()")
- headerLines.append(")")
- headerLines.append("#define T_TRACEPOINT_INSTANCE(name) \\")
- headerLines.append("TRACEPOINT_EVENT_INSTANCE(\\")
- headerLines.append(" " + providerName + ",\\")
- headerLines.append(" emptyTemplate,\\")
- headerLines.append(" name,\\")
- headerLines.append(" TP_ARGS()\\")
- headerLines.append(")")
- headerLines.append("")
- for eventNode in events:
- eventName = eventNode.getAttribute('symbol')
- templateName = eventNode.getAttribute('template')
- if not eventName:
- raise Exception(eventNode + " event does not have a symbol")
- if not templateName:
- headerLines.append("T_TRACEPOINT_INSTANCE(" + eventName + ")")
- continue
- headerLines.append(templateName + "T_TRACEPOINT_INSTANCE(" + eventName + ")")
- headerLines.append("#endif /* LTTNG_CHAKRA_H" + providerName + " */")
- headerLines.append("#include <lttng/tracepoint-event.h>")
- return "\n".join(headerLines)
- def generateMethodBody(template, providerName, eventName):
- # Convert from ETW's windows types to LTTng compatiable types
- methodBody = [""]
-
- functionSignature = template.signature
- if not shouldPackTemplate(template):
- invocation = ["do_tracepoint(" + providerName, eventName]
- for paramName in functionSignature.paramList:
- functionParam = functionSignature.getParam(paramName)
- wintypeName = functionParam.winType
- winCount = functionParam.count
-
- ctf_type = None
- if functionParam.outType:
- ctf_type = ctfDataTypeMapping.get(functionParam.outType)
- else:
- ctf_Type = ctfDataTypeMapping.get(winCount)
- if not ctf_type:
- ctf_type = ctfDataTypeMapping[wintypeName]
- if ctf_type == "ctf_string" and wintypeName == "win:UnicodeString":
- # Convert wchar unicode string to utf8
- if functionParam.length:
- methodBody.append("utf8::WideToNarrow " + paramName + "_converter(" + paramName + ", " + functionParam.length + ");")
- else:
- methodBody.append("utf8::WideToNarrow " + paramName + "_converter(" + paramName + ");")
- invocation.append(paramName + "_converter")
- # elif ctf_type == "ctf_sequence" or wintypeName == "win:Pointer":
- elif wintypeName == "win:Pointer":
- invocation.append("(" + lttngDataTypeMapping[wintypeName] + lttngDataTypeMapping[winCount] + ")" + paramName)
- else:
- invocation.append(paramName)
- methodBody.append(",\n ".join(invocation) + ");")
- else:
- # Packing results into buffer
- methodBody.append("char stackBuffer[" + str(template.estimatedSize) + "];")
- methodBody.append("char *buffer = stackBuffer;")
- methodBody.append("int offset = 0;")
- methodBody.append("int size = " + str(template.estimatedSize) + ";")
- methodBody.append("bool fixedBuffer = true;")
- methodBody.append("bool success = true;")
- for paramName in functionSignature.paramList:
- functionParameter = functionSignature.getParam(paramName)
- if paramName in template.structCounts:
- size = "(unsigned int)" + paramName + "_ElementSize * (unsigned int)" + template.structCounts[paramName]
- methodBody.append("success &= WriteToBuffer((const char *)" + paramName + ", " + size + ", buffer, offset, size, fixedBuffer);")
- elif paramName in template.arrayCounts:
- size = "sizeof(" + lttngDataTypeMapping[functionParameter.winType] + ") * (unsigned int)" + template.arrayCounts[paramName]
- methodBody.append("success &= WriteToBuffer((const char *)" + paramName + ", " + size + ", buffer, offset, size, fixedBuffer);")
- elif functionParameter.winType == "win:GUID":
- methodBody.append("success &= WriteToBuffer(*" + paramName + ", buffer, offset, size, fixedBuffer);")
- else:
- methodBody.append("success &= WriteToBuffer(" + paramName + ", buffer, offset, size, fixedBuffer);")
- methodBody.append("if (!success)")
- methodBody.append("{")
- methodBody.append(" if (!fixedBuffer) delete[] buffer;")
- methodBody.append(" return ERROR_WRITE_FAULT;")
- methodBody.append("}")
- methodBody.append("do_tracepoint(" + providerName + ", " + eventName + ", offset, buffer);")
- methodBody.append("if (!fixedBuffer) delete[] buffer;")
- return "\n ".join(methodBody) + "\n"
- def generateMethodSignature(template):
- if not template:
- return ""
-
- functionSignature = template.signature
- lineFunctionPrototype = []
- for paramName in functionSignature.paramList:
- functionParameter = functionSignature.getParam(paramName)
- wintypeName = functionParameter.winType
- mappedType = palDataTypeMapping[wintypeName]
- winCount = functionParameter.count
- mappedCount = palDataTypeMapping[winCount]
- if paramName in template.structCounts:
- lineFunctionPrototype.append(" int " + paramName + "_ElementSize")
- # lineFunctionPrototype.append("// " + wintypeName + " " + str(functionParameter.length))
- lineFunctionPrototype.append(
- " " + mappedType
- + (mappedCount if mappedCount != " " else "*" if functionParameter.length and not wintypeName in ["win:UnicodeString", "win:AnsiString"] else "")
- + " "
- + functionParameter.name)
- return ",\n".join(lineFunctionPrototype)
- def generateLttngTracepointProvider(providerName, lttngHeader, templates, events):
- providerLines = [];
- providerLines.append("#define TRACEPOINT_DEFINE")
- providerLines.append("#ifndef CHAKRA_STATIC_LIBRARY")
- providerLines.append("#define TRACEPOINT_PROBE_DYNAMIC_LINKAGE")
- providerLines.append("#endif")
- providerLines.append("#include \"stdlib.h\"")
- providerLines.append("#include \"Common.h\"")
- providerLines.append("#include \"Codex/Utf8Helper.h\"")
-
- providerLines.append("#include \"" + lttngHeader + "\"\n\n")
- providerLines.append("#ifndef tracepoint_enabled")
- providerLines.append("#define tracepoint_enabled(provider, name) 1")
- providerLines.append("#define do_tracepoint tracepoint")
- providerLines.append("#endif")
- providerLines.append("""
- bool ResizeBuffer(char *&buffer, int&size, int currentLength, int newSize, bool &fixedBuffer)
- {
- newSize *= 1.5;
- _ASSERTE(newSize > size); // Check for overflow
- if (newSize < 32)
- {
- newSize = 32;
- }
- char *newBuffer = new char[newSize];
- memcpy(newBuffer, buffer, currentLength);
- if (!fixedBuffer)
- {
- delete[] buffer;
- }
- buffer = newBuffer;
- size = newSize;
- fixedBuffer = false;
- return true;
- }
- bool WriteToBuffer(const char * src, int len, char *&buffer, int &offset, int &size, bool &fixedBuffer)
- {
- if (!src)
- {
- return true;
- }
- if (offset + len > size)
- {
- if (!ResizeBuffer(buffer, size, offset, size+len, fixedBuffer))
- {
- return false;
- }
- }
- memcpy(buffer + offset, src, len);
- offset += len;
- return true;
- }
- template <typename T>
- bool WriteToBuffer(const T &value, char *&buffer, int&offset, int&size, bool &fixedBuffer)
- {
- if (sizeof(T) + offset > size)
- {
- if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer))
- {
- return false;
- }
- }
- *(T *)(buffer + offset) = value;
- offset += sizeof(T);
- return true;
- }
- """)
- for eventNode in events:
- eventName = eventNode.getAttribute('symbol')
- templateName = eventNode.getAttribute('template')
- providerLines.append("extern \"C\" bool EventXplatEnabled%s(){ return tracepoint_enabled(%s, %s);}"
- % (eventName, providerName, eventName))
- providerLines.append("")
- template = None
- if templateName:
- template = templates[templateName]
- providerLines.append("extern \"C\" unsigned long FireEtXplat" + eventName + "(")
- providerLines.append(generateMethodSignature(template))
- providerLines.append(")")
- providerLines.append("{")
- providerLines.append(" if (!EventXplatEnabled" + eventName + "())")
- providerLines.append(" return ERROR_SUCCESS;")
- if template:
- providerLines.append(generateMethodBody(template, providerName, eventName))
- else:
- providerLines.append(" do_tracepoint(" + providerName + ", " + eventName +");")
- providerLines.append("")
- providerLines.append(" return ERROR_SUCCESS;")
- providerLines.append("}")
- providerLines.append("")
- return "\n".join(providerLines)
- def generateEtwHeader(templates, events):
- headerLines = []
- headerLines.append("#include \"pal.h\"")
- headerLines.append("")
-
- for event in events:
- eventName = event.getAttribute('symbol')
- templateName = event.getAttribute('template')
- template = None
- if templateName:
- template = templates[templateName]
- callArgs = []
- if template:
- functionSignature = template.signature
- for param in functionSignature.paramList:
- if param in template.structCounts:
- callArgs.append(param + "_ElementSize")
- callArgs.append(param)
- headerLines.append("extern \"C\" bool EventXplatEnabled" + eventName +"();")
- headerLines.append("inline bool EventEnabled" + eventName +"() { return EventXplatEnabled" + eventName + "();}")
- headerLines.append("")
- headerLines.append("extern \"C\" unsigned long FireEtXplat" + eventName +" (")
- headerLines.append(generateMethodSignature(template))
- headerLines.append(");")
- headerLines.append("inline unsigned long EventWrite" + eventName + "(")
- headerLines.append(generateMethodSignature(template))
- headerLines.append(")")
- headerLines.append("{")
- headerLines.append(" return FireEtXplat" + eventName + "(" + ", ".join(callArgs) + ");")
- headerLines.append("}")
- headerLines.append("")
-
- return "\n".join(headerLines)
- def generateCmakeFile(providerName):
- cmakeLines = []
- cmakeLines.append("project(Chakra.LTTng)")
- cmakeLines.append("")
- cmakeLines.append("add_compile_options(-fPIC)")
- cmakeLines.append("")
- cmakeLines.append("add_library (Chakra.LTTng OBJECT")
- cmakeLines.append(" eventprovider" + providerName + ".cpp")
- cmakeLines.append(" tracepointprovider" + providerName + ".cpp")
- cmakeLines.append(")")
- return "\n".join(cmakeLines)
- def generateLttngFiles(manifest, providerDirectory):
- import os
- tree = DOM.parse(manifest)
- if not os.path.exists(providerDirectory):
- os.makedirs(providerDirectory)
- if not os.path.exists(providerDirectory + "/lttng"):
- os.makedirs(providerDirectory + "/lttng")
- for providerNode in tree.getElementsByTagName("provider"):
- providerName = providerNode.getAttribute("name")
- providerName = providerName.replace("Microsoft-", "")
- providerNameFile = providerName.lower()
- lttngEventHeaderShortName = "tp" + providerNameFile + ".h"
- lttngEventHeaderPath = providerDirectory + "/lttng/" + lttngEventHeaderShortName
- lttngEventProvider = providerDirectory + "/lttng/eventprovider" + providerNameFile + ".cpp"
- lttngEventProviderTrace = providerDirectory + "/lttng/tracepointprovider" + providerNameFile + ".cpp"
- lttngEtwHeaderFile = providerDirectory + "/lttng/" + providerNameFile + "Etw.h"
- lttngCmakeFile = providerDirectory + "/lttng/CMakeLists.txt"
- lttngHeader = open(lttngEventHeaderPath, "w")
- lttngImplementation = open(lttngEventProvider, "w")
- lttngTraceImplementation = open(lttngEventProviderTrace, "w")
- lttngEtwHeader = open(lttngEtwHeaderFile, "w")
- lttngCmake = open(lttngCmakeFile, "w")
- # Create the lttng implementation
- lttngTraceImplementation.write("#define TRACEPOINT_CREATE_PROBES\n")
- lttngTraceImplementation.write("#include \"./"+lttngEventHeaderShortName+"\"\n")
- lttngTraceImplementation.close()
- # Create the lttng header
- templateNodes = providerNode.getElementsByTagName('template')
- eventNodes = providerNode.getElementsByTagName('event')
- allTemplates = parseTemplateNodes(templateNodes)
- lttngHeader.write(generateLttngHeader(providerName, lttngEventHeaderShortName, allTemplates, eventNodes))
- lttngHeader.close();
- lttngImplementation.write(generateLttngTracepointProvider(providerName, lttngEventHeaderShortName, allTemplates, eventNodes))
- lttngImplementation.close();
- lttngEtwHeader.write(generateEtwHeader(allTemplates, eventNodes))
- lttngEtwHeader.close()
- # Note: This in particular assumes that there is only one ETW provider
- lttngCmake.write(generateCmakeFile(providerNameFile))
- lttngCmake.close()
- if __name__ == '__main__':
- import argparse
- import sys
- 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('--intermediate', type=str, required=True,
- help='full path to eventprovider intermediate directory')
- args, unknown = parser.parse_known_args(sys.argv[1:])
- if unknown:
- print('Unknown argument(s): ', ', '.join(unknown))
- sys.exit(1)
- generateLttngFiles(args.man, args.intermediate)
- sys.exit(0)
|