summaryrefslogtreecommitdiff
path: root/src/scripts/genEventPipe.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts/genEventPipe.py')
-rw-r--r--src/scripts/genEventPipe.py313
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