Skip to content

Commit 136dfcd

Browse files
[mono][eventpipe] Write primitive types and UTF-16 strings in little endian order (#68648)
* [mono][eventpipe] Add big-endian support.
1 parent 15f67a2 commit 136dfcd

25 files changed

+552
-144
lines changed

src/coreclr/scripts/genEventPipe.py

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,20 @@ def generateClrEventPipeWriteEventsImpl(
239239

240240

241241
def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
242+
def winTypeToFixedWidthType(t):
243+
return {'win:Int8': 'int8_t',
244+
'win:UInt8': 'uint8_t',
245+
'win:Int16': 'int16_t',
246+
'win:UInt16': 'uint16_t',
247+
'win:Int32': 'int32_t',
248+
'win:UInt32': 'uint32_t',
249+
'win:Int64': 'int64_t',
250+
'win:UInt64': 'uint64_t',
251+
'win:Pointer': 'uintptr_t',
252+
'win:AnsiString': 'UTF8String',
253+
'win:UnicodeString': 'UTF16String'
254+
}[t]
255+
242256
fnSig = template.signature
243257
pack_list = []
244258

@@ -267,9 +281,33 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
267281
if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
268282
size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
269283
if runtimeFlavor.mono:
284+
pack_list.append("#if BIGENDIAN")
285+
pack_list.append(" const uint8_t *valuePtr = %s;" % paramName)
286+
pack_list.append(" for (uint32_t i = 0; i < %s; ++i) {" % template.structs[paramName])
287+
types = [winTypeToFixedWidthType(t) for t in template.structTypes[paramName]]
288+
for t in set(types) - {"UTF8String", "UTF16String"}:
289+
pack_list.append(" %(type)s value_%(type)s;" % {'type': t})
290+
if "UTF8String" in types or "UTF16String" in types:
291+
pack_list.append(" size_t value_len;")
292+
for t in types:
293+
if t == "UTF8String":
294+
pack_list.append(" value_len = strlen((const char *)valuePtr);")
295+
pack_list.append(" success &= write_buffer_string_utf8_t((const ep_char8_t *)valuePtr, value_len, &buffer, &offset, &size, &fixedBuffer);")
296+
pack_list.append(" valuePtr += value_len + 1;")
297+
elif t == "UTF16String":
298+
pack_list.append(" value_len = strlen((const char *)valuePtr);")
299+
pack_list.append(" success &= write_buffer_string_utf8_to_utf16_t((const ep_char8_t *)valuePtr, value_len, &buffer, &offset, &size, &fixedBuffer);")
300+
pack_list.append(" valuePtr += value_len + 1;")
301+
else:
302+
pack_list.append(" memcpy (&value_%(type)s, valuePtr, sizeof (value_%(type)s));" % {'type': t})
303+
pack_list.append(" valuePtr += sizeof (%s);" % t)
304+
pack_list.append(" success &= write_buffer_%(type)s (value_%(type)s, &buffer, &offset, &size, &fixedBuffer);" % {'type': t})
305+
pack_list.append(" }")
306+
pack_list.append("#else")
270307
pack_list.append(
271308
" success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" %
272309
(paramName, size))
310+
pack_list.append("#endif // BIGENDIAN")
273311
emittedWriteToBuffer = True
274312
elif runtimeFlavor.coreclr:
275313
pack_list.append(
@@ -283,9 +321,16 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
283321
if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
284322
size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
285323
if runtimeFlavor.mono:
324+
t = winTypeToFixedWidthType(parameter.winType)
325+
pack_list.append("#if BIGENDIAN")
326+
pack_list.append(" for (uint32_t i = 0; i < %s; ++i) {" % template.arrays[paramName])
327+
pack_list.append(" success &= write_buffer_%(type)s (%(name)s[i], &buffer, &offset, &size, &fixedBuffer);" % {'name': paramName, 'type': t})
328+
pack_list.append(" }")
329+
pack_list.append("#else")
286330
pack_list.append(
287331
" success &= write_buffer((const uint8_t *)%s, %s, &buffer, &offset, &size, &fixedBuffer);" %
288332
(paramName, size))
333+
pack_list.append("#endif // BIGENDIAN")
289334
emittedWriteToBuffer = True
290335
elif runtimeFlavor.coreclr:
291336
pack_list.append(
@@ -304,13 +349,13 @@ def generateWriteEventBody(template, providerName, eventName, runtimeFlavor):
304349
emittedWriteToBuffer = True
305350
elif parameter.winType == "win:AnsiString" and runtimeFlavor.mono:
306351
pack_list.append(
307-
" success &= write_buffer_string_utf8_t(%s, &buffer, &offset, &size, &fixedBuffer);" %
308-
(parameter.name,))
352+
" success &= write_buffer_string_utf8_t(%s, strlen((const char *)%s), &buffer, &offset, &size, &fixedBuffer);" %
353+
(parameter.name, parameter.name))
309354
emittedWriteToBuffer = True
310355
elif parameter.winType == "win:UnicodeString" and runtimeFlavor.mono:
311356
pack_list.append(
312-
" success &= write_buffer_string_utf8_to_utf16_t(%s, &buffer, &offset, &size, &fixedBuffer);" %
313-
(parameter.name,))
357+
" success &= write_buffer_string_utf8_to_utf16_t(%s, strlen((const char *)%s), &buffer, &offset, &size, &fixedBuffer);" %
358+
(parameter.name, parameter.name))
314359
emittedWriteToBuffer = True
315360
elif parameter.winType == "win:UInt8" and runtimeFlavor.mono:
316361
pack_list.append(
@@ -558,6 +603,7 @@ def getMonoEventPipeHelperFileImplPrefix():
558603
bool
559604
write_buffer_string_utf8_to_utf16_t (
560605
const ep_char8_t *value,
606+
size_t value_len,
561607
uint8_t **buffer,
562608
size_t *offset,
563609
size_t *size,
@@ -566,6 +612,7 @@ def getMonoEventPipeHelperFileImplPrefix():
566612
bool
567613
write_buffer_string_utf8_t (
568614
const ep_char8_t *value,
615+
size_t value_len,
569616
uint8_t **buffer,
570617
size_t *offset,
571618
size_t *size,
@@ -640,6 +687,7 @@ def getMonoEventPipeHelperFileImplPrefix():
640687
bool
641688
write_buffer_string_utf8_to_utf16_t (
642689
const ep_char8_t *value,
690+
size_t value_len,
643691
uint8_t **buffer,
644692
size_t *offset,
645693
size_t *size,
@@ -653,12 +701,12 @@ def getMonoEventPipeHelperFileImplPrefix():
653701
custom_alloc_data.buffer_size = *size - *offset;
654702
custom_alloc_data.req_buffer_size = 0;
655703
656-
if (!g_utf8_to_utf16_custom_alloc (value, -1, NULL, NULL, g_fixed_buffer_custom_allocator, &custom_alloc_data, NULL)) {
704+
if (!g_utf8_to_utf16le_custom_alloc (value, (glong)value_len, NULL, NULL, g_fixed_buffer_custom_allocator, &custom_alloc_data, NULL)) {
657705
ep_raise_error_if_nok (resize_buffer (buffer, size, *offset, *size + custom_alloc_data.req_buffer_size, fixed_buffer));
658706
custom_alloc_data.buffer = *buffer + *offset;
659707
custom_alloc_data.buffer_size = *size - *offset;
660708
custom_alloc_data.req_buffer_size = 0;
661-
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);
709+
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);
662710
}
663711
664712
*offset += custom_alloc_data.req_buffer_size;
@@ -671,6 +719,7 @@ def getMonoEventPipeHelperFileImplPrefix():
671719
bool
672720
write_buffer_string_utf8_t (
673721
const ep_char8_t *value,
722+
size_t value_len,
674723
uint8_t **buffer,
675724
size_t *offset,
676725
size_t *size,
@@ -679,10 +728,6 @@ def getMonoEventPipeHelperFileImplPrefix():
679728
if (!value)
680729
return true;
681730
682-
size_t value_len = 0;
683-
while (value [value_len])
684-
value_len++;
685-
686731
return write_buffer ((const uint8_t *)value, (value_len + 1) * sizeof(*value), buffer, offset, size, fixed_buffer);
687732
}
688733
@@ -802,6 +847,7 @@ def getMonoEventPipeImplFilePrefix():
802847
bool
803848
write_buffer_string_utf8_t (
804849
const ep_char8_t *value,
850+
size_t value_len,
805851
uint8_t **buffer,
806852
size_t *offset,
807853
size_t *size,
@@ -810,6 +856,7 @@ def getMonoEventPipeImplFilePrefix():
810856
bool
811857
write_buffer_string_utf8_to_utf16_t (
812858
const ep_char8_t *value,
859+
size_t value_len,
813860
uint8_t **buffer,
814861
size_t *offset,
815862
size_t *size,
@@ -851,6 +898,7 @@ def getMonoEventPipeImplFilePrefix():
851898
size_t *size,
852899
bool *fixed_buffer)
853900
{
901+
value = ep_rt_val_uint16_t (value);
854902
return write_buffer ((const uint8_t *)&value, sizeof (uint16_t), buffer, offset, size, fixed_buffer);
855903
}
856904
@@ -864,6 +912,7 @@ def getMonoEventPipeImplFilePrefix():
864912
size_t *size,
865913
bool *fixed_buffer)
866914
{
915+
value = ep_rt_val_uint32_t (value);
867916
return write_buffer ((const uint8_t *)&value, sizeof (uint32_t), buffer, offset, size, fixed_buffer);
868917
}
869918
@@ -877,6 +926,7 @@ def getMonoEventPipeImplFilePrefix():
877926
size_t *size,
878927
bool *fixed_buffer)
879928
{
929+
value = ep_rt_val_int32_t (value);
880930
return write_buffer ((const uint8_t *)&value, sizeof (int32_t), buffer, offset, size, fixed_buffer);
881931
}
882932
@@ -890,6 +940,7 @@ def getMonoEventPipeImplFilePrefix():
890940
size_t *size,
891941
bool *fixed_buffer)
892942
{
943+
value = ep_rt_val_uint64_t (value);
893944
return write_buffer ((const uint8_t *)&value, sizeof (uint64_t), buffer, offset, size, fixed_buffer);
894945
}
895946
@@ -903,6 +954,7 @@ def getMonoEventPipeImplFilePrefix():
903954
size_t *size,
904955
bool *fixed_buffer)
905956
{
957+
value = ep_rt_val_int64_t (value);
906958
return write_buffer ((const uint8_t *)&value, sizeof (int64_t), buffer, offset, size, fixed_buffer);
907959
}
908960
@@ -916,6 +968,12 @@ def getMonoEventPipeImplFilePrefix():
916968
size_t *size,
917969
bool *fixed_buffer)
918970
{
971+
#if BIGENDIAN
972+
uint64_t value_as_uint64_t;
973+
memcpy (&value_as_uint64_t, &value, sizeof (uint64_t));
974+
value_as_uint64_t = ep_rt_val_uint64_t (value_as_uint64_t);
975+
memcpy (&value, &value_as_uint64_t, sizeof (uint64_t));
976+
#endif
919977
return write_buffer ((const uint8_t *)&value, sizeof (double), buffer, offset, size, fixed_buffer);
920978
}
921979
@@ -942,6 +1000,7 @@ def getMonoEventPipeImplFilePrefix():
9421000
size_t *size,
9431001
bool *fixed_buffer)
9441002
{
1003+
value = ep_rt_val_uintptr_t (value);
9451004
return write_buffer ((const uint8_t *)&value, sizeof (uintptr_t), buffer, offset, size, fixed_buffer);
9461005
}
9471006

