static int EventProbeFilter()

in src/LttngHelpers.c [560:966]


static int EventProbeFilter(
    lttngh_ust_event_common const *pEvent,
#if lttngh_UST_VER >= 213
    void* pCallerIp,
#endif
    struct lttngh_DataDesc const *pDataDesc,
    unsigned cDataDesc)
    lttng_ust_notrace;
static int EventProbeFilter(
    lttngh_ust_event_common const *pEvent,
#if lttngh_UST_VER >= 213
    void* pCallerIp,
#endif
    struct lttngh_DataDesc const *pDataDesc,
    unsigned cDataDesc)
{
    int enableRecorder;
    unsigned cbBuffer;
    unsigned i;

    cbBuffer = 0;
    for (i = 0; i != cDataDesc; i += 1)
    {
        switch (pDataDesc[i].Type)
        {
        case lttngh_DataType_None:
            break;
        case lttngh_DataType_SignedLE:
        case lttngh_DataType_SignedBE:
            cbBuffer += (unsigned)sizeof(int64_t);
            break;
        case lttngh_DataType_UnsignedLE:
        case lttngh_DataType_UnsignedBE:
            cbBuffer += (unsigned)sizeof(uint64_t);
            break;
        case lttngh_DataType_FloatLE:
        case lttngh_DataType_FloatBE:
            cbBuffer += (unsigned)sizeof(double);
            break;
        case lttngh_DataType_String8:
        case lttngh_DataType_StringUtf16Transcoded:
        case lttngh_DataType_StringUtf32Transcoded:
#if lttngh_UST_VER >= 213
        case lttngh_DataType_Counted:
#endif
            cbBuffer += (unsigned)sizeof(void *);
            break;
#if lttngh_UST_VER < 213
        case lttngh_DataType_Counted:
#endif
        case lttngh_DataType_SequenceUtf16Transcoded:
        case lttngh_DataType_SequenceUtf32Transcoded:
            cbBuffer += (unsigned)(sizeof(unsigned long) + sizeof(void *));
            break;
        default:
            abort();
            break;
        }
    }

    // Scope for VLA
    {
        char stackData[cbBuffer] __attribute__((aligned(sizeof(size_t)))); // VLA
        char *pStackData = stackData;

        for (i = 0; i != cDataDesc; i += 1)
        {
            switch (pDataDesc[i].Type)
            {
            case lttngh_DataType_None:
                break;
            case lttngh_DataType_Signed:
            {
                switch (pDataDesc[i].Size)
                {
                case 1:
                {
                    int64_t val;
                    val = *(int8_t const *)pDataDesc[i].Data; // Sign-extend
                    memcpy(pStackData, &val, sizeof(int64_t));
                    break;
                }
                case 2:
                {
                    int64_t val;
                    int16_t tempVal;
                    memcpy(&tempVal, pDataDesc[i].Data, sizeof(tempVal));
                    val = tempVal; // Sign-extend
                    memcpy(pStackData, &val, sizeof(int64_t));
                    break;
                }
                case 4:
                {
                    int64_t val;
                    int32_t tempVal;
                    memcpy(&tempVal, pDataDesc[i].Data, sizeof(tempVal));
                    val = tempVal; // Sign-extend
                    memcpy(pStackData, &val, sizeof(int64_t));
                    break;
                }
                case 8:
                {
                    memcpy(pStackData, pDataDesc[i].Data, sizeof(int64_t));
                    break;
                }
                default:
                    abort();
                    break;
                }
                pStackData += sizeof(int64_t);
                break;
            }
            case (lttngh_DataType_Signed == lttngh_DataType_SignedLE
                ? lttngh_DataType_SignedBE
                : lttngh_DataType_SignedLE):
                {
                    switch (pDataDesc[i].Size)
                    {
                    case 1:
                    {
                        int64_t val;
                        val = *(int8_t const *)pDataDesc[i].Data; // Sign-extend
                        memcpy(pStackData, &val, sizeof(int64_t));
                        break;
                    }
                    case 2:
                    {
                        int64_t val;
                        int16_t tempVal;
                        uint16_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_16(tempValSwap);
                        memcpy(&tempVal, &tempValSwap, sizeof(tempVal));
                        val = tempVal; // Sign-extend
                        memcpy(pStackData, &val, sizeof(int64_t));
                        break;
                    }
                    case 4:
                    {
                        int64_t val;
                        int32_t tempVal;
                        uint32_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_32(tempValSwap);
                        memcpy(&tempVal, &tempValSwap, sizeof(tempVal));
                        val = tempVal; // Sign-extend
                        memcpy(pStackData, &val, sizeof(int64_t));
                        break;
                    }
                    case 8:
                    {
                        uint64_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_64(tempValSwap);
                        memcpy(pStackData, &tempValSwap, sizeof(int64_t));
                        break;
                    }
                    default:
                        abort();
                        break;
                    }
                    pStackData += sizeof(int64_t);
                    break;
                }
            case lttngh_DataType_Unsigned:
            {
                switch (pDataDesc[i].Size)
                {
                case 1:
                {
                    uint64_t val;
                    val = *(uint8_t const *)pDataDesc[i].Data; // Zero-extend
                    memcpy(pStackData, &val, sizeof(uint64_t));
                    break;
                }
                case 2:
                {
                    uint64_t val;
                    uint16_t tempVal;
                    memcpy(&tempVal, pDataDesc[i].Data, sizeof(tempVal));
                    val = tempVal; // Zero-extend
                    memcpy(pStackData, &val, sizeof(uint64_t));
                    break;
                }
                case 4:
                {
                    uint64_t val;
                    uint32_t tempVal;
                    memcpy(&tempVal, pDataDesc[i].Data, sizeof(tempVal));
                    val = tempVal; // Zero-extend
                    memcpy(pStackData, &val, sizeof(uint64_t));
                    break;
                }
                case 8:
                {
                    memcpy(pStackData, pDataDesc[i].Data, sizeof(uint64_t));
                    break;
                }
                default:
                    abort();
                    break;
                }
                pStackData += sizeof(uint64_t);
                break;
            }
            case (lttngh_DataType_Unsigned == lttngh_DataType_UnsignedLE
                ? lttngh_DataType_UnsignedBE
                : lttngh_DataType_UnsignedLE):
                {
                    switch (pDataDesc[i].Size)
                    {
                    case 1:
                    {
                        uint64_t val;
                        val = *(uint8_t const *)pDataDesc[i].Data; // Zero-extend
                        memcpy(pStackData, &val, sizeof(uint64_t));
                        break;
                    }
                    case 2:
                    {
                        uint64_t val;
                        uint16_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_16(tempValSwap);
                        val = tempValSwap; // Zero-extend
                        memcpy(pStackData, &val, sizeof(uint64_t));
                        break;
                    }
                    case 4:
                    {
                        uint64_t val;
                        uint32_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_32(tempValSwap);
                        val = tempValSwap; // Zero-extend
                        memcpy(pStackData, &val, sizeof(uint64_t));
                        break;
                    }
                    case 8:
                    {
                        uint64_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_64(tempValSwap);
                        memcpy(pStackData, &tempValSwap, sizeof(uint64_t));
                        break;
                    }
                    default:
                        abort();
                        break;
                    }
                    pStackData += sizeof(uint64_t);
                    break;
                }
            case lttngh_DataType_Float:
            {
                if (pDataDesc[i].Size == sizeof(float))
                {
                    double val;
                    float tempVal;
                    memcpy(&tempVal, pDataDesc[i].Data, sizeof(tempVal));
                    val = tempVal; // Convert
                    memcpy(pStackData, &val, sizeof(double));
                }
                else if (pDataDesc[i].Size == sizeof(double))
                {
                    memcpy(pStackData, pDataDesc[i].Data, sizeof(double));
                }
                else if (pDataDesc[i].Size == sizeof(long double))
                {
                    double val;
                    long double tempVal;
                    memcpy(&tempVal, pDataDesc[i].Data, sizeof(tempVal));
                    val = (double)tempVal; // Convert
                    memcpy(pStackData, &val, sizeof(double));
                }
                else
                {
                    abort();
                }
                pStackData += sizeof(double);
                break;
            }
            case (lttngh_DataType_Float == lttngh_DataType_FloatLE
                ? lttngh_DataType_FloatBE
                : lttngh_DataType_FloatLE):
                {
                    if (pDataDesc[i].Size == sizeof(float))
                    {
                        double val;
                        float tempVal;
                        uint32_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_32(tempValSwap);
                        memcpy(&tempVal, &tempValSwap, sizeof(tempVal));
                        val = tempVal; // Convert
                        memcpy(pStackData, &val, sizeof(double));
                    }
                    else if (pDataDesc[i].Size == sizeof(double))
                    {
                        uint64_t tempValSwap;
                        memcpy(&tempValSwap, pDataDesc[i].Data, sizeof(tempValSwap));
                        tempValSwap = bswap_64(tempValSwap);
                        memcpy(pStackData, &tempValSwap, sizeof(double));
                    }
                    else if (pDataDesc[i].Size == sizeof(long double))
                    {
                        double val;
                        long double tempVal;
                        char tempValSwap[sizeof(long double)];
                        char const *p = (char const*)pDataDesc[i].Data;
                        unsigned iSwap = sizeof(long double);
                        do
                        {
                            iSwap -= 1;
                            tempValSwap[iSwap] = *p;
                            p += 1;
                        } while (iSwap != 0);
                        memcpy(&tempVal, &tempValSwap, sizeof(tempVal));
                        val = (double)tempVal; // Convert
                        memcpy(pStackData, &val, sizeof(double));
                    }
                    else
                    {
                        abort();
                    }
                    pStackData += sizeof(double);
                    break;
                }
            case lttngh_DataType_String8:
            case lttngh_DataType_StringUtf16Transcoded:
            case lttngh_DataType_StringUtf32Transcoded:
#if lttngh_UST_VER >= 213
            case lttngh_DataType_Counted:
#endif
            {
                // TODO - convert to utf8 for filtering?
                memcpy(pStackData, &pDataDesc[i].Data, sizeof(void *));
                pStackData += sizeof(void *);
                break;
            }
#if lttngh_UST_VER < 213
            case lttngh_DataType_Counted:
            {
                unsigned long len = pDataDesc[i].Length;
                memcpy(pStackData, &len, sizeof(unsigned long));
                pStackData += sizeof(unsigned long);
                memcpy(pStackData, &pDataDesc[i].Data, sizeof(void *));
                pStackData += sizeof(void *);
                break;
            }
#endif // lttngh_UST_VER
            case lttngh_DataType_SequenceUtf16Transcoded:
            case lttngh_DataType_SequenceUtf32Transcoded:
            {
                // TODO - convert to utf8 for filtering?
                unsigned long len = pDataDesc[i].Size; // Type says "count of utf-8 bytes", so use size.
                memcpy(pStackData, &len, sizeof(unsigned long));
                pStackData += sizeof(unsigned long);
                memcpy(pStackData, &pDataDesc[i].Data, sizeof(void *));
                pStackData += sizeof(void *);
                break;
            }
            default:
                abort();
                break;
            }
        }

#if lttngh_UST_VER >= 213

        struct lttng_ust_probe_ctx probeCtx = {
            .struct_size = sizeof(probeCtx),
            .ip = pCallerIp };
        enableRecorder =
            !pEvent->eval_filter ||
            pEvent->run_filter(pEvent, stackData, &probeCtx, NULL) == LTTNG_UST_EVENT_FILTER_ACCEPT;
        if (enableRecorder &&
            pEvent->type == LTTNG_UST_EVENT_TYPE_NOTIFIER)
        {
            struct lttng_ust_event_notifier* pEventNotifier = (struct lttng_ust_event_notifier*)pEvent->child;
            struct lttng_ust_notification_ctx context = {
                .struct_size = sizeof(struct lttng_ust_notification_ctx),
                .eval_capture = CMM_ACCESS_ONCE(pEventNotifier->eval_capture) };
            pEventNotifier->notification_send(pEventNotifier, stackData, &probeCtx, &context);
        }

#else // lttngh_UST_VER

        enableRecorder = pEvent->has_enablers_without_bytecode;
        struct lttng_bytecode_runtime* pRuntime;
        for (pRuntime = cds_list_entry(
                 lttng_ust_rcu_dereference(pEvent->bytecode_runtime_head.next), __typeof__(*pRuntime), node);
             &pRuntime->node != &pEvent->bytecode_runtime_head;
             pRuntime = cds_list_entry(
                 lttng_ust_rcu_dereference(pRuntime->node.next), __typeof__(*pRuntime), node))
        {
            if (caa_unlikely(pRuntime->filter(pRuntime, stackData) & LTTNG_FILTER_RECORD_FLAG))
            {
                enableRecorder = 1;
            }
        }

#endif // lttngh_UST_VER
    }

    return enableRecorder;
}