Thread (13 messages) 13 messages, 3 authors, 2020-03-17

Re: [PATCH bpf-next 2/4] bpftool: Print as a string for char array

From: Martin KaFai Lau <hidden>
Date: 2020-03-17 21:03:25
Also in: bpf

On Tue, Mar 17, 2020 at 01:08:01PM -0700, Andrii Nakryiko wrote:
On Sun, Mar 15, 2020 at 5:57 PM Martin KaFai Lau [off-list ref] wrote:
quoted
A char[] is currently printed as an integer array.
This patch will print it as a string when
1) The array element type is an one byte int
2) The array element type has a BTF_INT_CHAR encoding or
   the array element type's name is "char"
3) All characters is between (0x1f, 0x7f) and it is terminated
   by a null character.

Signed-off-by: Martin KaFai Lau <redacted>
---
 tools/bpf/bpftool/btf_dumper.c | 41 ++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
index 57bd6c0fafc9..1d2d8d2cedea 100644
--- a/tools/bpf/bpftool/btf_dumper.c
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -77,6 +77,42 @@ static void btf_dumper_enum(const struct btf_dumper *d,
        jsonw_int(d->jw, value);
 }

+static bool is_str_array(const struct btf *btf, const struct btf_array *arr,
+                        const char *s)
+{
+       const struct btf_type *elem_type;
+       const char *end_s;
+
+       if (!arr->nelems)
+               return false;
+
+       elem_type = btf__type_by_id(btf, arr->type);
+       /* Not skipping typedef.  typedef to char does not count as
+        * a string now.
+        */
+       while (elem_type && btf_is_mod(elem_type))
+               elem_type = btf__type_by_id(btf, elem_type->type);
+
+       if (!elem_type || !btf_is_int(elem_type) || elem_type->size != 1)
+               return false;
+
+       if (btf_int_encoding(elem_type) != BTF_INT_CHAR &&
+           strcmp("char", btf__name_by_offset(btf, elem_type->name_off)))
+               return false;
+
+       end_s = s + arr->nelems;
+       while (s < end_s) {
+               if (!*s)
+                       return true;
+               if (*s <= 0x1f || *s >= 0x7f)
+                       return false;
+               s++;
+       }
+
+       /* '\0' is not found */
+       return false;
+}
+
 static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id,
                            const void *data)
 {
@@ -86,6 +122,11 @@ static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id,
        int ret = 0;
        __u32 i;

+       if (is_str_array(d->btf, arr, data)) {
+               jsonw_string(d->jw, data);
+               return 0;
+       }
+
Looks good, but curious how the string that contains ' or " will be
output in json? Will it be escaped properly or will result in
malformed JSON?
They will be escaped.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help