src/coreclr/scripts/genEventing.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,10 +188,11 @@ class Template:
188188
def __repr__(self):
189189
return "<Template " + self.name + ">"
190190

191-
def __init__(self, templateName, fnPrototypes, dependencies, structSizes, arrays):
191+
def __init__(self, templateName, fnPrototypes, dependencies, structSizes, structTypes, arrays):
192192
self.name = templateName
193193
self.signature = FunctionSignature()
194194
self.structs = structSizes
195+
self.structTypes = structTypes
195196
self.arrays = arrays
196197

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

274275
for templateNode in templateNodes:
275276
structCounts = {}
277+
structTypes = {}
276278
arrays = {}
277279
templateName = templateNode.getAttribute('tid')
278280
var_Dependencies = {}
@@ -337,11 +339,12 @@ def parseTemplateNodes(templateNodes):
337339
types = [x.attributes['inType'].value for x in structToBeMarshalled.getElementsByTagName("data")]
338340

339341
structCounts[structName] = countVarName
342+
structTypes[structName] = types
340343
var_Dependencies[structName] = [countVarName, structName]
341344
fnparam_pointer = FunctionParameter("win:Struct", structName, "win:count", countVarName)
342345
fnPrototypes.append(structName, fnparam_pointer)
343346

344-
allTemplates[templateName] = Template(templateName, fnPrototypes, var_Dependencies, structCounts, arrays)
347+
allTemplates[templateName] = Template(templateName, fnPrototypes, var_Dependencies, structCounts, structTypes, arrays)
345348

