Skip to content

Commit

Permalink
[mono][eventpipe] Write primitive types and UTF-16 strings in little …
Browse files Browse the repository at this point in the history
…endian order (#68648)

* [mono][eventpipe] Add big-endian support.
  • Loading branch information
stefan-sf-ibm authored Jul 4, 2022
1 parent 15f67a2 commit 136dfcd
Show file tree
Hide file tree
Showing 25 changed files with 552 additions and 144 deletions.
79 changes: 69 additions & 10 deletions src/coreclr/scripts/genEventPipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,20 @@ def generateClrEventPipeWriteEventsImpl(


def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
def winTypeToFixedWidthType(t):
return {'win:Int8': 'int8_t',
'win:UInt8': 'uint8_t',
'win:Int16': 'int16_t',
'win:UInt16': 'uint16_t',
'win:Int32': 'int32_t',
'win:UInt32': 'uint32_t',
'win:Int64': 'int64_t',
'win:UInt64': 'uint64_t',
'win:Pointer': 'uintptr_t',
'win:AnsiString': 'UTF8String',
'win:UnicodeString': 'UTF16String'
}[t]

fnSig = template.signature
pack_list = []

Expand Down Expand Up @@ -267,9 +281,33 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
if runtimeFlavor.mono:
pack_list.append("#if BIGENDIAN")
pack_list.append(" const uint8_t *valuePtr = %s;" % paramName)
pack_list.append(" for (uint32_t i = 0; i < %s; ++i) {" % template.structs[paramName])
types = [winTypeToFixedWidthType(t) for t in template.structTypes[paramName]]
for t in set(types) - {"UTF8String", "UTF16String"}:
pack_list.append(" %(type)s value_%(type)s;" % {'type': t})
if "UTF8String" in types or "UTF16String" in types:
pack_list.append(" size_t value_len;")
for t in types:
if t == "UTF8String":
pack_list.append(" value_len = strlen((const char *)valuePtr);")
pack_list.append(" success &= write_buffer_string_utf8_t((const ep_char8_t *)valuePtr, value_len, &buffer, &offset, &size, &fixedBuffer);")
pack_list.append(" valuePtr += value_len + 1;")
elif t == "UTF16String":
pack_list.append(" value_len = strlen((const char *)valuePtr);")
pack_list.append(" success &= write_buffer_string_utf8_to_utf16_t((const ep_char8_t *)valuePtr, value_len, &buffer, &offset, &size, &fixedBuffer);")
pack_list.append(" valuePtr += value_len + 1;")
else:
pack_list.append(" memcpy (&value_%(type)s, valuePtr, sizeof (value_%(type)s));" % {'type': t})
pack_list.append(" valuePtr += sizeof (%s);" % t)
pack_list.append(" success &= write_buffer_%(type)s (value_%(type)s, &buffer, &offset, &size, &fixedBuffer);" % {'type': t})
pack_list.append(" }")
pack_list.append("#else")
pack_list.append(
" success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" %
(paramName, size))
pack_list.append("#endif // BIGENDIAN")
emittedWriteToBuffer = True
elif runtimeFlavor.coreclr:
pack_list.append(
Expand All @@ -283,9 +321,16 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
if runtimeFlavor.mono:
t = winTypeToFixedWidthType(parameter.winType)
pack_list.append("#if BIGENDIAN")
pack_list.append(" for (uint32_t i = 0; i < %s; ++i) {" % template.arrays[paramName])
pack_list.append(" success &= write_buffer_%(type)s (%(name)s[i], &buffer, &offset, &size, &fixedBuffer);" % {'name': paramName, 'type': t})
pack_list.append(" }")
pack_list.append("#else")
pack_list.append(
" success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" %
(paramName, size))
pack_list.append("#endif // BIGENDIAN")
emittedWriteToBuffer = True
elif runtimeFlavor.coreclr:
pack_list.append(
Expand All @@ -304,13 +349,13 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
emittedWriteToBuffer = True
elif parameter.winType == "win:AnsiString" and runtimeFlavor.mono:
pack_list.append(
" success &= write_buffer_string_utf8_t(%s, &buffer, &offset, &size, &fixedBuffer);" %
(parameter.name,))
" success &= write_buffer_string_utf8_t(%s, strlen((const char *)%s), &buffer, &offset, &size, &fixedBuffer);" %
(parameter.name, parameter.name))
emittedWriteToBuffer = True
elif parameter.winType == "win:UnicodeString" and runtimeFlavor.mono:
pack_list.append(
" success &= write_buffer_string_utf8_to_utf16_t(%s, &buffer, &offset, &size, &fixedBuffer);" %
(parameter.name,))
" success &= write_buffer_string_utf8_to_utf16_t(%s, strlen((const char *)%s), &buffer, &offset, &size, &fixedBuffer);" %
(parameter.name, parameter.name))
emittedWriteToBuffer = True
elif parameter.winType == "win:UInt8" and runtimeFlavor.mono:
pack_list.append(
Expand Down Expand Up @@ -558,6 +603,7 @@ def getMonoEventPipeHelperFileImplPrefix():
bool
write_buffer_string_utf8_to_utf16_t (
const ep_char8_t *value,
size_t value_len,
uint8_t **buffer,
size_t *offset,
size_t *size,
Expand All @@ -566,6 +612,7 @@ def getMonoEventPipeHelperFileImplPrefix():
bool
write_buffer_string_utf8_t (
const ep_char8_t *value,
size_t value_len,
uint8_t **buffer,
size_t *offset,
size_t *size,
Expand Down Expand Up @@ -640,6 +687,7 @@ def getMonoEventPipeHelperFileImplPrefix():
bool
write_buffer_string_utf8_to_utf16_t (
const ep_char8_t *value,
size_t value_len,
uint8_t **buffer,
size_t *offset,
size_t *size,
Expand All @@ -653,12 +701,12 @@ def getMonoEventPipeHelperFileImplPrefix():
custom_alloc_data.buffer_size = *size - *offset;
custom_alloc_data.req_buffer_size = 0;
if (!g_utf8_to_utf16_custom_alloc (value, -1, NULL, NULL, g_fixed_buffer_custom_allocator, &custom_alloc_data, NULL)) {
if (!g_utf8_to_utf16le_custom_alloc (value, (glong)value_len, NULL, NULL, g_fixed_buffer_custom_allocator, &custom_alloc_data, NULL)) {
ep_raise_error_if_nok (resize_buffer (buffer, size, *offset, *size + custom_alloc_data.req_buffer_size, fixed_buffer));
custom_alloc_data.buffer = *buffer + *offset;
custom_alloc_data.buffer_size = *size - *offset;
custom_alloc_data.req_buffer_size = 0;
ep_raise_error_if_nok (g_utf8_to_utf16_custom_alloc (value, -1, NULL, NULL, g_fixed_buffer_custom_allocator, &custom_alloc_data, NULL) != NULL);
ep_raise_error_if_nok (g_utf8_to_utf16le_custom_alloc (value, (glong)value_len, NULL, NULL, g_fixed_buffer_custom_allocator, &custom_alloc_data, NULL) != NULL);
}
*offset += custom_alloc_data.req_buffer_size;
Expand All @@ -671,6 +719,7 @@ def getMonoEventPipeHelperFileImplPrefix():
bool
write_buffer_string_utf8_t (
const ep_char8_t *value,
size_t value_len,
uint8_t **buffer,
size_t *offset,
size_t *size,
Expand All @@ -679,10 +728,6 @@ def getMonoEventPipeHelperFileImplPrefix():
if (!value)
return true;
size_t value_len = 0;
while (value [value_len])
value_len++;
return write_buffer ((const uint8_t *)value, (value_len + 1) * sizeof(*value), buffer, offset, size, fixed_buffer);
}
Expand Down Expand Up @@ -802,6 +847,7 @@ def getMonoEventPipeImplFilePrefix():
bool
write_buffer_string_utf8_t (
const ep_char8_t *value,
size_t value_len,
uint8_t **buffer,
size_t *offset,
size_t *size,
Expand All @@ -810,6 +856,7 @@ def getMonoEventPipeImplFilePrefix():
bool
write_buffer_string_utf8_to_utf16_t (
const ep_char8_t *value,
size_t value_len,
uint8_t **buffer,
size_t *offset,
size_t *size,
Expand Down Expand Up @@ -851,6 +898,7 @@ def getMonoEventPipeImplFilePrefix():
size_t *size,
bool *fixed_buffer)
{
value = ep_rt_val_uint16_t (value);
return write_buffer ((const uint8_t *)&value, sizeof (uint16_t), buffer, offset, size, fixed_buffer);
}
Expand All @@ -864,6 +912,7 @@ def getMonoEventPipeImplFilePrefix():
size_t *size,
bool *fixed_buffer)
{
value = ep_rt_val_uint32_t (value);
return write_buffer ((const uint8_t *)&value, sizeof (uint32_t), buffer, offset, size, fixed_buffer);
}
Expand All @@ -877,6 +926,7 @@ def getMonoEventPipeImplFilePrefix():
size_t *size,
bool *fixed_buffer)
{
value = ep_rt_val_int32_t (value);
return write_buffer ((const uint8_t *)&value, sizeof (int32_t), buffer, offset, size, fixed_buffer);
}
Expand All @@ -890,6 +940,7 @@ def getMonoEventPipeImplFilePrefix():
size_t *size,
bool *fixed_buffer)
{
value = ep_rt_val_uint64_t (value);
return write_buffer ((const uint8_t *)&value, sizeof (uint64_t), buffer, offset, size, fixed_buffer);
}
Expand All @@ -903,6 +954,7 @@ def getMonoEventPipeImplFilePrefix():
size_t *size,
bool *fixed_buffer)
{
value = ep_rt_val_int64_t (value);
return write_buffer ((const uint8_t *)&value, sizeof (int64_t), buffer, offset, size, fixed_buffer);
}
Expand All @@ -916,6 +968,12 @@ def getMonoEventPipeImplFilePrefix():
size_t *size,
bool *fixed_buffer)
{
#if BIGENDIAN
uint64_t value_as_uint64_t;
memcpy (&value_as_uint64_t, &value, sizeof (uint64_t));
value_as_uint64_t = ep_rt_val_uint64_t (value_as_uint64_t);
memcpy (&value, &value_as_uint64_t, sizeof (uint64_t));
#endif
return write_buffer ((const uint8_t *)&value, sizeof (double), buffer, offset, size, fixed_buffer);
}
Expand All @@ -942,6 +1000,7 @@ def getMonoEventPipeImplFilePrefix():
size_t *size,
bool *fixed_buffer)
{
value = ep_rt_val_uintptr_t (value);
return write_buffer ((const uint8_t *)&value, sizeof (uintptr_t), buffer, offset, size, fixed_buffer);
}
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/scripts/genEventing.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,11 @@ class Template:
def __repr__(self):
return "<Template " + self.name + ">"

def __init__(self, templateName, fnPrototypes, dependencies, structSizes, arrays):
def __init__(self, templateName, fnPrototypes, dependencies, structSizes, structTypes, arrays):
self.name = templateName
self.signature = FunctionSignature()
self.structs = structSizes
self.structTypes = structTypes
self.arrays = arrays

for variable in fnPrototypes.paramlist:
Expand Down Expand Up @@ -273,6 +274,7 @@ def parseTemplateNodes(templateNodes):

for templateNode in templateNodes:
structCounts = {}
structTypes = {}
arrays = {}
templateName = templateNode.getAttribute('tid')
var_Dependencies = {}
Expand Down Expand Up @@ -337,11 +339,12 @@ def parseTemplateNodes(templateNodes):
types = [x.attributes['inType'].value for x in structToBeMarshalled.getElementsByTagName("data")]

structCounts[structName] = countVarName
structTypes[structName] = types
var_Dependencies[structName] = [countVarName, structName]
fnparam_pointer = FunctionParameter("win:Struct", structName, "win:count", countVarName)
fnPrototypes.append(structName, fnparam_pointer)

allTemplates[templateName] = Template(templateName, fnPrototypes, var_Dependencies, structCounts, arrays)
allTemplates[templateName] = Template(templateName, fnPrototypes, var_Dependencies, structCounts, structTypes, arrays)

return allTemplates

Expand Down
74 changes: 72 additions & 2 deletions src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,66 @@ ep_rt_runtime_version_get_utf8 (void)
return reinterpret_cast<const ep_char8_t*>(CLR_PRODUCT_VERSION);
}

/*
* Little-Endian Conversion.
*/

static
EP_ALWAYS_INLINE
uint16_t
ep_rt_val_uint16_t (uint16_t value)
{
return value;
}

static
EP_ALWAYS_INLINE
uint32_t
ep_rt_val_uint32_t (uint32_t value)
{
return value;
}

static
EP_ALWAYS_INLINE
uint64_t
ep_rt_val_uint64_t (uint64_t value)
{
return value;
}

static
EP_ALWAYS_INLINE
int16_t
ep_rt_val_int16_t (int16_t value)
{
return value;
}

static
EP_ALWAYS_INLINE
int32_t
ep_rt_val_int32_t (int32_t value)
{
return value;
}

static
EP_ALWAYS_INLINE
int64_t
ep_rt_val_int64_t (int64_t value)
{
return value;
}

static
EP_ALWAYS_INLINE
uintptr_t
ep_rt_val_uintptr_t (uintptr_t value)
{
return value;
}

/*
* Atomics.
*/
Expand Down Expand Up @@ -2154,7 +2214,7 @@ ep_rt_file_open_write (const ep_char8_t *path)
{
STATIC_CONTRACT_NOTHROW;

ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16_string (path, -1);
ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16le_string (path, -1);
ep_return_null_if_nok (path_utf16 != NULL);

CFileStream *file_stream = new (nothrow) CFileStream ();
Expand Down Expand Up @@ -2542,7 +2602,7 @@ ep_rt_utf8_string_replace (

static
ep_char16_t *
ep_rt_utf8_to_utf16_string (
ep_rt_utf8_to_utf16le_string (
const ep_char8_t *str,
size_t len)
{
Expand Down Expand Up @@ -2643,6 +2703,16 @@ ep_rt_utf16_to_utf8_string (
return str_utf8;
}

static
inline
ep_char8_t *
ep_rt_utf16le_to_utf8_string (
const ep_char16_t *str,
size_t len)
{
return ep_rt_utf16_to_utf8_string (str, len);
}

static
inline
void
Expand Down
Loading

0 comments on commit 136dfcd

Please sign in to comment.