lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 15 Jan 2019 17:07:52 -0800
From:   Yonghong Song <yhs@...com>
To:     <netdev@...r.kernel.org>
CC:     Alexei Starovoitov <ast@...com>,
        Daniel Borkmann <daniel@...earbox.net>, <kernel-team@...com>,
        Yonghong Song <yhs@...com>
Subject: [PATCH bpf-next 5/5] tools/bpf: support __int128 in bpftool map pretty dumper

For formatted output, currently when json is enabled, the decimal
number is required. Similar to kernel bpffs printout,
for int128 numbers, only hex numbers are dumped, which are
quoted as strings.

The below is an example to show plain and json pretty print
based on the map in test_btf pretty print test.

  $ bpftool m s
  75: hash  name pprint_test_has  flags 0x0
        key 4B  value 112B  max_entries 4  memlock 4096B
  $ bpftool m d id 75
  ......
    {
        "key": 3,
        "value": {
            "ui32": 3,
            "ui16": 0,
            "si32": -3,
            "unused_bits2a": 0x3,
            "bits28": 0x3,
            "unused_bits2b": 0x3,
            "": {
                "ui64": 3,
                "ui8a": [3,0,0,0,0,0,0,0
                ]
            },
            "aenum": 3,
            "ui32b": 4,
            "bits2c": 0x1,
            "si128a": 0x3,
            "si128b": 0xfffffffd,
            "bits3": 0x3,
            "bits80": 0x10000000000000003,
            "ui128": 0x20000000000000003
        }
    },
  ......

  $ bptfool -p -j m d id 75
  ......
  {
        "key": ["0x03","0x00","0x00","0x00"
        ],
        "value": ["0x03","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0xfd","0xff","0xff","0xff","0x0f","0x00","0x00","0xc0",
                  "0x03","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x03","0x00","0x00","0x00","0x04","0x00","0x00","0x00",
                  "0x01","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x00","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x03","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x00","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0xfd","0xff","0xff","0xff","0x00","0x00","0x00","0x00",
                  "0x00","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x1b","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x08","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x03","0x00","0x00","0x00","0x00","0x00","0x00","0x00",
                  "0x02","0x00","0x00","0x00","0x00","0x00","0x00","0x00"
        ],
        "formatted": {
            "key": 3,
            "value": {
                "ui32": 3,
                "ui16": 0,
                "si32": -3,
                "unused_bits2a": "0x3",
                "bits28": "0x3",
                "unused_bits2b": "0x3",
                "": {
                    "ui64": 3,
                    "ui8a": [3,0,0,0,0,0,0,0
                    ]
                },
                "aenum": 3,
                "ui32b": 4,
                "bits2c": "0x1",
                "si128a": "0x3",
                "si128b": "0xfffffffd",
                "bits3": "0x3",
                "bits80": "0x10000000000000003",
                "ui128": "0x20000000000000003"
            }
        }
    }
  ......

Acked-by: Martin KaFai Lau <kafai@...com>
Signed-off-by: Yonghong Song <yhs@...com>
---
 tools/bpf/bpftool/btf_dumper.c | 98 +++++++++++++++++++++++++++++-----
 1 file changed, 86 insertions(+), 12 deletions(-)

diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
index 6ba5f567a9d8..e63bce0755eb 100644
--- a/tools/bpf/bpftool/btf_dumper.c
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -73,35 +73,104 @@ static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id,
 	return ret;
 }
 