346349
return allTemplates
347350

src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,66 @@ ep_rt_runtime_version_get_utf8 (void)
11491149
return reinterpret_cast<const ep_char8_t*>(CLR_PRODUCT_VERSION);
11501150
}
11511151

1152+
/*
1153+
* Little-Endian Conversion.
1154+
*/
1155+
1156+
static
1157+
EP_ALWAYS_INLINE
1158+
uint16_t
1159+
ep_rt_val_uint16_t (uint16_t value)
1160+
{
1161+
return value;
1162+
}
1163+
1164+
static
1165+
EP_ALWAYS_INLINE
1166+
uint32_t
1167+
ep_rt_val_uint32_t (uint32_t value)
1168+
{
1169+
return value;
1170+
}
1171+
1172+
static
1173+
EP_ALWAYS_INLINE
1174+
uint64_t
1175+
ep_rt_val_uint64_t (uint64_t value)
1176+
{
1177+
return value;
1178+
}
1179+
1180+
static
1181+
EP_ALWAYS_INLINE
1182+
int16_t
1183+
ep_rt_val_int16_t (int16_t value)
1184+
{
1185+
return value;
1186+
}
1187+
1188+
static
1189+
EP_ALWAYS_INLINE
1190+
int32_t
1191+
ep_rt_val_int32_t (int32_t value)
1192+
{
1193+
return value;
1194+
}
1195+
1196+
static
1197+
EP_ALWAYS_INLINE
1198+
int64_t
1199+
ep_rt_val_int64_t (int64_t value)
1200+
{
1201+
return value;
1202+
}
1203+
1204+
static
1205+
EP_ALWAYS_INLINE
1206+
uintptr_t
1207+
ep_rt_val_uintptr_t (uintptr_t value)
1208+
{
1209+
return value;
1210+
}
1211+
11521212
/*
11531213
* Atomics.
11541214
*/
@@ -2154,7 +2214,7 @@ ep_rt_file_open_write (const ep_char8_t *path)
21542214
{
21552215
STATIC_CONTRACT_NOTHROW;
21562216

2157-
ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16_string (path, -1);
2217+
ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16le_string (path, -1);
21582218
ep_return_null_if_nok (path_utf16 != NULL);
21592219

21602220
CFileStream *file_stream = new (nothrow) CFileStream ();
@@ -2542,7 +2602,7 @@ ep_rt_utf8_string_replace (
25422602

25432603
static
25442604
ep_char16_t *
2545-
ep_rt_utf8_to_utf16_string (
2605+
ep_rt_utf8_to_utf16le_string (
25462606
const ep_char8_t *str,
25472607
size_t len)
25482608
{
@@ -2643,6 +2703,16 @@ ep_rt_utf16_to_utf8_string (
26432703
return str_utf8;
26442704
}
26452705

2706+
static
2707+
inline
2708+
ep_char8_t *
2709+
ep_rt_utf16le_to_utf8_string (
2710+
const ep_char16_t *str,
2711+
size_t len)
2712+
{
2713+
return ep_rt_utf16_to_utf8_string (str, len);
2714+
}
2715+
26462716
static
26472717
inline
26482718
void

0 commit comments

Comments
 (0)