Skip to content

Tags

Tags give the ability to mark specific points in history as being important
  • acmel/1.17
    e709afe6 · dwarves: Prep v1.17 ·
    v1.17 changes:
    
    tl;dr:
    
    BTF loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux.
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name:
    
         $ pahole sk_buff
    
      - Do not require a class name to operate without a file name.
    
          $ pahole          # is equivalent to:
          $ pahole vmlinux
    
      - Make --find_pointers_to consider unions:
    
          $ pahole --find_pointers_to ehci_qh
    
      - Make --contains and --find_pointers_to honour --unions
    
          $ pahole --unions --contains inet_sock
    
      - Add support for finding pointers to void:
    
         $ pahole --find_pointers_to void
    
      - Make --contains and --find_pointers_to to work with base types:
    
          $ pahole --find_pointers_to 'short unsigned int'
    
      - Make --contains look for more than just unions, structs:
    
          $ pahole --contains raw_spinlock_t
    
      - Consider unions when looking for classes containing some class:
    
          $ pahole --contains tpacket_req
    
      - Introduce --unions to consider just unions:
    
          $ pahole --unions --sizes
          $ pahole --unions --prefix tcp
          $ pahole --unions --nr_members
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
          $ pahole --nr_methods
    
    man-pages:
    
      - Add section about --hex + -E to locate offsets deep into sub structs.
    
      - Add more information about BTF.
    
      - Add some examples.
    
    ----------------------------------
    
    I want the details:
    
    btf loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux
    
        Be it automatically when no -F option is passed and
        /sys/kernel/btf/vmlinux is available, or when /sys/kernel/btf/vmlinux is
        passed as the filename to the tool, i.e.:
    
          $ pahole -C 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 */
          };
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
          $ pahole -C list_head /sys/kernel/btf/vmlinux
          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 */
          };
          $
    
        If one wants to grab the matching vmlinux to use its DWARF info instead,
        which is useful to compare the results with what we have from BTF, for
        instance, its just a matter of using '-F dwarf'.
    
        This in turn shows something that at first came as a surprise, but then
        has a simple explanation:
    
        For very common data structures, that will probably appear in all of the
        DWARF CUs (Compilation Units), like 'struct list_head', using '-F dwarf'
        is faster:
    
          $ perf stat -e cycles pahole -F btf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F btf -C list_head':
    
                  45,722,518      cycles:u
    
                 0.023717300 seconds time elapsed
    
                 0.016474000 seconds user
                 0.007212000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C list_head':
    
                  14,170,321      cycles:u
    
                 0.006668904 seconds time elapsed
    
                 0.005562000 seconds user
                 0.001109000 seconds sys
    
          $
    
        But for something that is more specific to a subsystem, the DWARF loader
        will have to process way more stuff till it gets to that struct:
    
          $ perf stat -e cycles pahole -F dwarf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C tcp_sock':
    
              31,579,795,238      cycles:u
    
                 8.332272930 seconds time elapsed
    
                 8.032124000 seconds user
                 0.286537000 seconds sys
    
          $
    
        While using the BTF loader the time should be constant, as it loads
        everything from /sys/kernel/btf/vmlinux:
    
          $ perf stat -e cycles pahole -F btf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F btf -C tcp_sock':
    
                  48,823,488      cycles:u
    
                 0.024102760 seconds time elapsed
    
                 0.012035000 seconds user
                 0.012046000 seconds sys
    
          $
    
        Above I used '-F btf' just to show that it can be used, but its not
        really needed, i.e. those are equivalent:
    
          $ strace -e openat pahole -F btf -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
    
        The btf_raw__load() function that ends up being grafted into the
        preexisting btf_elf routines was based on libbpf's btf_load_raw().
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name.
    
        With that it becomes as compact as it gets for kernel data structures,
        just state the name of the struct and it'll try to find that as a file,
        not being a file it'll use /sys/kernel/btf/vmlinux and the argument as a
        list of structs, i.e.:
    
          $ pahole skb_ext,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 */
          };
          struct skb_ext {
                refcount_t                 refcnt;               /*     0     4 */
                u8                         offset[3];            /*     4     3 */
                u8                         chunks;               /*     7     1 */
                char                       data[];               /*     8     0 */
    
                /* size: 8, cachelines: 1, members: 4 */
                /* last cacheline: 8 bytes */
          };
          $ pahole hlist_node
          struct hlist_node {
                struct hlist_node *        next;                 /*     0     8 */
                struct hlist_node * *      pprev;                /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
        Of course -C continues to work:
    
          $ pahole -C inode | tail
                __u32                      i_fsnotify_mask;      /*   556     4 */
                struct fsnotify_mark_connector * i_fsnotify_marks; /*   560     8 */
                struct fscrypt_info *      i_crypt_info;         /*   568     8 */
                /* --- cacheline 9 boundary (576 bytes) --- */
                struct fsverity_info *     i_verity_info;        /*   576     8 */
                void *                     i_private;            /*   584     8 */
    
                /* size: 592, cachelines: 10, members: 53 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Add support for finding pointers to void, e.g.:
    
          $ pahole --find_pointers_to void --prefix tcp
          tcp_md5sig_pool: scratch
          $ pahole tcp_md5sig_pool
          struct tcp_md5sig_pool {
                struct ahash_request *     md5_req;              /*     0     8 */
                void *                     scratch;              /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Make --contains and --find_pointers_to to work with base types
    
        I.e. with plain 'int', 'long', 'short int', etc:
    
          $ pahole --find_pointers_to 'short unsigned int'
          uv_hub_info_s: socket_to_node
          uv_hub_info_s: socket_to_pnode
          uv_hub_info_s: pnode_to_socket
          vc_data: vc_screenbuf
          vc_data: vc_translate
          filter_pred: ops
          ext4_sb_info: s_mb_offsets
          $ pahole ext4_sb_info | 'sort unsigned int'
          bash: sort unsigned int: command not found...
          ^[^C
          $
          $ pahole ext4_sb_info | grep 'sort unsigned int'
          $ pahole ext4_sb_info | grep 'short unsigned int'
                short unsigned int         s_mount_state;        /*   160     2 */
                short unsigned int         s_pad;                /*   162     2 */
                short unsigned int *       s_mb_offsets;         /*   664     8 */
          $ pahole --contains 'short unsigned int'
          apm_info
          desc_ptr
          thread_struct
          mpc_table
          mpc_intsrc
          fsnotify_mark_connector
          <SNIP>
          sock_fprog
          blk_mq_hw_ctx
          skb_shared_info
          $
    
      - Make --contains look for more than just unions, structs, look for
        typedefs, enums and types that descend from 'struct type':
    
        So now we can do more interesting queries, lets see, what are the data
        structures that embed a raw spinlock in the linux kernel?
    
          $ pahole --contains raw_spinlock_t
          task_struct
          rw_semaphore
          hrtimer_cpu_base
          prev_cputime
          percpu_counter
          ratelimit_state
          perf_event_context
          task_delay_info
          <SNIP>
          lpm_trie
          bpf_queue_stack
          $
    
        Look at the csets comments to see more examples.
    
      - Make --contains and --find_pointers_to honour --unions
    
        I.e. when looking for unions or structs that contains/embeds or looking
        for unions/structs that have pointers to a given type.
    
        E.g:
    
          $ pahole --contains inet_sock
          sctp_sock
          inet_connection_sock
          raw_sock
          udp_sock
          raw6_sock
          $ pahole --unions --contains inet_sock
          $
    
        We have structs embedding 'struct inet_sock', but no unions doing that.
    
      - Make --find_pointers_to consider unions
    
        I.e.:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          $
    
        Wasn't considering:
    
          $ pahole -C ehci_shadow
          union ehci_shadow {
                struct ehci_qh *           qh;                 /*     0     8 */
                struct ehci_itd *          itd;                /*     0     8 */
                struct ehci_sitd *         sitd;               /*     0     8 */
                struct ehci_fstn *         fstn;               /*     0     8 */
                __le32 *                   hw_next;            /*     0     8 */
                void *                     ptr;                /*     0     8 */
          };
          $
    
        Fix it:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          ehci_shadow: qh
          $
    
      - Consider unions when looking for classes containing some class:
    
        I.e.:
    
          $ pahole --contains tpacket_req
          tpacket_req_u
          $
    
        Wasn't working, but should be considered with --contains/-i:
    
          $ pahole -C tpacket_req_u
          union tpacket_req_u {
                struct tpacket_req         req;                /*     0    16 */
                struct tpacket_req3        req3;               /*     0    28 */
          };
          $
    
      - Introduce --unions to consider just unions
    
        Most filters can be used together with it, for instance to see the
        biggest unions in the kernel:
    
          $ pahole --unions --sizes | sort -k2 -nr | head
          thread_union            16384 0
          swap_header              4096 0
          fpregs_state             4096 0
          autofs_v5_packet_union    304 0
          autofs_packet_union       272 0
          pptp_ctrl_union           208 0
          acpi_parse_object         200 0
          acpi_descriptor           200 0
          bpf_attr                  120 0
          phy_configure_opts        112 0
          $
    
        Or just some unions that have some specific prefix:
    
          $ pahole --unions --prefix tcp
          union tcp_md5_addr {
                struct in_addr             a4;                 /*     0     4 */
                struct in6_addr            a6;                 /*     0    16 */
          };
          union tcp_word_hdr {
                struct tcphdr              hdr;                /*     0    20 */
                __be32                     words[5];           /*     0    20 */
          };
          union tcp_cc_info {
                struct tcpvegas_info       vegas;              /*     0    16 */
                struct tcp_dctcp_info      dctcp;              /*     0    16 */
                struct tcp_bbr_info        bbr;                /*     0    20 */
          };
          $
    
        What are the biggest unions in terms of number of members?
    
          $ pahole --unions --nr_members | sort -k2 -nr | head
          security_list_options 218
          aml_resource           36
          acpi_resource_data     29
          acpi_operand_object    26
          iwreq_data             18
          sctp_params            15
          ib_flow_spec           14
          ethtool_flow_union     14
          pptp_ctrl_union        13
          bpf_attr               12
          $
    
        If you want to script most of the queries can change the separator:
    
          $ pahole --unions --nr_members -t, | sort -t, -k2 -nr | head
          security_list_options,218
          aml_resource,36
          acpi_resource_data,29
          acpi_operand_object,26
          iwreq_data,18
          sctp_params,15
          ib_flow_spec,14
          ethtool_flow_union,14
          pptp_ctrl_union,13
          bpf_attr,12
          $
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
        We had to use the same hack as in pfunct, as implemented in ccf3eebfcd9c
        ("btf_loader: Add support for BTF_KIND_FUNC"), will hide that 'struct
        ftype' (aka function prototype) indirection behind the parameter
        iterator (function__for_each_parameter).
    
        For now, here is the top 10 Linux kernel data structures in terms of
        number of functions receiving as one of its parameters a pointer to it,
        using /sys/kernel/btf/vmlinux to look at all the vmlinux types and
        functions (the ones visible in kallsyms, but with the parameters and its
        types):
    
          $ pahole -m | sort -k2 -nr | head
          device        955
          sock          568
          sk_buff       541
          task_struct   437
          inode         421
          pci_dev       390
          page          351
          net_device    347
          file          315
          net           312
          $
          $ pahole --help |& grep -- -m
            -m, --nr_methods           show number of methods
          $
    
      - Do not require a class name to operate without a file name
    
        Since we default to operating on the running kernel data structures, we
        should make the default to, with no options passed, to pretty print all
        the running kernel data structures, or do what was asked in terms of
        number of members, size of structs, etc, i.e.:
    
          # pahole --help |& head
          Usage: pahole [OPTION...] FILE
    
            -a, --anon_include         include anonymous classes
            -A, --nested_anon_include  include nested (inside other structs) anonymous
                                       classes
            -B, --bit_holes=NR_HOLES   Show only structs at least NR_HOLES bit holes
            -c, --cacheline_size=SIZE  set cacheline size to SIZE
                --classes_as_structs   Use 'struct' when printing classes
            -C, --class_name=CLASS_NAME   Show just this class
            -d, --recursive            recursive mode, affects several other flags
          #
    
        Continues working as before, but if you do:
    
          pahole
    
        It will work just as if you did:
    
          pahole vmlinux
    
        and that vmlinux file is the running kernel vmlinux.
    
        And since the default now is to read BTF info, then it will do all its
        operations on /sys/kernel/btf/vmlinux, when present, i.e. want to know
        what are the fattest data structures in the running kernel:
    
          # pahole -s | sort -k2 -nr | head
          cmp_data      290904  1
          dec_data      274520  1
          cpu_entry_area        217088  0
          pglist_data   172928  4
          saved_cmdlines_buffer 131104  1
          debug_store_buffers   131072  0
          hid_parser    110848  1
          hid_local     110608  0
          zonelist      81936   0
          e820_table    64004   0
          #
    
        How many data structures in the running kernel vmlinux area embbed
        'struct list_head'?
    
          # pahole -i list_head | wc -l
          260
          #
    
        Lets see some of those?
    
          # pahole -C fsnotify_event
          struct fsnotify_event {
                struct list_head           list;                 /*     0    16 */
                struct inode *             inode;                /*    16     8 */
    
                /* size: 24, cachelines: 1, members: 2 */
                /* last cacheline: 24 bytes */
          };
          # pahole -C audit_chunk
          struct audit_chunk {
                struct list_head           hash;                 /*     0    16 */
                long unsigned int          key;                  /*    16     8 */
                struct fsnotify_mark *     mark;                 /*    24     8 */
                struct list_head           trees;                /*    32    16 */
                int                        count;                /*    48     4 */
    
                /* XXX 4 bytes hole, try to pack */
    
                atomic_long_t              refs;                 /*    56     8 */
                /* --- cacheline 1 boundary (64 bytes) --- */
                struct callback_head       head;                 /*    64    16 */
                struct node                owners[];             /*    80     0 */
    
                /* size: 80, cachelines: 2, members: 8 */
                /* sum members: 76, holes: 1, sum holes: 4 */
                /* last cacheline: 16 bytes */
          };
          #
    
    
  • upstream/1.17
    e709afe6 · dwarves: Prep v1.17 ·
    v1.17 changes:
    
    tl;dr:
    
    BTF loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux.
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name:
    
         $ pahole sk_buff
    
      - Do not require a class name to operate without a file name.
    
          $ pahole          # is equivalent to:
          $ pahole vmlinux
    
      - Make --find_pointers_to consider unions:
    
          $ pahole --find_pointers_to ehci_qh
    
      - Make --contains and --find_pointers_to honour --unions
    
          $ pahole --unions --contains inet_sock
    
      - Add support for finding pointers to void:
    
         $ pahole --find_pointers_to void
    
      - Make --contains and --find_pointers_to to work with base types:
    
          $ pahole --find_pointers_to 'short unsigned int'
    
      - Make --contains look for more than just unions, structs:
    
          $ pahole --contains raw_spinlock_t
    
      - Consider unions when looking for classes containing some class:
    
          $ pahole --contains tpacket_req
    
      - Introduce --unions to consider just unions:
    
          $ pahole --unions --sizes
          $ pahole --unions --prefix tcp
          $ pahole --unions --nr_members
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
          $ pahole --nr_methods
    
    man-pages:
    
      - Add section about --hex + -E to locate offsets deep into sub structs.
    
      - Add more information about BTF.
    
      - Add some examples.
    
    ----------------------------------
    
    I want the details:
    
    btf loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux
    
        Be it automatically when no -F option is passed and
        /sys/kernel/btf/vmlinux is available, or when /sys/kernel/btf/vmlinux is
        passed as the filename to the tool, i.e.:
    
          $ pahole -C 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 */
          };
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
          $ pahole -C list_head /sys/kernel/btf/vmlinux
          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 */
          };
          $
    
        If one wants to grab the matching vmlinux to use its DWARF info instead,
        which is useful to compare the results with what we have from BTF, for
        instance, its just a matter of using '-F dwarf'.
    
        This in turn shows something that at first came as a surprise, but then
        has a simple explanation:
    
        For very common data structures, that will probably appear in all of the
        DWARF CUs (Compilation Units), like 'struct list_head', using '-F dwarf'
        is faster:
    
          $ perf stat -e cycles pahole -F btf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F btf -C list_head':
    
                  45,722,518      cycles:u
    
                 0.023717300 seconds time elapsed
    
                 0.016474000 seconds user
                 0.007212000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C list_head':
    
                  14,170,321      cycles:u
    
                 0.006668904 seconds time elapsed
    
                 0.005562000 seconds user
                 0.001109000 seconds sys
    
          $
    
        But for something that is more specific to a subsystem, the DWARF loader
        will have to process way more stuff till it gets to that struct:
    
          $ perf stat -e cycles pahole -F dwarf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C tcp_sock':
    
              31,579,795,238      cycles:u
    
                 8.332272930 seconds time elapsed
    
                 8.032124000 seconds user
                 0.286537000 seconds sys
    
          $
    
        While using the BTF loader the time should be constant, as it loads
        everything from /sys/kernel/btf/vmlinux:
    
          $ perf stat -e cycles pahole -F btf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F btf -C tcp_sock':
    
                  48,823,488      cycles:u
    
                 0.024102760 seconds time elapsed
    
                 0.012035000 seconds user
                 0.012046000 seconds sys
    
          $
    
        Above I used '-F btf' just to show that it can be used, but its not
        really needed, i.e. those are equivalent:
    
          $ strace -e openat pahole -F btf -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
    
        The btf_raw__load() function that ends up being grafted into the
        preexisting btf_elf routines was based on libbpf's btf_load_raw().
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name.
    
        With that it becomes as compact as it gets for kernel data structures,
        just state the name of the struct and it'll try to find that as a file,
        not being a file it'll use /sys/kernel/btf/vmlinux and the argument as a
        list of structs, i.e.:
    
          $ pahole skb_ext,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 */
          };
          struct skb_ext {
                refcount_t                 refcnt;               /*     0     4 */
                u8                         offset[3];            /*     4     3 */
                u8                         chunks;               /*     7     1 */
                char                       data[];               /*     8     0 */
    
                /* size: 8, cachelines: 1, members: 4 */
                /* last cacheline: 8 bytes */
          };
          $ pahole hlist_node
          struct hlist_node {
                struct hlist_node *        next;                 /*     0     8 */
                struct hlist_node * *      pprev;                /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
        Of course -C continues to work:
    
          $ pahole -C inode | tail
                __u32                      i_fsnotify_mask;      /*   556     4 */
                struct fsnotify_mark_connector * i_fsnotify_marks; /*   560     8 */
                struct fscrypt_info *      i_crypt_info;         /*   568     8 */
                /* --- cacheline 9 boundary (576 bytes) --- */
                struct fsverity_info *     i_verity_info;        /*   576     8 */
                void *                     i_private;            /*   584     8 */
    
                /* size: 592, cachelines: 10, members: 53 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Add support for finding pointers to void, e.g.:
    
          $ pahole --find_pointers_to void --prefix tcp
          tcp_md5sig_pool: scratch
          $ pahole tcp_md5sig_pool
          struct tcp_md5sig_pool {
                struct ahash_request *     md5_req;              /*     0     8 */
                void *                     scratch;              /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Make --contains and --find_pointers_to to work with base types
    
        I.e. with plain 'int', 'long', 'short int', etc:
    
          $ pahole --find_pointers_to 'short unsigned int'
          uv_hub_info_s: socket_to_node
          uv_hub_info_s: socket_to_pnode
          uv_hub_info_s: pnode_to_socket
          vc_data: vc_screenbuf
          vc_data: vc_translate
          filter_pred: ops
          ext4_sb_info: s_mb_offsets
          $ pahole ext4_sb_info | 'sort unsigned int'
          bash: sort unsigned int: command not found...
          ^[^C
          $
          $ pahole ext4_sb_info | grep 'sort unsigned int'
          $ pahole ext4_sb_info | grep 'short unsigned int'
                short unsigned int         s_mount_state;        /*   160     2 */
                short unsigned int         s_pad;                /*   162     2 */
                short unsigned int *       s_mb_offsets;         /*   664     8 */
          $ pahole --contains 'short unsigned int'
          apm_info
          desc_ptr
          thread_struct
          mpc_table
          mpc_intsrc
          fsnotify_mark_connector
          <SNIP>
          sock_fprog
          blk_mq_hw_ctx
          skb_shared_info
          $
    
      - Make --contains look for more than just unions, structs, look for
        typedefs, enums and types that descend from 'struct type':
    
        So now we can do more interesting queries, lets see, what are the data
        structures that embed a raw spinlock in the linux kernel?
    
          $ pahole --contains raw_spinlock_t
          task_struct
          rw_semaphore
          hrtimer_cpu_base
          prev_cputime
          percpu_counter
          ratelimit_state
          perf_event_context
          task_delay_info
          <SNIP>
          lpm_trie
          bpf_queue_stack
          $
    
        Look at the csets comments to see more examples.
    
      - Make --contains and --find_pointers_to honour --unions
    
        I.e. when looking for unions or structs that contains/embeds or looking
        for unions/structs that have pointers to a given type.
    
        E.g:
    
          $ pahole --contains inet_sock
          sctp_sock
          inet_connection_sock
          raw_sock
          udp_sock
          raw6_sock
          $ pahole --unions --contains inet_sock
          $
    
        We have structs embedding 'struct inet_sock', but no unions doing that.
    
      - Make --find_pointers_to consider unions
    
        I.e.:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          $
    
        Wasn't considering:
    
          $ pahole -C ehci_shadow
          union ehci_shadow {
                struct ehci_qh *           qh;                 /*     0     8 */
                struct ehci_itd *          itd;                /*     0     8 */
                struct ehci_sitd *         sitd;               /*     0     8 */
                struct ehci_fstn *         fstn;               /*     0     8 */
                __le32 *                   hw_next;            /*     0     8 */
                void *                     ptr;                /*     0     8 */
          };
          $
    
        Fix it:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          ehci_shadow: qh
          $
    
      - Consider unions when looking for classes containing some class:
    
        I.e.:
    
          $ pahole --contains tpacket_req
          tpacket_req_u
          $
    
        Wasn't working, but should be considered with --contains/-i:
    
          $ pahole -C tpacket_req_u
          union tpacket_req_u {
                struct tpacket_req         req;                /*     0    16 */
                struct tpacket_req3        req3;               /*     0    28 */
          };
          $
    
      - Introduce --unions to consider just unions
    
        Most filters can be used together with it, for instance to see the
        biggest unions in the kernel:
    
          $ pahole --unions --sizes | sort -k2 -nr | head
          thread_union            16384 0
          swap_header              4096 0
          fpregs_state             4096 0
          autofs_v5_packet_union    304 0
          autofs_packet_union       272 0
          pptp_ctrl_union           208 0
          acpi_parse_object         200 0
          acpi_descriptor           200 0
          bpf_attr                  120 0
          phy_configure_opts        112 0
          $
    
        Or just some unions that have some specific prefix:
    
          $ pahole --unions --prefix tcp
          union tcp_md5_addr {
                struct in_addr             a4;                 /*     0     4 */
                struct in6_addr            a6;                 /*     0    16 */
          };
          union tcp_word_hdr {
                struct tcphdr              hdr;                /*     0    20 */
                __be32                     words[5];           /*     0    20 */
          };
          union tcp_cc_info {
                struct tcpvegas_info       vegas;              /*     0    16 */
                struct tcp_dctcp_info      dctcp;              /*     0    16 */
                struct tcp_bbr_info        bbr;                /*     0    20 */
          };
          $
    
        What are the biggest unions in terms of number of members?
    
          $ pahole --unions --nr_members | sort -k2 -nr | head
          security_list_options 218
          aml_resource           36
          acpi_resource_data     29
          acpi_operand_object    26
          iwreq_data             18
          sctp_params            15
          ib_flow_spec           14
          ethtool_flow_union     14
          pptp_ctrl_union        13
          bpf_attr               12
          $
    
        If you want to script most of the queries can change the separator:
    
          $ pahole --unions --nr_members -t, | sort -t, -k2 -nr | head
          security_list_options,218
          aml_resource,36
          acpi_resource_data,29
          acpi_operand_object,26
          iwreq_data,18
          sctp_params,15
          ib_flow_spec,14
          ethtool_flow_union,14
          pptp_ctrl_union,13
          bpf_attr,12
          $
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
        We had to use the same hack as in pfunct, as implemented in ccf3eebfcd9c
        ("btf_loader: Add support for BTF_KIND_FUNC"), will hide that 'struct
        ftype' (aka function prototype) indirection behind the parameter
        iterator (function__for_each_parameter).
    
        For now, here is the top 10 Linux kernel data structures in terms of
        number of functions receiving as one of its parameters a pointer to it,
        using /sys/kernel/btf/vmlinux to look at all the vmlinux types and
        functions (the ones visible in kallsyms, but with the parameters and its
        types):
    
          $ pahole -m | sort -k2 -nr | head
          device        955
          sock          568
          sk_buff       541
          task_struct   437
          inode         421
          pci_dev       390
          page          351
          net_device    347
          file          315
          net           312
          $
          $ pahole --help |& grep -- -m
            -m, --nr_methods           show number of methods
          $
    
      - Do not require a class name to operate without a file name
    
        Since we default to operating on the running kernel data structures, we
        should make the default to, with no options passed, to pretty print all
        the running kernel data structures, or do what was asked in terms of
        number of members, size of structs, etc, i.e.:
    
          # pahole --help |& head
          Usage: pahole [OPTION...] FILE
    
            -a, --anon_include         include anonymous classes
            -A, --nested_anon_include  include nested (inside other structs) anonymous
                                       classes
            -B, --bit_holes=NR_HOLES   Show only structs at least NR_HOLES bit holes
            -c, --cacheline_size=SIZE  set cacheline size to SIZE
                --classes_as_structs   Use 'struct' when printing classes
            -C, --class_name=CLASS_NAME   Show just this class
            -d, --recursive            recursive mode, affects several other flags
          #
    
        Continues working as before, but if you do:
    
          pahole
    
        It will work just as if you did:
    
          pahole vmlinux
    
        and that vmlinux file is the running kernel vmlinux.
    
        And since the default now is to read BTF info, then it will do all its
        operations on /sys/kernel/btf/vmlinux, when present, i.e. want to know
        what are the fattest data structures in the running kernel:
    
          # pahole -s | sort -k2 -nr | head
          cmp_data      290904  1
          dec_data      274520  1
          cpu_entry_area        217088  0
          pglist_data   172928  4
          saved_cmdlines_buffer 131104  1
          debug_store_buffers   131072  0
          hid_parser    110848  1
          hid_local     110608  0
          zonelist      81936   0
          e820_table    64004   0
          #
    
        How many data structures in the running kernel vmlinux area embbed
        'struct list_head'?
    
          # pahole -i list_head | wc -l
          260
          #
    
        Lets see some of those?
    
          # pahole -C fsnotify_event
          struct fsnotify_event {
                struct list_head           list;                 /*     0    16 */
                struct inode *             inode;                /*    16     8 */
    
                /* size: 24, cachelines: 1, members: 2 */
                /* last cacheline: 24 bytes */
          };
          # pahole -C audit_chunk
          struct audit_chunk {
                struct list_head           hash;                 /*     0    16 */
                long unsigned int          key;                  /*    16     8 */
                struct fsnotify_mark *     mark;                 /*    24     8 */
                struct list_head           trees;                /*    32    16 */
                int                        count;                /*    48     4 */
    
                /* XXX 4 bytes hole, try to pack */
    
                atomic_long_t              refs;                 /*    56     8 */
                /* --- cacheline 1 boundary (64 bytes) --- */
                struct callback_head       head;                 /*    64    16 */
                struct node                owners[];             /*    80     0 */
    
                /* size: 80, cachelines: 2, members: 8 */
                /* sum members: 76, holes: 1, sum holes: 4 */
                /* last cacheline: 16 bytes */
          };
          #
    
    
  • upstream/v1.17
    e709afe6 · dwarves: Prep v1.17 ·
    v1.17 changes:
    
    tl;dr:
    
    BTF loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux.
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name:
    
         $ pahole sk_buff
    
      - Do not require a class name to operate without a file name.
    
          $ pahole          # is equivalent to:
          $ pahole vmlinux
    
      - Make --find_pointers_to consider unions:
    
          $ pahole --find_pointers_to ehci_qh
    
      - Make --contains and --find_pointers_to honour --unions
    
          $ pahole --unions --contains inet_sock
    
      - Add support for finding pointers to void:
    
         $ pahole --find_pointers_to void
    
      - Make --contains and --find_pointers_to to work with base types:
    
          $ pahole --find_pointers_to 'short unsigned int'
    
      - Make --contains look for more than just unions, structs:
    
          $ pahole --contains raw_spinlock_t
    
      - Consider unions when looking for classes containing some class:
    
          $ pahole --contains tpacket_req
    
      - Introduce --unions to consider just unions:
    
          $ pahole --unions --sizes
          $ pahole --unions --prefix tcp
          $ pahole --unions --nr_members
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
          $ pahole --nr_methods
    
    man-pages:
    
      - Add section about --hex + -E to locate offsets deep into sub structs.
    
      - Add more information about BTF.
    
      - Add some examples.
    
    ----------------------------------
    
    I want the details:
    
    btf loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux
    
        Be it automatically when no -F option is passed and
        /sys/kernel/btf/vmlinux is available, or when /sys/kernel/btf/vmlinux is
        passed as the filename to the tool, i.e.:
    
          $ pahole -C 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 */
          };
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
          $ pahole -C list_head /sys/kernel/btf/vmlinux
          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 */
          };
          $
    
        If one wants to grab the matching vmlinux to use its DWARF info instead,
        which is useful to compare the results with what we have from BTF, for
        instance, its just a matter of using '-F dwarf'.
    
        This in turn shows something that at first came as a surprise, but then
        has a simple explanation:
    
        For very common data structures, that will probably appear in all of the
        DWARF CUs (Compilation Units), like 'struct list_head', using '-F dwarf'
        is faster:
    
          $ perf stat -e cycles pahole -F btf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F btf -C list_head':
    
                  45,722,518      cycles:u
    
                 0.023717300 seconds time elapsed
    
                 0.016474000 seconds user
                 0.007212000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C list_head':
    
                  14,170,321      cycles:u
    
                 0.006668904 seconds time elapsed
    
                 0.005562000 seconds user
                 0.001109000 seconds sys
    
          $
    
        But for something that is more specific to a subsystem, the DWARF loader
        will have to process way more stuff till it gets to that struct:
    
          $ perf stat -e cycles pahole -F dwarf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C tcp_sock':
    
              31,579,795,238      cycles:u
    
                 8.332272930 seconds time elapsed
    
                 8.032124000 seconds user
                 0.286537000 seconds sys
    
          $
    
        While using the BTF loader the time should be constant, as it loads
        everything from /sys/kernel/btf/vmlinux:
    
          $ perf stat -e cycles pahole -F btf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F btf -C tcp_sock':
    
                  48,823,488      cycles:u
    
                 0.024102760 seconds time elapsed
    
                 0.012035000 seconds user
                 0.012046000 seconds sys
    
          $
    
        Above I used '-F btf' just to show that it can be used, but its not
        really needed, i.e. those are equivalent:
    
          $ strace -e openat pahole -F btf -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
    
        The btf_raw__load() function that ends up being grafted into the
        preexisting btf_elf routines was based on libbpf's btf_load_raw().
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name.
    
        With that it becomes as compact as it gets for kernel data structures,
        just state the name of the struct and it'll try to find that as a file,
        not being a file it'll use /sys/kernel/btf/vmlinux and the argument as a
        list of structs, i.e.:
    
          $ pahole skb_ext,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 */
          };
          struct skb_ext {
                refcount_t                 refcnt;               /*     0     4 */
                u8                         offset[3];            /*     4     3 */
                u8                         chunks;               /*     7     1 */
                char                       data[];               /*     8     0 */
    
                /* size: 8, cachelines: 1, members: 4 */
                /* last cacheline: 8 bytes */
          };
          $ pahole hlist_node
          struct hlist_node {
                struct hlist_node *        next;                 /*     0     8 */
                struct hlist_node * *      pprev;                /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
        Of course -C continues to work:
    
          $ pahole -C inode | tail
                __u32                      i_fsnotify_mask;      /*   556     4 */
                struct fsnotify_mark_connector * i_fsnotify_marks; /*   560     8 */
                struct fscrypt_info *      i_crypt_info;         /*   568     8 */
                /* --- cacheline 9 boundary (576 bytes) --- */
                struct fsverity_info *     i_verity_info;        /*   576     8 */
                void *                     i_private;            /*   584     8 */
    
                /* size: 592, cachelines: 10, members: 53 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Add support for finding pointers to void, e.g.:
    
          $ pahole --find_pointers_to void --prefix tcp
          tcp_md5sig_pool: scratch
          $ pahole tcp_md5sig_pool
          struct tcp_md5sig_pool {
                struct ahash_request *     md5_req;              /*     0     8 */
                void *                     scratch;              /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Make --contains and --find_pointers_to to work with base types
    
        I.e. with plain 'int', 'long', 'short int', etc:
    
          $ pahole --find_pointers_to 'short unsigned int'
          uv_hub_info_s: socket_to_node
          uv_hub_info_s: socket_to_pnode
          uv_hub_info_s: pnode_to_socket
          vc_data: vc_screenbuf
          vc_data: vc_translate
          filter_pred: ops
          ext4_sb_info: s_mb_offsets
          $ pahole ext4_sb_info | 'sort unsigned int'
          bash: sort unsigned int: command not found...
          ^[^C
          $
          $ pahole ext4_sb_info | grep 'sort unsigned int'
          $ pahole ext4_sb_info | grep 'short unsigned int'
                short unsigned int         s_mount_state;        /*   160     2 */
                short unsigned int         s_pad;                /*   162     2 */
                short unsigned int *       s_mb_offsets;         /*   664     8 */
          $ pahole --contains 'short unsigned int'
          apm_info
          desc_ptr
          thread_struct
          mpc_table
          mpc_intsrc
          fsnotify_mark_connector
          <SNIP>
          sock_fprog
          blk_mq_hw_ctx
          skb_shared_info
          $
    
      - Make --contains look for more than just unions, structs, look for
        typedefs, enums and types that descend from 'struct type':
    
        So now we can do more interesting queries, lets see, what are the data
        structures that embed a raw spinlock in the linux kernel?
    
          $ pahole --contains raw_spinlock_t
          task_struct
          rw_semaphore
          hrtimer_cpu_base
          prev_cputime
          percpu_counter
          ratelimit_state
          perf_event_context
          task_delay_info
          <SNIP>
          lpm_trie
          bpf_queue_stack
          $
    
        Look at the csets comments to see more examples.
    
      - Make --contains and --find_pointers_to honour --unions
    
        I.e. when looking for unions or structs that contains/embeds or looking
        for unions/structs that have pointers to a given type.
    
        E.g:
    
          $ pahole --contains inet_sock
          sctp_sock
          inet_connection_sock
          raw_sock
          udp_sock
          raw6_sock
          $ pahole --unions --contains inet_sock
          $
    
        We have structs embedding 'struct inet_sock', but no unions doing that.
    
      - Make --find_pointers_to consider unions
    
        I.e.:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          $
    
        Wasn't considering:
    
          $ pahole -C ehci_shadow
          union ehci_shadow {
                struct ehci_qh *           qh;                 /*     0     8 */
                struct ehci_itd *          itd;                /*     0     8 */
                struct ehci_sitd *         sitd;               /*     0     8 */
                struct ehci_fstn *         fstn;               /*     0     8 */
                __le32 *                   hw_next;            /*     0     8 */
                void *                     ptr;                /*     0     8 */
          };
          $
    
        Fix it:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          ehci_shadow: qh
          $
    
      - Consider unions when looking for classes containing some class:
    
        I.e.:
    
          $ pahole --contains tpacket_req
          tpacket_req_u
          $
    
        Wasn't working, but should be considered with --contains/-i:
    
          $ pahole -C tpacket_req_u
          union tpacket_req_u {
                struct tpacket_req         req;                /*     0    16 */
                struct tpacket_req3        req3;               /*     0    28 */
          };
          $
    
      - Introduce --unions to consider just unions
    
        Most filters can be used together with it, for instance to see the
        biggest unions in the kernel:
    
          $ pahole --unions --sizes | sort -k2 -nr | head
          thread_union            16384 0
          swap_header              4096 0
          fpregs_state             4096 0
          autofs_v5_packet_union    304 0
          autofs_packet_union       272 0
          pptp_ctrl_union           208 0
          acpi_parse_object         200 0
          acpi_descriptor           200 0
          bpf_attr                  120 0
          phy_configure_opts        112 0
          $
    
        Or just some unions that have some specific prefix:
    
          $ pahole --unions --prefix tcp
          union tcp_md5_addr {
                struct in_addr             a4;                 /*     0     4 */
                struct in6_addr            a6;                 /*     0    16 */
          };
          union tcp_word_hdr {
                struct tcphdr              hdr;                /*     0    20 */
                __be32                     words[5];           /*     0    20 */
          };
          union tcp_cc_info {
                struct tcpvegas_info       vegas;              /*     0    16 */
                struct tcp_dctcp_info      dctcp;              /*     0    16 */
                struct tcp_bbr_info        bbr;                /*     0    20 */
          };
          $
    
        What are the biggest unions in terms of number of members?
    
          $ pahole --unions --nr_members | sort -k2 -nr | head
          security_list_options 218
          aml_resource           36
          acpi_resource_data     29
          acpi_operand_object    26
          iwreq_data             18
          sctp_params            15
          ib_flow_spec           14
          ethtool_flow_union     14
          pptp_ctrl_union        13
          bpf_attr               12
          $
    
        If you want to script most of the queries can change the separator:
    
          $ pahole --unions --nr_members -t, | sort -t, -k2 -nr | head
          security_list_options,218
          aml_resource,36
          acpi_resource_data,29
          acpi_operand_object,26
          iwreq_data,18
          sctp_params,15
          ib_flow_spec,14
          ethtool_flow_union,14
          pptp_ctrl_union,13
          bpf_attr,12
          $
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
        We had to use the same hack as in pfunct, as implemented in ccf3eebfcd9c
        ("btf_loader: Add support for BTF_KIND_FUNC"), will hide that 'struct
        ftype' (aka function prototype) indirection behind the parameter
        iterator (function__for_each_parameter).
    
        For now, here is the top 10 Linux kernel data structures in terms of
        number of functions receiving as one of its parameters a pointer to it,
        using /sys/kernel/btf/vmlinux to look at all the vmlinux types and
        functions (the ones visible in kallsyms, but with the parameters and its
        types):
    
          $ pahole -m | sort -k2 -nr | head
          device        955
          sock          568
          sk_buff       541
          task_struct   437
          inode         421
          pci_dev       390
          page          351
          net_device    347
          file          315
          net           312
          $
          $ pahole --help |& grep -- -m
            -m, --nr_methods           show number of methods
          $
    
      - Do not require a class name to operate without a file name
    
        Since we default to operating on the running kernel data structures, we
        should make the default to, with no options passed, to pretty print all
        the running kernel data structures, or do what was asked in terms of
        number of members, size of structs, etc, i.e.:
    
          # pahole --help |& head
          Usage: pahole [OPTION...] FILE
    
            -a, --anon_include         include anonymous classes
            -A, --nested_anon_include  include nested (inside other structs) anonymous
                                       classes
            -B, --bit_holes=NR_HOLES   Show only structs at least NR_HOLES bit holes
            -c, --cacheline_size=SIZE  set cacheline size to SIZE
                --classes_as_structs   Use 'struct' when printing classes
            -C, --class_name=CLASS_NAME   Show just this class
            -d, --recursive            recursive mode, affects several other flags
          #
    
        Continues working as before, but if you do:
    
          pahole
    
        It will work just as if you did:
    
          pahole vmlinux
    
        and that vmlinux file is the running kernel vmlinux.
    
        And since the default now is to read BTF info, then it will do all its
        operations on /sys/kernel/btf/vmlinux, when present, i.e. want to know
        what are the fattest data structures in the running kernel:
    
          # pahole -s | sort -k2 -nr | head
          cmp_data      290904  1
          dec_data      274520  1
          cpu_entry_area        217088  0
          pglist_data   172928  4
          saved_cmdlines_buffer 131104  1
          debug_store_buffers   131072  0
          hid_parser    110848  1
          hid_local     110608  0
          zonelist      81936   0
          e820_table    64004   0
          #
    
        How many data structures in the running kernel vmlinux area embbed
        'struct list_head'?
    
          # pahole -i list_head | wc -l
          260
          #
    
        Lets see some of those?
    
          # pahole -C fsnotify_event
          struct fsnotify_event {
                struct list_head           list;                 /*     0    16 */
                struct inode *             inode;                /*    16     8 */
    
                /* size: 24, cachelines: 1, members: 2 */
                /* last cacheline: 24 bytes */
          };
          # pahole -C audit_chunk
          struct audit_chunk {
                struct list_head           hash;                 /*     0    16 */
                long unsigned int          key;                  /*    16     8 */
                struct fsnotify_mark *     mark;                 /*    24     8 */
                struct list_head           trees;                /*    32    16 */
                int                        count;                /*    48     4 */
    
                /* XXX 4 bytes hole, try to pack */
    
                atomic_long_t              refs;                 /*    56     8 */
                /* --- cacheline 1 boundary (64 bytes) --- */
                struct callback_head       head;                 /*    64    16 */
                struct node                owners[];             /*    80     0 */
    
                /* size: 80, cachelines: 2, members: 8 */
                /* sum members: 76, holes: 1, sum holes: 4 */
                /* last cacheline: 16 bytes */
          };
          #
    
    
  • v1.17
    e709afe6 · dwarves: Prep v1.17 ·
    v1.17 changes:
    
    tl;dr:
    
    BTF loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux.
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name:
    
         $ pahole sk_buff
    
      - Do not require a class name to operate without a file name.
    
          $ pahole          # is equivalent to:
          $ pahole vmlinux
    
      - Make --find_pointers_to consider unions:
    
          $ pahole --find_pointers_to ehci_qh
    
      - Make --contains and --find_pointers_to honour --unions
    
          $ pahole --unions --contains inet_sock
    
      - Add support for finding pointers to void:
    
         $ pahole --find_pointers_to void
    
      - Make --contains and --find_pointers_to to work with base types:
    
          $ pahole --find_pointers_to 'short unsigned int'
    
      - Make --contains look for more than just unions, structs:
    
          $ pahole --contains raw_spinlock_t
    
      - Consider unions when looking for classes containing some class:
    
          $ pahole --contains tpacket_req
    
      - Introduce --unions to consider just unions:
    
          $ pahole --unions --sizes
          $ pahole --unions --prefix tcp
          $ pahole --unions --nr_members
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
          $ pahole --nr_methods
    
    man-pages:
    
      - Add section about --hex + -E to locate offsets deep into sub structs.
    
      - Add more information about BTF.
    
      - Add some examples.
    
    ----------------------------------
    
    I want the details:
    
    btf loader:
    
      - Support raw BTF as available in /sys/kernel/btf/vmlinux
    
        Be it automatically when no -F option is passed and
        /sys/kernel/btf/vmlinux is available, or when /sys/kernel/btf/vmlinux is
        passed as the filename to the tool, i.e.:
    
          $ pahole -C 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 */
          };
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
          $ pahole -C list_head /sys/kernel/btf/vmlinux
          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 */
          };
          $
    
        If one wants to grab the matching vmlinux to use its DWARF info instead,
        which is useful to compare the results with what we have from BTF, for
        instance, its just a matter of using '-F dwarf'.
    
        This in turn shows something that at first came as a surprise, but then
        has a simple explanation:
    
        For very common data structures, that will probably appear in all of the
        DWARF CUs (Compilation Units), like 'struct list_head', using '-F dwarf'
        is faster:
    
          $ perf stat -e cycles pahole -F btf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F btf -C list_head':
    
                  45,722,518      cycles:u
    
                 0.023717300 seconds time elapsed
    
                 0.016474000 seconds user
                 0.007212000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf -C list_head > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C list_head':
    
                  14,170,321      cycles:u
    
                 0.006668904 seconds time elapsed
    
                 0.005562000 seconds user
                 0.001109000 seconds sys
    
          $
    
        But for something that is more specific to a subsystem, the DWARF loader
        will have to process way more stuff till it gets to that struct:
    
          $ perf stat -e cycles pahole -F dwarf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F dwarf -C tcp_sock':
    
              31,579,795,238      cycles:u
    
                 8.332272930 seconds time elapsed
    
                 8.032124000 seconds user
                 0.286537000 seconds sys
    
          $
    
        While using the BTF loader the time should be constant, as it loads
        everything from /sys/kernel/btf/vmlinux:
    
          $ perf stat -e cycles pahole -F btf -C tcp_sock > /dev/null
    
           Performance counter stats for 'pahole -F btf -C tcp_sock':
    
                  48,823,488      cycles:u
    
                 0.024102760 seconds time elapsed
    
                 0.012035000 seconds user
                 0.012046000 seconds sys
    
          $
    
        Above I used '-F btf' just to show that it can be used, but its not
        really needed, i.e. those are equivalent:
    
          $ strace -e openat pahole -F btf -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $ strace -e openat pahole -C list_head |& grep /sys/kernel/btf/vmlinux
          openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 3
          $
    
        The btf_raw__load() function that ends up being grafted into the
        preexisting btf_elf routines was based on libbpf's btf_load_raw().
    
    pahole:
    
      - When the sole argument passed isn't a file, take it as a class name.
    
        With that it becomes as compact as it gets for kernel data structures,
        just state the name of the struct and it'll try to find that as a file,
        not being a file it'll use /sys/kernel/btf/vmlinux and the argument as a
        list of structs, i.e.:
    
          $ pahole skb_ext,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 */
          };
          struct skb_ext {
                refcount_t                 refcnt;               /*     0     4 */
                u8                         offset[3];            /*     4     3 */
                u8                         chunks;               /*     7     1 */
                char                       data[];               /*     8     0 */
    
                /* size: 8, cachelines: 1, members: 4 */
                /* last cacheline: 8 bytes */
          };
          $ pahole hlist_node
          struct hlist_node {
                struct hlist_node *        next;                 /*     0     8 */
                struct hlist_node * *      pprev;                /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
        Of course -C continues to work:
    
          $ pahole -C inode | tail
                __u32                      i_fsnotify_mask;      /*   556     4 */
                struct fsnotify_mark_connector * i_fsnotify_marks; /*   560     8 */
                struct fscrypt_info *      i_crypt_info;         /*   568     8 */
                /* --- cacheline 9 boundary (576 bytes) --- */
                struct fsverity_info *     i_verity_info;        /*   576     8 */
                void *                     i_private;            /*   584     8 */
    
                /* size: 592, cachelines: 10, members: 53 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Add support for finding pointers to void, e.g.:
    
          $ pahole --find_pointers_to void --prefix tcp
          tcp_md5sig_pool: scratch
          $ pahole tcp_md5sig_pool
          struct tcp_md5sig_pool {
                struct ahash_request *     md5_req;              /*     0     8 */
                void *                     scratch;              /*     8     8 */
    
                /* size: 16, cachelines: 1, members: 2 */
                /* last cacheline: 16 bytes */
          };
          $
    
      - Make --contains and --find_pointers_to to work with base types
    
        I.e. with plain 'int', 'long', 'short int', etc:
    
          $ pahole --find_pointers_to 'short unsigned int'
          uv_hub_info_s: socket_to_node
          uv_hub_info_s: socket_to_pnode
          uv_hub_info_s: pnode_to_socket
          vc_data: vc_screenbuf
          vc_data: vc_translate
          filter_pred: ops
          ext4_sb_info: s_mb_offsets
          $ pahole ext4_sb_info | 'sort unsigned int'
          bash: sort unsigned int: command not found...
          ^[^C
          $
          $ pahole ext4_sb_info | grep 'sort unsigned int'
          $ pahole ext4_sb_info | grep 'short unsigned int'
                short unsigned int         s_mount_state;        /*   160     2 */
                short unsigned int         s_pad;                /*   162     2 */
                short unsigned int *       s_mb_offsets;         /*   664     8 */
          $ pahole --contains 'short unsigned int'
          apm_info
          desc_ptr
          thread_struct
          mpc_table
          mpc_intsrc
          fsnotify_mark_connector
          <SNIP>
          sock_fprog
          blk_mq_hw_ctx
          skb_shared_info
          $
    
      - Make --contains look for more than just unions, structs, look for
        typedefs, enums and types that descend from 'struct type':
    
        So now we can do more interesting queries, lets see, what are the data
        structures that embed a raw spinlock in the linux kernel?
    
          $ pahole --contains raw_spinlock_t
          task_struct
          rw_semaphore
          hrtimer_cpu_base
          prev_cputime
          percpu_counter
          ratelimit_state
          perf_event_context
          task_delay_info
          <SNIP>
          lpm_trie
          bpf_queue_stack
          $
    
        Look at the csets comments to see more examples.
    
      - Make --contains and --find_pointers_to honour --unions
    
        I.e. when looking for unions or structs that contains/embeds or looking
        for unions/structs that have pointers to a given type.
    
        E.g:
    
          $ pahole --contains inet_sock
          sctp_sock
          inet_connection_sock
          raw_sock
          udp_sock
          raw6_sock
          $ pahole --unions --contains inet_sock
          $
    
        We have structs embedding 'struct inet_sock', but no unions doing that.
    
      - Make --find_pointers_to consider unions
    
        I.e.:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          $
    
        Wasn't considering:
    
          $ pahole -C ehci_shadow
          union ehci_shadow {
                struct ehci_qh *           qh;                 /*     0     8 */
                struct ehci_itd *          itd;                /*     0     8 */
                struct ehci_sitd *         sitd;               /*     0     8 */
                struct ehci_fstn *         fstn;               /*     0     8 */
                __le32 *                   hw_next;            /*     0     8 */
                void *                     ptr;                /*     0     8 */
          };
          $
    
        Fix it:
    
          $ pahole --find_pointers_to ehci_qh
          ehci_hcd: qh_scan_next
          ehci_hcd: async
          ehci_hcd: dummy
          ehci_shadow: qh
          $
    
      - Consider unions when looking for classes containing some class:
    
        I.e.:
    
          $ pahole --contains tpacket_req
          tpacket_req_u
          $
    
        Wasn't working, but should be considered with --contains/-i:
    
          $ pahole -C tpacket_req_u
          union tpacket_req_u {
                struct tpacket_req         req;                /*     0    16 */
                struct tpacket_req3        req3;               /*     0    28 */
          };
          $
    
      - Introduce --unions to consider just unions
    
        Most filters can be used together with it, for instance to see the
        biggest unions in the kernel:
    
          $ pahole --unions --sizes | sort -k2 -nr | head
          thread_union            16384 0
          swap_header              4096 0
          fpregs_state             4096 0
          autofs_v5_packet_union    304 0
          autofs_packet_union       272 0
          pptp_ctrl_union           208 0
          acpi_parse_object         200 0
          acpi_descriptor           200 0
          bpf_attr                  120 0
          phy_configure_opts        112 0
          $
    
        Or just some unions that have some specific prefix:
    
          $ pahole --unions --prefix tcp
          union tcp_md5_addr {
                struct in_addr             a4;                 /*     0     4 */
                struct in6_addr            a6;                 /*     0    16 */
          };
          union tcp_word_hdr {
                struct tcphdr              hdr;                /*     0    20 */
                __be32                     words[5];           /*     0    20 */
          };
          union tcp_cc_info {
                struct tcpvegas_info       vegas;              /*     0    16 */
                struct tcp_dctcp_info      dctcp;              /*     0    16 */
                struct tcp_bbr_info        bbr;                /*     0    20 */
          };
          $
    
        What are the biggest unions in terms of number of members?
    
          $ pahole --unions --nr_members | sort -k2 -nr | head
          security_list_options 218
          aml_resource           36
          acpi_resource_data     29
          acpi_operand_object    26
          iwreq_data             18
          sctp_params            15
          ib_flow_spec           14
          ethtool_flow_union     14
          pptp_ctrl_union        13
          bpf_attr               12
          $
    
        If you want to script most of the queries can change the separator:
    
          $ pahole --unions --nr_members -t, | sort -t, -k2 -nr | head
          security_list_options,218
          aml_resource,36
          acpi_resource_data,29
          acpi_operand_object,26
          iwreq_data,18
          sctp_params,15
          ib_flow_spec,14
          ethtool_flow_union,14
          pptp_ctrl_union,13
          bpf_attr,12
          $
    
      - Fix -m/--nr_methods - Number of functions operating on a type pointer
    
        We had to use the same hack as in pfunct, as implemented in ccf3eebfcd9c
        ("btf_loader: Add support for BTF_KIND_FUNC"), will hide that 'struct
        ftype' (aka function prototype) indirection behind the parameter
        iterator (function__for_each_parameter).
    
        For now, here is the top 10 Linux kernel data structures in terms of
        number of functions receiving as one of its parameters a pointer to it,
        using /sys/kernel/btf/vmlinux to look at all the vmlinux types and
        functions (the ones visible in kallsyms, but with the parameters and its
        types):
    
          $ pahole -m | sort -k2 -nr | head
          device        955
          sock          568
          sk_buff       541
          task_struct   437
          inode         421
          pci_dev       390
          page          351
          net_device    347
          file          315
          net           312
          $
          $ pahole --help |& grep -- -m
            -m, --nr_methods           show number of methods
          $
    
      - Do not require a class name to operate without a file name
    
        Since we default to operating on the running kernel data structures, we
        should make the default to, with no options passed, to pretty print all
        the running kernel data structures, or do what was asked in terms of
        number of members, size of structs, etc, i.e.:
    
          # pahole --help |& head
          Usage: pahole [OPTION...] FILE
    
            -a, --anon_include         include anonymous classes
            -A, --nested_anon_include  include nested (inside other structs) anonymous
                                       classes
            -B, --bit_holes=NR_HOLES   Show only structs at least NR_HOLES bit holes
            -c, --cacheline_size=SIZE  set cacheline size to SIZE
                --classes_as_structs   Use 'struct' when printing classes
            -C, --class_name=CLASS_NAME   Show just this class
            -d, --recursive            recursive mode, affects several other flags
          #
    
        Continues working as before, but if you do:
    
          pahole
    
        It will work just as if you did:
    
          pahole vmlinux
    
        and that vmlinux file is the running kernel vmlinux.
    
        And since the default now is to read BTF info, then it will do all its
        operations on /sys/kernel/btf/vmlinux, when present, i.e. want to know
        what are the fattest data structures in the running kernel:
    
          # pahole -s | sort -k2 -nr | head
          cmp_data      290904  1
          dec_data      274520  1
          cpu_entry_area        217088  0
          pglist_data   172928  4
          saved_cmdlines_buffer 131104  1
          debug_store_buffers   131072  0
          hid_parser    110848  1
          hid_local     110608  0
          zonelist      81936   0
          e820_table    64004   0
          #
    
        How many data structures in the running kernel vmlinux area embbed
        'struct list_head'?
    
          # pahole -i list_head | wc -l
          260
          #
    
        Lets see some of those?
    
          # pahole -C fsnotify_event
          struct fsnotify_event {
                struct list_head           list;                 /*     0    16 */
                struct inode *             inode;                /*    16     8 */
    
                /* size: 24, cachelines: 1, members: 2 */
                /* last cacheline: 24 bytes */
          };
          # pahole -C audit_chunk
          struct audit_chunk {
                struct list_head           hash;                 /*     0    16 */
                long unsigned int          key;                  /*    16     8 */
                struct fsnotify_mark *     mark;                 /*    24     8 */
                struct list_head           trees;                /*    32    16 */
                int                        count;                /*    48     4 */
    
                /* XXX 4 bytes hole, try to pack */
    
                atomic_long_t              refs;                 /*    56     8 */
                /* --- cacheline 1 boundary (64 bytes) --- */
                struct callback_head       head;                 /*    64    16 */
                struct node                owners[];             /*    80     0 */
    
                /* size: 80, cachelines: 2, members: 8 */
                /* sum members: 76, holes: 1, sum holes: 4 */
                /* last cacheline: 16 bytes */
          };
          #
    
    
  • debian/1.16-2
    Release 1.16-2
    
  • debian/1.16-1
    Release 1.16-1
    
  • acmel/1.16
    1c1af2cd · dwarves: Prep v1.16 ·
    v1.16 changes:
    
    BTF encoder:
    
      Andrii Nakryiko <andriin@fb.com>:
    
      - Preserve and encode exported functions as BTF_KIND_FUNC.
    
        Add encoding of DWARF's DW_TAG_subprogram_type into BTF's BTF_KIND_FUNC
        (plus corresponding BTF_KIND_FUNC_PROTO). Only exported functions are converted
        for now. This allows to capture all the exported kernel functions, same subset
        that's exposed through /proc/kallsyms.
    
    BTF loader:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - Add support for BTF_KIND_FUNC
    
        Some changes to the fprintf routines were needed, as BTF has as the
        function type just a BTF_KIND_FUNC_PROTO, while DWARF has as the type for a
        function its return value type. With a function->btf flag this was overcome and
        all the other goodies in pfunct are present.
    
    Pretty printer:
    
      Arnaldo Carvalho de Melo:
    
      - Account inline type __aligned__ member types for spacing:
    
                  union {
                          refcount_t         rcu_users;            /*  2568     4 */
                          struct callback_head rcu __attribute__((__aligned__(8))); /*  2568    16 */
          -       } __attribute__((__aligned__(8)));                                               /*  2568    16 */
          +       } __attribute__((__aligned__(8)));               /*  2568    16 */
                  struct pipe_inode_info *   splice_pipe;          /*  2584     8 */
    
      - Fix alignment of class members that are structs/enums/unions
    
        E.g. look at that 'completion' member in this struct:
    
           struct cpu_stop_done {
                  atomic_t                   nr_todo;              /*     0     4 */
                  int                        ret;                  /*     4     4 */
          -       struct completion  completion;                   /*     8    32 */
          +       struct completion          completion;           /*     8    32 */
    
                  /* size: 40, cachelines: 1, members: 3 */
                  /* last cacheline: 40 bytes */
    
      - Fixup handling classes with no members, solving a NULL deref.
    
      Gareth Lloyd <gareth.lloyd@uk.ibm.com>:
    
      - Avoid infinite loop trying to determine type with static data member of its own type.
    
    RPM spec file.
    
    Jiri Olsa <jolsa@redhat.com>
    
        Add dwarves dependency on libdwarves1.
    
    pfunct:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - type->type == 0 is void, fix --compile for that
    
        We were using the fall back for that, i.e. 'return 0;' was being emitted
        for a function returning void, noticed with using BTF as the format.
    
    pdwtags:
    
        - Print DW_TAG_subroutine_type as well
    
          So that we can see at least via pdwtags those tags, be it from DWARF of BTF.
    
    core:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
        Fix ptr_table__add_with_id() handling of pt->nr_entries, covering how
        BTF variables IDs are encoded.
    
    pglobal:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Allow passing the format path specifier, to use with BTF
    
        I.e. now we can, just like with pahole, use:
    
          pglobal -F btf --variable foo.o
    
        To get the global variables.
    
    Tree wide:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Fixup issues pointed out by various coverity reports.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/1.16
    1c1af2cd · dwarves: Prep v1.16 ·
    v1.16 changes:
    
    BTF encoder:
    
      Andrii Nakryiko <andriin@fb.com>:
    
      - Preserve and encode exported functions as BTF_KIND_FUNC.
    
        Add encoding of DWARF's DW_TAG_subprogram_type into BTF's BTF_KIND_FUNC
        (plus corresponding BTF_KIND_FUNC_PROTO). Only exported functions are converted
        for now. This allows to capture all the exported kernel functions, same subset
        that's exposed through /proc/kallsyms.
    
    BTF loader:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - Add support for BTF_KIND_FUNC
    
        Some changes to the fprintf routines were needed, as BTF has as the
        function type just a BTF_KIND_FUNC_PROTO, while DWARF has as the type for a
        function its return value type. With a function->btf flag this was overcome and
        all the other goodies in pfunct are present.
    
    Pretty printer:
    
      Arnaldo Carvalho de Melo:
    
      - Account inline type __aligned__ member types for spacing:
    
                  union {
                          refcount_t         rcu_users;            /*  2568     4 */
                          struct callback_head rcu __attribute__((__aligned__(8))); /*  2568    16 */
          -       } __attribute__((__aligned__(8)));                                               /*  2568    16 */
          +       } __attribute__((__aligned__(8)));               /*  2568    16 */
                  struct pipe_inode_info *   splice_pipe;          /*  2584     8 */
    
      - Fix alignment of class members that are structs/enums/unions
    
        E.g. look at that 'completion' member in this struct:
    
           struct cpu_stop_done {
                  atomic_t                   nr_todo;              /*     0     4 */
                  int                        ret;                  /*     4     4 */
          -       struct completion  completion;                   /*     8    32 */
          +       struct completion          completion;           /*     8    32 */
    
                  /* size: 40, cachelines: 1, members: 3 */
                  /* last cacheline: 40 bytes */
    
      - Fixup handling classes with no members, solving a NULL deref.
    
      Gareth Lloyd <gareth.lloyd@uk.ibm.com>:
    
      - Avoid infinite loop trying to determine type with static data member of its own type.
    
    RPM spec file.
    
    Jiri Olsa <jolsa@redhat.com>
    
        Add dwarves dependency on libdwarves1.
    
    pfunct:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - type->type == 0 is void, fix --compile for that
    
        We were using the fall back for that, i.e. 'return 0;' was being emitted
        for a function returning void, noticed with using BTF as the format.
    
    pdwtags:
    
        - Print DW_TAG_subroutine_type as well
    
          So that we can see at least via pdwtags those tags, be it from DWARF of BTF.
    
    core:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
        Fix ptr_table__add_with_id() handling of pt->nr_entries, covering how
        BTF variables IDs are encoded.
    
    pglobal:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Allow passing the format path specifier, to use with BTF
    
        I.e. now we can, just like with pahole, use:
    
          pglobal -F btf --variable foo.o
    
        To get the global variables.
    
    Tree wide:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Fixup issues pointed out by various coverity reports.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/v1.16
    1c1af2cd · dwarves: Prep v1.16 ·
    v1.16 changes:
    
    BTF encoder:
    
      Andrii Nakryiko <andriin@fb.com>:
    
      - Preserve and encode exported functions as BTF_KIND_FUNC.
    
        Add encoding of DWARF's DW_TAG_subprogram_type into BTF's BTF_KIND_FUNC
        (plus corresponding BTF_KIND_FUNC_PROTO). Only exported functions are converted
        for now. This allows to capture all the exported kernel functions, same subset
        that's exposed through /proc/kallsyms.
    
    BTF loader:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - Add support for BTF_KIND_FUNC
    
        Some changes to the fprintf routines were needed, as BTF has as the
        function type just a BTF_KIND_FUNC_PROTO, while DWARF has as the type for a
        function its return value type. With a function->btf flag this was overcome and
        all the other goodies in pfunct are present.
    
    Pretty printer:
    
      Arnaldo Carvalho de Melo:
    
      - Account inline type __aligned__ member types for spacing:
    
                  union {
                          refcount_t         rcu_users;            /*  2568     4 */
                          struct callback_head rcu __attribute__((__aligned__(8))); /*  2568    16 */
          -       } __attribute__((__aligned__(8)));                                               /*  2568    16 */
          +       } __attribute__((__aligned__(8)));               /*  2568    16 */
                  struct pipe_inode_info *   splice_pipe;          /*  2584     8 */
    
      - Fix alignment of class members that are structs/enums/unions
    
        E.g. look at that 'completion' member in this struct:
    
           struct cpu_stop_done {
                  atomic_t                   nr_todo;              /*     0     4 */
                  int                        ret;                  /*     4     4 */
          -       struct completion  completion;                   /*     8    32 */
          +       struct completion          completion;           /*     8    32 */
    
                  /* size: 40, cachelines: 1, members: 3 */
                  /* last cacheline: 40 bytes */
    
      - Fixup handling classes with no members, solving a NULL deref.
    
      Gareth Lloyd <gareth.lloyd@uk.ibm.com>:
    
      - Avoid infinite loop trying to determine type with static data member of its own type.
    
    RPM spec file.
    
    Jiri Olsa <jolsa@redhat.com>
    
        Add dwarves dependency on libdwarves1.
    
    pfunct:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - type->type == 0 is void, fix --compile for that
    
        We were using the fall back for that, i.e. 'return 0;' was being emitted
        for a function returning void, noticed with using BTF as the format.
    
    pdwtags:
    
        - Print DW_TAG_subroutine_type as well
    
          So that we can see at least via pdwtags those tags, be it from DWARF of BTF.
    
    core:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
        Fix ptr_table__add_with_id() handling of pt->nr_entries, covering how
        BTF variables IDs are encoded.
    
    pglobal:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Allow passing the format path specifier, to use with BTF
    
        I.e. now we can, just like with pahole, use:
    
          pglobal -F btf --variable foo.o
    
        To get the global variables.
    
    Tree wide:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Fixup issues pointed out by various coverity reports.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • v1.16
    1c1af2cd · dwarves: Prep v1.16 ·
    v1.16 changes:
    
    BTF encoder:
    
      Andrii Nakryiko <andriin@fb.com>:
    
      - Preserve and encode exported functions as BTF_KIND_FUNC.
    
        Add encoding of DWARF's DW_TAG_subprogram_type into BTF's BTF_KIND_FUNC
        (plus corresponding BTF_KIND_FUNC_PROTO). Only exported functions are converted
        for now. This allows to capture all the exported kernel functions, same subset
        that's exposed through /proc/kallsyms.
    
    BTF loader:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - Add support for BTF_KIND_FUNC
    
        Some changes to the fprintf routines were needed, as BTF has as the
        function type just a BTF_KIND_FUNC_PROTO, while DWARF has as the type for a
        function its return value type. With a function->btf flag this was overcome and
        all the other goodies in pfunct are present.
    
    Pretty printer:
    
      Arnaldo Carvalho de Melo:
    
      - Account inline type __aligned__ member types for spacing:
    
                  union {
                          refcount_t         rcu_users;            /*  2568     4 */
                          struct callback_head rcu __attribute__((__aligned__(8))); /*  2568    16 */
          -       } __attribute__((__aligned__(8)));                                               /*  2568    16 */
          +       } __attribute__((__aligned__(8)));               /*  2568    16 */
                  struct pipe_inode_info *   splice_pipe;          /*  2584     8 */
    
      - Fix alignment of class members that are structs/enums/unions
    
        E.g. look at that 'completion' member in this struct:
    
           struct cpu_stop_done {
                  atomic_t                   nr_todo;              /*     0     4 */
                  int                        ret;                  /*     4     4 */
          -       struct completion  completion;                   /*     8    32 */
          +       struct completion          completion;           /*     8    32 */
    
                  /* size: 40, cachelines: 1, members: 3 */
                  /* last cacheline: 40 bytes */
    
      - Fixup handling classes with no members, solving a NULL deref.
    
      Gareth Lloyd <gareth.lloyd@uk.ibm.com>:
    
      - Avoid infinite loop trying to determine type with static data member of its own type.
    
    RPM spec file.
    
    Jiri Olsa <jolsa@redhat.com>
    
        Add dwarves dependency on libdwarves1.
    
    pfunct:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
      - type->type == 0 is void, fix --compile for that
    
        We were using the fall back for that, i.e. 'return 0;' was being emitted
        for a function returning void, noticed with using BTF as the format.
    
    pdwtags:
    
        - Print DW_TAG_subroutine_type as well
    
          So that we can see at least via pdwtags those tags, be it from DWARF of BTF.
    
    core:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>
    
        Fix ptr_table__add_with_id() handling of pt->nr_entries, covering how
        BTF variables IDs are encoded.
    
    pglobal:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Allow passing the format path specifier, to use with BTF
    
        I.e. now we can, just like with pahole, use:
    
          pglobal -F btf --variable foo.o
    
        To get the global variables.
    
    Tree wide:
    
      Arnaldo Carvalho de Melo <acme@redhat.com>:
    
      - Fixup issues pointed out by various coverity reports.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • debian/1.15-2
    8fa0aedd · Release 1.15-2 ·
    Release 1.15-2
    
  • debian/1.15-1
    05fbd5ae · Release 1.15-1 ·
    Release 1.15-1
    
  • acmel/1.15
    52990357 · v1.15: New release ·
    v1.15 June 2019
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/1.15
    52990357 · v1.15: New release ·
    v1.15 June 2019
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/v1.15
    52990357 · v1.15: New release ·
    v1.15 June 2019
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • v1.15
    52990357 · v1.15: New release ·
    v1.15 June 2019
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • acmel/1.14
    v1.14:
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/1.14
    v1.14:
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/v1.14
    v1.14:
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • v1.14
    v1.14:
    
    Bugfix release, see NEWS file.
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>