[mono][eventpipe] Write primitive types and UTF-16 strings in little endian order...
authorStefan Schulze Frielinghaus <stefansf@linux.ibm.com>
Mon, 4 Jul 2022 18:56:50 +0000 (20:56 +0200)
committerGitHub <noreply@github.com>
Mon, 4 Jul 2022 18:56:50 +0000 (20:56 +0200)
* [mono][eventpipe] Add big-endian support.

25 files changed:
src/coreclr/scripts/genEventPipe.py
src/coreclr/scripts/genEventing.py
src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h
src/mono/mono/eglib/giconv.c
src/mono/mono/eglib/glib.h
src/mono/mono/eventpipe/CMakeLists.txt
src/mono/mono/eventpipe/ds-rt-mono.h
src/mono/mono/eventpipe/ep-rt-mono.c
src/mono/mono/eventpipe/ep-rt-mono.h
src/native/eventpipe/ds-dump-protocol.c
src/native/eventpipe/ds-eventpipe-protocol.c
src/native/eventpipe/ds-process-protocol.c
src/native/eventpipe/ds-protocol.c
src/native/eventpipe/ds-types.h
src/native/eventpipe/ep-block.c
src/native/eventpipe/ep-config.c
src/native/eventpipe/ep-event-source.c
src/native/eventpipe/ep-file.c
src/native/eventpipe/ep-metadata-generator.c
src/native/eventpipe/ep-provider.c
src/native/eventpipe/ep-rt.h
src/native/eventpipe/ep-stack-contents.h
src/native/eventpipe/ep-stream.c
src/native/eventpipe/ep-stream.h
src/native/eventpipe/ep.h

index 2f46735..fa737ea 100644 (file)
@@ -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 = []
 
@@ -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(
@@ -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(
@@ -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(
@@ -558,6 +603,7 @@ write_buffer (
 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,
@@ -566,6 +612,7 @@ write_buffer_string_utf8_to_utf16_t (
 bool
 write_buffer_string_utf8_t (
     const ep_char8_t *value,
+    size_t value_len,
     uint8_t **buffer,
     size_t *offset,
     size_t *size,
@@ -640,6 +687,7 @@ ep_on_error:
 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,
@@ -653,12 +701,12 @@ write_buffer_string_utf8_to_utf16_t (
     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;
@@ -671,6 +719,7 @@ ep_on_error:
 bool
 write_buffer_string_utf8_t (
     const ep_char8_t *value,
+    size_t value_len,
     uint8_t **buffer,
     size_t *offset,
     size_t *size,
@@ -679,10 +728,6 @@ write_buffer_string_utf8_t (
     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);
 }
 
@@ -802,6 +847,7 @@ write_buffer (
 bool
 write_buffer_string_utf8_t (
     const ep_char8_t *value,
+    size_t value_len,
     uint8_t **buffer,
     size_t *offset,
     size_t *size,
@@ -810,6 +856,7 @@ write_buffer_string_utf8_t (
 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,
@@ -851,6 +898,7 @@ write_buffer_uint16_t (
     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);
 }
 
@@ -864,6 +912,7 @@ write_buffer_uint32_t (
     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);
 }
 
@@ -877,6 +926,7 @@ write_buffer_int32_t (
     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);
 }
 
@@ -890,6 +940,7 @@ write_buffer_uint64_t (
     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);
 }
 
@@ -903,6 +954,7 @@ write_buffer_int64_t (
     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);
 }
 
@@ -916,6 +968,12 @@ write_buffer_double_t (
     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);
 }
 
@@ -942,6 +1000,7 @@ write_buffer_uintptr_t (
     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);
 }
 
index e557a8e..a711373 100644 (file)
@@ -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:
@@ -273,6 +274,7 @@ def parseTemplateNodes(templateNodes):
 
     for templateNode in templateNodes:
         structCounts = {}
+        structTypes  = {}
         arrays = {}
         templateName    = templateNode.getAttribute('tid')
         var_Dependencies = {}
@@ -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
 
index c4246df..9b940ad 100644 (file)
@@ -1150,6 +1150,66 @@ ep_rt_runtime_version_get_utf8 (void)
 }
 
 /*
+ * 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.
 */
 
@@ -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 ();
@@ -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)
 {
@@ -2645,6 +2705,16 @@ ep_rt_utf16_to_utf8_string (
 
 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
 ep_rt_utf16_string_free (ep_char16_t *str)
 {
index f7ca5c3..fff2b1d 100644 (file)
@@ -476,28 +476,35 @@ g_unichar_to_utf8 (gunichar c, gchar *outbuf)
 }
 
 static FORCE_INLINE (int)
-g_unichar_to_utf16 (gunichar c, gunichar2 *outbuf)
+g_unichar_to_utf16_endian (gunichar c, gunichar2 *outbuf, unsigned endian)
 {
        gunichar c2;
 
        if (c < 0xd800) {
                if (outbuf)
-                       *outbuf = (gunichar2) c;
+                       *outbuf = (gunichar2) (endian == G_BIG_ENDIAN ? GUINT16_TO_BE(c) : GUINT16_TO_LE(c));
 
                return 1;
        } else if (c < 0xe000) {
                return -1;
        } else if (c < 0x10000) {
                if (outbuf)
-                       *outbuf = (gunichar2) c;
+                       *outbuf = (gunichar2) (endian == G_BIG_ENDIAN ? GUINT16_TO_BE(c) : GUINT16_TO_LE(c));
 
                return 1;
        } else if (c < 0x110000) {
                if (outbuf) {
                        c2 = c - 0x10000;
 
-                       outbuf[0] = (gunichar2) ((c2 >> 10) + 0xd800);
-                       outbuf[1] = (gunichar2) ((c2 & 0x3ff) + 0xdc00);
+                       gunichar2 part1 = (c2 >> 10) + 0xd800;
+                       gunichar2 part2 = (c2 & 0x3ff) + 0xdc00;
+                       if (endian == G_BIG_ENDIAN) {
+                               outbuf[0] = (gunichar2) GUINT16_TO_BE(part1);
+                               outbuf[1] = (gunichar2) GUINT16_TO_BE(part2);
+                       } else {
+                               outbuf[0] = (gunichar2) GUINT16_TO_LE(part1);
+                               outbuf[1] = (gunichar2) GUINT16_TO_LE(part2);
+                       }
                }
 
                return 2;
@@ -506,6 +513,24 @@ g_unichar_to_utf16 (gunichar c, gunichar2 *outbuf)
        }
 }
 
+static FORCE_INLINE (int)
+g_unichar_to_utf16 (gunichar c, gunichar2 *outbuf)
+{
+       return g_unichar_to_utf16_endian (c, outbuf, G_BYTE_ORDER);
+}
+
+static FORCE_INLINE (int)
+g_unichar_to_utf16be (gunichar c, gunichar2 *outbuf)
+{
+       return g_unichar_to_utf16_endian (c, outbuf, G_BIG_ENDIAN);
+}
+
+static FORCE_INLINE (int)
+g_unichar_to_utf16le (gunichar c, gunichar2 *outbuf)
+{
+       return g_unichar_to_utf16_endian (c, outbuf, G_LITTLE_ENDIAN);
+}
+
 gunichar *
 g_utf8_to_ucs4_fast (const gchar *str, glong len, glong *items_written)
 {
@@ -534,7 +559,7 @@ g_utf8_to_ucs4_fast (const gchar *str, glong len, glong *items_written)
 }
 
 static gunichar2 *
-eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong *items_written, gboolean include_nuls, gboolean replace_invalid_codepoints, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err)
+eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong *items_written, gboolean include_nuls, gboolean replace_invalid_codepoints, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err, unsigned endian)
 {
        gunichar2 *outbuf, *outptr;
        size_t outlen = 0;
@@ -564,7 +589,7 @@ eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong
                if (c == 0 && !include_nuls)
                        break;
 
-               if ((u = g_unichar_to_utf16 (c, NULL)) < 0) {
+               if ((u = g_unichar_to_utf16_endian (c, NULL, endian)) < 0) {
                        if (replace_invalid_codepoints) {
                                u = 2;
                        } else {
@@ -604,7 +629,7 @@ eg_utf8_to_utf16_general (const gchar *str, glong len, glong *items_read, glong
                if (c == 0 && !include_nuls)
                        break;
 
-               u = g_unichar_to_utf16 (c, outptr);
+               u = g_unichar_to_utf16_endian (c, outptr, endian);
                if ((u < 0) && replace_invalid_codepoints) {
                        outptr[0] = 0xFFFD;
                        outptr[1] = 0xFFFD;
@@ -646,25 +671,49 @@ error:
 gunichar2 *
 g_utf8_to_utf16 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err)
 {
-       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, NULL, NULL, err);
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, NULL, NULL, err, G_BYTE_ORDER);
+}
+
+gunichar2 *
+g_utf8_to_utf16be (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err)
+{
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, NULL, NULL, err, G_BIG_ENDIAN);
+}
+
+gunichar2 *
+g_utf8_to_utf16le (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err)
+{
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, NULL, NULL, err, G_LITTLE_ENDIAN);
 }
 
 gunichar2 *
 g_utf8_to_utf16_custom_alloc (const gchar *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err)
 {
-       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, custom_alloc_func, custom_alloc_data, err);
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, custom_alloc_func, custom_alloc_data, err, G_BYTE_ORDER);
+}
+
+gunichar2 *
+g_utf8_to_utf16be_custom_alloc (const gchar *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err)
+{
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, custom_alloc_func, custom_alloc_data, err, G_BIG_ENDIAN);
+}
+
+gunichar2 *
+g_utf8_to_utf16le_custom_alloc (const gchar *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err)
+{
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, FALSE, FALSE, custom_alloc_func, custom_alloc_data, err, G_LITTLE_ENDIAN);
 }
 
 gunichar2 *
 eg_utf8_to_utf16_with_nuls (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err)
 {
-       return eg_utf8_to_utf16_general (str, len, items_read, items_written, TRUE, FALSE, NULL, NULL, err);
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, TRUE, FALSE, NULL, NULL, err, G_BYTE_ORDER);
 }
 
 gunichar2 *
 eg_wtf8_to_utf16 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err)
 {
-       return eg_utf8_to_utf16_general (str, len, items_read, items_written, TRUE, TRUE, NULL, NULL, err);
+       return eg_utf8_to_utf16_general (str, len, items_read, items_written, TRUE, TRUE, NULL, NULL, err, G_BYTE_ORDER);
 }
 
 gunichar *
