• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Alan-Jowett / ebpf-verifier / 22316701280

22 Feb 2026 08:43PM UTC coverage: 88.93% (+0.9%) from 88.002%
22316701280

push

github

web-flow
Human-friendly CLI output for bin/prevail (#1042)

* Replace CSV output with human-friendly PASS/FAIL CLI output

The default output was `{0|1},{seconds},{memory_kb}` — a CSV row for
benchmarking scripts that is unfriendly for humans. Benchmarking is
better done externally (time, /usr/bin/time -v).

New output: `PASS: section/function` or `FAIL: section/function` with
the first error and a hint line pointing to --failure-slice / -v.
Add -q/--quiet (exit code only) and --cfg (replaces --domain cfg).

Remove dead code: --domain option (linux, stats, zoneCrab selectors),
linux_verifier, memsize helpers, collect_stats/stats_headers, fnv1a64,
@headers special filename, bin/check alias, and stale benchmark scripts.

Move src/main/check.cpp → src/main.cpp (simplified, rewritten).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Elazar Gershuni <elazarg@gmail.com>

* Graduate loop3.o from skip to expected failure

The >4x performance improvement means loop3.o no longer hangs.
It now completes quickly but is rejected due to type precision
loss through the loop join (VerifierTypeTracking).

* Remove redundant install exclude, fix doc path

- Remove `PATTERN "main.cpp" EXCLUDE` from install — the glob only
  matches *.hpp/*.h so main.cpp would never be included anyway.
- Fix `./prevail` → `./bin/prevail` in docs/architecture.md for
  consistency with the actual binary location.

---------

Signed-off-by: Elazar Gershuni <elazarg@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

1 of 1 new or added line in 1 file covered. (100.0%)

198 existing lines in 11 files now uncovered.

13159 of 14797 relevant lines covered (88.93%)

4658715.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.03
/src/linux/kfunc.cpp
1
// Copyright (c) Prevail Verifier contributors.
2
// SPDX-License-Identifier: MIT
3

4
#include "linux/kfunc.hpp"
5

6
#include <algorithm>
7
#include <array>
8
#include <stdexcept>
9
#include <string_view>
10

11
#include "spec/function_prototypes.hpp"
12

13
namespace prevail {
14

15
namespace {
16

17
struct KfuncPrototypeEntry {
18
    int32_t btf_id;
19
    EbpfHelperPrototype proto;
20
    KfuncFlags flags;
21
    std::string_view required_program_type;
22
    bool requires_privileged;
23
};
24

25
constexpr std::array<KfuncPrototypeEntry, 10> kfunc_prototypes{{
26
    {
27
        12,
28
        EbpfHelperPrototype{
29
            .name = "kfunc_test_id_overlap_tail_call",
30
            .return_type = EBPF_RETURN_TYPE_INTEGER,
31
            .argument_type = {EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
32
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
33
            .reallocate_packet = false,
34
            .context_descriptor = nullptr,
35
            .unsupported = false,
36
        },
37
        KfuncFlags::none,
38
        "",
39
        false,
40
    },
41
    {
42
        1000,
43
        EbpfHelperPrototype{
44
            .name = "kfunc_test_ret_int",
45
            .return_type = EBPF_RETURN_TYPE_INTEGER,
46
            .argument_type = {EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
47
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
48
            .reallocate_packet = false,
49
            .context_descriptor = nullptr,
50
            .unsupported = false,
51
        },
52
        KfuncFlags::none,
53
        "",
54
        false,
55
    },
56
    {
57
        1001,
58
        EbpfHelperPrototype{
59
            .name = "kfunc_test_ctx_arg",
60
            .return_type = EBPF_RETURN_TYPE_INTEGER,
61
            .argument_type = {EBPF_ARGUMENT_TYPE_PTR_TO_CTX, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
62
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
63
            .reallocate_packet = false,
64
            .context_descriptor = nullptr,
65
            .unsupported = false,
66
        },
67
        KfuncFlags::none,
68
        "",
69
        false,
70
    },
71
    {
72
        1002,
73
        EbpfHelperPrototype{
74
            .name = "kfunc_test_acquire_flag",
75
            .return_type = EBPF_RETURN_TYPE_INTEGER,
76
            .argument_type = {EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
77
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
78
            .reallocate_packet = false,
79
            .context_descriptor = nullptr,
80
            .unsupported = false,
81
        },
82
        KfuncFlags::acquire,
83
        "",
84
        false,
85
    },
86
    {
87
        1003,
88
        EbpfHelperPrototype{
89
            .name = "kfunc_test_xdp_only",
90
            .return_type = EBPF_RETURN_TYPE_INTEGER,
91
            .argument_type = {EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
92
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
93
            .reallocate_packet = false,
94
            .context_descriptor = nullptr,
95
            .unsupported = false,
96
        },
97
        KfuncFlags::none,
98
        "xdp",
99
        false,
100
    },
101
    {
102
        1004,
103
        EbpfHelperPrototype{
104
            .name = "kfunc_test_privileged_only",
105
            .return_type = EBPF_RETURN_TYPE_INTEGER,
106
            .argument_type = {EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
107
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
108
            .reallocate_packet = false,
109
            .context_descriptor = nullptr,
110
            .unsupported = false,
111
        },
112
        KfuncFlags::none,
113
        "",
114
        true,
115
    },
116
    {
117
        1005,
118
        EbpfHelperPrototype{
119
            .name = "kfunc_test_ret_map_value_or_null",
120
            .return_type = EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL,
121
            .argument_type = {EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
122
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
123
            .reallocate_packet = false,
124
            .context_descriptor = nullptr,
125
            .unsupported = false,
126
        },
127
        KfuncFlags::none,
128
        "",
129
        false,
130
    },
131
    {
132
        1006,
133
        EbpfHelperPrototype{
134
            .name = "kfunc_test_readable_mem_or_null_size",
135
            .return_type = EBPF_RETURN_TYPE_INTEGER,
136
            .argument_type = {EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL, EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO,
137
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
138
            .reallocate_packet = false,
139
            .context_descriptor = nullptr,
140
            .unsupported = false,
141
        },
142
        KfuncFlags::none,
143
        "",
144
        false,
145
    },
146
    {
147
        1007,
148
        EbpfHelperPrototype{
149
            .name = "kfunc_test_writable_mem_size",
150
            .return_type = EBPF_RETURN_TYPE_INTEGER,
151
            .argument_type = {EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM, EBPF_ARGUMENT_TYPE_CONST_SIZE,
152
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
153
            .reallocate_packet = false,
154
            .context_descriptor = nullptr,
155
            .unsupported = false,
156
        },
157
        KfuncFlags::none,
158
        "",
159
        false,
160
    },
161
    {
162
        1008,
163
        EbpfHelperPrototype{
164
            .name = "kfunc_test_release_flag",
165
            .return_type = EBPF_RETURN_TYPE_INTEGER,
166
            .argument_type = {EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE,
167
                              EBPF_ARGUMENT_TYPE_DONTCARE, EBPF_ARGUMENT_TYPE_DONTCARE},
168
            .reallocate_packet = false,
169
            .context_descriptor = nullptr,
170
            .unsupported = false,
171
        },
172
        KfuncFlags::release,
173
        "",
174
        false,
175
    },
176
}};
177

178
constexpr bool kfunc_prototypes_are_sorted_by_btf_id() {
179
    for (size_t i = 1; i < kfunc_prototypes.size(); ++i) {
180
        if (kfunc_prototypes[i - 1].btf_id >= kfunc_prototypes[i].btf_id) {
181
            return false;
182
        }
183
    }
184
    return true;
185
}
186

187
static_assert(kfunc_prototypes_are_sorted_by_btf_id(), "kfunc_prototypes must be strictly sorted by btf_id");
188

189
std::optional<KfuncPrototypeEntry> lookup_kfunc_prototype(const int32_t btf_id) {
38✔
190
    const auto it =
19✔
191
        std::lower_bound(kfunc_prototypes.begin(), kfunc_prototypes.end(), btf_id,
38✔
192
                         [](const KfuncPrototypeEntry& entry, const int32_t id) { return entry.btf_id < id; });
136✔
193
    if (it != kfunc_prototypes.end() && it->btf_id == btf_id) {
38✔
194
        return *it;
36✔
195
    }
196
    return std::nullopt;
2✔
197
}
198

199
ArgSingle::Kind to_arg_single_kind(const ebpf_argument_type_t t) {
4✔
200
    switch (t) {
4✔
201
    case EBPF_ARGUMENT_TYPE_ANYTHING: return ArgSingle::Kind::ANYTHING;
UNCOV
202
    case EBPF_ARGUMENT_TYPE_PTR_TO_STACK:
×
UNCOV
203
    case EBPF_ARGUMENT_TYPE_PTR_TO_STACK_OR_NULL: return ArgSingle::Kind::PTR_TO_STACK;
×
UNCOV
204
    case EBPF_ARGUMENT_TYPE_PTR_TO_MAP: return ArgSingle::Kind::MAP_FD;
×
UNCOV
205
    case EBPF_ARGUMENT_TYPE_PTR_TO_MAP_OF_PROGRAMS: return ArgSingle::Kind::MAP_FD_PROGRAMS;
×
206
    case EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY: return ArgSingle::Kind::PTR_TO_MAP_KEY;
×
UNCOV
207
    case EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE: return ArgSingle::Kind::PTR_TO_MAP_VALUE;
×
208
    case EBPF_ARGUMENT_TYPE_PTR_TO_CTX:
4✔
209
    case EBPF_ARGUMENT_TYPE_PTR_TO_CTX_OR_NULL: return ArgSingle::Kind::PTR_TO_CTX;
4✔
UNCOV
210
    default: break;
×
211
    }
UNCOV
212
    throw std::runtime_error("internal error: unmapped kfunc single-arg type " + std::to_string(static_cast<int>(t)));
×
213
}
214

215
ArgPair::Kind to_arg_pair_kind(const ebpf_argument_type_t t) {
12✔
216
    switch (t) {
12✔
217
    case EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL:
3✔
218
    case EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM: return ArgPair::Kind::PTR_TO_READABLE_MEM;
3✔
219
    case EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM_OR_NULL:
6✔
220
    case EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM: return ArgPair::Kind::PTR_TO_WRITABLE_MEM;
6✔
UNCOV
221
    default: break;
×
222
    }
UNCOV
223
    throw std::runtime_error("internal error: unmapped kfunc pair-arg type " + std::to_string(static_cast<int>(t)));
×
224
}
225

226
void set_unsupported(std::string* why_not, const std::string& reason) {
8✔
227
    if (why_not) {
5✔
228
        *why_not = reason;
8✔
229
    }
230
}
4✔
231

232
} // namespace
233

234
std::optional<Call> make_kfunc_call(const int32_t btf_id, const ProgramInfo* info, std::string* why_not) {
38✔
235
    const auto entry = lookup_kfunc_prototype(btf_id);
38✔
236
    if (!entry) {
38✔
237
        set_unsupported(why_not, "kfunc prototype lookup failed for BTF id " + std::to_string(btf_id));
3✔
238
        return std::nullopt;
2✔
239
    }
240
    const auto& proto = entry->proto;
36✔
241

242
    Call res;
36✔
243
    res.func = btf_id;
36✔
244
    res.kind = CallKind::kfunc;
36✔
245
    res.name = proto.name;
36✔
246
    res.reallocate_packet = proto.reallocate_packet;
36✔
247
    res.is_map_lookup = proto.return_type == EBPF_RETURN_TYPE_PTR_TO_MAP_VALUE_OR_NULL;
36✔
248

249
    // Per-flag handling: accept flags whose safety properties are covered by existing type checking,
250
    // reject flags that require unimplemented reference lifecycle tracking.
251
    constexpr auto accepted_flags =
36✔
252
        KfuncFlags::acquire | KfuncFlags::destructive | KfuncFlags::trusted_args | KfuncFlags::sleepable;
253
    // KF_ACQUIRE: type propagation works; release obligation not enforced (same gap as ringbuf).
254
    // KF_DESTRUCTIVE: privilege-level gate; no verification machinery needed.
255
    // KF_TRUSTED_ARGS: arguments already type-checked via the normal assertion path.
256
    // KF_SLEEPABLE: context constraint; not a memory-safety property.
257
    // KF_RELEASE: rejected — requires acquire/release state machine (see docs/parity/lifetime.md).
258
    if ((entry->flags & ~accepted_flags) != KfuncFlags::none) {
36✔
259
        set_unsupported(why_not, std::string("kfunc has unsupported flags (release requires lifecycle tracking): ") +
3✔
260
                                     proto.name);
2✔
261
        return std::nullopt;
2✔
262
    }
263
    if (info && !entry->required_program_type.empty() && info->type.name != entry->required_program_type) {
34✔
264
        set_unsupported(why_not,
2✔
265
                        std::string("kfunc is unavailable for program type ") + info->type.name + ": " + proto.name);
7✔
266
        return std::nullopt;
2✔
267
    }
268
    if (info && entry->requires_privileged && !info->type.is_privileged) {
32✔
269
        set_unsupported(why_not, std::string("kfunc requires privileged program type: ") + proto.name);
5✔
270
        return std::nullopt;
2✔
271
    }
272

273
    if (proto.unsupported || proto.return_type == EBPF_RETURN_TYPE_UNSUPPORTED) {
30✔
UNCOV
274
        set_unsupported(why_not, std::string("kfunc prototype is unavailable on this platform: ") + proto.name);
×
UNCOV
275
        return std::nullopt;
×
276
    }
277
    const auto return_info = classify_call_return_type(proto.return_type);
30✔
278
    if (!return_info.has_value()) {
30✔
UNCOV
279
        set_unsupported(why_not, std::string("kfunc return type is unsupported on this platform: ") + proto.name);
×
280
        return std::nullopt;
×
281
    }
282
    res.return_ptr_type = return_info->pointer_type;
30✔
283
    res.return_nullable = return_info->pointer_nullable;
30✔
284

285
    const std::array<ebpf_argument_type_t, 7> args = {
30✔
286
        {EBPF_ARGUMENT_TYPE_DONTCARE, proto.argument_type[0], proto.argument_type[1], proto.argument_type[2],
30✔
287
         proto.argument_type[3], proto.argument_type[4], EBPF_ARGUMENT_TYPE_DONTCARE}};
30✔
288
    for (size_t i = 1; i < args.size() - 1; i++) {
69✔
289
        switch (args[i]) {
46✔
290
        case EBPF_ARGUMENT_TYPE_DONTCARE: return res;
30✔
291
        case EBPF_ARGUMENT_TYPE_UNSUPPORTED:
×
292
            set_unsupported(why_not, std::string("kfunc argument type is unavailable on this platform: ") + proto.name);
×
UNCOV
293
            return std::nullopt;
×
294
        case EBPF_ARGUMENT_TYPE_ANYTHING:
4✔
295
        case EBPF_ARGUMENT_TYPE_PTR_TO_MAP:
2✔
296
        case EBPF_ARGUMENT_TYPE_PTR_TO_MAP_OF_PROGRAMS:
2✔
297
        case EBPF_ARGUMENT_TYPE_PTR_TO_MAP_KEY:
2✔
298
        case EBPF_ARGUMENT_TYPE_PTR_TO_MAP_VALUE:
2✔
299
        case EBPF_ARGUMENT_TYPE_PTR_TO_STACK:
2✔
300
        case EBPF_ARGUMENT_TYPE_PTR_TO_CTX:
2✔
301
            res.singles.push_back({to_arg_single_kind(args[i]), false, Reg{gsl::narrow<uint8_t>(i)}});
4✔
302
            break;
4✔
303
        case EBPF_ARGUMENT_TYPE_PTR_TO_STACK_OR_NULL:
×
304
        case EBPF_ARGUMENT_TYPE_PTR_TO_CTX_OR_NULL:
UNCOV
305
            res.singles.push_back({to_arg_single_kind(args[i]), true, Reg{gsl::narrow<uint8_t>(i)}});
×
UNCOV
306
            break;
×
UNCOV
307
        case EBPF_ARGUMENT_TYPE_CONST_SIZE:
×
UNCOV
308
            set_unsupported(
×
309
                why_not,
UNCOV
310
                std::string("mismatched kfunc EBPF_ARGUMENT_TYPE_PTR_TO* and EBPF_ARGUMENT_TYPE_CONST_SIZE: ") +
×
UNCOV
311
                    proto.name);
×
UNCOV
312
            return std::nullopt;
×
313
        case EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO:
×
UNCOV
314
            set_unsupported(why_not, std::string("mismatched kfunc EBPF_ARGUMENT_TYPE_PTR_TO* and "
×
315
                                                 "EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO: ") +
×
316
                                         proto.name);
×
317
            return std::nullopt;
×
318
        case EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL:
12✔
319
        case EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM:
6✔
320
        case EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM_OR_NULL:
6✔
321
        case EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM: {
6✔
322
            // args[i+1] is always in bounds: args has a DONTCARE sentinel at index 6.
323
            if (args[i + 1] != EBPF_ARGUMENT_TYPE_CONST_SIZE && args[i + 1] != EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO) {
12✔
324
                set_unsupported(why_not,
×
325
                                std::string("kfunc pointer argument not followed by EBPF_ARGUMENT_TYPE_CONST_SIZE or "
×
326
                                            "EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO: ") +
×
327
                                    proto.name);
×
328
                return std::nullopt;
×
329
            }
330
            const bool can_be_zero = (args[i + 1] == EBPF_ARGUMENT_TYPE_CONST_SIZE_OR_ZERO);
12✔
331
            const bool or_null = args[i] == EBPF_ARGUMENT_TYPE_PTR_TO_READABLE_MEM_OR_NULL ||
15✔
332
                                 args[i] == EBPF_ARGUMENT_TYPE_PTR_TO_WRITABLE_MEM_OR_NULL;
6✔
333
            res.pairs.push_back({to_arg_pair_kind(args[i]), or_null, Reg{gsl::narrow<uint8_t>(i)},
18✔
334
                                 Reg{gsl::narrow<uint8_t>(i + 1)}, can_be_zero});
12✔
335
            i++;
12✔
336
            break;
12✔
337
        }
338
        case EBPF_ARGUMENT_TYPE_PTR_TO_BTF_ID_SOCK_COMMON:
×
339
        case EBPF_ARGUMENT_TYPE_PTR_TO_SOCK_COMMON:
UNCOV
340
            res.singles.push_back({ArgSingle::Kind::PTR_TO_SOCKET, false, Reg{gsl::narrow<uint8_t>(i)}});
×
341
            break;
×
342
        case EBPF_ARGUMENT_TYPE_PTR_TO_BTF_ID:
×
343
        case EBPF_ARGUMENT_TYPE_PTR_TO_PERCPU_BTF_ID:
UNCOV
344
            res.singles.push_back({ArgSingle::Kind::PTR_TO_BTF_ID, false, Reg{gsl::narrow<uint8_t>(i)}});
×
345
            break;
×
UNCOV
346
        case EBPF_ARGUMENT_TYPE_PTR_TO_ALLOC_MEM:
×
UNCOV
347
            res.singles.push_back({ArgSingle::Kind::PTR_TO_ALLOC_MEM, false, Reg{gsl::narrow<uint8_t>(i)}});
×
UNCOV
348
            break;
×
UNCOV
349
        case EBPF_ARGUMENT_TYPE_PTR_TO_SPIN_LOCK:
×
UNCOV
350
            res.singles.push_back({ArgSingle::Kind::PTR_TO_SPIN_LOCK, false, Reg{gsl::narrow<uint8_t>(i)}});
×
UNCOV
351
            break;
×
UNCOV
352
        case EBPF_ARGUMENT_TYPE_PTR_TO_TIMER:
×
UNCOV
353
            res.singles.push_back({ArgSingle::Kind::PTR_TO_TIMER, false, Reg{gsl::narrow<uint8_t>(i)}});
×
UNCOV
354
            break;
×
UNCOV
355
        case EBPF_ARGUMENT_TYPE_CONST_ALLOC_SIZE_OR_ZERO:
×
UNCOV
356
            res.singles.push_back({ArgSingle::Kind::CONST_SIZE_OR_ZERO, false, Reg{gsl::narrow<uint8_t>(i)}});
×
357
            res.alloc_size_reg = Reg{gsl::narrow<uint8_t>(i)};
8✔
358
            break;
UNCOV
359
        case EBPF_ARGUMENT_TYPE_PTR_TO_LONG:
×
UNCOV
360
            res.singles.push_back({ArgSingle::Kind::PTR_TO_WRITABLE_LONG, false, Reg{gsl::narrow<uint8_t>(i)}});
×
UNCOV
361
            break;
×
UNCOV
362
        case EBPF_ARGUMENT_TYPE_PTR_TO_INT:
×
UNCOV
363
            res.singles.push_back({ArgSingle::Kind::PTR_TO_WRITABLE_INT, false, Reg{gsl::narrow<uint8_t>(i)}});
×
UNCOV
364
            break;
×
UNCOV
365
        case EBPF_ARGUMENT_TYPE_PTR_TO_CONST_STR:
×
366
        default:
UNCOV
367
            set_unsupported(why_not, std::string("kfunc argument type is unsupported on this platform: ") + proto.name);
×
UNCOV
368
            return std::nullopt;
×
369
        }
370
    }
UNCOV
371
    return res;
×
372
}
36✔
373

374
} // namespace prevail
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc