diff options
Diffstat (limited to 'tools/lib/bpf/btf_dump.c')
| -rw-r--r-- | tools/lib/bpf/btf_dump.c | 39 | 
1 files changed, 37 insertions, 2 deletions
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index cf711168d34a..57c00fa63932 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -13,6 +13,7 @@  #include <errno.h>  #include <linux/err.h>  #include <linux/btf.h> +#include <linux/kernel.h>  #include "btf.h"  #include "hashmap.h"  #include "libbpf.h" @@ -60,6 +61,7 @@ struct btf_dump {  	const struct btf_ext *btf_ext;  	btf_dump_printf_fn_t printf_fn;  	struct btf_dump_opts opts; +	int ptr_sz;  	bool strip_mods;  	/* per-type auxiliary state */ @@ -138,6 +140,7 @@ struct btf_dump *btf_dump__new(const struct btf *btf,  	d->btf_ext = btf_ext;  	d->printf_fn = printf_fn;  	d->opts.ctx = opts ? opts->ctx : NULL; +	d->ptr_sz = btf__pointer_size(btf) ? : sizeof(void *);  	d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);  	if (IS_ERR(d->type_names)) { @@ -549,6 +552,9 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)  	}  } +static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id, +					  const struct btf_type *t); +  static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,  				     const struct btf_type *t);  static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id, @@ -671,6 +677,9 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)  	switch (kind) {  	case BTF_KIND_INT: +		/* Emit type alias definitions if necessary */ +		btf_dump_emit_missing_aliases(d, id, t); +  		tstate->emit_state = EMITTED;  		break;  	case BTF_KIND_ENUM: @@ -797,7 +806,7 @@ static void btf_dump_emit_bit_padding(const struct btf_dump *d,  				      int align, int lvl)  {  	int off_diff = m_off - cur_off; -	int ptr_bits = sizeof(void *) * 8; +	int ptr_bits = d->ptr_sz * 8;  	if (off_diff <= 0)  		/* no gap */ @@ -870,7 +879,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,  			btf_dump_printf(d, ": %d", m_sz);  			off = m_off + m_sz;  		} else { -			m_sz = max(0, btf__resolve_size(d->btf, m->type)); +			m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type));  			off = m_off + m_sz * 8;  		}  		btf_dump_printf(d, ";"); @@ -890,6 +899,32 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,  		btf_dump_printf(d, " __attribute__((packed))");  } +static const char *missing_base_types[][2] = { +	/* +	 * GCC emits typedefs to its internal __PolyX_t types when compiling Arm +	 * SIMD intrinsics. Alias them to standard base types. +	 */ +	{ "__Poly8_t",		"unsigned char" }, +	{ "__Poly16_t",		"unsigned short" }, +	{ "__Poly64_t",		"unsigned long long" }, +	{ "__Poly128_t",	"unsigned __int128" }, +}; + +static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id, +					  const struct btf_type *t) +{ +	const char *name = btf_dump_type_name(d, id); +	int i; + +	for (i = 0; i < ARRAY_SIZE(missing_base_types); i++) { +		if (strcmp(name, missing_base_types[i][0]) == 0) { +			btf_dump_printf(d, "typedef %s %s;\n\n", +					missing_base_types[i][1], name); +			break; +		} +	} +} +  static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,  				   const struct btf_type *t)  {  |