[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <67ffe6998af5cf88bdda6eaa1e6b085db1e093ed.1609855479.git.sean@mess.org>
Date: Tue, 5 Jan 2021 14:45:33 +0000
From: Sean Young <sean@...s.org>
To: Yonghong Song <yhs@...com>, Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Andrii Nakryiko <andrii@...nel.org>,
Martin KaFai Lau <kafai@...com>,
Song Liu <songliubraving@...com>,
John Fastabend <john.fastabend@...il.com>,
KP Singh <kpsingh@...nel.org>,
Nathan Chancellor <natechancellor@...il.com>,
Nick Desaulniers <ndesaulniers@...gle.com>,
Quentin Monnet <quentin@...valent.com>,
Toke Høiland-Jørgensen <toke@...hat.com>,
linux-doc@...r.kernel.org, netdev@...r.kernel.org,
bpf@...r.kernel.org, linux-kernel@...r.kernel.org,
clang-built-linux@...glegroups.com
Subject: [PATCH v3 3/4] bpftool: add support for ints larger than 128 bits
clang supports arbitrary length ints using the _ExtInt extension. This
can be useful to hold very large values, e.g. 256 bit or 512 bit types.
This requires the _ExtInt extension enabled in clang, which is under
review.
Link: https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types
Link: https://reviews.llvm.org/D93103
Signed-off-by: Sean Young <sean@...s.org>
---
tools/bpf/bpftool/btf_dumper.c | 40 ++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
index 0e9310727281..8b5318ec5c26 100644
--- a/tools/bpf/bpftool/btf_dumper.c
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -271,6 +271,41 @@ static void btf_int128_print(json_writer_t *jw, const void *data,
}
}
+static void btf_bigint_print(json_writer_t *jw, const void *data, int nr_bits,
+ bool is_plain_text)
+{
+ char buf[nr_bits / 4 + 1];
+ int last_u64 = nr_bits / 64 - 1;
+ bool seen_nonzero = false;
+ int i;
+
+ for (i = 0; i <= last_u64; i++) {
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u64 v = ((__u64 *)data)[i];
+#else
+ __u64 v = ((__u64 *)data)[last_u64 - i];
+#endif
+
+ if (!seen_nonzero) {
+ if (!v && i != last_u64)
+ continue;
+
+ snprintf(buf, sizeof(buf), "%llx", v);
+
+ seen_nonzero = true;
+ } else {
+ size_t off = strlen(buf);
+
+ snprintf(buf + off, sizeof(buf) - off, "%016llx", v);
+ }
+ }
+
+ if (is_plain_text)
+ jsonw_printf(jw, "0x%s", buf);
+ else
+ jsonw_printf(jw, "\"0x%s\"", buf);
+}
+
static void btf_int128_shift(__u64 *print_num, __u16 left_shift_bits,
__u16 right_shift_bits)
{
@@ -373,6 +408,11 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
return 0;
}
+ if (nr_bits > 128) {
+ btf_bigint_print(jw, data, nr_bits, is_plain_text);
+ return 0;
+ }
+
if (nr_bits == 128) {
btf_int128_print(jw, data, is_plain_text);
return 0;
--
2.29.2
Powered by blists - more mailing lists