+static void btf_int128_print(json_writer_t *jw, const void *data,
+			     bool is_plain_text)
+{
+	/* data points to a __int128 number.
+	 * Suppose
+	 *     int128_num = *(__int128 *)data;
+	 * The below formulas shows what upper_num and lower_num represents:
+	 *     upper_num = int128_num >> 64;
+	 *     lower_num = int128_num & 0xffffffffFFFFFFFFULL;
+	 */
+	__u64 upper_num, lower_num;
+
+#ifdef __BIG_ENDIAN_BITFIELD
+	upper_num = *(__u64 *)data;
+	lower_num = *(__u64 *)(data + 8);
+#else
+	upper_num = *(__u64 *)(data + 8);
+	lower_num = *(__u64 *)data;
+#endif
+
+	if (is_plain_text) {
+		if (upper_num == 0)
+			jsonw_printf(jw, "0x%llx", lower_num);
+		else
+			jsonw_printf(jw, "0x%llx%016llx", upper_num, lower_num);
+	} else {
+		if (upper_num == 0)
+			jsonw_printf(jw, "\"0x%llx\"", lower_num);
+		else
+			jsonw_printf(jw, "\"0x%llx%016llx\"", upper_num, lower_num);
+	}
+}
+
+static void btf_int128_shift(__u64 *print_num, u16 left_shift_bits,
+			     u16 right_shift_bits)
+{
+	__u64 upper_num, lower_num;
+
+#ifdef __BIG_ENDIAN_BITFIELD
+	upper_num = print_num[0];
+	lower_num = print_num[1];
+#else
+	upper_num = print_num[1];
+	lower_num = print_num[0];
+#endif
+
+	/* shake out un-needed bits by shift/or operations */
+	if (left_shift_bits >= 64) {
+		upper_num = lower_num << (left_shift_bits - 64);
+		lower_num = 0;
+	} else {
+		upper_num = (upper_num << left_shift_bits) |
+			    (lower_num >> (64 - left_shift_bits));
+		lower_num = lower_num << left_shift_bits;
+	}
+
+	if (right_shift_bits >= 64) {
+		lower_num = upper_num >> (right_shift_bits - 64);
+		upper_num = 0;
+	} else {
+		lower_num = (lower_num >> right_shift_bits) |
+			    (upper_num << (64 - right_shift_bits));
+		upper_num = upper_num >> right_shift_bits;
+	}
+
+#ifdef __BIG_ENDIAN_BITFIELD
+	print_num[0] = upper_num;
+	print_num[1] = lower_num;
+#else
+	print_num[0] = lower_num;
+	print_num[1] = upper_num;
+#endif
+}
+
 static void btf_dumper_bitfield(__u32 nr_bits, __u8 bit_offset,
 				const void *data, json_writer_t *jw,
 				bool is_plain_text)
 {
 	int left_shift_bits, right_shift_bits;
+	__u64 print_num[2] = {};
 	int bytes_to_copy;
 	int bits_to_copy;
-	__u64 print_num;
 
 	bits_to_copy = bit_offset + nr_bits;
 	bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy);
 
-	print_num = 0;
-	memcpy(&print_num, data, bytes_to_copy);
+	memcpy(print_num, data, bytes_to_copy);
 #if defined(__BIG_ENDIAN_BITFIELD)
 	left_shift_bits = bit_offset;
 #elif defined(__LITTLE_ENDIAN_BITFIELD)
-	left_shift_bits = 64 - bits_to_copy;
+	left_shift_bits = 128 - bits_to_copy;
 #else
 #error neither big nor little endian
 #endif
-	right_shift_bits = 64 - nr_bits;
+	right_shift_bits = 128 - nr_bits;
 
-	print_num <<= left_shift_bits;
-	print_num >>= right_shift_bits;
-	if (is_plain_text)
-		jsonw_printf(jw, "0x%llx", print_num);
-	else
-		jsonw_printf(jw, "%llu", print_num);
+	btf_int128_shift(print_num, left_shift_bits, right_shift_bits);
+	btf_int128_print(jw, print_num, is_plain_text);
 }
 
 
@@ -113,7 +182,7 @@ static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
 	int total_bits_offset;
 
 	/* bits_offset is at most 7.
-	 * BTF_INT_OFFSET() cannot exceed 64 bits.
+	 * BTF_INT_OFFSET() cannot exceed 128 bits.
 	 */
 	total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type);
 	data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
@@ -139,6 +208,11 @@ static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
 		return 0;
 	}
 
+	if (nr_bits == 128) {
+		btf_int128_print(jw, data, is_plain_text);
+		return 0;
+	}
+
 	switch (BTF_INT_ENCODING(*int_type)) {
 	case 0:
 		if (BTF_INT_BITS(*int_type) == 64)
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