@@ -741,7 +790,7 @@ g_utf8_to_ucs4 (const gchar *str, glong len, glong *items_read, glong *items_wri
 
 static
 gchar *
-eg_utf16_to_utf8_general (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err)
+eg_utf16_to_utf8_general (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err, unsigned endian)
 {
        char *inptr, *outbuf, *outptr;
        size_t outlen = 0;
@@ -761,7 +810,7 @@ eg_utf16_to_utf8_general (const gunichar2 *str, glong len, glong *items_read, gl
        inleft = len * 2;
 
        while (inleft > 0) {
-               if ((n = decode_utf16 (inptr, inleft, &c)) < 0) {
+               if ((n = decode_utf16_endian (inptr, inleft, &c, endian)) < 0) {
                        if (n == -2 && inleft > 2) {
                                /* This means that the first UTF-16 char was read, but second failed */
                                inleft -= 2;
@@ -816,7 +865,7 @@ eg_utf16_to_utf8_general (const gunichar2 *str, glong len, glong *items_read, gl
        inleft = len * 2;
 
        while (inleft > 0) {
-               if ((n = decode_utf16 (inptr, inleft, &c)) < 0)
+               if ((n = decode_utf16_endian (inptr, inleft, &c, endian)) < 0)
                        break;
                else if (c == 0)
                        break;
@@ -834,13 +883,25 @@ eg_utf16_to_utf8_general (const gunichar2 *str, glong len, glong *items_read, gl
 gchar *
 g_utf16_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err)
 {
-       return eg_utf16_to_utf8_general (str, len, items_read, items_written, NULL, NULL, err);
+       return eg_utf16_to_utf8_general (str, len, items_read, items_written, NULL, NULL, err, G_BYTE_ORDER);
+}
+
+gchar *
+g_utf16le_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err)
+{
+       return eg_utf16_to_utf8_general (str, len, items_read, items_written, NULL, NULL, err, G_LITTLE_ENDIAN);
+}
+
+gchar *
+g_utf16be_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err)
+{
+       return eg_utf16_to_utf8_general (str, len, items_read, items_written, NULL, NULL, err, G_BIG_ENDIAN);
 }
 
 gchar *
 g_utf16_to_utf8_custom_alloc (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err)
 {
-       return eg_utf16_to_utf8_general (str, len, items_read, items_written, custom_alloc_func, custom_alloc_data, err);
+       return eg_utf16_to_utf8_general (str, len, items_read, items_written, custom_alloc_func, custom_alloc_data, err, G_BYTE_ORDER);
 }
 
 gunichar *
index 0276020..671e08b 100644 (file)
@@ -882,10 +882,14 @@ gunichar  *g_utf8_to_ucs4_fast (const gchar *str, glong len, glong *items_writte
 gunichar  *g_utf8_to_ucs4 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err);
 G_EXTERN_C // Used by libtest, at least.
 gunichar2 *g_utf8_to_utf16 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err);
+gunichar2 *g_utf8_to_utf16be (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err);
+gunichar2 *g_utf8_to_utf16le (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err);
 gunichar2 *eg_utf8_to_utf16_with_nuls (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err);
 gunichar2 *eg_wtf8_to_utf16 (const gchar *str, glong len, glong *items_read, glong *items_written, GError **err);
 G_EXTERN_C // Used by libtest, at least.
 gchar     *g_utf16_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err);
+gchar     *g_utf16le_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err);
+gchar     *g_utf16be_to_utf8 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err);
 gunichar  *g_utf16_to_ucs4 (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GError **err);
 gchar     *g_ucs4_to_utf8  (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **err);
 gunichar2 *g_ucs4_to_utf16 (const gunichar *str, glong len, glong *items_read, glong *items_written, GError **err);
@@ -911,6 +915,8 @@ gpointer
 g_fixed_buffer_custom_allocator (gsize req_size, gpointer custom_alloc_data);
 
 gunichar2 *g_utf8_to_utf16_custom_alloc (const gchar *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err);
+gunichar2 *g_utf8_to_utf16be_custom_alloc (const gchar *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err);
+gunichar2 *g_utf8_to_utf16le_custom_alloc (const gchar *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err);
 gchar *g_utf16_to_utf8_custom_alloc (const gunichar2 *str, glong len, glong *items_read, glong *items_written, GCustomAllocator custom_alloc_func, gpointer custom_alloc_data, GError **err);
 
 /*
index 30d3139..e1e9b20 100644 (file)
@@ -22,6 +22,10 @@ if(ENABLE_PERFTRACING)
         add_definitions(-DDISABLE_PERFTRACING_CONNECT_PORTS)
     endif (FEATURE_PERFTRACING_DISABLE_CONNECT_PORTS)
 
+    if (TARGET_S390X)
+        add_definitions(-DBIGENDIAN)
+    endif (TARGET_S390X)
+
     include (${SHARED_EVENTPIPE_SOURCE_PATH}CMakeLists.txt)
 
     set(MONO_EVENTPIPE_SHIM_SOURCES "")
index f674dfa..e951ca1 100644 (file)
@@ -258,8 +258,8 @@ static
 uint32_t
 ds_rt_set_environment_variable (const ep_char16_t *name, const ep_char16_t *value)
 {
-       gchar *nameNarrow = ep_rt_utf16_to_utf8_string (name, ep_rt_utf16_string_len (name));
-       gchar *valueNarrow = ep_rt_utf16_to_utf8_string (value, ep_rt_utf16_string_len (value));
+       gchar *nameNarrow = ep_rt_utf16le_to_utf8_string (name, ep_rt_utf16_string_len (name));
+       gchar *valueNarrow = ep_rt_utf16le_to_utf8_string (value, ep_rt_utf16_string_len (value));
 
        gboolean success = g_setenv(nameNarrow, valueNarrow, true);
 
index 1d7e5ac..36ee962 100644 (file)
@@ -2151,7 +2151,7 @@ ep_rt_mono_file_open_write (const ep_char8_t *path)
        if (!path)
                return INVALID_HANDLE_VALUE;
 
-       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);
 
        if (!path_utf16)
                return INVALID_HANDLE_VALUE;
@@ -2636,7 +2636,7 @@ ep_rt_mono_os_environment_get_utf16 (ep_rt_env_array_utf16_t *env_array)
 #else
        gchar **next = NULL;
        for (next = environ; *next != NULL; ++next)
-               ep_rt_env_array_utf16_append (env_array, ep_rt_utf8_to_utf16_string (*next, -1));
+               ep_rt_env_array_utf16_append (env_array, ep_rt_utf8_to_utf16le_string (*next, -1));
 #endif
 }
 
@@ -2843,7 +2843,8 @@ ep_rt_mono_sample_profiler_write_sampling_event_for_threads (
                                        mono_jit_info_table_find_internal ((gpointer)data->stack_contents.stack_frames [frame_count], TRUE, FALSE);
                        }
                        mono_thread_info_set_tid (&adapter, ep_rt_uint64_t_to_thread_id_t (data->thread_id));
-                       ep_write_sample_profile_event (sampling_thread, sampling_event, &adapter, &data->stack_contents, (uint8_t *)&data->payload_data, sizeof (data->payload_data));
+                       uint32_t payload_data = ep_rt_val_uint32_t (data->payload_data);
+                       ep_write_sample_profile_event (sampling_thread, sampling_event, &adapter, &data->stack_contents, (uint8_t *)&payload_data, sizeof (payload_data));
                }
        }
 
@@ -5873,12 +5874,10 @@ mono_profiler_get_generic_types (
                        *generic_type_count = generic_instance->type_argc;
                        for (uint32_t i = 0; i < generic_instance->type_argc; ++i) {
                                uint8_t type = generic_instance->type_argv [i]->type;
-                               memcpy (buffer, &type, sizeof (type));
-                               buffer += sizeof (type);
+                               ep_write_buffer_uint8_t (&buffer, type);
 
                                uint64_t class_id = (uint64_t)mono_class_from_mono_type_internal (generic_instance->type_argv [i]);
-                               memcpy (buffer, &class_id, sizeof (class_id));
-                               buffer += sizeof (class_id);
+                               ep_write_buffer_uint64_t (&buffer, class_id);
                        }
                }
        }
index ebe81a0..095266b 100644 (file)
@@ -540,6 +540,70 @@ ep_rt_mono_thread_teardown (void)
 }
 
 /*
+ * Little-Endian Conversion.
+ */
+
+static
+EP_ALWAYS_INLINE
+uint16_t
+ep_rt_val_uint16_t (uint16_t value)
+{
+       return GUINT16_TO_LE (value);
+}
+
+static
+EP_ALWAYS_INLINE
+uint32_t
+ep_rt_val_uint32_t (uint32_t value)
+{
+       return GUINT32_TO_LE (value);
+}
+
+static
+EP_ALWAYS_INLINE
+uint64_t
+ep_rt_val_uint64_t (uint64_t value)
+{
+       return GUINT64_TO_LE (value);
+}
+
+static
+EP_ALWAYS_INLINE
+int16_t
+ep_rt_val_int16_t (int16_t value)
+{
+       return (int16_t)GUINT16_TO_LE ((uint16_t)value);
+}
+
+static
+EP_ALWAYS_INLINE
+int32_t
+ep_rt_val_int32_t (int32_t value)
+{
+       return (int32_t)GUINT32_TO_LE ((uint32_t)value);
+}
+
+static
+EP_ALWAYS_INLINE
+int64_t
+ep_rt_val_int64_t (int64_t value)
+{
+       return (int64_t)GUINT64_TO_LE ((uint64_t)value);
+}
+
+static
+EP_ALWAYS_INLINE
+uintptr_t
+ep_rt_val_uintptr_t (uintptr_t value)
+{
+#if SIZEOF_VOID_P == 4
+       return (uintptr_t)GUINT32_TO_LE ((uint32_t)value);
+#else
+       return (uintptr_t)GUINT64_TO_LE ((uint64_t)value);
+#endif
+}
+
+/*
 * Atomics.
 */
 
@@ -1755,11 +1819,11 @@ ep_rt_utf8_string_replace (
 static
 inline
 ep_char16_t *
-ep_rt_utf8_to_utf16_string (
+ep_rt_utf8_to_utf16le_string (
        const ep_char8_t *str,
        size_t len)
 {
-       return (ep_char16_t *)(g_utf8_to_utf16 ((const gchar *)str, (glong)len, NULL, NULL, NULL));
+       return (ep_char16_t *)(g_utf8_to_utf16le ((const gchar *)str, (glong)len, NULL, NULL, NULL));
 }
 
 static
@@ -1802,6 +1866,16 @@ ep_rt_utf16_to_utf8_string (
 
 static
 inline
+ep_char8_t *
+ep_rt_utf16le_to_utf8_string (
+       const ep_char16_t *str,
+       size_t len)
+{
+       return g_utf16le_to_utf8 ((const gunichar2 *)str, (glong)len, NULL, NULL, NULL);
+}
+
+static
+inline
 void
 ep_rt_utf16_string_free (ep_char16_t *str)
 {
index 42ee6a2..869d960 100644 (file)
@@ -106,7 +106,7 @@ dump_protocol_generate_core_dump_response_init(
 
        payload->error = error;
        // If this conversion failures it will set error_message to NULL which will send an empty message
-       payload->error_message = ep_rt_utf8_to_utf16_string (errorText, -1);
+       payload->error_message = ep_rt_utf8_to_utf16le_string (errorText, -1);
 }
 
 static
index f5082bf..2f7ccd5 100644 (file)
@@ -182,7 +182,7 @@ eventpipe_collect_tracing_command_try_parse_config (
                uint32_t provider_name_byte_array_len = 0;
                ep_raise_error_if_nok (ds_ipc_message_try_parse_string_utf16_t_byte_array_alloc (buffer, buffer_len, &provider_name_byte_array, &provider_name_byte_array_len));
 
-               provider_name_utf8 = ep_rt_utf16_to_utf8_string ((const ep_char16_t *)provider_name_byte_array, -1);
+               provider_name_utf8 = ep_rt_utf16le_to_utf8_string ((const ep_char16_t *)provider_name_byte_array, -1);
                ep_raise_error_if_nok (provider_name_utf8 != NULL);
 
                ep_raise_error_if_nok (!ep_rt_utf8_string_is_null_or_empty (provider_name_utf8));
@@ -195,7 +195,7 @@ eventpipe_collect_tracing_command_try_parse_config (
 
                // This parameter is optional.
                if (filter_data_byte_array) {
-                       filter_data_utf8 = ep_rt_utf16_to_utf8_string ((const ep_char16_t *)filter_data_byte_array, -1);
+                       filter_data_utf8 = ep_rt_utf16le_to_utf8_string ((const ep_char16_t *)filter_data_byte_array, -1);
                        ep_raise_error_if_nok (filter_data_utf8 != NULL);
 
                        ep_rt_byte_array_free (filter_data_byte_array);
index 6f97ac2..52c210a 100644 (file)
@@ -428,6 +428,7 @@ env_info_stream_env_block (
 
        // Array<Array<WCHAR>>
        uint32_t env_len = (uint32_t)ep_rt_env_array_utf16_size (&env_info->env_array);
+       env_len = ep_rt_val_uint32_t (env_len);
        success &= ds_ipc_stream_write (stream, (const uint8_t *)&env_len, sizeof (env_len), &bytes_written, EP_INFINITE_WAIT);
 
        ep_rt_env_array_utf16_iterator_t iterator = ep_rt_env_array_utf16_iterator_begin (&env_info->env_array);
@@ -485,13 +486,13 @@ process_protocol_helper_get_process_info (
        DiagnosticsProcessInfoPayload payload;
        DiagnosticsProcessInfoPayload *process_info_payload = NULL;
 
-       command_line = ep_rt_utf8_to_utf16_string (ep_rt_diagnostics_command_line_get (), -1);
+       command_line = ep_rt_utf8_to_utf16le_string (ep_rt_diagnostics_command_line_get (), -1);
        ep_raise_error_if_nok (command_line != NULL);
 
-       os_info = ep_rt_utf8_to_utf16_string (ep_event_source_get_os_info (), -1);
+       os_info = ep_rt_utf8_to_utf16le_string (ep_event_source_get_os_info (), -1);
        ep_raise_error_if_nok (os_info != NULL);
 
-       arch_info = ep_rt_utf8_to_utf16_string (ep_event_source_get_arch_info (), -1);
+       arch_info = ep_rt_utf8_to_utf16le_string (ep_event_source_get_arch_info (), -1);
        ep_raise_error_if_nok (arch_info != NULL);
 
        process_info_payload = ds_process_info_payload_init (
@@ -547,19 +548,19 @@ process_protocol_helper_get_process_info_2 (
        DiagnosticsProcessInfo2Payload payload;
        DiagnosticsProcessInfo2Payload *process_info_2_payload = NULL;
 
-       command_line = ep_rt_utf8_to_utf16_string (ep_rt_diagnostics_command_line_get (), -1);
+       command_line = ep_rt_utf8_to_utf16le_string (ep_rt_diagnostics_command_line_get (), -1);
        ep_raise_error_if_nok (command_line != NULL);
 
-       os_info = ep_rt_utf8_to_utf16_string (ep_event_source_get_os_info (), -1);
+       os_info = ep_rt_utf8_to_utf16le_string (ep_event_source_get_os_info (), -1);
        ep_raise_error_if_nok (os_info != NULL);
 
-       arch_info = ep_rt_utf8_to_utf16_string (ep_event_source_get_arch_info (), -1);
+       arch_info = ep_rt_utf8_to_utf16le_string (ep_event_source_get_arch_info (), -1);
        ep_raise_error_if_nok (arch_info != NULL);
 
-       managed_entrypoint_assembly_name = ep_rt_utf8_to_utf16_string (ep_rt_entrypoint_assembly_name_get_utf8 (), -1);
+       managed_entrypoint_assembly_name = ep_rt_utf8_to_utf16le_string (ep_rt_entrypoint_assembly_name_get_utf8 (), -1);
        ep_raise_error_if_nok (managed_entrypoint_assembly_name != NULL);
 
-       clr_product_version = ep_rt_utf8_to_utf16_string (ep_rt_runtime_version_get_utf8 (), -1);
+       clr_product_version = ep_rt_utf8_to_utf16le_string (ep_rt_runtime_version_get_utf8 (), -1);
        ep_raise_error_if_nok (clr_product_version != NULL);
 
        process_info_2_payload = ds_process_info_2_payload_init (
index 2ad6e7c..228a574 100644 (file)
@@ -102,7 +102,7 @@ ds_icp_advertise_v1_send (DiagnosticsIpcStream *stream)
 {
        uint8_t advertise_buffer [DOTNET_IPC_V1_ADVERTISE_SIZE];
        uint8_t *cookie = ds_ipc_advertise_cookie_v1_get ();
-       uint64_t pid = DS_VAL64 (ep_rt_current_process_get_id ());
+       uint64_t pid = ep_rt_val_uint64_t (ep_rt_current_process_get_id ());
        uint64_t *buffer = (uint64_t *)advertise_buffer;
        bool result = false;
 
@@ -152,6 +152,7 @@ ipc_message_try_send_string_utf16_t (
        uint32_t total_written = 0;
        uint32_t written = 0;
 
+       string_len = ep_rt_val_uint32_t (string_len);
        bool result = ds_ipc_stream_write (stream, (const uint8_t *)&string_len, (uint32_t)sizeof (string_len), &written, EP_INFINITE_WAIT);
        total_written += written;
 
@@ -188,7 +189,7 @@ ipc_message_flatten_blitable_type (
        ep_raise_error_if_nok (buffer != NULL);
 
        buffer_cursor = buffer;
-       message->header.size = message->size;
+       message->header.size = ep_rt_val_uint16_t (message->size);
 
        memcpy (buffer_cursor, &message->header, sizeof (message->header));
        buffer_cursor += sizeof (message->header);
@@ -230,14 +231,14 @@ ipc_message_try_parse (
        if (!result || (bytes_read < sizeof (message->header)))
                ep_raise_error ();
 
-       if (message->header.size < sizeof (message->header))
-               ep_raise_error ();
+       message->size = ep_rt_val_uint16_t (message->header.size);
 
-       message->size = message->header.size;
+       if (message->size < sizeof (message->header))
+               ep_raise_error ();
 
        // Then read out payload to buffer.
        uint16_t payload_len;
-       payload_len = message->header.size - sizeof (message->header);
+       payload_len = message->size - sizeof (message->header);
        if (payload_len != 0) {
                buffer = ep_rt_byte_array_alloc (payload_len);
                ep_raise_error_if_nok (buffer != NULL);
@@ -288,7 +289,7 @@ ipc_message_flatten (
 
        uint8_t * buffer_cursor;
        buffer_cursor = buffer;
-       message->header.size = message->size;
+       message->header.size = ep_rt_val_uint16_t (message->size);
 
        memcpy (buffer_cursor, &message->header, sizeof (DiagnosticsIpcHeader));
        buffer_cursor += sizeof (DiagnosticsIpcHeader);
@@ -415,7 +416,7 @@ ds_ipc_message_try_parse_uint64_t (
 
        bool result = ds_ipc_message_try_parse_value (buffer, buffer_len, (uint8_t *)value, (uint32_t)sizeof (uint64_t));
        if (result)
-               *value = DS_VAL64 (*value);
+               *value = ep_rt_val_uint64_t (*value);
        return result;
 }
 
@@ -431,7 +432,7 @@ ds_ipc_message_try_parse_uint32_t (
 
        bool result = ds_ipc_message_try_parse_value (buffer, buffer_len, (uint8_t*)value, (uint32_t)sizeof (uint32_t));
        if (result)
-               *value = DS_VAL32 (*value);
+               *value = ep_rt_val_uint32_t (*value);
        return result;
 }
 
@@ -499,6 +500,7 @@ ds_ipc_message_initialize_header_uint32_t_payload (
        EP_ASSERT (header);
 
        message->header = *header;
+       payload = ep_rt_val_uint32_t (payload);
        return ipc_message_flatten_blitable_type (message, (uint8_t *)&payload, sizeof (payload));
 }
 
@@ -512,6 +514,7 @@ ds_ipc_message_initialize_header_uint64_t_payload (
        EP_ASSERT (header);
 
        message->header = *header;
+       payload = ep_rt_val_uint64_t (payload);
        return ipc_message_flatten_blitable_type (message, (uint8_t *)&payload, sizeof (payload));
 }
 
@@ -560,6 +563,7 @@ ds_ipc_message_try_write_string_utf16_t (
 
        bool result = true;
        uint32_t string_len = (uint32_t)(ep_rt_utf16_string_len (value) + 1);
+       uint32_t string_len_le = ep_rt_val_uint32_t (string_len);
        size_t total_bytes = (string_len * sizeof (ep_char16_t)) + sizeof(uint32_t);
 
        EP_ASSERT (total_bytes <= UINT16_MAX);
@@ -567,8 +571,8 @@ ds_ipc_message_try_write_string_utf16_t (
        if (*buffer_len < (uint16_t)total_bytes || total_bytes > UINT16_MAX)
                ep_raise_error ();
 
-       memcpy (*buffer, &string_len, sizeof (string_len));
-       *buffer += sizeof (string_len);
+       memcpy (*buffer, &string_len_le, sizeof (string_len_le));
+       *buffer += sizeof (string_len_le);
 
        memcpy (*buffer, value, string_len * sizeof (ep_char16_t));
        *buffer += (string_len * sizeof (ep_char16_t));
@@ -594,11 +598,12 @@ ds_ipc_message_try_write_string_utf16_t_to_stream (
        bool result = true;
        uint32_t bytes_written = 0;
        uint32_t string_len = (uint32_t)(ep_rt_utf16_string_len (value) + 1);
+       uint32_t string_len_le = ep_rt_val_uint32_t (string_len);
        size_t total_bytes = (string_len * sizeof (ep_char16_t)) + sizeof(uint32_t);
 
        EP_ASSERT (total_bytes <= UINT16_MAX);
 
-       result &= ds_ipc_stream_write (stream, (const uint8_t *)&string_len, sizeof (string_len), &bytes_written, EP_INFINITE_WAIT);
+       result &= ds_ipc_stream_write (stream, (const uint8_t *)&string_len_le, sizeof (string_len_le), &bytes_written, EP_INFINITE_WAIT);
        total_bytes -= bytes_written;
        if (result) {
                result &= ds_ipc_stream_write (stream, (const uint8_t *)value, string_len * sizeof (ep_char16_t), &bytes_written, EP_INFINITE_WAIT);
index 29baf22..0787f20 100644 (file)
@@ -114,16 +114,6 @@ typedef enum {
 #define DOTNET_IPC_V1_ADVERTISE_MAGIC "ADVR_V1"
 #define DOTNET_IPC_V1_ADVERTISE_SIZE 34
 
-#if BIGENDIAN
-#define DS_VAL16(x)    (((x) >> 8) | ((x) << 8))
-#define DS_VAL32(y)    (((y) >> 24) | (((y) >> 8) & 0x0000FF00L) | (((y) & 0x0000FF00L) << 8) | ((y) << 24))
-#define DS_VAL64(z)    (((uint64_t)DS_VAL32(z) << 32) | DS_VAL32((z) >> 32))
-#else
-#define DS_VAL16(x) x
-#define DS_VAL32(x) x
-#define DS_VAL64(x) x
-#endif // BIGENDIAN
-
 typedef int32_t ds_ipc_result_t;
 
 #define DS_IPC_S_OK ((ds_ipc_result_t)(0L))
index 4561ee2..c40d768 100644 (file)
@@ -327,7 +327,7 @@ ep_block_fast_serialize (
 
        uint32_t header_size =  ep_block_get_header_size_vcall (block);
        uint32_t total_size = data_size + header_size;
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&total_size, sizeof (total_size));
+       ep_fast_serializer_write_uint32_t (fast_serializer, total_size);
 
        uint32_t required_padding = ep_fast_serializer_get_required_padding (fast_serializer);
        if (required_padding != 0) {
@@ -495,16 +495,16 @@ ep_event_block_base_serialize_header (
        ep_return_void_if_nok (((EventPipeBlock *)event_block_base)->format != EP_SERIALIZATION_FORMAT_NETPERF_V3);
 
        const uint16_t header_size = (uint16_t)ep_block_get_header_size_vcall ((EventPipeBlock *)event_block_base);
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&header_size, sizeof (header_size));
+       ep_fast_serializer_write_uint16_t (fast_serializer, header_size);
 
        const uint16_t flags = event_block_base->use_header_compression ? 1 : 0;
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&flags, sizeof (flags));
+       ep_fast_serializer_write_uint16_t (fast_serializer, flags);
 
        ep_timestamp_t min_timestamp = event_block_base->min_timestamp;
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&min_timestamp, sizeof (min_timestamp));
+       ep_fast_serializer_write_int64_t (fast_serializer, min_timestamp);
 
        ep_timestamp_t max_timestamp = event_block_base->max_timestamp;
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&max_timestamp, sizeof (max_timestamp));
+       ep_fast_serializer_write_int64_t (fast_serializer, max_timestamp);
 }
 
 bool
@@ -536,41 +536,32 @@ ep_event_block_base_write_event (
 
                aligned_end = write_pointer + total_size + sizeof (total_size);
 
-               memcpy (write_pointer, &total_size, sizeof (total_size));
-               write_pointer += sizeof (total_size);
+               ep_write_buffer_uint32_t (&write_pointer, total_size);
 
                uint32_t metadata_id = ep_event_instance_get_metadata_id (event_instance);
                EP_ASSERT ((metadata_id & (1 << 31)) == 0);
 
                metadata_id |= (!is_sorted_event ? 1 << 31 : 0);
-               memcpy (write_pointer, &metadata_id, sizeof (metadata_id));
-               write_pointer += sizeof (metadata_id);
+               ep_write_buffer_uint32_t (&write_pointer, metadata_id);
 
                if (block->format == EP_SERIALIZATION_FORMAT_NETPERF_V3) {
                        uint32_t thread_id = (uint32_t)ep_event_instance_get_thread_id (event_instance);
-                       memcpy (write_pointer, &thread_id, sizeof (thread_id));
-                       write_pointer += sizeof (thread_id);
+                       ep_write_buffer_uint32_t (&write_pointer, thread_id);
                } else if (block->format == EP_SERIALIZATION_FORMAT_NETTRACE_V4) {
-                       memcpy (write_pointer, &sequence_number, sizeof (sequence_number));
-                       write_pointer += sizeof (sequence_number);
+                       ep_write_buffer_uint32_t (&write_pointer, sequence_number);
 
                        uint64_t thread_id = ep_event_instance_get_thread_id (event_instance);
-                       memcpy (write_pointer, &thread_id, sizeof (thread_id));
-                       write_pointer += sizeof (thread_id);
+                       ep_write_buffer_uint64_t (&write_pointer, thread_id);
 
-                       memcpy (write_pointer, &capture_thread_id, sizeof (capture_thread_id));
-                       write_pointer += sizeof (capture_thread_id);
+                       ep_write_buffer_uint64_t (&write_pointer, capture_thread_id);
 
-                       memcpy (write_pointer, &capture_proc_number, sizeof (capture_proc_number));
-                       write_pointer += sizeof (capture_proc_number);
+                       ep_write_buffer_uint32_t (&write_pointer, capture_proc_number);
 
-                       memcpy (write_pointer, &stack_id, sizeof (stack_id));
-                       write_pointer += sizeof (stack_id);
+                       ep_write_buffer_uint32_t (&write_pointer, stack_id);
                }
 
                ep_timestamp_t timestamp = ep_event_instance_get_timestamp (event_instance);
-               memcpy (write_pointer, &timestamp, sizeof (timestamp));
-               write_pointer += sizeof (timestamp);
+               ep_write_buffer_int64_t (&write_pointer, timestamp);
 
                const uint8_t *activity_id = ep_event_instance_get_activity_id_cref (event_instance);
                memcpy (write_pointer, activity_id, EP_ACTIVITY_ID_SIZE);
@@ -581,8 +572,7 @@ ep_event_block_base_write_event (
                write_pointer += EP_ACTIVITY_ID_SIZE;
 
                data_len = ep_event_instance_get_data_len (event_instance);
-               memcpy (write_pointer, &data_len, sizeof (data_len));
-               write_pointer += sizeof (data_len);
+               ep_write_buffer_uint32_t (&write_pointer, data_len);
        } else { // using header compression
                uint8_t flags = 0;
                uint8_t *header_write_pointer = &event_block_base->compressed_header[0];
@@ -672,8 +662,7 @@ ep_event_block_base_write_event (
 
        if (block->format == EP_SERIALIZATION_FORMAT_NETPERF_V3) {
                uint32_t stack_size = ep_stack_contents_instance_get_size (ep_event_instance_get_stack_contents_instance_ref (event_instance));
-               memcpy (write_pointer, &stack_size, sizeof (stack_size));
-               write_pointer += sizeof (stack_size);
+               ep_write_buffer_uint32_t (&write_pointer, stack_size);
 
                if (stack_size > 0) {
                        memcpy (write_pointer, ep_stack_contents_instance_get_pointer (ep_event_instance_get_stack_contents_instance_ref (event_instance)), stack_size);
@@ -909,12 +898,10 @@ ep_sequence_point_block_init (
                EP_SERIALIZATION_FORMAT_NETTRACE_V4) != NULL);
 
        const ep_timestamp_t timestamp = ep_sequence_point_get_timestamp (sequence_point);
-       memcpy (sequence_point_block->block.write_pointer, &timestamp, sizeof (timestamp));
-       sequence_point_block->block.write_pointer += sizeof (timestamp);
+       ep_write_buffer_timestamp (&sequence_point_block->block.write_pointer, timestamp);
 
        const uint32_t thread_count = ep_rt_thread_sequence_number_map_count (ep_sequence_point_get_thread_sequence_numbers_cref (sequence_point));
-       memcpy (sequence_point_block->block.write_pointer, &thread_count, sizeof (thread_count));
-       sequence_point_block->block.write_pointer += sizeof (thread_count);
+       ep_write_buffer_uint32_t (&sequence_point_block->block.write_pointer, thread_count);
 
        for (ep_rt_thread_sequence_number_hash_map_iterator_t iterator = ep_rt_thread_sequence_number_map_iterator_begin (ep_sequence_point_get_thread_sequence_numbers_cref (sequence_point));
                !ep_rt_thread_sequence_number_map_iterator_end (ep_sequence_point_get_thread_sequence_numbers_cref (sequence_point), &iterator);
@@ -923,12 +910,10 @@ ep_sequence_point_block_init (
                const EventPipeThreadSessionState *key = ep_rt_thread_sequence_number_map_iterator_key (&iterator);
 
                const uint64_t thread_id = ep_thread_get_os_thread_id (ep_thread_session_state_get_thread (key));
-               memcpy (sequence_point_block->block.write_pointer, &thread_id, sizeof (thread_id));
-               sequence_point_block->block.write_pointer += sizeof (thread_id);
+               ep_write_buffer_uint64_t (&sequence_point_block->block.write_pointer, thread_id);
 
                const uint32_t sequence_number = ep_rt_thread_sequence_number_map_iterator_value (&iterator);
-               memcpy (sequence_point_block->block.write_pointer, &sequence_number, sizeof (sequence_number));
-               sequence_point_block->block.write_pointer += sizeof (sequence_number);
+               ep_write_buffer_uint32_t (&sequence_point_block->block.write_pointer, sequence_number);
        }
 
        return sequence_point_block;
@@ -1003,8 +988,8 @@ stack_block_serialize_header_func (
        EP_ASSERT (fast_serializer != NULL);
 
        EventPipeStackBlock *stack_block = (EventPipeStackBlock *)object;
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&stack_block->initial_index, sizeof (stack_block->initial_index));
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&stack_block->count, sizeof (stack_block->count));
+       ep_fast_serializer_write_uint32_t (fast_serializer, stack_block->initial_index);
+       ep_fast_serializer_write_uint32_t (fast_serializer, stack_block->count);
 }
 
 static EventPipeBlockVtable stack_block_vtable = {
@@ -1072,8 +1057,7 @@ ep_stack_block_write_stack (
 
        stack_block->count++;
 
-       memcpy (write_pointer, &stack_size, sizeof (stack_size));
-       write_pointer += sizeof (stack_size);
+       ep_write_buffer_uint32_t (&write_pointer, stack_size);
 
        if (stack_size > 0) {
                memcpy (write_pointer, ep_stack_contents_instance_get_pointer (stack), stack_size);
index f2b24b2..626e07b 100644 (file)
@@ -367,11 +367,9 @@ ep_config_build_event_metadata_event (
        uint8_t *current;
        current = instance_payload;
 
-       memcpy(current, &metadata_id, sizeof(metadata_id));
-       current += sizeof(metadata_id);
+       ep_write_buffer_uint32_t (&current, metadata_id);
 
-       memcpy(current, provider_name_utf16, provider_name_len);
-       current += provider_name_len;
+       ep_write_buffer_string_utf16_t (&current, provider_name_utf16, provider_name_len);
 
        // Write the incoming payload data.
        memcpy(current, payload_data, payload_data_len);
index 5fd07ab..497de0e 100644 (file)
@@ -108,19 +108,19 @@ ep_event_source_init (EventPipeEventSource *event_source)
        uint32_t params_len;
        params_len = (uint32_t)ARRAY_SIZE (params);
 
-       command_line_arg_utf16 = ep_rt_utf8_to_utf16_string ("CommandLine", -1);
+       command_line_arg_utf16 = ep_rt_utf8_to_utf16le_string ("CommandLine", -1);
        ep_raise_error_if_nok (command_line_arg_utf16 != NULL);
        ep_parameter_desc_init (&params[0], EP_PARAMETER_TYPE_STRING, command_line_arg_utf16);
 
-       os_info_arg_utf16 = ep_rt_utf8_to_utf16_string ("OSInformation", -1);
+       os_info_arg_utf16 = ep_rt_utf8_to_utf16le_string ("OSInformation", -1);
        ep_raise_error_if_nok (os_info_arg_utf16 != NULL);
        ep_parameter_desc_init (&params[1], EP_PARAMETER_TYPE_STRING, os_info_arg_utf16);
 
-       arch_info_arg_utf16 = ep_rt_utf8_to_utf16_string ("ArchInformation", -1);
+       arch_info_arg_utf16 = ep_rt_utf8_to_utf16le_string ("ArchInformation", -1);
        ep_raise_error_if_nok (arch_info_arg_utf16 != NULL);
        ep_parameter_desc_init (&params[2], EP_PARAMETER_TYPE_STRING, arch_info_arg_utf16);
 
-       event_name_utf16 = ep_rt_utf8_to_utf16_string ("ProcessInfo", -1);
+       event_name_utf16 = ep_rt_utf8_to_utf16le_string ("ProcessInfo", -1);
        ep_raise_error_if_nok (event_name_utf16 != NULL);
 
        size_t metadata_len;
@@ -215,9 +215,9 @@ ep_event_source_send_process_info (
        ep_char16_t *os_info_utf16 = NULL;
        ep_char16_t *arch_info_utf16 = NULL;
 
-       command_line_utf16 = ep_rt_utf8_to_utf16_string (command_line, -1);
-       os_info_utf16 = ep_rt_utf8_to_utf16_string (ep_event_source_get_os_info (), -1);
-       arch_info_utf16 = ep_rt_utf8_to_utf16_string (ep_event_source_get_arch_info (), -1);
+       command_line_utf16 = ep_rt_utf8_to_utf16le_string (command_line, -1);
+       os_info_utf16 = ep_rt_utf8_to_utf16le_string (ep_event_source_get_os_info (), -1);
+       arch_info_utf16 = ep_rt_utf8_to_utf16le_string (ep_event_source_get_arch_info (), -1);
 
        EventData data [3] = { { 0 } };
        if (command_line_utf16)
index c587365..04291be 100644 (file)
@@ -93,15 +93,15 @@ file_fast_serialize_func (void *object, FastSerializer *fast_serializer)
        EP_ASSERT (fast_serializer != NULL);
 
        EventPipeFile *file = (EventPipeFile *)object;
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->file_open_system_time, sizeof (file->file_open_system_time));
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->file_open_timestamp, sizeof (file->file_open_timestamp));
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->timestamp_frequency, sizeof (file->timestamp_frequency));
+       ep_fast_serializer_write_system_time (fast_serializer, &file->file_open_system_time);
+       ep_fast_serializer_write_timestamp (fast_serializer, file->file_open_timestamp);
+       ep_fast_serializer_write_int64_t (fast_serializer, file->timestamp_frequency);
 
        // the beginning of V3
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->pointer_size, sizeof (file->pointer_size));
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->current_process_id, sizeof (file->current_process_id));
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->number_of_processors, sizeof (file->number_of_processors));
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&file->sampling_rate_in_ns, sizeof (file->sampling_rate_in_ns));
+       ep_fast_serializer_write_uint32_t (fast_serializer, file->pointer_size);
+       ep_fast_serializer_write_uint32_t (fast_serializer, file->current_process_id);
+       ep_fast_serializer_write_uint32_t (fast_serializer, file->number_of_processors);
+       ep_fast_serializer_write_uint32_t (fast_serializer, file->sampling_rate_in_ns);
 }
 
 static
index 25a8b64..4a8e669 100644 (file)
@@ -176,6 +176,7 @@ metadata_generator_write_uint32_to_buffer (
        uint32_t value)
 {
        EP_ASSERT ((*offset + sizeof (value)) <= buffer_len);
+       value = ep_rt_val_uint32_t (value);
        memcpy (buffer + *offset, &value, sizeof (value));
        *offset += sizeof (value);
 }
@@ -189,6 +190,7 @@ metadata_generator_write_int64_to_buffer (
        int64_t value)
 {
        EP_ASSERT ((*offset + sizeof (value)) <= buffer_len);
+       value = ep_rt_val_int64_t (value);
        memcpy (buffer + *offset, &value, sizeof (value));
        *offset += sizeof (value);
 }
index 566b092..c864043 100644 (file)
@@ -178,7 +178,7 @@ ep_provider_alloc (
        instance->provider_name = ep_rt_utf8_string_dup (provider_name);
        ep_raise_error_if_nok (instance->provider_name != NULL);
 
-       instance->provider_name_utf16 = ep_rt_utf8_to_utf16_string (provider_name, -1);
+       instance->provider_name_utf16 = ep_rt_utf8_to_utf16le_string (provider_name, -1);
        ep_raise_error_if_nok (instance->provider_name_utf16 != NULL);
 
        ep_rt_event_list_alloc (&instance->event_list);
index 8684e15..efd681f 100644 (file)
@@ -151,6 +151,45 @@ prefix_name ## _rt_ ## type_name ## _ ## func_name
 #define EP_RT_DEFINE_HASH_MAP_ITERATOR ep_rt_redefine
 
 /*
+ * Little-Endian Conversion.
+ */
+
+static
+inline
+uint16_t
+ep_rt_val_uint16_t (uint16_t value);
+
+static
+inline
+uint32_t
+ep_rt_val_uint32_t (uint32_t value);
+
+static
+inline
+uint64_t
+ep_rt_val_uint64_t (uint64_t value);
+
+static
+inline
+int16_t
+ep_rt_val_int16_t (int16_t value);
+
+static
+inline
+int32_t
+ep_rt_val_int32_t (int32_t value);
+
+static
+inline
+int64_t
+ep_rt_val_int64_t (int64_t value);
+
+static
+inline
+uintptr_t
+ep_rt_val_uintptr_t (uintptr_t value);
+
+/*
 * Atomics.
 */
 
@@ -725,7 +764,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);
 
@@ -748,6 +787,12 @@ ep_rt_utf16_to_utf8_string (
        size_t len);
 
 static
+ep_char8_t *
+ep_rt_utf16le_to_utf8_string (
+       const ep_char16_t *str,
+       size_t len);
+
+static
 void
 ep_rt_utf16_string_free (ep_char16_t *str);
 
index bf82c02..b006bae 100644 (file)
@@ -4,6 +4,7 @@
 #include "ep-rt-config.h"
 
 #ifdef ENABLE_PERFTRACING
+#include "ep-rt.h"
 #include "ep-types.h"
 
 #undef EP_IMPL_GETTER_SETTER
@@ -109,7 +110,7 @@ ep_stack_contents_append (
        EP_ASSERT (stack_contents != NULL);
        uint32_t next_frame = ep_stack_contents_get_next_available_frame (stack_contents);
        if (next_frame < EP_MAX_STACK_DEPTH) {
-               ep_stack_contents_get_stack_frames_ref (stack_contents)[next_frame] = control_pc;
+               ep_stack_contents_get_stack_frames_ref (stack_contents)[next_frame] = ep_rt_val_uintptr_t (control_pc);
 #ifdef EP_CHECKED_BUILD
                ep_stack_contents_get_methods_ref (stack_contents)[next_frame] = method;
 #endif
index 3f35516..cad5516 100644 (file)
@@ -136,24 +136,22 @@ static
 void
 fast_serializer_write_serialization_type (
        FastSerializer *fast_serializer,
-       FastSerializableObject *fast_serializable_ojbect)
+       FastSerializableObject *fast_serializable_object)
 {
-       EP_ASSERT (fast_serializable_ojbect != NULL);
+       EP_ASSERT (fast_serializable_object != NULL);
 
        // Write the BeginObject tag.
-       ep_fast_serializer_write_tag (fast_serializer, fast_serializable_ojbect->is_private ? FAST_SERIALIZER_TAGS_BEGIN_PRIVATE_OBJECT : FAST_SERIALIZER_TAGS_BEGIN_OBJECT, NULL, 0);
+       ep_fast_serializer_write_tag (fast_serializer, fast_serializable_object->is_private ? FAST_SERIALIZER_TAGS_BEGIN_PRIVATE_OBJECT : FAST_SERIALIZER_TAGS_BEGIN_OBJECT, NULL, 0);
 
        // Write a NullReferenceTag, which implies that the following fields belong to SerializationType.
        ep_fast_serializer_write_tag (fast_serializer, FAST_SERIALIZER_TAGS_NULL_REFERENCE, NULL, 0);
 
        // Write the SerializationType version fields.
-       int32_t serialization_type [2];
-       serialization_type [0] = fast_serializable_ojbect->object_version;
-       serialization_type [1] = fast_serializable_ojbect->min_reader_version;
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)serialization_type, sizeof (serialization_type));
+       ep_fast_serializer_write_int32_t (fast_serializer, fast_serializable_object->object_version);
+       ep_fast_serializer_write_int32_t (fast_serializer, fast_serializable_object->min_reader_version);
 
        // Write the SerializationType TypeName field.
-       const ep_char8_t *type_name = ep_fast_serializable_object_get_type_name_vcall (fast_serializable_ojbect);
+       const ep_char8_t *type_name = ep_fast_serializable_object_get_type_name_vcall (fast_serializable_object);
        if (type_name)
                ep_fast_serializer_write_string (fast_serializer, type_name, (uint32_t)strlen (type_name));
 
@@ -225,6 +223,28 @@ ep_fast_serializer_write_buffer (
 }
 
 void
+ep_fast_serializer_write_system_time (
+       FastSerializer *fast_serializer,
+       const EventPipeSystemTime *system_time)
+{
+       EP_ASSERT (fast_serializer != NULL);
+       EP_ASSERT (system_time != NULL);
+
+#if BIGENDIAN
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->year);
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->month);
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->day_of_week);
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->day);
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->hour);
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->minute);
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->second);
+       ep_fast_serializer_write_uint16_t (fast_serializer, system_time->milliseconds);
+#else
+       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)system_time, sizeof (*system_time));
+#endif
+}
+
+void
 ep_fast_serializer_write_object (
        FastSerializer *fast_serializer,
        FastSerializableObject *fast_serializable_ojbect)
@@ -249,7 +269,7 @@ ep_fast_serializer_write_string (
        uint32_t contents_len)
 {
        // Write the string length.
-       ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)&contents_len, sizeof (contents_len));
+       ep_fast_serializer_write_uint32_t (fast_serializer, contents_len);
 
        //Wirte the string contents.
        ep_fast_serializer_write_buffer (fast_serializer, (const uint8_t *)contents, contents_len);
index 4e4215e..52c1023 100644 (file)
@@ -186,6 +186,42 @@ ep_fast_serializer_write_buffer (
        const uint8_t *buffer,
        uint32_t buffer_len);
 
+#define EP_FAST_SERIALIZER_WRITE_INT(BITS, SIGNEDNESS) \
+static \
+inline \
+void \
+ep_fast_serializer_write_##SIGNEDNESS##int##BITS##_t ( \
+       FastSerializer *fast_serializer, \
+       SIGNEDNESS##int##BITS##_t value) \
+{ \
+       value = ep_rt_val_##SIGNEDNESS##int##BITS##_t (value); \
+       ep_fast_serializer_write_buffer (fast_serializer, (uint8_t *)&value, sizeof (value)); \
+}
+
+EP_FAST_SERIALIZER_WRITE_INT (16, )
+EP_FAST_SERIALIZER_WRITE_INT (16, u)
+EP_FAST_SERIALIZER_WRITE_INT (32, )
+EP_FAST_SERIALIZER_WRITE_INT (32, u)
+EP_FAST_SERIALIZER_WRITE_INT (64, )
+EP_FAST_SERIALIZER_WRITE_INT (64, u)
+
+#undef EP_FAST_SERIALIZER_WRITE_INT
+
+static
+inline
+void
+ep_fast_serializer_write_timestamp (
+       FastSerializer *fast_serializer,
+       ep_timestamp_t value)
+{
+       ep_fast_serializer_write_int64_t (fast_serializer, value);
+}
+
+void
+ep_fast_serializer_write_system_time (
+       FastSerializer *fast_serializer,
+       const EventPipeSystemTime *system_time);
+
 void
 ep_fast_serializer_write_object (
        FastSerializer *fast_serializer,
index daeaa8d..29176c5 100644 (file)
@@ -288,6 +288,56 @@ ep_system_time_get (EventPipeSystemTime *system_time)
 void
 ep_ipc_stream_factory_callback_set (EventPipeIpcStreamFactorySuspendedPortsCallback suspended_ports_callback);
 
+/*
+ * EventPipeWriteBuffer.
+ */
+
+static
+inline
+void
+ep_write_buffer_uint8_t (uint8_t **buffer, uint8_t value)
+{
+       memcpy (*buffer, &value, sizeof (value));
+       *buffer += sizeof (value);
+}
+
+#define EP_WRITE_BUFFER_INT(BITS, SIGNEDNESS) \
+static \
+inline \
+void \
+ep_write_buffer_##SIGNEDNESS##int##BITS##_t (uint8_t **buffer, SIGNEDNESS##int##BITS##_t value) \
+{ \
+       value = ep_rt_val_##SIGNEDNESS##int##BITS##_t (value); \
+       memcpy (*buffer, &value, sizeof (value)); \
+       *buffer += sizeof (value); \
+}
+
+EP_WRITE_BUFFER_INT (16, )
+EP_WRITE_BUFFER_INT (16, u)
+EP_WRITE_BUFFER_INT (32, )
+EP_WRITE_BUFFER_INT (32, u)
+EP_WRITE_BUFFER_INT (64, )
+EP_WRITE_BUFFER_INT (64, u)
+
+#undef EP_WRITE_BUFFER_INT
+
+static
+inline
+void
+ep_write_buffer_string_utf16_t (uint8_t **buf, const ep_char16_t *str, size_t len)
+{
+       memcpy (*buf, str, len);
+       *buf += len;
+}
+
+static
+inline
+void
+ep_write_buffer_timestamp (uint8_t **buffer, ep_timestamp_t value)
+{
+       ep_write_buffer_int64_t (buffer, value);
+}
+
 #else /* ENABLE_PERFTRACING */
 
 static