diff options
Diffstat (limited to 'src/scripts/genEventPipe.py')
-rw-r--r-- | src/scripts/genEventPipe.py | 313 |
1 files changed, 178 insertions, 135 deletions
diff --git a/src/scripts/genEventPipe.py b/src/scripts/genEventPipe.py index 8a970794c0..96755ea459 100644 --- a/src/scripts/genEventPipe.py +++ b/src/scripts/genEventPipe.py @@ -1,10 +1,11 @@ from __future__ import print_function -from genXplatEventing import * -from genXplatLttng import * +from genEventing import * +from genLttngProvider import * 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. +stdprolog_cpp = """// 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. @@ -14,6 +15,7 @@ DO NOT MODIFY. AUTOGENERATED FILE. This file is generated using the logic from <root>/src/scripts/genEventPipe.py ******************************************************************/ + """ stdprolog_cmake = """# @@ -24,11 +26,54 @@ stdprolog_cmake = """# #This file is generated using the logic from <root>/src/scripts/genEventPipe.py #****************************************************************** + """ +eventpipe_dirname = "eventpipe" + +def generateMethodSignatureEnabled(eventName): + return "BOOL EventPipeEventEnabled%s()" % (eventName,) + +def generateMethodSignatureWrite(eventName, template, extern): + sig_pieces = [] + + if extern: sig_pieces.append('extern "C" ') + sig_pieces.append("ULONG EventPipeWriteEvent") + sig_pieces.append(eventName) + sig_pieces.append("(") + + if template: + sig_pieces.append("\n") + fnSig = template.signature + for paramName in fnSig.paramlist: + fnparam = fnSig.getParam(paramName) + wintypeName = fnparam.winType + typewName = palDataTypeMapping[wintypeName] + winCount = fnparam.count + countw = palDataTypeMapping[winCount] + + if paramName in template.structs: + sig_pieces.append( + "%sint %s_ElementSize,\n" % + (lindent, paramName)) + + sig_pieces.append(lindent) + sig_pieces.append(typewName) + if countw != " ": + sig_pieces.append(countw) + + sig_pieces.append(" ") + sig_pieces.append(fnparam.name) + sig_pieces.append(",\n") + + if len(sig_pieces) > 0: + del sig_pieces[-1] + + sig_pieces.append(")") + return ''.join(sig_pieces) def generateClrEventPipeWriteEventsImpl( - providerName, eventNodes, allTemplates, exclusionListFile): + providerName, eventNodes, allTemplates, extern): providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') @@ -47,54 +92,24 @@ def generateClrEventPipeWriteEventsImpl( templateName = eventNode.getAttribute('template') # generate EventPipeEventEnabled function - eventEnabledImpl = """bool EventPipeEventEnabled%s() + eventEnabledImpl = generateMethodSignatureEnabled(eventName) + """ { return EventPipeEvent%s->IsEnabled(); } -""" % (eventName, eventName) +""" % eventName WriteEventImpl.append(eventEnabledImpl) # generate EventPipeWriteEvent function fnptype = [] - linefnptype = [] - fnptype.append("extern \"C\" ULONG EventPipeWriteEvent") - fnptype.append(eventName) - fnptype.append("(\n") if templateName: template = allTemplates[templateName] else: template = None - if template: - fnSig = template.signature - for paramName in fnSig.paramlist: - fnparam = fnSig.getParam(paramName) - wintypeName = fnparam.winType - typewName = palDataTypeMapping[wintypeName] - winCount = fnparam.count - countw = palDataTypeMapping[winCount] - - if paramName in template.structs: - linefnptype.append( - "%sint %s_ElementSize,\n" % - (lindent, paramName)) - - linefnptype.append(lindent) - linefnptype.append(typewName) - if countw != " ": - linefnptype.append(countw) - - linefnptype.append(" ") - linefnptype.append(fnparam.name) - linefnptype.append(",\n") - - if len(linefnptype) > 0: - del linefnptype[-1] - - fnptype.extend(linefnptype) - fnptype.append(")\n{\n") + fnptype.append(generateMethodSignatureWrite(eventName, template, extern)) + fnptype.append("\n{\n") checking = """ if (!EventPipeEventEnabled%s()) return ERROR_SUCCESS; """ % (eventName) @@ -115,8 +130,9 @@ def generateClrEventPipeWriteEventsImpl( WriteEventImpl.append("\n return ERROR_SUCCESS;\n}\n\n") # EventPipeProvider and EventPipeEvent initialization + if extern: WriteEventImpl.append('extern "C" ') WriteEventImpl.append( - "extern \"C\" void Init" + + "void Init" + providerPrettyName + "()\n{\n") WriteEventImpl.append( @@ -134,7 +150,6 @@ def generateClrEventPipeWriteEventsImpl( eventVersion = eventNode.getAttribute('version') eventLevel = eventNode.getAttribute('level') eventLevel = eventLevel.replace("win:", "EventPipeEventLevel::") - exclusionInfo = parseExclusionList(exclusionListFile) taskName = eventNode.getAttribute('task') initEvent = """ EventPipeEvent%s = EventPipeProvider%s->AddEvent(%s,%s,%s,%s); @@ -150,8 +165,8 @@ def generateWriteEventBody(template, providerName, eventName): header = """ char stackBuffer[%s]; char *buffer = stackBuffer; - unsigned int offset = 0; - unsigned int size = %s; + size_t offset = 0; + size_t size = %s; bool fixedBuffer = true; bool success = true; @@ -198,7 +213,7 @@ def generateWriteEventBody(template, providerName, eventName): }\n\n""" body = " EventPipe::WriteEvent(*EventPipeEvent" + \ - eventName + ", (BYTE *)buffer, offset);\n" + eventName + ", (BYTE *)buffer, (unsigned int)offset);\n" footer = """ if (!fixedBuffer) @@ -221,20 +236,23 @@ def generateEventKeywords(eventKeywords): return mask -def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory): +def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory, extern): tree = DOM.parse(etwmanifest) - with open(eventpipe_directory + "CMakeLists.txt", 'w') as topCmake: - topCmake.write(stdprolog_cmake + "\n") - topCmake.write("""cmake_minimum_required(VERSION 2.8.12.2) + with open_for_update(os.path.join(eventpipe_directory, "CMakeLists.txt")) as cmake_file: + cmake_file.write(stdprolog_cmake) + cmake_file.write("cmake_minimum_required(VERSION 2.8.12.2)\n") + if extern: cmake_file.write("\nproject(eventpipe)\n") + cmake_file.write(""" - project(eventpipe) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +include_directories(${CLR_DIR}/src/vm) - set(CMAKE_INCLUDE_CURRENT_DIR ON) - include_directories(${CLR_DIR}/src/vm) - - add_library(eventpipe - STATIC\n""") +""") + if extern: cmake_file.write("add_library") + else: cmake_file.write("add_library_clr") + cmake_file.write("""(eventpipe + STATIC\n""") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') @@ -244,34 +262,41 @@ def generateEventPipeCmakeFile(etwmanifest, eventpipe_directory): providerName_File = providerName.replace('-', '') providerName_File = providerName_File.lower() - topCmake.write(' "%s.cpp"\n' % (providerName_File)) - topCmake.write(' "eventpipehelpers.cpp"\n') - topCmake.write(""" ) - - add_dependencies(eventpipe GeneratedEventingFiles) - - # Install the static eventpipe library - install(TARGETS eventpipe DESTINATION lib) - """) - - topCmake.close() + cmake_file.write(' "%s/%s.cpp"\n' % (eventpipe_dirname, providerName_File)) + cmake_file.write(' "%s/eventpipehelpers.cpp"\n)' % (eventpipe_dirname,)) + if extern: cmake_file.write(""" +# Install the static eventpipe library +install(TARGETS eventpipe DESTINATION lib) +""") -def generateEventPipeHelperFile(etwmanifest, eventpipe_directory): - with open(eventpipe_directory + "eventpipehelpers.cpp", 'w') as helper: - helper.write(stdprolog) +def generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern): + with open_for_update(os.path.join(eventpipe_directory, "eventpipehelpers.cpp")) as helper: + helper.write(stdprolog_cpp) helper.write(""" -#include "stdlib.h" - -bool ResizeBuffer(char *&buffer, unsigned int& size, unsigned int currLen, unsigned int newSize, bool &fixedBuffer) +#include "common.h" +#include <stdlib.h> +#include <string.h> + +#ifndef FEATURE_PAL +#include <windef.h> +#include <crtdbg.h> +#else +#include "pal.h" +#endif //FEATURE_PAL + +bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer) { - newSize *= 1.5; + newSize = (size_t)(newSize * 1.5); _ASSERTE(newSize > size); // check for overflow if (newSize < 32) newSize = 32; - char *newBuffer = new char[newSize]; + char *newBuffer = new (nothrow) char[newSize]; + + if (newBuffer == NULL) + return false; memcpy(newBuffer, buffer, currLen); @@ -285,7 +310,7 @@ bool ResizeBuffer(char *&buffer, unsigned int& size, unsigned int currLen, unsig return true; } -bool WriteToBuffer(const BYTE *src, unsigned int len, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) +bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) { if(!src) return true; if (offset + len > size) @@ -299,10 +324,10 @@ bool WriteToBuffer(const BYTE *src, unsigned int len, char *&buffer, unsigned in return true; } -bool WriteToBuffer(PCWSTR str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) +bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) { if(!str) return true; - unsigned int byteCount = (PAL_wcslen(str) + 1) * sizeof(*str); + size_t byteCount = (wcslen(str) + 1) * sizeof(*str); if (offset + byteCount > size) { @@ -315,10 +340,10 @@ bool WriteToBuffer(PCWSTR str, char *&buffer, unsigned int& offset, unsigned int return true; } -bool WriteToBuffer(const char *str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) +bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) { if(!str) return true; - unsigned int len = strlen(str) + 1; + size_t len = strlen(str) + 1; if (offset + len > size) { if (!ResizeBuffer(buffer, size, offset, size + len, fixedBuffer)) @@ -339,12 +364,18 @@ bool WriteToBuffer(const char *str, char *&buffer, unsigned int& offset, unsigne providerPrettyName = providerName.replace("Windows-", '') providerPrettyName = providerPrettyName.replace("Microsoft-", '') providerPrettyName = providerPrettyName.replace('-', '_') + if extern: helper.write( + 'extern "C" ' + ) helper.write( - "extern \"C\" void Init" + + "void Init" + providerPrettyName + "();\n\n") - helper.write("extern \"C\" void InitProvidersAndEvents()\n{\n") + if extern: helper.write( + 'extern "C" ' + ) + helper.write("void InitProvidersAndEvents()\n{\n") for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') providerPrettyName = providerName.replace("Windows-", '') @@ -355,11 +386,20 @@ bool WriteToBuffer(const char *str, char *&buffer, unsigned int& offset, unsigne helper.close() - def generateEventPipeImplFiles( - etwmanifest, eventpipe_directory, exclusionListFile): + etwmanifest, eventpipe_directory, extern): tree = DOM.parse(etwmanifest) - coreclrRoot = os.getcwd() + + # Find the src directory starting with the assumption that + # A) It is named 'src' + # B) This script lives in it + src_dirname = os.path.dirname(__file__) + while os.path.basename(src_dirname) != "src": + src_dirname = os.path.dirname(src_dirname) + + if os.path.basename(src_dirname) == "": + raise IOError("Could not find the Core CLR 'src' directory") + for providerNode in tree.getElementsByTagName('provider'): providerName = providerNode.getAttribute('name') @@ -368,74 +408,77 @@ def generateEventPipeImplFiles( providerName_File = providerPrettyName.replace('-', '') providerName_File = providerName_File.lower() providerPrettyName = providerPrettyName.replace('-', '_') - eventpipefile = eventpipe_directory + providerName_File + ".cpp" - eventpipeImpl = open(eventpipefile, 'w') - eventpipeImpl.write(stdprolog) + eventpipefile = os.path.join(eventpipe_directory, providerName_File + ".cpp") + with open_for_update(eventpipefile) as eventpipeImpl: + eventpipeImpl.write(stdprolog_cpp) + + header = """ +#include "{root:s}/vm/common.h" +#include "{root:s}/vm/eventpipeprovider.h" +#include "{root:s}/vm/eventpipeevent.h" +#include "{root:s}/vm/eventpipe.h" - header = """ -#include \"%s/src/vm/common.h\" -#include \"%s/src/vm/eventpipeprovider.h\" -#include \"%s/src/vm/eventpipeevent.h\" -#include \"%s/src/vm/eventpipe.h\" +#if defined(FEATURE_PAL) +#define wcslen PAL_wcslen +#endif -bool ResizeBuffer(char *&buffer, unsigned int& size, unsigned int currLen, unsigned int newSize, bool &fixedBuffer); -bool WriteToBuffer(PCWSTR str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer); -bool WriteToBuffer(const char *str, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer); -bool WriteToBuffer(const BYTE *src, unsigned int len, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer); +bool ResizeBuffer(char *&buffer, size_t& size, size_t currLen, size_t newSize, bool &fixedBuffer); +bool WriteToBuffer(PCWSTR str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); +bool WriteToBuffer(const char *str, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); +bool WriteToBuffer(const BYTE *src, size_t len, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer); template <typename T> -bool WriteToBuffer(const T &value, char *&buffer, unsigned int& offset, unsigned int& size, bool &fixedBuffer) -{ +bool WriteToBuffer(const T &value, char *&buffer, size_t& offset, size_t& size, bool &fixedBuffer) +{{ if (sizeof(T) + offset > size) - { - if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) - return false; - } + {{ + if (!ResizeBuffer(buffer, size, offset, size + sizeof(T), fixedBuffer)) + return false; + }} *(T *)(buffer + offset) = value; offset += sizeof(T); return true; -} +}} -""" % (coreclrRoot, coreclrRoot, coreclrRoot, coreclrRoot) +""".format(root=src_dirname.replace('\\', '/')) - eventpipeImpl.write(header) - eventpipeImpl.write( - "const WCHAR* %sName = W(\"%s\");\n" % ( - providerPrettyName, - providerName + eventpipeImpl.write(header) + eventpipeImpl.write( + "const WCHAR* %sName = W(\"%s\");\n" % ( + providerPrettyName, + providerName + ) ) - ) - eventpipeImpl.write( - "EventPipeProvider *EventPipeProvider%s = nullptr;\n" % ( - providerPrettyName, + eventpipeImpl.write( + "EventPipeProvider *EventPipeProvider%s = nullptr;\n" % ( + providerPrettyName, + ) ) - ) - templateNodes = providerNode.getElementsByTagName('template') - allTemplates = parseTemplateNodes(templateNodes) - eventNodes = providerNode.getElementsByTagName('event') - eventpipeImpl.write( - generateClrEventPipeWriteEventsImpl( - providerName, - eventNodes, - allTemplates, - exclusionListFile) + "\n") - eventpipeImpl.close() + templateNodes = providerNode.getElementsByTagName('template') + allTemplates = parseTemplateNodes(templateNodes) + eventNodes = providerNode.getElementsByTagName('event') + eventpipeImpl.write( + generateClrEventPipeWriteEventsImpl( + providerName, + eventNodes, + allTemplates, + extern) + "\n") def generateEventPipeFiles( - etwmanifest, eventpipe_directory, exclusionListFile): - eventpipe_directory = eventpipe_directory + "/" + etwmanifest, intermediate, extern): + eventpipe_directory = os.path.join(intermediate, eventpipe_dirname) tree = DOM.parse(etwmanifest) if not os.path.exists(eventpipe_directory): os.makedirs(eventpipe_directory) - # generate Cmake file - generateEventPipeCmakeFile(etwmanifest, eventpipe_directory) + # generate CMake file + generateEventPipeCmakeFile(etwmanifest, intermediate, extern) # generate helper file - generateEventPipeHelperFile(etwmanifest, eventpipe_directory) + generateEventPipeHelperFile(etwmanifest, eventpipe_directory, extern) # generate all keywords for keywordNode in tree.getElementsByTagName('keyword'): @@ -447,12 +490,12 @@ def generateEventPipeFiles( generateEventPipeImplFiles( etwmanifest, eventpipe_directory, - exclusionListFile) + extern + ) import argparse import sys - def main(argv): # parse the command line @@ -464,19 +507,19 @@ def main(argv): 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') - required.add_argument('--exc', type=str, required=True, - help='full path to exclusion list') + required.add_argument('--nonextern', action='store_true', + help='if specified, will generate files to be compiled into the CLR rather than extern' ) args, unknown = parser.parse_known_args(argv) if unknown: print('Unknown argument(s): ', ', '.join(unknown)) - return const.UnknownArguments + return 1 sClrEtwAllMan = args.man intermediate = args.intermediate - exclusionListFile = args.exc + extern = not args.nonextern - generateEventPipeFiles(sClrEtwAllMan, intermediate, exclusionListFile) + generateEventPipeFiles(sClrEtwAllMan, intermediate, extern) if __name__ == '__main__': return_code = main(sys.argv[1:]) - sys.exit(return_code) + sys.exit(return_code)
\ No newline at end of file |