Commit 78e4a955 authored by Andrii Nakryiko's avatar Andrii Nakryiko

Merge branch 'libbpf: BTF typed dump cleanups'

Alan Maguire says:

====================

Fix issues with libbpf BTF typed dump code.  Patch 1 addresses handling
of unaligned data. Patch 2 fixes issues Andrii noticed when compiling
on ppc64le.  Patch 3 simplifies typed dump by getting rid of allocation
of dump data structure which tracks dump state etc.

Changes since v1:

 - Andrii suggested using a function instead of a macro for checking
   alignment of data, and pointed out that we need to consider dump
   ptr size versus native pointer size (patch 1)
====================
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
parents 068dfc65 add192f8
...@@ -1654,6 +1654,11 @@ static int btf_dump_base_type_check_zero(struct btf_dump *d, ...@@ -1654,6 +1654,11 @@ static int btf_dump_base_type_check_zero(struct btf_dump *d,
return 0; return 0;
} }
static bool ptr_is_aligned(const void *data, int data_sz)
{
return ((uintptr_t)data) % data_sz == 0;
}
static int btf_dump_int_data(struct btf_dump *d, static int btf_dump_int_data(struct btf_dump *d,
const struct btf_type *t, const struct btf_type *t,
__u32 type_id, __u32 type_id,
...@@ -1672,7 +1677,7 @@ static int btf_dump_int_data(struct btf_dump *d, ...@@ -1672,7 +1677,7 @@ static int btf_dump_int_data(struct btf_dump *d,
/* handle packed int data - accesses of integers not aligned on /* handle packed int data - accesses of integers not aligned on
* int boundaries can cause problems on some platforms. * int boundaries can cause problems on some platforms.
*/ */
if (((uintptr_t)data) % sz) if (!ptr_is_aligned(data, sz))
return btf_dump_bitfield_data(d, t, data, 0, 0); return btf_dump_bitfield_data(d, t, data, 0, 0);
switch (sz) { switch (sz) {
...@@ -1739,7 +1744,7 @@ static int btf_dump_float_data(struct btf_dump *d, ...@@ -1739,7 +1744,7 @@ static int btf_dump_float_data(struct btf_dump *d,
int sz = t->size; int sz = t->size;
/* handle unaligned data; copy to local union */ /* handle unaligned data; copy to local union */
if (((uintptr_t)data) % sz) { if (!ptr_is_aligned(data, sz)) {
memcpy(&fl, data, sz); memcpy(&fl, data, sz);
flp = &fl; flp = &fl;
} }
...@@ -1892,12 +1897,27 @@ static int btf_dump_struct_data(struct btf_dump *d, ...@@ -1892,12 +1897,27 @@ static int btf_dump_struct_data(struct btf_dump *d,
return err; return err;
} }
union ptr_data {
unsigned int p;
unsigned long long lp;
};
static int btf_dump_ptr_data(struct btf_dump *d, static int btf_dump_ptr_data(struct btf_dump *d,
const struct btf_type *t, const struct btf_type *t,
__u32 id, __u32 id,
const void *data) const void *data)
{ {
if (ptr_is_aligned(data, d->ptr_sz) && d->ptr_sz == sizeof(void *)) {
btf_dump_type_values(d, "%p", *(void **)data); btf_dump_type_values(d, "%p", *(void **)data);
} else {
union ptr_data pt;
memcpy(&pt, data, d->ptr_sz);
if (d->ptr_sz == 4)
btf_dump_type_values(d, "0x%x", pt.p);
else
btf_dump_type_values(d, "0x%llx", pt.lp);
}
return 0; return 0;
} }
...@@ -1910,7 +1930,7 @@ static int btf_dump_get_enum_value(struct btf_dump *d, ...@@ -1910,7 +1930,7 @@ static int btf_dump_get_enum_value(struct btf_dump *d,
int sz = t->size; int sz = t->size;
/* handle unaligned enum value */ /* handle unaligned enum value */
if (((uintptr_t)data) % sz) { if (!ptr_is_aligned(data, sz)) {
*value = (__s64)btf_dump_bitfield_get_data(d, t, data, 0, 0); *value = (__s64)btf_dump_bitfield_get_data(d, t, data, 0, 0);
return 0; return 0;
} }
...@@ -1989,8 +2009,8 @@ static int btf_dump_type_data_check_overflow(struct btf_dump *d, ...@@ -1989,8 +2009,8 @@ static int btf_dump_type_data_check_overflow(struct btf_dump *d,
__s64 size = btf__resolve_size(d->btf, id); __s64 size = btf__resolve_size(d->btf, id);
if (size < 0 || size >= INT_MAX) { if (size < 0 || size >= INT_MAX) {
pr_warn("unexpected size [%lld] for id [%u]\n", pr_warn("unexpected size [%zu] for id [%u]\n",
size, id); (size_t)size, id);
return -EINVAL; return -EINVAL;
} }
...@@ -2218,6 +2238,7 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id, ...@@ -2218,6 +2238,7 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
const void *data, size_t data_sz, const void *data, size_t data_sz,
const struct btf_dump_type_data_opts *opts) const struct btf_dump_type_data_opts *opts)
{ {
struct btf_dump_data typed_dump = {};
const struct btf_type *t; const struct btf_type *t;
int ret; int ret;
...@@ -2228,12 +2249,10 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id, ...@@ -2228,12 +2249,10 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
if (!t) if (!t)
return libbpf_err(-ENOENT); return libbpf_err(-ENOENT);
d->typed_dump = calloc(1, sizeof(struct btf_dump_data)); d->typed_dump = &typed_dump;
if (!d->typed_dump)
return libbpf_err(-ENOMEM);
d->typed_dump->data_end = data + data_sz; d->typed_dump->data_end = data + data_sz;
d->typed_dump->indent_lvl = OPTS_GET(opts, indent_level, 0); d->typed_dump->indent_lvl = OPTS_GET(opts, indent_level, 0);
/* default indent string is a tab */ /* default indent string is a tab */
if (!opts->indent_str) if (!opts->indent_str)
d->typed_dump->indent_str[0] = '\t'; d->typed_dump->indent_str[0] = '\t';
...@@ -2247,7 +2266,7 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id, ...@@ -2247,7 +2266,7 @@ int btf_dump__dump_type_data(struct btf_dump *d, __u32 id,
ret = btf_dump_dump_type_data(d, NULL, t, id, data, 0, 0); ret = btf_dump_dump_type_data(d, NULL, t, id, data, 0, 0);
free(d->typed_dump); d->typed_dump = NULL;
return libbpf_err(ret); return libbpf_err(ret);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment