libbpf: Fix determine_ptr_size() guessing
authorDouglas Raillard <douglas.raillard@arm.com>
Tue, 24 May 2022 09:44:47 +0000 (10:44 +0100)
committerAndrii Nakryiko <andrii@kernel.org>
Thu, 2 Jun 2022 23:26:51 +0000 (16:26 -0700)
One strategy employed by libbpf to guess the pointer size is by finding
the size of "unsigned long" type. This is achieved by looking for a type
of with the expected name and checking its size.

Unfortunately, the C syntax is friendlier to humans than to computers
as there is some variety in how such a type can be named. Specifically,
gcc and clang do not use the same names for integer types in debug info:

    - clang uses "unsigned long"
    - gcc uses "long unsigned int"

Lookup all the names for such a type so that libbpf can hope to find the
information it wants.

Signed-off-by: Douglas Raillard <douglas.raillard@arm.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20220524094447.332186-1-douglas.raillard@arm.com
tools/lib/bpf/btf.c

index bb1e06e..3d6c30d 100644 (file)
@@ -472,9 +472,22 @@ const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
 
 static int determine_ptr_size(const struct btf *btf)
 {
+       static const char * const long_aliases[] = {
+               "long",
+               "long int",
+               "int long",
+               "unsigned long",
+               "long unsigned",
+               "unsigned long int",
+               "unsigned int long",
+               "long unsigned int",
+               "long int unsigned",
+               "int unsigned long",
+               "int long unsigned",
+       };
        const struct btf_type *t;
        const char *name;
-       int i, n;
+       int i, j, n;
 
        if (btf->base_btf && btf->base_btf->ptr_sz > 0)
                return btf->base_btf->ptr_sz;
@@ -485,15 +498,16 @@ static int determine_ptr_size(const struct btf *btf)
                if (!btf_is_int(t))
                        continue;
 
+               if (t->size != 4 && t->size != 8)
+                       continue;
+
                name = btf__name_by_offset(btf, t->name_off);
                if (!name)
                        continue;
 
-               if (strcmp(name, "long int") == 0 ||
-                   strcmp(name, "long unsigned int") == 0) {
-                       if (t->size != 4 && t->size != 8)
-                               continue;
-                       return t->size;
+               for (j = 0; j < ARRAY_SIZE(long_aliases); j++) {
+                       if (strcmp(name, long_aliases[j]) == 0)
+                               return t->size;
                }
        }