in src/LttngHelpers.c [976:1166]
static int EventProbeComputeSizes(
struct lttngh_EventProbeContext* pContext,
struct lttngh_DataDesc* pDataDesc,
unsigned cDataDesc)
lttng_ust_notrace;
static int EventProbeComputeSizes(
struct lttngh_EventProbeContext* pContext,
struct lttngh_DataDesc* pDataDesc,
unsigned cDataDesc)
{
unsigned cbTranscodeWanted = 0;
pContext->maxAlign = 1;
assert(pContext->cbData == 0);
unsigned i;
for (i = 0; i != cDataDesc; i += 1)
{
switch (pDataDesc[i].Type)
{
case lttngh_DataType_StringUtf16Transcoded:
case lttngh_DataType_StringUtf32Transcoded:
{
unsigned cbUtf8;
if (pDataDesc[i].Type == lttngh_DataType_StringUtf16Transcoded)
{
unsigned cch16 = (unsigned)(pDataDesc[i].Size / sizeof(char16_t));
assert(cch16 != 0); // Error in caller - Size should have included NUL.
cch16 -= 1; // Do not count NUL.
if (caa_unlikely(cch16 > 65535))
{
if (cch16 == ~0u)
{
cch16 = 0; // Error in caller - Size was 0.
}
else
{
cch16 = 65535;
}
}
cbUtf8 = Utf16ToUtf8Size((char16_t const*)pDataDesc[i].Data, cch16);
}
else
{
unsigned cch32 = (unsigned)(pDataDesc[i].Size / sizeof(char32_t));
assert(cch32 != 0); // Error in caller - Size should have included NUL.
cch32 -= 1; // Do not count NUL.
if (caa_unlikely(cch32 > 65535))
{
if (cch32 == ~0u)
{
cch32 = 0; // Error in caller - Size was 0.
}
else
{
cch32 = 65535;
}
}
cbUtf8 = Utf32ToUtf8Size((char32_t const*)pDataDesc[i].Data, cch32);
}
if (caa_unlikely(cbUtf8 > 65535))
{
cbUtf8 = 65535;
}
// Use DataDesc.Length as scratch space to store utf-8 content size.
pDataDesc[i].Length = (uint16_t)cbUtf8; // Does not count NUL.
cbUtf8 += 1; // Include room for 8-bit NUL.
if (caa_unlikely(cbTranscodeWanted < cbUtf8))
{
cbTranscodeWanted = cbUtf8;
}
pContext->cbData += cbUtf8;
if (caa_unlikely(pContext->cbData < cbUtf8))
{
return EOVERFLOW;
}
break;
}
case lttngh_DataType_SequenceUtf16Transcoded:
case lttngh_DataType_SequenceUtf32Transcoded:
{
#if lttngh_UST_RING_BUFFER_NATURAL_ALIGN
if (__alignof__(uint16_t) > pContext->maxAlign)
{
pContext->maxAlign = __alignof__(uint16_t);
}
unsigned const alignAdjust =
lib_ring_buffer_align(pContext->cbData, __alignof__(uint16_t));
pContext->cbData += alignAdjust;
if (caa_unlikely(pContext->cbData < alignAdjust))
{
return EOVERFLOW;
}
#endif // lttngh_UST_RING_BUFFER_NATURAL_ALIGN
unsigned cbUtf8;
if (pDataDesc[i].Type == lttngh_DataType_SequenceUtf16Transcoded)
{
unsigned cch16 = (unsigned)(pDataDesc[i].Size / sizeof(char16_t));
if (caa_unlikely(cch16 > 65535))
{
cch16 = 65535;
}
cbUtf8 = Utf16ToUtf8Size((char16_t const*)pDataDesc[i].Data, cch16);
}
else
{
unsigned cch32 = (unsigned)(pDataDesc[i].Size / sizeof(char32_t));
if (caa_unlikely(cch32 > 65535))
{
cch32 = 65535;
}
cbUtf8 = Utf32ToUtf8Size((char32_t const*)pDataDesc[i].Data, cch32);
}
if (caa_unlikely(cbUtf8 > 65535))
{
cbUtf8 = 65535;
}
// Use DataDesc.Length as scratch space to store utf-8 content size.
pDataDesc[i].Length = (uint16_t)cbUtf8;
cbUtf8 += 2; // Include room for 16-bit length.
if (caa_unlikely(cbTranscodeWanted < cbUtf8))
{
cbTranscodeWanted = cbUtf8;
}
pContext->cbData += cbUtf8;
if (caa_unlikely(pContext->cbData < cbUtf8))
{
return EOVERFLOW;
}
break;
}
default:
{
#if lttngh_UST_RING_BUFFER_NATURAL_ALIGN
if (pDataDesc[i].Alignment > pContext->maxAlign)
{
pContext->maxAlign = pDataDesc[i].Alignment;
}
unsigned const alignAdjust =
lib_ring_buffer_align(pContext->cbData, pDataDesc[i].Alignment);
pContext->cbData += alignAdjust;
if (caa_unlikely(pContext->cbData < alignAdjust))
{
return EOVERFLOW;
}
#endif // lttngh_UST_RING_BUFFER_NATURAL_ALIGN
pContext->cbData += pDataDesc[i].Size;
if (pContext->cbData < pDataDesc[i].Size)
{
return EOVERFLOW;
}
break;
}
}
}
// If our scratch buffer is too small, try to heap allocate.
if (caa_unlikely(pContext->cbTranscodeScratch < cbTranscodeWanted))
{
unsigned char* pbTranscodeWanted = (unsigned char*)malloc(cbTranscodeWanted);
if (caa_unlikely(pbTranscodeWanted == NULL))
{
return ENOMEM;
}
pContext->cbTranscodeScratch = cbTranscodeWanted;
pContext->pbTranscodeScratch = pbTranscodeWanted;
}
return 0;
}