pahole(1) dwarves pahole(1) (NAME) pahole - (SYNOPSIS) pahole [options] files (DESCRIPTION) pahole DWARF CTF BTF . : ABI . : $ pahole --header elf64_hdr --prettify /lib/modules/5.8.0-rc6+/build/vmlinux { .e_ident = { 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .e_type = 2, .e_machine = 62, .e_version = 1, .e_entry = 16777216, .e_phoff = 64, .e_shoff = 604653784, .e_flags = 0, .e_ehsize = 64, .e_phentsize = 56, .e_phnum = 5, .e_shentsize = 64, .e_shnum = 80, .e_shstrndx = 79, }, $ << (PRETTY PRINTING)>> . . ELF . -g . ELF . DWARF ELF .debug_info ( ) . CTF ELF .SUNW_ctf . BTF ELF .BTF .BTF.ext . debuginfo pahole . pahole struct . /sys/kernel/btf/vmlinux BTF : $ 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 */ }; $ /sys/kernel/btf/vmlinux PAHOLE_VMLINUX_BTF_FILENAME . BTF vmlinux . pahole . BTF vmlinux build-id debuginfo DWARF . << (EXAMPLES)>> . . --count . (OPTIONS) pahole . -C, --class_name=CLASS_NAMES . URL (: file://class_list.txt) -c, --cacheline_size=SIZE cacheline SIZE . --sort . BTF DWARF thread DWARF (CUs) . --compile : $ pahole --compile > vmlinux.h C . BTF DWARF build- id . --skip_emitting_atomic_typedefs --compile 'typedef _Atomic int atomic_int' . gcc 12.2.1 DWARF typedef . --count=COUNT COUNT . --skip=COUNT COUNT . -E, --expand_types . struct struct . -F, --format_path . "btf" "ctf" "dwarf" . "-F dwarf,btf,ctf" . --hashbits=BITS . "dwarf" . . --hex (). -r, --rel_offset struct . -p, --expand_pointers . -R, --reorganize struct bitfield (alignment holes) padding. -S, --show_reorg_steps struct . -i, --contains=CLASS_NAME CLASS_NAME . --contains_enumerator=ENUMERATOR_NAME (enumeration) ENUMERATOR_NAME . $ pahole --contains_enumerator S_VERSION enum file_time_flags { S_ATIME = 1, S_MTIME = 2, S_CTIME = 4, S_VERSION = 8, } $ -a, --anon_include (anonymous). -A, --nested_anon_include ( struct ). -B, --bit_holes=NR_HOLES struct NR_HOLES . -d, --recursive . -D, --decl_exclude=PREFIX PREFIX. -f, --find_pointers_to=CLASS_NAME CLASS_NAME. -H, --holes=NR_HOLES struct NR_HOLES . --padding=SIZE_PADDING struct SIZE_PADDING padding . --padding_ge=SIZE_PADDING struct SIZE_PADDING padding . -I, --show_decl_info . --skip_encoding_btf_vars VAR percpu . VAR . "global_var" . --skip_encoding_btf_decl_tag (decl tags) BTF. --skip_encoding_btf_enum64 enum64 BTF. --skip_encoding_btf_type_tag (type tags) BTF. --skip_encoding_btf_inconsistent_proto (prototype) . -j, --jobs=N N . ( 'ninja'). -J, --btf_encode BTF DWARF CONFIG_DEBUG_INFO_BTF=y . . BPF CO-RE ( - ) . : https://nakryiko.com/posts/bpf-portability- and-co-re --btf_encode_detached=FILENAME -J/--btf_encode BTF . --btf_encode_force BTF . --btf_base=PATH BTF vmlinux BTF . /sys/kernel/btf/MODULE "/sys/kernel/btf/vmlinux" . --btf_gen_floats BTF_KIND_FLOAT DWARF vmlinux (float) . --btf_gen_optimized BTF ( isra. constprop.). --btf_gen_all BTF pahole. --btf_features=FEATURE_LIST BTF 'default' . BTF 'default' BTF BTF . 'default' pahole . : encode_force Ignore invalid symbols when encoding BTF; for example if a symbol has an invalid name, it will be ignored and BTF encoding will continue. var Encode percpu variables using BTF_KIND_VAR in BTF. float Encode floating-point types in BTF. decl_tag Encode declaration tags using BTF_KIND_DECL_TAG. type_tag Encode type tags using BTF_KIND_TYPE_TAG. enum64 Encode enum64 values with BTF_KIND_ENUM64. optimized_func Encode representations of optimized functions with suffixes like ".isra.0". consistent_func Avoid encoding inconsistent static functions. These occur when a parameter is optimized out in some CUs and not others, or when the same function name has inconsistent BTF descriptions in different CUs. ( 'default' ): attributes Allow generation of decl_tags and type_tags with kind_flag = 1. These tags can be used to encode arbitrary compiler attributes in BTF, but are backward incompatible. decl_tag_kfuncs Inject a BTF_KIND_DECL_TAG for each discovered kfunc. distilled_base For split BTF, generate a distilled version of the associated base BTF to support later relocation of split BTF with a possibly changed base, storing it in a .BTF.base ELF section. global_var Encode all global variables using BTF_KIND_VAR in BTF. --btf_encode=var,enum64 BTF ( BTF) enum64 . '+' : --btf_features=+reproducible_build 'reproducible_build' . --btf_features_strict --btf_features pahole . --supported_btf_features BTF --btf_features . --btf_features . --running_kernel_vmlinux, vmlinux build-id ( /sys/kernel/notes) debuginfo . -l, --show_first_biggest_size_base_type_member (base_type) . -m, --nr_methods . : $ pahole --nr_methods | grep -w sock sock 1005 $ BTF /sys/kernel/btf/vmlinux . -M, --show_only_data_members . ++C . -n, --nr_members . -N, --class_name_len . -O, --dwarf_offset=OFFSET DWARF OFFSET . -P, --packable struct --reorganize. -P, --with_flexible_array struct (flexible array) . -P, --with_embedded_flexible_array struct struct << >>. -q, --quiet . -s, --sizes . -t, --separator=SEP SEP . -T, --nr_definitions struct . -u, --defined_in (CUs) CLASS_NAME (-C) . --flat_arrays array[10][2] array[20] . CTF/BTF DWARF . --suppress_aligned_attribute BTF CTF ( ) DWARF . --suppress_force_paddings padding bitfield struct DW_AT_alignment DWARF BTF CTF . --suppress_packed __attribute__((__packed__)) BTF CTF DW_AT_alignment BTF . --fixup_silly_bitfields bitfield "int foo:32" "int foo". -V, --verbose . --ptr_table_stats ptr_table vmlinux . -w, --word_size=WORD_SIZE WORD_SIZE. -x, --exclude=PREFIX PREFIX. -X, --cu_exclude=PREFIX PREFIX. --lang=languages . : ada83, ada95, asm, bliss, c, c89, c99, c11, c++, c++03, c++11, c++14, cobol74, cobol85, d, dylan, fortran77, fortran90, fortran95, fortran03, fortran08, go, haskell, java, julia, modula2, modula3, objc, objc++, ocaml, opencl, pascal83, pli, python, renderscript, rust, swift, upc 'c89' . --lang_exclude=languages . Rust : pahole -j --btf_encode --lang_exclude rust PAHOLE_LANG_EXCLUDE : export PAHOLE_LANG_EXCLUDE=rust pahole -j --btf_encode 'rust' . pahole pfunct lang_exclude-- . -y, --prefix_filter=PREFIX PREFIX. -z, --hole_size_ge=HOLE_SIZE struct HOLE_SIZE. --structs struct struct --structs --sizes . --packed struct (packed) struct packed --packed --sizes . --unions union union --union --sizes . --version : "v1.18". --numeric_version Makefile : 118 "v1.18". --kabi_prefix=STRING STRING STRING . (NOTES) CONFIG_DEBUG_INFO . make menuconfig : "Kernel Hacking" -> "Compile-time checks and compiler options" -> "Compile the kernel with debug info". CONFIG_DEBUG_INFO_BTF menuconfig "Generate BTF typeinfo" . eBPF pahole . debuginfo kernel-debuginfo ( C ++C) . (EXAMPLES) /sys/kernel/btf/vmlinux ( ) build-id /sys/kernel/notes vmlinux . : $ pahole -C __u64 typedef long long unsigned int __u64; $ : $ pahole raw_spinlock_t typedef struct raw_spinlock raw_spinlock_t; $ : $ 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; $ : $ 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 */ }; $ OOPS () : $ 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 */ }; $ 'struct thread_struct' 0x178 struct 'fpu' ... 'struct thread_struct' grep : $ 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; /* 0x178 0x8 */ /* --- cacheline 6 boundary (384 bytes) --- */ /* typedef u32 -> __u32 */ unsigned int entry_eip; /* 0x180 0x4 */ } soft; /* 0x100 0x88 */ struct xregs_state { $ 'struct thread_struct' $ pahole -I thread_struct | head -2 /* Used at: /sys/kernel/btf/vmlinux */ /* <0> (null):0 */ $ BTF DWARF vmlinux : $ 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 */ $ : $ 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 $ . raw spinlock RCU : $ pahole --contains raw_spinlock_t --prefix rcu rcu_node rcu_data rcu_state $ grep : $ 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 */ }; $ (PRETTY PRINTING) pahole --prettify . '--prettify -' . stdin : $ pahole -C modversion_info drivers/scsi/sg.ko struct modversion_info { long unsigned int crc; /* 0 8 */ char name[56]; /* 8 56 */ /* size: 64, cachelines: 1, members: 2 */ }; $ $ objcopy -O binary --only-section=__versions drivers/scsi/sg.ko versions $ $ ls -la versions -rw-rw-r--. 1 acme acme 7616 Jun 25 11:33 versions $ $ pahole --count 3 -C modversion_info drivers/scsi/sg.ko --prettify versions { .crc = 0x8dabd84, .name = "module_layout", }, { .crc = 0x45e4617b, .name = "no_llseek", }, { .crc = 0xa23fae8c, .name = "param_ops_int", }, $ $ pahole --skip 1 --count 2 -C modversion_info drivers/scsi/sg.ko --prettify - < versions { .crc = 0x45e4617b, .name = "no_llseek", }, { .crc = 0xa23fae8c, .name = "param_ops_int", }, $ : $ pahole --seek_bytes 64 --count 1 -C modversion_info drivers/scsi/sg.ko --prettify versions { .crc = 0x45e4617b, .name = "no_llseek", }, $ -C, --class_name=CLASS_NAME . : -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_EXIT)' 'struct perf_event_header' 'size' struct ( ) 'enum perf_event_type' perf_event_header->type struct ( ) enum type 'perf_event_header' . << (PRETTY PRINTING EXAMPLES)>> . 'filter=' '==' 'type' 'PERF_RECORD_EXIT' type_enum . 'sizeof' 'size' 'sizeof=sz' . 'type=other_member_name' 'type' . (PRETTY PRINTING EXAMPLES) ELF vmlinux BTF ELF : $ pahole --sizes | grep -i elf | grep -i _h elf64_hdr 64 0 elf32_hdr 52 0 $ : $ pahole -C elf64_hdr --count 1 --prettify /lib/modules/5.8.0-rc3+/build/vmlinux { .e_ident = { 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, .e_type = 2, .e_machine = 62, .e_version = 1, .e_entry = 16777216, .e_phoff = 64, .e_shoff = 775923840, .e_flags = 0, .e_ehsize = 64, .e_phentsize = 56, .e_phnum = 5, .e_shentsize = 64, .e_shnum = 80, .e_shstrndx = 79, }, $ : $ pahole --header elf64_hdr --prettify /lib/modules/5.8.0-rc3+/build/vmlinux --header . perf.data: $ pahole --hex ~/bin/perf --header perf_file_header --prettify perf.data { .magic = 0x32454c4946524550, .size = 0x68, .attr_size = 0x88, .attrs = { .offset = 0xa8, .size = 0x88, }, .data = { .offset = 0x130, .size = 0x588, }, .event_types = { .offset = 0, .size = 0, }, .adds_features = { 0x16717ffc, 0, 0, 0 }, }, $ cgroups perf_file_header.data : $ 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,filter=type==PERF_RECORD_CGROUP)' --prettify perf.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", }, { .header = { .type = PERF_RECORD_CGROUP, .misc = 0, .size = 48, }, .id = 8, .path = "/machine.slice", }, { .header = { .type = PERF_RECORD_CGROUP, .misc = 0, .size = 128, }, .id = 7828, .path = "/machine.slice/libpod-42be8e8d4eb9d22405845005f0d04ea398548dccc934a150fbaa3c1f1f9492c2.scope", }, { .header = { .type = PERF_RECORD_CGROUP, .misc = 0, .size = 88, }, .id = 13, .path = "/machine.slice/machine-qemu\x2d1\x2drhel6.sandy.scope", }, $ 'offset' 'size' : $ pahole ~/bin/perf --header=perf_file_header --range=data -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_CGROUP)' --prettify perf.data ~/bin/perf 'struct perf_file_header' '$header.data.offset' '$header.data.size' . 'filter=type==CGROUP' '=filter' 'type==CGROUP' : : $ pahole ~/bin/perf -C perf_event_header struct perf_event_header { __u32 type; /* 0 4 */ __u16 misc; /* 4 2 */ __u16 size; /* 6 2 */ /* size: 8, cachelines: 1, members: 3 */ /* last cacheline: 8 bytes */ }; $ : $ pahole ~/bin/perf -C perf_event_type enum perf_event_type { PERF_RECORD_MMAP = 1, PERF_RECORD_LOST = 2, PERF_RECORD_COMM = 3, PERF_RECORD_EXIT = 4, PERF_RECORD_THROTTLE = 5, PERF_RECORD_UNTHROTTLE = 6, PERF_RECORD_FORK = 7, PERF_RECORD_READ = 8, PERF_RECORD_SAMPLE = 9, PERF_RECORD_MMAP2 = 10, PERF_RECORD_AUX = 11, PERF_RECORD_ITRACE_START = 12, PERF_RECORD_LOST_SAMPLES = 13, PERF_RECORD_SWITCH = 14, PERF_RECORD_SWITCH_CPU_WIDE = 15, PERF_RECORD_NAMESPACES = 16, PERF_RECORD_KSYMBOL = 17, PERF_RECORD_BPF_EVENT = 18, PERF_RECORD_CGROUP = 19, PERF_RECORD_TEXT_POKE = 20, PERF_RECORD_MAX = 21, }; $ : $ pahole ~/bin/perf -C perf_record_cgroup struct perf_record_cgroup { struct perf_event_header header; /* 0 8 */ __u64 id; /* 8 8 */ char path[4096]; /* 16 4096 */ /* size: 4112, cachelines: 65, members: 3 */ /* last cacheline: 16 bytes */ }; $ perf_event_header.type __u32 (PERF_RECORD_CGROUP) . type_enum=perf_event_type 'struct perf_event_header' 'struct perf_record_cgroup' header.type : $ pahole ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,filter=type==19)' --prettify perf.data { .type = 19, .misc = 0, .size = 40, }, { .type = 19, .misc = 0, .size = 48, }, { .type = 19, .misc = 0, .size = 48, }, { .type = 19, .misc = 0, .size = 128, }, { .type = 19, .misc = 0, .size = 88, }, $ 'type_enum=perf_event_type' . perf 'enum perf_user_event_type' <>> enum '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 --prettify 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 = "/", }, $ '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 --prettify 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", }, $ perf.data dump perf_file_header perf_file_attr attrs perf_event_header data : pahole ~/bin/perf --header=perf_file_header -C 'perf_file_attr(range=attrs),perf_event_header(range=data,sizeof,type,type_enum=perf_event_type+perf_user_event_type)' --prettify perf.data (SEE ALSO) eu-readelf(1), readelf(1), objdump(1). https://www.kernel.org/doc/ols/2007/ols2007v2-pages-35-44.pdf. (AUTHOR) pahole Arnaldo Carvalho de Melo . Andrii Nakryiko Martin KaFai Lau BTF BTF .BTF DWARF gcc . Andrii BTF (deduplicator) libbpf pahole . Conectiva Mandriva Red Hat . . . dwarves January 16, 2020 pahole(1)