blob: 8c58ba1ed55c387ba6cf630ae857bcbf30b282e1 [file] [log] [blame]
.\" Man page for pahole
.\" Arnaldo Carvalho de Melo, 2009
.\" Licensed under version 2 of the GNU General Public License.
.TH pahole 1 "January 16, 2020" "dwarves" "dwarves"
.\"
.SH NAME
pahole \- Shows and manipulates data structure layout.
.SH SYNOPSIS
\fBpahole\fR [\fIoptions\fR] \fIfiles\fR
.SH DESCRIPTION
.B pahole
shows data structure layouts encoded in debugging information formats,
DWARF and CTF being supported.
This is useful for, among other things: optimizing important data structures by
reducing its size, figuring out what is the field sitting at an offset from the
start of a data structure, investigating ABI changes and more generally
understanding a new codebase you have to work with.
The files must have associated debugging information. This information may be
inside the file itself, in ELF sections, or in another file.
One way to have this information is to specify the \fB\-g\fR option to the
compiler when building it. When this is done the information will be stored in
an ELF section. For the DWARF debugging information format this, adds, among
others, the \fB.debug_info\fR ELF section. For CTF it is found in just one ELF
section, \fB.SUNW_ctf\fR. BTF comes in at least the \fB.BTF\fR ELF section, and
may come also with the \fB.BTF.ext\fR ELF section.
The \fBdebuginfo\fR packages available in most Linux distributions are also
supported by \fBpahole\fR, where the debugging information is available in a
separate file.
By default, \fBpahole\fR shows the layout of all named structs in the files
specified.
If no files are specified, then it will look if the /sys/kernel/btf/vmlinux
is present, using the BTF information present in it about the running kernel,
i.e. this works:
.PP
.nf
$ pahole list_head
struct list_head {
struct list_head * next; /* 0 8 */
struct list_head * prev; /* 8 8 */
/* size: 16, cachelines: 1, members: 2 */
/* last cacheline: 16 bytes */
};
$
.fi
If BTF is not present and no file is passed, then a vmlinux that matches the
build-id for the running kernel will be looked up in the usual places,
including where the kernel debuginfo packages put it, looking for DWARF info
instead.
See the EXAMPLES section for more usage suggestions.
.SH OPTIONS
pahole supports the following options.
.TP
.B \-C, \-\-class_name=CLASS_NAMES
Show just these classes. This can be a comma separated list of class names
or file URLs (e.g.: file://class_list.txt)
.TP
.B \-c, \-\-cacheline_size=SIZE
Set cacheline size to SIZE bytes.
.TP
.B \-E, \-\-expand_types
Expand class members. Useful to find in what member of inner structs where an
offset from the beginning of a struct is.
.TP
.B \-F, \-\-format_path
Allows specifying a list of debugging formats to try, in order. Right now this
includes "ctf" and "dwarf". The default format path used is equivalent to
"-F dwarf,ctf".
.TP
.B \-\-hex
Print offsets and sizes in hexadecimal.
.TP
.B \-r, \-\-rel_offset
Show relative offsets of members in inner structs.
.TP
.B \-p, \-\-expand_pointers
Expand class pointer members.
.TP
.B \-R, \-\-reorganize
Reorganize struct, demoting and combining bitfields, moving members to remove
alignment holes and padding.
.TP
.B \-S, \-\-show_reorg_steps
Show the struct layout at each reorganization step.
.TP
.B \-i, \-\-contains=CLASS_NAME
Show classes that contains CLASS_NAME.
.TP
.B \-a, \-\-anon_include
Include anonymous classes.
.TP
.B \-A, \-\-nested_anon_include
Include nested (inside other structs) anonymous classes.
.TP
.B \-B, \-\-bit_holes=NR_HOLES
Show only structs at least NR_HOLES bit holes.
.TP
.B \-d, \-\-recursive
Recursive mode, affects several other flags.
.TP
.B \-D, \-\-decl_exclude=PREFIX
exclude classes declared in files with PREFIX.
.TP
.B \-f, \-\-find_pointers_to=CLASS_NAME
Find pointers to CLASS_NAME.
.TP
.B \-H, \-\-holes=NR_HOLES
Show only structs with at least NR_HOLES holes.
.TP
.B \-I, \-\-show_decl_info
Show the file and line number where the tags were defined, if available in
the debugging information.
.TP
.B \-l, \-\-show_first_biggest_size_base_type_member
Show first biggest size base_type member.
.TP
.B \-m, \-\-nr_methods
Show number of methods.
.TP
.B \-M, \-\-show_only_data_members
Show only the members that use space in the class layout. C++ methods will be
suppressed.
.TP
.B \-n, \-\-nr_members
Show number of members.
.TP
.B \-N, \-\-class_name_len
Show size of classes.
.TP
.B \-O, \-\-dwarf_offset=OFFSET
Show tag with DWARF OFFSET.
.TP
.B \-P, \-\-packable
Show only structs that has holes that can be packed if members are reorganized,
for instance when using the \fB\-\-reorganize\fR option.
.TP
.B \-q, \-\-quiet
Be quieter.
.TP
.B \-s, \-\-sizes
Show size of classes.
.TP
.B \-t, \-\-separator=SEP
Use SEP as the field separator.
.TP
.B \-T, \-\-nr_definitions
Show how many times struct was defined.
.TP
.B \-u, \-\-defined_in
Show CUs where CLASS_NAME (-C) is defined.
.TP
.B \-\-flat_arrays
Flatten arrays, so that array[10][2] becomes array[20].
Useful when generating from both CTF/BTF and DWARF encodings
for the same binary for testing purposes.
.TP
.B \-\-suppress_aligned_attribute
Suppress forced alignment markers, so that one can compare BTF or
CTF output, that don't have that info, to output from DWARF >= 5.
.TP
.B \-\-suppress_force_paddings
Suppress bitfield forced padding at the end of structs, as this requires
something like DWARF's DW_AT_alignment, so that one can compare BTF or CTF
output, that don't have that info.
.TP
.B \-\-suppress_packed
Suppress the output of the inference of __attribute__((__packed__)), so that
one can compare BTF or CTF output, the inference algorithm uses things like
DW_AT_alignment, so until it is improved to infer that as well for BTF, allow
disabling this output.
.TP
.B \-\-fixup_silly_bitfields
Converts silly bitfields such as "int foo:32" to plain "int foo".
.TP
.B \-V, \-\-verbose
be verbose
.TP
.B \-w, \-\-word_size=WORD_SIZE
Change the arch word size to WORD_SIZE.
.TP
.B \-x, \-\-exclude=PREFIX
Exclude PREFIXed classes.
.TP
.B \-X, \-\-cu_exclude=PREFIX
Exclude PREFIXed compilation units.
.TP
.B \-y, \-\-prefix_filter=PREFIX
Include PREFIXed classes.
.TP
.B \-z, \-\-hole_size_ge=HOLE_SIZE
Show only structs with at least one hole greater or equal to HOLE_SIZE.
.TP
.B \-\-structs
Show only structs, all the other filters apply, i.e. to show just the sizes of all structs
coimbine --structs with --sizes, etc.
.TP
.B \-\-unions
Show only unions, all the other filters apply, i.e. to show just the sizes of all unions
coimbine --union with --sizes, etc.
.SH NOTES
To enable the generation of debugging information in the Linux kernel build
process select CONFIG_DEBUG_INFO. This can be done using make menuconfig by
this path: "Kernel Hacking" -> "Compile-time checks and compiler options" ->
"Compile the kernel with debug info". Consider as well enabling
CONFIG_DEBUG_INFO_BTF by going thru the aforementioned menuconfig path and then
selecting "Generate BTF typeinfo". Most modern distributions with eBPF support
should come with that in all its kernels, greatly facilitating the use of
pahole.
Many distributions also come with debuginfo packages, so just enable it in your
package manager repository configuration and install the kernel-debuginfo, or
any other userspace program written in a language that the compiler generates
debuginfo (C, C++, for instance).
.SH EXAMPLES
All the examples here use either /sys/kernel/btf/vmlinux, if present, or lookup
a vmlinux file matching the running kernel, using the build-id info found in
/sys/kernel/notes to make sure it matches.
.P
Show a type:
.PP
.nf
$ pahole -C __u64
typedef long long unsigned int __u64;
$
.fi
.P
Works as well if the only argument is a type name:
.PP
.nf
$ pahole raw_spinlock_t
typedef struct raw_spinlock raw_spinlock_t;
$
.fi
.P
Multiple types can be passed, separated by commas:
.PP
.nf
$ pahole raw_spinlock_t,raw_spinlock
struct raw_spinlock {
arch_spinlock_t raw_lock; /* 0 4 */
/* size: 4, cachelines: 1, members: 1 */
/* last cacheline: 4 bytes */
};
typedef struct raw_spinlock raw_spinlock_t;
$
.fi
.P
Types can be expanded:
.PP
.nf
$ pahole -E raw_spinlock
struct raw_spinlock {
/* typedef arch_spinlock_t */ struct qspinlock {
union {
/* typedef atomic_t */ struct {
int counter; /* 0 4 */
} val; /* 0 4 */
struct {
/* typedef u8 -> __u8 */ unsigned char locked; /* 0 1 */
/* typedef u8 -> __u8 */ unsigned char pending; /* 1 1 */
}; /* 0 2 */
struct {
/* typedef u16 -> __u16 */ short unsigned int locked_pending; /* 0 2 */
/* typedef u16 -> __u16 */ short unsigned int tail; /* 2 2 */
}; /* 0 4 */
}; /* 0 4 */
} raw_lock; /* 0 4 */
/* size: 4, cachelines: 1, members: 1 */
/* last cacheline: 4 bytes */
};
$
.fi
.P
When decoding OOPSes you may want to see the offsets and sizes in hexadecimal:
.PP
.nf
$ pahole --hex thread_struct
struct thread_struct {
struct desc_struct tls_array[3]; /* 0 0x18 */
long unsigned int sp; /* 0x18 0x8 */
short unsigned int es; /* 0x20 0x2 */
short unsigned int ds; /* 0x22 0x2 */
short unsigned int fsindex; /* 0x24 0x2 */
short unsigned int gsindex; /* 0x26 0x2 */
long unsigned int fsbase; /* 0x28 0x8 */
long unsigned int gsbase; /* 0x30 0x8 */
struct perf_event * ptrace_bps[4]; /* 0x38 0x20 */
/* --- cacheline 1 boundary (64 bytes) was 24 bytes ago --- */
long unsigned int debugreg6; /* 0x58 0x8 */
long unsigned int ptrace_dr7; /* 0x60 0x8 */
long unsigned int cr2; /* 0x68 0x8 */
long unsigned int trap_nr; /* 0x70 0x8 */
long unsigned int error_code; /* 0x78 0x8 */
/* --- cacheline 2 boundary (128 bytes) --- */
struct io_bitmap * io_bitmap; /* 0x80 0x8 */
long unsigned int iopl_emul; /* 0x88 0x8 */
mm_segment_t addr_limit; /* 0x90 0x8 */
unsigned int sig_on_uaccess_err:1; /* 0x98: 0 0x4 */
unsigned int uaccess_err:1; /* 0x98:0x1 0x4 */
/* XXX 30 bits hole, try to pack */
/* XXX 36 bytes hole, try to pack */
/* --- cacheline 3 boundary (192 bytes) --- */
struct fpu fpu; /* 0xc0 0x1040 */
/* size: 4352, cachelines: 68, members: 20 */
/* sum members: 4312, holes: 1, sum holes: 36 */
/* sum bitfield members: 2 bits, bit holes: 1, sum bit holes: 30 bits */
};
$
.fi
.P
OK, I know the offset that causes its a 'struct thread_struct' and that the offset is 0x178,
so must be in that 'fpu' struct... No problem, expand 'struct thread_struct' and combine with \fBgrep\fR:
.PP
.nf
$ pahole --hex -E thread_struct | egrep '(0x178|struct fpu)' -B4 -A4
/* XXX 30 bits hole, try to pack */
/* XXX 36 bytes hole, try to pack */
/* --- cacheline 3 boundary (192 bytes) --- */
struct fpu {
unsigned int last_cpu; /* 0xc0 0x4 */
/* XXX 4 bytes hole, try to pack */
--
/* typedef u8 -> __u8 */ unsigned char alimit; /* 0x171 0x1 */
/* XXX 6 bytes hole, try to pack */
struct math_emu_info * info; /* \fI0x178\fR 0x8 */
/* --- cacheline 6 boundary (384 bytes) --- */
/* typedef u32 -> __u32 */ unsigned int entry_eip; /* 0x180 0x4 */
} soft; /* 0x100 0x88 */
struct xregs_state {
$
.fi
.P
Want to know where 'struct thread_struct' is defined in the kernel sources?
.PP
.nf
$ pahole -I thread_struct | head -2
/* Used at: /sys/kernel/btf/vmlinux */
/* <0> (null):0 */
$
.fi
.P
Not present in BTF, so use DWARF, takes a little bit longer, and assuming it finds the matching vmlinux file:
.PP
.nf
$ pahole -Fdwarf -I thread_struct | head -2
/* Used at: /home/acme/git/linux/arch/x86/kernel/head64.c */
/* <3333> /home/acme/git/linux/arch/x86/include/asm/processor.h:485 */
$
.fi
.P
To find the biggest data structures in the Linux kernel:
.PP
.nf
$ pahole -s | sort -k2 -nr | head -5
cmp_data 290904 1
dec_datas 274520 1
cpu_entry_area 217088 0
pglist_data 172928 4
saved_cmdlines_buffer 131104 1
$
.fi
.P
The second column is the size in bytes and the third is the number of alignment holes in
that structure.
.P
Show data structures that have a raw spinlock and are related to the RCU mechanism:
.PP
.nf
$ pahole --contains raw_spinlock_t --prefix rcu
rcu_node
rcu_data
rcu_state
$
.fi
.P
To see that in context, combine it with \fIgrep\fR:
.PP
.nf
$ pahole rcu_state | grep raw_spinlock_t -B1 -A5
/* --- cacheline 52 boundary (3328 bytes) --- */
raw_spinlock_t ofl_lock; /* 3328 4 */
/* size: 3392, cachelines: 53, members: 35 */
/* sum members: 3250, holes: 7, sum holes: 82 */
/* padding: 60 */
};
$
.fi
.P
.SH SEE ALSO
\fIeu-readelf\fR(1), \fIreadelf\fR(1), \fIobjdump\fR(1).
.P
\fIhttps://www.kernel.org/doc/ols/2007/ols2007v2-pages-35-44.pdf\fR.
.SH AUTHOR
\fBpahole\fR was written and is maintained by Arnaldo Carvalho de Melo <acme@kernel.org>.
.P
Thanks to Andrii Nakryiko and Martin KaFai Lau for providing the BTF encoder
and improving the codebase while making sure the BTF encoder works as needed
to be used in encoding the Linux kernel .BTF section from the DWARF info
generated by gcc. For that Andrii wrote a BTF deduplicator in libbpf that is
used by \fBpahole\fR.
.P
Please send bug reports to <dwarves@vger.kernel.org>.
.P
No\ subscription is required.