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/ker‐
64       nel/btf/vmlinux is present, using the BTF  information  present  in  it
65       about the 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       -l, --show_first_biggest_size_base_type_member
204              Show first biggest size base_type member.
205
206
207       -m, --nr_methods
208              Show number of methods.
209
210
211       -M, --show_only_data_members
212              Show  only  the  members that use space in the class layout. C++
213              methods will be suppressed.
214
215
216       -n, --nr_members
217              Show number of members.
218
219
220       -N, --class_name_len
221              Show size of classes.
222
223
224       -O, --dwarf_offset=OFFSET
225              Show tag with DWARF OFFSET.
226
227
228       -P, --packable
229              Show only structs that has holes that can be packed  if  members
230              are  reorganized,  for  instance  when  using  the  --reorganize
231              option.
232
233
234       -q, --quiet
235              Be quieter.
236
237
238       -s, --sizes
239              Show size of classes.
240
241
242       -t, --separator=SEP
243              Use SEP as the field separator.
244
245
246       -T, --nr_definitions
247              Show how many times struct was defined.
248
249
250       -u, --defined_in
251              Show CUs where CLASS_NAME (-C) is defined.
252
253
254       --flat_arrays
255              Flatten arrays, so that array[10][2] becomes array[20].   Useful
256              when  generating  from  both CTF/BTF and DWARF encodings for the
257              same binary for testing purposes.
258
259
260       --suppress_aligned_attribute
261              Suppress forced alignment markers, so that one can  compare  BTF
262              or  CTF  output, that don't have that info, to output from DWARF
263              >= 5.
264
265
266       --suppress_force_paddings
267
268              Suppress bitfield forced padding at the end of structs, as  this
269              requires something like DWARF's DW_AT_alignment, so that one can
270              compare BTF or CTF output, that don't have that info.
271
272
273       --suppress_packed
274
275              Suppress     the     output     of     the     inference      of
276              __attribute__((__packed__)),  so that one can compare BTF or CTF
277              output, the inference algorithm uses  things  like  DW_AT_align‐
278              ment,  so  until  it  is improved to infer that as well for BTF,
279              allow disabling this output.
280
281
282       --fixup_silly_bitfields
283              Converts silly bitfields such as  "int  foo:32"  to  plain  "int
284              foo".
285
286
287       -V, --verbose
288              be verbose
289
290
291       -w, --word_size=WORD_SIZE
292              Change the arch word size to WORD_SIZE.
293
294
295       -x, --exclude=PREFIX
296              Exclude PREFIXed classes.
297
298
299       -X, --cu_exclude=PREFIX
300              Exclude PREFIXed compilation units.
301
302
303       -y, --prefix_filter=PREFIX
304              Include PREFIXed classes.
305
306
307       -z, --hole_size_ge=HOLE_SIZE
308              Show  only  structs  with  at least one hole greater or equal to
309              HOLE_SIZE.
310
311
312       --structs
313              Show only structs, all the other filters  apply,  i.e.  to  show
314              just  the  sizes  of all structs combine --structs with --sizes,
315              etc.
316
317
318       --packed
319              Show only packed structs, all the other filters apply,  i.e.  to
320              show  just the sizes of all packed structs combine --packed with
321              --sizes, etc.
322
323
324       --unions
325              Show only unions, all the other filters apply, i.e. to show just
326              the sizes of all unions combine --union with --sizes, etc.
327
328
329       --version
330              Show a traditional string version, i.e.: "v1.18".
331
332
333       --numeric_version
334              Show  a  numeric only version, suitable for use in Makefiles and
335              scripts where one wants to know what if  the  installed  version
336              has some feature, i.e.: 118 instead of "v1.18".
337
338

NOTES

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

EXAMPLES

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

PRETTY PRINTING

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

PRETTY PRINTING EXAMPLES

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

SEE ALSO

924       eu-readelf(1), readelf(1), objdump(1).
925
926       https://www.kernel.org/doc/ols/2007/ols2007v2-pages-35-44.pdf.
927

AUTHOR

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