When doing BTF encoding/deduping, DWARF CUs are never used after BTF encoding
is done, so there is no point in wasting memory and keeping them in memory. So
discard them immediately.
Committer testing:
$ pahole -J vmlinux
$ ./btfdiff vmlinux
$
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Fix the logic of determining if __ARRAY_SIZE_TYPE__ needs to be emitted.
Previously, such type could be emitted unnecessarily due to some
particular CU not having an int type in it. That would happen even if
there was no array type in that CU. Fix it by keeping track of 'int'
type across CUs and only emitting __ARRAY_SIZE_TYPE__ if a given CU has
array type, but we still haven't found 'int' type.
Testing against vmlinux shows that now there are no __ARRAY_SIZE_TYPE__
integers emitted.
Committer testing:
$ pahole -J vmlinux
$ ./btfdiff vmlinux
$
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Switch BTF loading to completely use libbpf's own struct btf and related
APIs.
BTF encoding is still happening with pahole's own code, so these two
code paths are not sharing anything now. String fetching is happening
based on whether btfe->strings were set to non-NULL pointer by
btf_encoder.
Committer testing:
$ cp ~/git/build/bpf-next-v5.9.0-rc8+/vmlinux .
$ readelf -SW vmlinux | grep BTF
[24] .BTF PROGBITS ffffffff82494ac0 1694ac0 340207 00 A 0 0 1
[25] .BTF_ids PROGBITS ffffffff827d4cc8 19d4cc8 0000a4 00 A 0 0 1
$ ./btfdiff vmlinux
$
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Maintain a pointer to debug_fmt_ops corresponding to currently used debug info
format loader (DWARF, BTF, or CTF), to allow various parts of libdwarves to do
things like resolve string offset to actual string pointer in
a format-agnostic format. This allows to, say, load DWARF debug info, and use
it for BTF generation, without either of them making assumptions about how
strings are actually stored internally.
This is going to be used in the next patch to allow BTF loader and encoder to
use a very different way of storing strings (not a global shared gobuffer).
Committer notes:
Since it is available in multiple object files, add a dwarves__ prefix
namespace and add an extern for it in dwarves.h.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Don't silently swallow BTF encoding errors and continue onto next CU. If
any of CU fails to properly encode BTF, exit with an error message.
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
To show just packed structs.
For instance, here are the top packed structures in the Linux kernel,
using BTF data:
$ pahole --packed --sizes | sort -k2 -nr | head
e820_table 64004 0
boot_params 4096 0
btrfs_super_block 3531 0
efi_variable 2084 0
ntb_info_regs 800 0
tboot 568 0
_legacy_mbr 512 0
disklabel 512 0
btrfs_root_item 439 0
saved_context 317 0
$
If you then look at:
$ pahole e820_table
struct e820_table {
__u32 nr_entries; /* 0 4 */
struct e820_entry entries[3200]; /* 4 64000 */
/* size: 64004, cachelines: 1001, members: 2 */
/* last cacheline: 4 bytes */
} __attribute__((__packed__));
$
In arch/x86/include/asm/e820/types.h we have:
/*
* The whole array of E820 entries:
*/
struct e820_table {
__u32 nr_entries;
struct e820_entry entries[E820_MAX_ENTRIES];
};
I.e. no explicit __packed__ attributes, but if we expand this a bit:
$ pahole -E e820_table
struct e820_table {
/* typedef __u32 */ unsigned int nr_entries; /* 0 4 */
struct e820_entry {
/* typedef u64 -> __u64 */ long long unsigned int addr; /* 4 8 */
/* typedef u64 -> __u64 */ long long unsigned int size; /* 12 8 */
enum e820_type type; /* 20 4 */
} __attribute__((__packed__)) entries[3200]; /* 4 64000 */
/* size: 64004, cachelines: 1001, members: 2 */
/* last cacheline: 4 bytes */
} __attribute__((__packed__));
$
We see that is that entries member that is packed, because:
$ pahole e820_entry
struct e820_entry {
u64 addr; /* 0 8 */
u64 size; /* 8 8 */
enum e820_type type; /* 16 4 */
/* size: 20, cachelines: 1, members: 3 */
/* last cacheline: 20 bytes */
} __attribute__((__packed__));
$
In arch/x86/include/asm/e820/types.h we have:
/*
* A single E820 map entry, describing a memory range of [addr...addr+size-1],
* of 'type' memory type:
*
* (We pack it because there can be thousands of them on large systems.)
*/
struct e820_entry {
u64 addr;
u64 size;
enum e820_type type;
} __attribute__((packed));
So yeah, it is there, BTF doesn't explicitly states it is packed (as
DWARF does) and pahole was able to infer that correctly.
Tested-by: Richard Weinberger <richard@nod.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
We also ignore it when it appears inside a DW_TAG_subprogram, so just
don't emit the warning that it is not supported when it appears in the
top level.
So far it doesn't look useful for what these tools do, need to revisit
it when the need arises.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
pdwtags -F btf vmlinux
Was segfaulting when trying to iterate on the function main lexblock,
which was zeroed instead of INIT_LIST_HEAD'ed, fix it.
This also made pfunct misbehave when used with BTF. pahole unnafected as
it doesn't try to go thru functions in most cases.
Fixes: ccf3eebfcd ("btf_loader: Add support for BTF_KIND_FUNC")
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
It is found on gcc 8.2 that global percpu variables generate the
following dwarf entry in the cu where the variable is defined[1].
Take the global variable "bpf_prog_active" defined in
kernel/bpf/syscall.c as an example. The debug info for syscall.c has two
dwarf entries for "bpf_prog_active".
> readelf -wi kernel/bpf/syscall.o
0x00013534: DW_TAG_variable
DW_AT_name ("bpf_prog_active")
DW_AT_decl_file
("/data/users/yhs/work/net-next/include/linux/bpf.h")
DW_AT_decl_line (1074)
DW_AT_decl_column (0x01)
DW_AT_type (0x000000d6 "int")
DW_AT_external (true)
DW_AT_declaration (true)
0x00021a25: DW_TAG_variable
DW_AT_specification (0x00013534 "bpf_prog_active")
DW_AT_decl_file
("/data/users/yhs/work/net-next/kernel/bpf/syscall.c")
DW_AT_decl_line (43)
DW_AT_location (DW_OP_addr 0x0)
Note that second DW_TAG_variable entry contains specification that
points to the first entry. This causes problem for btf_encoder when
encoding global variables. The tag generated for the second entry
doesn't have the type and scope info. Therefore the BTF VARs encoded
using this tag has incorrect type_id and scope.
As fix, when creating variable, examine the dwarf entry. If it has
a DW_AT_specification, store the referred struct variable in a 'spec'
field. When encoding VARs, check this 'spec', if it's non-empty, follow
the pointer to use the referred var.
[1] https://www.mail-archive.com/netdev@vger.kernel.org/msg348144.html
Tested: Tested using gcc 4.9 and gcc 8.2. The types and scopes of global
vars are now generated correctly.
[21] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[21102] VAR 'bpf_prog_active' type_id=21, linkage=global-alloc
Signed-off-by: Hao Luo <haoluo@google.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This usually means we're trying each of the type loaders (DWARF, BTF,
CTF) on some invalid file, so no need to show that message, use verbose
mode to get it, so that we show that all loaders are being tried.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This usually means we're trying each of the type loaders (DWARF, BTF,
CTF) on some invalid file, so no need to show that message, use verbose
mode to get it, so that we show that all loaders are being tried.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
We need to check for this sentinel return everywhere we use
die__process_tag(), fix the last two places where this wasn't being
done: when processing DW_TAG_namespace and DW_TAG_subroutine_type.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
When die__process_tag() gets some tag it hasn't support for, it returns
the special zeroed 'unsupported_tag' struct tag pointer, and now all
places are checking for that, warn the user in all places when that
happens.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
When die__process_tag() gets some tag it hasn't support for, it returns
the special zeroed 'unsupported_tag' struct tag pointer, but
die__process_class() wasn't handling that, assuming since it isn't NULL
that it is a valid 'struct tag' pointer and proceeded to try to use its
->priv area, b00m.
So catch that and print an "unsuported tag FOO" for that case, this
makes the code way more robust as any unsupported tag will not cause a
segfault, just a warning.
So, for the case in the Bugtracker tag below, we don't segfault instead
we show just that DW_TAG_variant_part isn't supported when found inside
a DW_TAG_structure_type (or DW_TAG_class_type) as is the case with ADA
95.
Reported-by: Tom de Vries
Bugtracker: https://github.com/acmel/dwarves/issues/9#issuecomment-697250246
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This was found in a ADA object, part of gdb's test suite, for now just
make the code a bit more robust when not finding a type for some struct
member, etc, which avoids segfaults and produces output from ADA
objects, but there are other problems to solve as this is a _type tag, I
need to provide some better support so that type resolution works.
[foo.debug.gz](https://github.com/acmel/dwarves/files/5257332/foo.debug.gz)
Foo.debug, an ada exec:
```
$ ~/dwarves/build/pahole foo.debug
die__process_unit: DW_TAG_subrange_type (0x21) @ <0x10b> not handled!
die__process_unit: DW_TAG_subrange_type (0x21) @ <0x134> not handled!
die__process_unit: DW_TAG_subrange_type (0x21) @ <0x148> not handled!
die__process_class: DW_TAG_subrange_type (0x21) @ <0x201> not handled!
Segmentation fault (core dumped)
$
These are fixed, the warnings continue to be produced.
Reported-by: Tom de Vries
Bugtracker: https://github.com/acmel/dwarves/issues/9#issuecomment-696282005
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Some parts are corrupt, and most are empty CUs, that were causing the
segfault, now pahole doesn't crash and pdwtags, a debug utility that
prints most dwarf tags, produces some output.
[acme@quaco pahole]$ readelf -wi examples/asm/dw2-error.debug | grep -i corrupt
readelf: examples/asm/dw2-error.debug: Warning: Invalid pointer size (0) in compunit header, using 4 instead
readelf: examples/asm/dw2-error.debug: Warning: CU at offset 90 contains corrupt or unsupported version number: 153.
[acme@quaco pahole]$ pahole examples/asm/dw2-error.debug
[acme@quaco pahole]$ pdwtags examples/asm/dw2-error.debug
/* Types: */
/* Functions: */
/* Variables: */
/* Types: */
/* 1 */
int
/* size: 4 */
/* 2 */
/* tag__fprintf: const_type tag not supported! */; /* size: 4 */
/* Functions: */
/* Variables: */
const int _IO_stdin_used; /* size: 4 */
/* Types: */
/* Functions: */
/* Variables: */
[acme@quaco pahole]$
Reported-by: Tom de Vries
Bugtracker: https://github.com/acmel/dwarves/issues/9#issuecomment-696284602
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Commit f3d9054ba8 ("btf_encoder: Teach pahole to store percpu
variables in vmlinux BTF.") introduced an option '-j' that makes
effort in emitting VAR entries in BTF. Before no one has been using
this flag, replace the one-letter option '-j' with a full flag name
'--btf_encode_force' to save '-j' for future uses.
Committer notes:
Added missing man page entry.
Signed-off-by: Hao Luo <haoluo@google.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
A new feature was introduced in commit f3d9054ba8 ("btf_encoder: Teach
pahole to store percpu variables in vmlinux BTF.") which encodes kernel
percpu variables into BTF. Add a flag --skip_encoding_btf_vars to allow
users to toggle this feature off, so that the rollout of pahole v1.18
can be protected by potential bugs in this feature.
Committer notes:
Added missing man page entry.
Signed-off-by: Hao Luo <haoluo@google.com>
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
We don't really reconstruct source code for FORTRAN, we just print it as
if it was C:
$ pahole examples/fortran95/derived-type.debug
struct bar {
integer(kind=4) c; /* 0 4 */
real(kind=4) d; /* 4 4 */
/* size: 8, cachelines: 1, members: 2 */
/* last cacheline: 8 bytes */
};
struct foo {
real(kind=4) a; /* 0 4 */
struct bar x; /* 4 8 */
string b[7]; /* 12 7 */
/* size: 20, cachelines: 1, members: 3 */
/* padding: 1 */
/* last cacheline: 20 bytes */
};
$
This comes from GCC build tests:
$ readelf -wi examples/fortran95/derived-type.debug | grep Fortran -A2
<9c> DW_AT_producer : (indirect string, offset: 0x1fb): GNU Fortran2008 10.2.1 20200728 [revision c0438ced53bcf57e4ebb1c38c226e41571aca892] -mtune=generic -march=x86-64 -g -fno-stack-protector -J /home/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.fortran/derived-type -fintrinsic-modules-path /usr/lib64/gcc/x86_64-suse-linux/10/finclude -fpre-include=/usr/include/finclude/math-vector-fortran.h
<a0> DW_AT_language : 14 (Fortran 95)
<a1> DW_AT_identifier_case: 2 (down_case)
<a2> DW_AT_name : (indirect string, offset: 0x365): /home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.fortran/derived-type.f90
[acme@five pahole]$ readelf -wi examples/fortran95/derived-type.debug | grep DW_TAG_string_type -A2
<1><122>: Abbrev Number: 6 (DW_TAG_string_type)
<123> DW_AT_byte_size : 7
$
Now lets see whats more that is there segfaulting pahole, but for now I
think I don't have any segfaults, so just wait a bit for Hao to submit
the patch to selectively encode the per-cpu variables in BTF and then
cut v1.18.
Reported-by: Tom de Vries
Bugtracker: https://github.com/acmel/dwarves/issues/9
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This dodges a SEGFAULT at type__check_structs_at_unnatural_alignments()
so that we can finish processing, give the warnings and produce as much
as we can:
$ pahole examples/fortran95/derived-type.debug
die__process_unit: DW_TAG_string_type (0x12) @ <0x122> not handled!
namespace__recode_dwarf_types: couldn't find 0x122 type for 0x116 (member)!
struct bar {
integer(kind=4) c; /* 0 4 */
real(kind=4) d; /* 4 4 */
/* size: 8, cachelines: 1, members: 2 */
/* last cacheline: 8 bytes */
};
struct foo {
real(kind=4) a; /* 0 4 */
struct bar x; /* 4 8 */
<ERROR(__class__fprintf:1519): 0 not found!>
/* size: 20, cachelines: 1, members: 3 */
/* padding: 8 */
/* last cacheline: 20 bytes */
};
$
Reported-by: Tom de Vries
Bugtracker: https://github.com/acmel/dwarves/issues/9
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
We need to support these in a future version, for now, just bail out to
avoid segfaults afterwards.
$ pahole examples/sles/vmlinux-5.3.18-109.g8ff6392-default.debug
WARNING: DW_TAG_partial_unit used, some types will not be considered!
Probably this was optimized using a tool like 'dwz'
A future version of pahole will take support this.
$
Reported-by: Tom de Vries
Bugtracker: https://github.com/acmel/dwarves/issues/10
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
We will have to keep all CUs in memory and do lookups in imported units,
for now, just don't segfault.
Reported-by: Tom de Vries
Bugtracker: https://github.com/acmel/dwarves/issues/10
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This was on a ubuntu:18.04 system, using their cross build packages and
elfutils and zlib cross built from sources.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
To avoid build failures in architectures where HAVE_DWFL_MODULE_BUILD_ID
isn't defined.
Noticed while cross building for s390x.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
To address this clang 11 build error:
[ 86%] Building C object CMakeFiles/pahole.dir/pahole.c.o
/home/acme/git/pahole/pahole.c:1626:33: error: format string is not a string literal (potentially insecure) [-Werror,-Wformat-security]
snprintf(name, sizeof(name), enumerator__name(enumerator, cu_enumerator));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/acme/git/pahole/pahole.c:1626:33: note: treat the string as an argument to avoid this
snprintf(name, sizeof(name), enumerator__name(enumerator, cu_enumerator));
^
"%s",
1 error generated.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Another prep patch to allow for having multiple pretty printing types,
now we need to resolve all the types needed for all the classes to then
allow for multiple types.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
I.e. this:
pahole ~/bin/perf --header=perf_file_header \
-C 'perf_event_header(range=data,sizeof,type,type_enum=perf_event_type+perf_user_event_type)' < perf.data
Is equivalent to:
pahole ~/bin/perf --header=perf_file_header --range=data \
-C 'perf_event_header(sizeof,type,type_enum=perf_event_type+perf_user_event_type)' < perf.data
This is prep work for pretty printing multiple types of records, doing
it just fot that per-type range.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
I.e. when we get the type= field value, look it up in the type_enum=,
get the struct enumerator and if it is the first time that we're looking
up the string representation of that enumerator, do it and then cache
the results, so that next time we reuse it.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Since we store both the tag and the cu when we find it, defer deleting
it till we're completely sure we don't need it anymore.
Sometimes this is the only reason for us to fallback to looking at all
the cus to get all the needed types, so keeping it may make the DWARF
"stealer" to be able to, after finding the header type in one CU, find
the other needed types in another and we end up not having to process
all the CUs in a DWARF based session, speeding up the process.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
See the pahole man page:
Some of the records are not found in 'type_enum=perf_event_type' so some of the
records don't get converted to a type that fully shows its contents. For perf
we know that those are in another enumeration, 'enum perf_user_event_type', so,
for these cases, we can create a 'virtual enum', i.e. the sum of two enums
and then get all those entries decoded and properly casted, first few records
with just 'enum perf_event_type':
$ pahole ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type)' --count 4 < perf.data
{
.type = 79,
.misc = 0,
.size = 32,
},
{
.type = 73,
.misc = 0,
.size = 40,
},
{
.type = 74,
.misc = 0,
.size = 32,
},
{
.header = {
.type = PERF_RECORD_CGROUP,
.misc = 0,
.size = 40,
},
.id = 1,
.path = "/",
},
$
Now with both enumerations, i.e. with 'type_enum=perf_event_type+perf_user_event_type':
$ pahole ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type+perf_user_event_type)' --count 5 < perf.data
{
.header = {
.type = PERF_RECORD_TIME_CONV,
.misc = 0,
.size = 32,
},
.time_shift = 31,
.time_mult = 1016803377,
.time_zero = 435759009518382,
},
{
.header = {
.type = PERF_RECORD_THREAD_MAP,
.misc = 0,
.size = 40,
},
.nr = 1,
.entries = 0x50 0x7e 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00,
},
{
.header = {
.type = PERF_RECORD_CPU_MAP,
.misc = 0,
.size = 32,
},
.data = {
.type = 1,
.data = "",
},
},
{
.header = {
.type = PERF_RECORD_CGROUP,
.misc = 0,
.size = 40,
},
.id = 1,
.path = "/",
},
{
.header = {
.type = PERF_RECORD_CGROUP,
.misc = 0,
.size = 48,
},
.id = 1553,
.path = "/system.slice",
},
$
And since the fun never ends, this needs to be properly supported (arrays of
structs):
$ pahole ~/bin/perf -C perf_record_thread_map_entry
struct perf_record_thread_map_entry {
__u64 pid; /* 0 8 */
char comm[16]; /* 8 16 */
/* size: 24, cachelines: 1, members: 2 */
/* last cacheline: 24 bytes */
};
$
that 'nr' field:
$ pahole ~/bin/perf -C perf_record_thread_map
struct perf_record_thread_map {
struct perf_event_header header; /* 0 8 */
__u64 nr; /* 8 8 */
struct perf_record_thread_map_entry entries[]; /* 16 0 */
/* size: 16, cachelines: 1, members: 3 */
/* last cacheline: 16 bytes */
};
$
So probably we need something like a file with types and its pretty printing
details, with one for 'struct perf_record_thread_map':
perf_record_thread_map(entries.nr_entries=$nr)
Meaning: the perf_record_thread_map 'entries' has a number of
sizeof(typeof entries) that is defined in the perf_record_thread_map
'nr' member. Everything starting with a '$' needs to be evaluated, like
the '$header.*' we already have, since there is no 'namespace selector'
($header. in the header case) this means: the current record.
So, when pretty printing a record that has such type (perf_record_thread_map)
this has to be taken into account, and validated by the containing 'struct
perf_event_header->size' field.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
As sometimes we have multiple enums to represent some struct type, like
with perf_event_attr->type, that has 'enum perf_event_type' in Linux's
UAPI and 'enum perf_user_event_type' for purely userspace types, like
the ones synthesized for Intel PT, like PERF_RECORD_AUXTRACE, etc.
This patch just transforms type->type_enum into a list, the support for
multiple types comes next.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>