1pahole(1)                           dwarves                          pahole(1)
2
3
4

NAME

6       pahole - Shows, manipulates data structure layout and pretty prints raw
7       data.
8

SYNOPSIS

10       pahole [options] files
11

DESCRIPTION

13       pahole shows data structure layouts encoded  in  debugging  information
14       formats, DWARF, CTF and BTF being supported.
15
16       This  is  useful  for,  among  other  things: optimizing important data
17       structures by reducing its size, figuring out what is the field sitting
18       at  an  offset  from  the  start of a data structure, investigating ABI
19       changes and more generally understanding a new  codebase  you  have  to
20       work with.
21
22       It  also  uses these structure layouts to pretty print data feed to its
23       standard input, e.g.:
24
25       $ pahole --header elf64_hdr < /lib/modules/5.8.0-rc6+/build/vmlinux
26       {
27            .e_ident = { 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
28            .e_type = 2,
29            .e_machine = 62,
30            .e_version = 1,
31            .e_entry = 16777216,
32            .e_phoff = 64,
33            .e_shoff = 604653784,
34            .e_flags = 0,
35            .e_ehsize = 64,
36            .e_phentsize = 56,
37            .e_phnum = 5,
38            .e_shentsize = 64,
39            .e_shnum = 80,
40            .e_shstrndx = 79,
41       },
42       $
43
44       See the PRETTY PRINTING section for further examples and documentation.
45
46       The files must have associated debugging information.  This information
47       may be inside the file itself, in ELF sections, or in another file.
48
49       One  way  to  have  this information is to specify the -g option to the
50       compiler when building it. When this is done the  information  will  be
51       stored  in  an  ELF section. For the DWARF debugging information format
52       this, adds, among others, the .debug_info ELF section. For  CTF  it  is
53       found  in  just  one  ELF section, .SUNW_ctf. BTF comes in at least the
54       .BTF ELF section, and may come also with the .BTF.ext ELF section.
55
56       The debuginfo packages available in most Linux distributions  are  also
57       supported  by pahole, where the debugging information is available in a
58       separate file.
59
60       By default, pahole shows the layout of all named structs in  the  files
61       specified.
62
63       If no files are specified, then it will look if the /sys/kernel/btf/vm‐
64       linux is present, using the BTF information present  in  it  about  the
65       running kernel, i.e. this works:
66
67       $ pahole list_head
68       struct list_head {
69            struct list_head *         next;                 /*     0     8 */
70            struct list_head *         prev;                 /*     8     8 */
71
72            /* size: 16, cachelines: 1, members: 2 */
73            /* last cacheline: 16 bytes */
74       };
75       $
76
77       If  BTF  is  not  present  and  no  file is passed, then a vmlinux that
78       matches the build-id for the running kernel will be looked  up  in  the
79       usual  places,  including  where  the kernel debuginfo packages put it,
80       looking for DWARF info instead.
81
82       See the EXAMPLES section for more usage suggestions.
83
84       It also pretty prints whatever is fed to its standard input,  according
85       to the type specified, see the EXAMPLE session.
86
87       Use --count to state how many records should be pretty printed.
88
89

OPTIONS

91       pahole supports the following options.
92
93
94       -C, --class_name=CLASS_NAMES
95              Show  just  these classes. This can be a comma separated list of
96              class names or file URLs (e.g.: file://class_list.txt)
97
98
99       -c, --cacheline_size=SIZE
100              Set cacheline size to SIZE bytes.
101
102
103       --count=COUNT
104              Pretty print the first COUNT records from input.
105
106
107       --skip=COUNT
108              Skip COUNT input records.
109
110
111       -E, --expand_types
112              Expand class members. Useful to find in  what  member  of  inner
113              structs where an offset from the beginning of a struct is.
114
115
116       -F, --format_path
117              Allows  specifying a list of debugging formats to try, in order.
118              Right now this includes "ctf" and "dwarf".  The  default  format
119              path used is equivalent to "-F dwarf,ctf".
120
121
122       --hex  Print offsets and sizes in hexadecimal.
123
124
125       -r, --rel_offset
126              Show relative offsets of members in inner structs.
127
128
129       -p, --expand_pointers
130              Expand class pointer members.
131
132
133       -R, --reorganize
134              Reorganize struct, demoting and combining bitfields, moving mem‐
135              bers to remove alignment holes and padding.
136
137
138       -S, --show_reorg_steps
139              Show the struct layout at each reorganization step.
140
141
142       -i, --contains=CLASS_NAME
143              Show classes that contains CLASS_NAME.
144
145
146       -a, --anon_include
147              Include anonymous classes.
148
149
150       -A, --nested_anon_include
151              Include nested (inside other structs) anonymous classes.
152
153
154       -B, --bit_holes=NR_HOLES
155              Show only structs at least NR_HOLES bit holes.
156
157
158       -d, --recursive
159              Recursive mode, affects several other flags.
160
161
162       -D, --decl_exclude=PREFIX
163              exclude classes declared in files with PREFIX.
164
165
166       -f, --find_pointers_to=CLASS_NAME
167              Find pointers to CLASS_NAME.
168
169
170       -H, --holes=NR_HOLES
171              Show only structs with at least NR_HOLES holes.
172
173
174       -I, --show_decl_info
175              Show the file and line number where the tags  were  defined,  if
176              available in the debugging information.
177
178
179       --skip_encoding_btf_vars
180              Do not encode VARs in BTF.
181
182
183       -J, --btf_encode
184              Encode  BTF  information  from  DWARF,  used in the Linux kernel
185              build process when CONFIG_DEBUG_INFO_BTF=y  is  present,  intro‐
186              duced  in Linux v5.2. Used to implement features such as BPF CO-
187              RE (Compile Once - Run Everywhere).
188
189              See https://nakryiko.com/posts/bpf-portability-and-co-re/.
190
191
192       --btf_encode_force
193              Ignore those symbols found invalid when encoding BTF.
194
195
196       --btf_base=PATH
197              Path to the base BTF file, for instance: vmlinux  when  encoding
198              kernel module BTF information.  This may be inferred when asking
199              for a /sys/kernel/btf/MODULE, when it will be autoconfigured  to
200              "/sys/kernel/btf/vmlinux".
201
202
203       --btf_gen_floats
204              Allow  producing BTF_KIND_FLOAT entries in systems where the vm‐
205              linux DWARF information has float types.
206
207
208       --btf_gen_all
209              Allow using all the BTF features supported by pahole.
210
211
212       -l, --show_first_biggest_size_base_type_member
213              Show first biggest size base_type member.
214
215
216       -m, --nr_methods
217              Show number of methods.
218
219
220       -M, --show_only_data_members
221              Show only the members that use space in the  class  layout.  C++
222              methods will be suppressed.
223
224
225       -n, --nr_members
226              Show number of members.
227
228
229       -N, --class_name_len
230              Show size of classes.
231
232
233       -O, --dwarf_offset=OFFSET
234              Show tag with DWARF OFFSET.
235
236
237       -P, --packable
238              Show  only  structs that has holes that can be packed if members
239              are reorganized, for instance when using  the  --reorganize  op‐
240              tion.
241
242
243       -q, --quiet
244              Be quieter.
245
246
247       -s, --sizes
248              Show size of classes.
249
250
251       -t, --separator=SEP
252              Use SEP as the field separator.
253
254
255       -T, --nr_definitions
256              Show how many times struct was defined.
257
258
259       -u, --defined_in
260              Show CUs where CLASS_NAME (-C) is defined.
261
262
263       --flat_arrays
264              Flatten  arrays, so that array[10][2] becomes array[20].  Useful
265              when generating from both CTF/BTF and DWARF  encodings  for  the
266              same binary for testing purposes.
267
268
269       --suppress_aligned_attribute
270              Suppress  forced  alignment markers, so that one can compare BTF
271              or CTF output, that don't have that info, to output  from  DWARF
272              >= 5.
273
274
275       --suppress_force_paddings
276
277              Suppress  bitfield forced padding at the end of structs, as this
278              requires something like DWARF's DW_AT_alignment, so that one can
279              compare BTF or CTF output, that don't have that info.
280
281
282       --suppress_packed
283
284              Suppress    the    output   of   the   inference   of   __attri‐
285              bute__((__packed__)), so that one can compare BTF or CTF output,
286              the inference algorithm uses things like DW_AT_alignment, so un‐
287              til it is improved to infer that as well  for  BTF,  allow  dis‐
288              abling this output.
289
290
291       --fixup_silly_bitfields
292              Converts  silly  bitfields  such  as  "int foo:32" to plain "int
293              foo".
294
295
296       -V, --verbose
297              be verbose
298
299
300       -w, --word_size=WORD_SIZE
301              Change the arch word size to WORD_SIZE.
302
303
304       -x, --exclude=PREFIX
305              Exclude PREFIXed classes.
306
307
308       -X, --cu_exclude=PREFIX
309              Exclude PREFIXed compilation units.
310
311
312       -y, --prefix_filter=PREFIX
313              Include PREFIXed classes.
314
315
316       -z, --hole_size_ge=HOLE_SIZE
317              Show only structs with at least one hole  greater  or  equal  to
318              HOLE_SIZE.
319
320
321       --structs
322              Show  only  structs,  all  the other filters apply, i.e. to show
323              just the sizes of all structs combine  --structs  with  --sizes,
324              etc.
325
326
327       --packed
328              Show  only  packed structs, all the other filters apply, i.e. to
329              show just the sizes of all packed structs combine --packed  with
330              --sizes, etc.
331
332
333       --unions
334              Show only unions, all the other filters apply, i.e. to show just
335              the sizes of all unions combine --union with --sizes, etc.
336
337
338       --version
339              Show a traditional string version, i.e.: "v1.18".
340
341
342       --numeric_version
343              Show a numeric only version, suitable for use in  Makefiles  and
344              scripts  where  one  wants to know what if the installed version
345              has some feature, i.e.: 118 instead of "v1.18".
346
347

NOTES

349       To enable the generation of debugging information in the  Linux  kernel
350       build  process  select  CONFIG_DEBUG_INFO.  This can be done using make
351       menuconfig by this path: "Kernel Hacking" -> "Compile-time  checks  and
352       compiler  options" -> "Compile the kernel with debug info". Consider as
353       well enabling CONFIG_DEBUG_INFO_BTF by going  thru  the  aforementioned
354       menuconfig path and then selecting "Generate BTF typeinfo". Most modern
355       distributions with eBPF support should come with that in all  its  ker‐
356       nels, greatly facilitating the use of pahole.
357
358       Many distributions also come with debuginfo packages, so just enable it
359       in your package manager repository configuration and install  the  ker‐
360       nel-debuginfo,  or  any  other  userspace program written in a language
361       that the compiler generates debuginfo (C, C++, for instance).
362
363

EXAMPLES

365       All the examples here use either /sys/kernel/btf/vmlinux,  if  present,
366       or  lookup a vmlinux file matching the running kernel, using the build-
367       id info found in /sys/kernel/notes to make sure it matches.
368
369       Show a type:
370
371       $ pahole -C __u64
372       typedef long long unsigned int __u64;
373       $
374
375
376       Works as well if the only argument is a type name:
377
378       $ pahole raw_spinlock_t
379       typedef struct raw_spinlock raw_spinlock_t;
380       $
381
382
383       Multiple types can be passed, separated by commas:
384
385       $ pahole raw_spinlock_t,raw_spinlock
386       struct raw_spinlock {
387            arch_spinlock_t            raw_lock;             /*     0     4 */
388
389            /* size: 4, cachelines: 1, members: 1 */
390            /* last cacheline: 4 bytes */
391       };
392       typedef struct raw_spinlock raw_spinlock_t;
393       $
394
395
396       Types can be expanded:
397
398       $ pahole -E raw_spinlock
399       struct raw_spinlock {
400               /* typedef arch_spinlock_t */ struct qspinlock {
401                       union {
402                               /* typedef atomic_t */ struct {
403                                       int counter;                                                  /*     0     4 */
404                               } val;                                                                /*     0     4 */
405                               struct {
406                                       /* typedef u8 -> __u8 */ unsigned char locked;                /*     0     1 */
407                                       /* typedef u8 -> __u8 */ unsigned char pending;               /*     1     1 */
408                               };                                                                    /*     0     2 */
409                               struct {
410                                       /* typedef u16 -> __u16 */ short unsigned int locked_pending; /*     0     2 */
411                                       /* typedef u16 -> __u16 */ short unsigned int tail;           /*     2     2 */
412                               };                                                                    /*     0     4 */
413                       };                                                                            /*     0     4 */
414               } raw_lock;                                                                           /*     0     4 */
415
416               /* size: 4, cachelines: 1, members: 1 */
417               /* last cacheline: 4 bytes */
418       };
419       $
420
421
422       When decoding OOPSes you may want to see the offsets and sizes in hexa‐
423       decimal:
424
425       $ pahole --hex thread_struct
426       struct thread_struct {
427               struct desc_struct         tls_array[3];         /*     0  0x18 */
428               long unsigned int          sp;                   /*  0x18   0x8 */
429               short unsigned int         es;                   /*  0x20   0x2 */
430               short unsigned int         ds;                   /*  0x22   0x2 */
431               short unsigned int         fsindex;              /*  0x24   0x2 */
432               short unsigned int         gsindex;              /*  0x26   0x2 */
433               long unsigned int          fsbase;               /*  0x28   0x8 */
434               long unsigned int          gsbase;               /*  0x30   0x8 */
435               struct perf_event *        ptrace_bps[4];        /*  0x38  0x20 */
436               /* --- cacheline 1 boundary (64 bytes) was 24 bytes ago --- */
437               long unsigned int          debugreg6;            /*  0x58   0x8 */
438               long unsigned int          ptrace_dr7;           /*  0x60   0x8 */
439               long unsigned int          cr2;                  /*  0x68   0x8 */
440               long unsigned int          trap_nr;              /*  0x70   0x8 */
441               long unsigned int          error_code;           /*  0x78   0x8 */
442               /* --- cacheline 2 boundary (128 bytes) --- */
443               struct io_bitmap *         io_bitmap;            /*  0x80   0x8 */
444               long unsigned int          iopl_emul;            /*  0x88   0x8 */
445               mm_segment_t               addr_limit;           /*  0x90   0x8 */
446               unsigned int               sig_on_uaccess_err:1; /*  0x98: 0 0x4 */
447               unsigned int               uaccess_err:1;        /*  0x98:0x1 0x4 */
448
449               /* XXX 30 bits hole, try to pack */
450               /* XXX 36 bytes hole, try to pack */
451
452               /* --- cacheline 3 boundary (192 bytes) --- */
453               struct fpu                 fpu;                  /*  0xc0 0x1040 */
454
455               /* size: 4352, cachelines: 68, members: 20 */
456               /* sum members: 4312, holes: 1, sum holes: 36 */
457               /* sum bitfield members: 2 bits, bit holes: 1, sum bit holes: 30 bits */
458       };
459       $
460
461
462       OK, I know the offset that causes its a 'struct thread_struct' and that
463       the offset is 0x178, so must be in that 'fpu' struct... No problem, ex‐
464       pand 'struct thread_struct' and combine with grep:
465
466       $ pahole --hex -E thread_struct | egrep '(0x178|struct fpu)' -B4 -A4
467               /* XXX 30 bits hole, try to pack */
468               /* XXX 36 bytes hole, try to pack */
469
470               /* --- cacheline 3 boundary (192 bytes) --- */
471               struct fpu {
472                       unsigned int       last_cpu;                                             /*  0xc0   0x4 */
473
474                       /* XXX 4 bytes hole, try to pack */
475
476       --
477                                       /* typedef u8 -> __u8 */ unsigned char alimit;           /* 0x171   0x1 */
478
479                                       /* XXX 6 bytes hole, try to pack */
480
481                                       struct math_emu_info * info;                             /* 0x178   0x8 */
482                                       /* --- cacheline 6 boundary (384 bytes) --- */
483                                       /* typedef u32 -> __u32 */ unsigned int entry_eip;       /* 0x180   0x4 */
484                               } soft; /* 0x100  0x88 */
485                               struct xregs_state {
486       $
487
488
489       Want  to  know  where  'struct  thread_struct' is defined in the kernel
490       sources?
491
492       $ pahole -I thread_struct | head -2
493       /* Used at: /sys/kernel/btf/vmlinux */
494       /* <0> (null):0 */
495       $
496
497
498       Not present in BTF, so use DWARF, takes a little bit longer, and assum‐
499       ing it finds the matching vmlinux file:
500
501       $ pahole -Fdwarf -I thread_struct | head -2
502       /* Used at: /home/acme/git/linux/arch/x86/kernel/head64.c */
503       /* <3333> /home/acme/git/linux/arch/x86/include/asm/processor.h:485 */
504       $
505
506
507       To find the biggest data structures in the Linux kernel:
508
509       $ pahole -s | sort -k2 -nr | head -5
510       cmp_data               290904 1
511       dec_datas              274520 1
512       cpu_entry_area         217088 0
513       pglist_data            172928 4
514       saved_cmdlines_buffer  131104 1
515       $
516
517       The  second  column is the size in bytes and the third is the number of
518       alignment holes in that structure.
519
520       Show data structures that have a raw spinlock and are  related  to  the
521       RCU mechanism:
522
523       $ pahole --contains raw_spinlock_t --prefix rcu
524       rcu_node
525       rcu_data
526       rcu_state
527       $
528
529       To see that in context, combine it with grep:
530
531       $ pahole rcu_state | grep raw_spinlock_t -B1 -A5
532            /* --- cacheline 52 boundary (3328 bytes) --- */
533            raw_spinlock_t             ofl_lock;             /*  3328     4 */
534
535            /* size: 3392, cachelines: 53, members: 35 */
536            /* sum members: 3250, holes: 7, sum holes: 82 */
537            /* padding: 60 */
538       };
539       $
540
541       It  can  also  pretty  print  raw data from stdin according to the type
542       specified:
543
544       $ pahole -C modversion_info drivers/scsi/sg.ko
545       struct modversion_info {
546             long unsigned int          crc;                  /*     0     8 */
547             char                       name[56];             /*     8    56 */
548
549             /* size: 64, cachelines: 1, members: 2 */
550       };
551       $
552       $ objcopy -O binary --only-section=__versions drivers/scsi/sg.ko versions
553       $
554       $ ls -la versions
555       -rw-rw-r--. 1 acme acme 7616 Jun 25 11:33 versions
556       $
557       $ pahole --count 3 -C modversion_info drivers/scsi/sg.ko < versions
558       {
559             .crc = 0x8dabd84,
560             .name = "module_layout",
561       },
562       {
563             .crc = 0x45e4617b,
564             .name = "no_llseek",
565       },
566       {
567             .crc = 0xa23fae8c,
568             .name = "param_ops_int",
569       },
570       $
571       $ pahole --skip 1 --count 2 -C modversion_info drivers/scsi/sg.ko < versions
572       {
573             .crc = 0x45e4617b,
574             .name = "no_llseek",
575       },
576       {
577             .crc = 0xa23fae8c,
578             .name = "param_ops_int",
579       },
580       $
581       This is equivalent to:
582
583       $ pahole --seek_bytes 64 --count 1 -C modversion_info drivers/scsi/sg.ko < versions
584       {
585            .crc = 0x45e4617b,
586            .name = "no_llseek",
587       },
588       $
589

PRETTY PRINTING

591       pahole can also use the data structure types to pretty print  raw  data
592       coming from its standard input.
593
594
595       -C, --class_name=CLASS_NAME
596              Pretty print according to this class. Arguments may be passed to
597              it to affect how the pretty printing is performed, e.g.:
598
599
600           -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_EXIT)'
601
602       This would select the 'struct perf_event_header' as the type to use  to
603       pretty print records states that the 'size' field in that struct should
604       be used to figure out the size of the record (variable sized  records),
605       that  the 'enum perf_event_type' should be used to pretty print the nu‐
606       meric value in perf_event_header->type and furthermore that  it  should
607       be  used  to  heuristically look for structs with the same name (lower‐
608       case) of the enum entry that is converted from the type field, using it
609       to  pretty  print instead of the base 'perf_event_header' type. See the
610       PRETTY PRINTING EXAMPLES section below.
611
612       Furthermore the 'filter=' part can be used, so far with only  the  '=='
613       operator  to filter based on the 'type' field and converting the string
614       'PERF_RECORD_EXIT' to a number according to type_enum.
615
616       The 'sizeof' arg defaults to the 'size' member name,  if  the  name  is
617       different, one can use
618        'sizeof=sz'  form,  ditto for 'type=other_member_name' field, that de‐
619       faults to 'type'.
620
621

PRETTY PRINTING EXAMPLES

623       Looking at the ELF header for a vmlinux file,  using  BTF,  first  lets
624       discover the ELF header type:
625
626       $ pahole --sizes | grep -i elf | grep -i _h
627       elf64_hdr 64   0
628       elf32_hdr 52   0
629       $
630
631       Now we can use this to show the first record from offset zero:
632
633       $ pahole -C elf64_hdr --count 1 < /lib/modules/5.8.0-rc3+/build/vmlinux
634       {
635            .e_ident = { 127, 69, 76, 70, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
636            .e_type = 2,
637            .e_machine = 62,
638            .e_version = 1,
639            .e_entry = 16777216,
640            .e_phoff = 64,
641            .e_shoff = 775923840,
642            .e_flags = 0,
643            .e_ehsize = 64,
644            .e_phentsize = 56,
645            .e_phnum = 5,
646            .e_shentsize = 64,
647            .e_shnum = 80,
648            .e_shstrndx = 79,
649       },
650       $
651
652       This is equivalent to:
653
654       $ pahole --header elf64_hdr < /lib/modules/5.8.0-rc3+/build/vmlinux
655
656       The --header option also allows reference in other command line options
657       to fields in the header.  This is useful when one wants to show  multi‐
658       ple  records  in a file and the range where those fields are located is
659       specified in header fields, such as for perf.data files:
660
661       $ pahole --hex ~/bin/perf --header perf_file_header < perf.data
662       {
663            .magic = 0x32454c4946524550,
664            .size = 0x68,
665            .attr_size = 0x88,
666            .attrs = {
667                 .offset = 0xa8,
668                 .size = 0x88,
669            },
670            .data = {
671                 .offset = 0x130,
672                 .size = 0x588,
673            },
674            .event_types = {
675                 .offset = 0,
676                 .size = 0,
677            },
678            .adds_features = { 0x16717ffc, 0, 0, 0 },
679       },
680       $
681
682       So to display the cgroups records in the perf_file_header.data  section
683       we can use:
684
685       $ 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)' < perf.data
686       {
687            .header = {
688                 .type = PERF_RECORD_CGROUP,
689                 .misc = 0,
690                 .size = 40,
691            },
692            .id = 1,
693            .path = "/",
694       },
695       {
696            .header = {
697                 .type = PERF_RECORD_CGROUP,
698                 .misc = 0,
699                 .size = 48,
700            },
701            .id = 1553,
702            .path = "/system.slice",
703       },
704       {
705            .header = {
706                 .type = PERF_RECORD_CGROUP,
707                 .misc = 0,
708                 .size = 48,
709            },
710            .id = 8,
711            .path = "/machine.slice",
712       },
713       {
714            .header = {
715                 .type = PERF_RECORD_CGROUP,
716                 .misc = 0,
717                 .size = 128,
718            },
719            .id = 7828,
720            .path = "/machine.slice/libpod-42be8e8d4eb9d22405845005f0d04ea398548dccc934a150fbaa3c1f1f9492c2.scope",
721       },
722       {
723            .header = {
724                 .type = PERF_RECORD_CGROUP,
725                 .misc = 0,
726                 .size = 88,
727            },
728            .id = 13,
729            .path = "/machine.slice/machine-qemud1drhel6.sandy.scope",
730       },
731       $
732
733       For the common case of the header having a member that has the 'offset'
734       and 'size' members, it is possible to use this more compact form:
735
736       $ 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)' < perf.data
737
738       This uses ~/bin/perf to get the type definitions, the  defines  'struct
739       perf_file_header' as the header, then seeks '$header.data.offset' bytes
740       from the start of the file,  and  considers  '$header.data.size'  bytes
741       worth  of such records. The filter expression may omit a common prefix,
742       in this case it could additonally be equivalently written as both 'fil‐
743       ter=type==CGROUP' or the 'filter=' can also be omitted, getting as com‐
744       pact as 'type==CGROUP':
745
746       If we look at:
747
748       $ pahole ~/bin/perf -C perf_event_header
749       struct perf_event_header {
750            __u32                      type;                 /*     0     4 */
751            __u16                      misc;                 /*     4     2 */
752            __u16                      size;                 /*     6     2 */
753
754            /* size: 8, cachelines: 1, members: 3 */
755            /* last cacheline: 8 bytes */
756       };
757       $
758
759       And:
760
761       $ pahole ~/bin/perf -C perf_event_type
762       enum perf_event_type {
763            PERF_RECORD_MMAP = 1,
764            PERF_RECORD_LOST = 2,
765            PERF_RECORD_COMM = 3,
766            PERF_RECORD_EXIT = 4,
767            PERF_RECORD_THROTTLE = 5,
768            PERF_RECORD_UNTHROTTLE = 6,
769            PERF_RECORD_FORK = 7,
770            PERF_RECORD_READ = 8,
771            PERF_RECORD_SAMPLE = 9,
772            PERF_RECORD_MMAP2 = 10,
773            PERF_RECORD_AUX = 11,
774            PERF_RECORD_ITRACE_START = 12,
775            PERF_RECORD_LOST_SAMPLES = 13,
776            PERF_RECORD_SWITCH = 14,
777            PERF_RECORD_SWITCH_CPU_WIDE = 15,
778            PERF_RECORD_NAMESPACES = 16,
779            PERF_RECORD_KSYMBOL = 17,
780            PERF_RECORD_BPF_EVENT = 18,
781            PERF_RECORD_CGROUP = 19,
782            PERF_RECORD_TEXT_POKE = 20,
783            PERF_RECORD_MAX = 21,
784       };
785       $
786
787       And furthermore:
788
789       $ pahole ~/bin/perf -C perf_record_cgroup
790       struct perf_record_cgroup {
791            struct perf_event_header   header;               /*     0     8 */
792            __u64                      id;                   /*     8     8 */
793            char                       path[4096];           /*    16  4096 */
794
795            /* size: 4112, cachelines: 65, members: 3 */
796            /* last cacheline: 16 bytes */
797       };
798       $
799
800       Then we can see how the perf_event_header.type could be converted  from
801       a   __u32   to  a  string  (PERF_RECORD_CGROUP).   If  we  remove  that
802       type_enum=perf_event_type, we  will  lose  the  conversion  of  'struct
803       perf_event_header' to the more descriptive 'struct perf_record_cgroup',
804       and also the beautification of the header.type field:
805
806       $ 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)' < perf.data
807       {
808            .type = 19,
809            .misc = 0,
810            .size = 40,
811       },
812       {
813            .type = 19,
814            .misc = 0,
815            .size = 48,
816       },
817       {
818            .type = 19,
819            .misc = 0,
820            .size = 48,
821       },
822       {
823            .type = 19,
824            .misc = 0,
825            .size = 128,
826       },
827       {
828            .type = 19,
829            .misc = 0,
830            .size = 88,
831       },
832       $
833
834       Some of the records are not  found  in  'type_enum=perf_event_type'  so
835       some  of the records don't get converted to a type that fully shows its
836       contents. For perf we know that those are in another enumeration, 'enum
837       perf_user_event_type',  so,  for  these cases, we can create a 'virtual
838       enum', i.e. the sum of two enums and then get all those entries decoded
839       and    properly   casted,   first   few   records   with   just   'enum
840       perf_event_type':
841
842       $ 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
843       {
844            .type = 79,
845            .misc = 0,
846            .size = 32,
847       },
848       {
849            .type = 73,
850            .misc = 0,
851            .size = 40,
852       },
853       {
854            .type = 74,
855            .misc = 0,
856            .size = 32,
857       },
858       {
859            .header = {
860                 .type = PERF_RECORD_CGROUP,
861                 .misc = 0,
862                 .size = 40,
863            },
864            .id = 1,
865            .path = "/",
866       },
867       $
868
869       Now       with        both        enumerations,        i.e.        with
870       'type_enum=perf_event_type+perf_user_event_type':
871
872       $ 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
873       {
874            .header = {
875                 .type = PERF_RECORD_TIME_CONV,
876                 .misc = 0,
877                 .size = 32,
878            },
879            .time_shift = 31,
880            .time_mult = 1016803377,
881            .time_zero = 435759009518382,
882       },
883       {
884            .header = {
885                 .type = PERF_RECORD_THREAD_MAP,
886                 .misc = 0,
887                 .size = 40,
888            },
889            .nr = 1,
890            .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,
891       },
892       {
893            .header = {
894                 .type = PERF_RECORD_CPU_MAP,
895                 .misc = 0,
896                 .size = 32,
897            },
898            .data = {
899                 .type = 1,
900                 .data = "",
901            },
902       },
903       {
904            .header = {
905                 .type = PERF_RECORD_CGROUP,
906                 .misc = 0,
907                 .size = 40,
908            },
909            .id = 1,
910            .path = "/",
911       },
912       {
913            .header = {
914                 .type = PERF_RECORD_CGROUP,
915                 .misc = 0,
916                 .size = 48,
917            },
918            .id = 1553,
919            .path = "/system.slice",
920       },
921       $
922
923       It  is  possible to pass multiple types, one has only to make sure they
924       appear in the file in sequence, i.e. for the perf.data example, see the
925       perf_file_header  dump  above, one can print the perf_file_attr structs
926       in the header attrs range, then the perf_event_header in the data range
927       with the following command:
928
929       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)' < perf.data
930
931

SEE ALSO

933       eu-readelf(1), readelf(1), objdump(1).
934
935       https://www.kernel.org/doc/ols/2007/ols2007v2-pages-35-44.pdf.
936

AUTHOR

938       pahole  was  written  and  is  maintained  by  Arnaldo Carvalho de Melo
939       <acme@kernel.org>.
940
941       Thanks to Andrii Nakryiko and Martin KaFai Lau for  providing  the  BTF
942       encoder  and  improving  the codebase while making sure the BTF encoder
943       works as needed to be used in encoding the Linux  kernel  .BTF  section
944       from the DWARF info generated by gcc. For that Andrii wrote a BTF dedu‐
945       plicator in libbpf that is used by pahole.
946
947       Also thanks to Conectiva, Mandriva and Red Hat for allowing me to  work
948       on these tools.
949
950       Please send bug reports to <dwarves@vger.kernel.org>.
951
952       No subscription is required.
953
954
955
956dwarves                        January 16, 2020                      pahole(1)
Impressum