Skip to content

Tags

Tags give the ability to mark specific points in history as being important
  • acmel/1.13

    Here is a summary of changes for the 1.13 version of pahole and its friends:
    
    - BTF
    
      - Use of the recently introduced BTF deduplication algorithm present in the
        Linux kernel's libbpf library, which allows for all the types in a multi
        compile unit binary such as vmlinux to be compactly stored, without duplicates.
    
        E.g.: from roughly:
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .debug_info.*PROGBITS
          [63] .debug_info PROGBITS 0000000000000000 1d80be0 c3c18b9 00 0 0 1
        $
        195 MiB
    
        to:
    
        $ time pahole --btf_encode ../build/v5.1-rc4+/vmlinux
        real    0m19.168s
        user    0m17.707s         # On a Lenovo t480s (i7-8650U) SSD
        sys     0m1.337s
        $
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .BTF.*PROGBITS
          [78] .BTF        PROGBITS 0000000000000000 27b49f61 1e23c3 00 0 0 1
        $
        ~2 MiB
    
      - Introduce a 'btfdiff' utility that prints the output from DWARF and from
        BTF, comparing the pretty printed outputs, running it on various linux
        kernel images, such as an allyesconfig for ppc64.
    
        Running it on the above 5.1-rc4+ vmlinux:
    
          $ btfdiff ../build/v5.1-rc4+/vmlinux
          $
    
        No differences from the types generated from the DWARF ELF sections to the
        ones generated from the BTF ELF section.
    
      - Add a BTF loader, i.e. 'pahole -F btf' allows pretty printing of structs
        and unions in the same fashion as with DWARF info, and since BTF is way
        more compact, using it is much faster than using DWARF.
    
          $ cat ../build/v5.1-rc4+/vmlinux > /dev/null
          $ perf stat -e cycles pahole -F btf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F btf ../build/v5.1-rc4+/vmlinux':
    
                 229,712,692      cycles:u
                 0.063379597 seconds time elapsed
                 0.056265000 seconds user
                 0.006911000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F dwarf ../build/v5.1-rc4+/vmlinux':
    
              49,579,679,466      cycles:u
                13.063487352 seconds time elapsed
                12.612512000 seconds user
                 0.426226000 seconds sys
          $
    
    - Better union support:
    
      - Allow unions to be specified in pahole in the same fashion as structs
    
        $ pahole -C thread_union ../build/v5.1-rc4+/net/ipv4/tcp.o
        union thread_union {
                struct task_struct task __attribute__((__aligned__(64))); /* 0 11008 */
                long unsigned int          stack[2048];                   /* 0 16384 */
        };
        $
    
    - Infer __attribute__((__packed__)) when structs have no alignment holes
      and violate basic types (integer, longs, short integer) natural alignment
      requirements. Several heuristics are used to infer the __packed__
      attribute, see the changeset log for descriptions.
    
      $ pahole -F btf -C boot_e820_entry ../build/v5.1-rc4+/vmlinux
      struct boot_e820_entry {
              __u64             addr;     /*     0     8 */
              __u64             size;     /*     8     8 */
              __u32             type;     /*    16     4 */
    
    	/* size: 20, cachelines: 1, members: 3 */
    	/* last cacheline: 20 bytes */
      } __attribute__((__packed__));
      $
    
      $ pahole -F btf -C lzma_header ../build/v5.1-rc4+/vmlinux
      struct lzma_header {
              uint8_t                    pos;                  /*     0     1 */
              uint32_t                   dict_size;            /*     1     4 */
              uint64_t                   dst_size;             /*     5     8 */
    
              /* size: 13, cachelines: 1, members: 3 */
              /* last cacheline: 13 bytes */
      } __attribute__((__packed__));
    
    - Support DWARF5's DW_AT_alignment, which, together with the __packed__
      attribute inference algorithms produce output that, when compiled, should
      produce structures with layouts that match the original source code.
    
      See it in action with 'struct task_struct', which will also show some of the
      new information at the struct summary, at the end of the struct:
    
      $ pahole -C task_struct ../build/v5.1-rc4+/vmlinux | tail -19
      	/* --- cacheline 103 boundary (6592 bytes) --- */
      	struct vm_struct   * stack_vm_area;              /*  6592     8 */
      	refcount_t                 stack_refcount;       /*  6600     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	void *                     security;             /*  6608     8 */
    
      	/* XXX 40 bytes hole, try to pack */
    
      	/* --- cacheline 104 boundary (6656 bytes) --- */
      	struct thread_struct thread __attribute__((__aligned__(64))); /*  6656  4352 */
    
      	/* size: 11008, cachelines: 172, members: 207 */
      	/* sum members: 10902, holes: 16, sum holes: 98 */
      	/* sum bitfield members: 10 bits, bit holes: 2, sum bit holes: 54 bits */
      	/* paddings: 3, sum paddings: 14 */
      	/* forced alignments: 6, forced holes: 1, sum forced holes: 40 */
      } __attribute__((__aligned__(64)));
      $
    
    - Add a '--compile' option to 'pfunct' that produces compileable output for the
      function prototypes in an object file. There are still some bugs but the vast
      majority of the kernel single compilation unit files the ones produced from a
      single .c file are working, see the new 'fullcircle' utility that uses this
      feature.
    
      Example of it in action:
    
      $ pfunct --compile=static_key_false ../build/v5.1-rc4+/net/ipv4/tcp.o
      typedef _Bool bool;
      typedef struct {
      	int                        counter;              /*     0     4 */
    
      	/* size: 4, cachelines: 1, members: 1 */
      	/* last cacheline: 4 bytes */
      } atomic_t;
    
      struct jump_entry;
    
      struct static_key_mod;
    
      struct static_key {
      	atomic_t                   enabled;              /*     0     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	union {
      		long unsigned int  type;                 /*     8     8 */
      		struct jump_entry * entries;             /*     8     8 */
      		struct static_key_mod * next;            /*     8     8 */
      	};                                               /*     8     8 */
    
      	/* size: 16, cachelines: 1, members: 2 */
      	/* sum members: 12, holes: 1, sum holes: 4 */
      	/* last cacheline: 16 bytes */
      };
    
      bool static_key_false(struct static_key * key)
      {
      	return *(bool *)1;
      }
    
      $
    
    The generation of compilable code from the type information and its use in the
    new tool 'fullcircle, helps validate all the parts of this codebase, finding
    bugs that were lurking forever, go read the csets to find all sorts of curious
    C language features that are rarely seen, like unnamed zero sized bitfields and
    the way people have been using it over the years in a codebase like the linux
    kernel.
    
    Certainly there are several other features, changes and fixes that I forgot to
    mention! Now lemme release this version so that we can use it more extensively
    together with a recent patch merged for 5.2:
    
      [PATCH bpf-next] kbuild: add ability to generate BTF type info for vmlinux
    
    With it BTF will be always available for all the types of the kernel, which will
    open a pandora box of cool new features that are in the works, and, for people
    already using pahole, will greatly speed up its usage.
    
    Please try to alias it to use btf, i.e.
    
       alias pahole='pahole -F btf'
    
    Please report any problems you may find with this new version or with the BTF
    loader or any errors in the layout generated/pretty printed.
    
    Thanks to the fine BTF guys at Facebook for the patches and help in testing,
    fixing bugs and getting this out of the door, the stats for this release are:
    
          Changesets: 157
    
          113 Arnaldo Carvalho de Melo       Red Hat
           32 Andrii Nakryiko                Facebook
           10 Yonghong Song                  Facebook
            1 Martin Lau                     Facebook
            1 Domenico Andreoli
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/1.13

    Here is a summary of changes for the 1.13 version of pahole and its friends:
    
    - BTF
    
      - Use of the recently introduced BTF deduplication algorithm present in the
        Linux kernel's libbpf library, which allows for all the types in a multi
        compile unit binary such as vmlinux to be compactly stored, without duplicates.
    
        E.g.: from roughly:
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .debug_info.*PROGBITS
          [63] .debug_info PROGBITS 0000000000000000 1d80be0 c3c18b9 00 0 0 1
        $
        195 MiB
    
        to:
    
        $ time pahole --btf_encode ../build/v5.1-rc4+/vmlinux
        real    0m19.168s
        user    0m17.707s         # On a Lenovo t480s (i7-8650U) SSD
        sys     0m1.337s
        $
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .BTF.*PROGBITS
          [78] .BTF        PROGBITS 0000000000000000 27b49f61 1e23c3 00 0 0 1
        $
        ~2 MiB
    
      - Introduce a 'btfdiff' utility that prints the output from DWARF and from
        BTF, comparing the pretty printed outputs, running it on various linux
        kernel images, such as an allyesconfig for ppc64.
    
        Running it on the above 5.1-rc4+ vmlinux:
    
          $ btfdiff ../build/v5.1-rc4+/vmlinux
          $
    
        No differences from the types generated from the DWARF ELF sections to the
        ones generated from the BTF ELF section.
    
      - Add a BTF loader, i.e. 'pahole -F btf' allows pretty printing of structs
        and unions in the same fashion as with DWARF info, and since BTF is way
        more compact, using it is much faster than using DWARF.
    
          $ cat ../build/v5.1-rc4+/vmlinux > /dev/null
          $ perf stat -e cycles pahole -F btf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F btf ../build/v5.1-rc4+/vmlinux':
    
                 229,712,692      cycles:u
                 0.063379597 seconds time elapsed
                 0.056265000 seconds user
                 0.006911000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F dwarf ../build/v5.1-rc4+/vmlinux':
    
              49,579,679,466      cycles:u
                13.063487352 seconds time elapsed
                12.612512000 seconds user
                 0.426226000 seconds sys
          $
    
    - Better union support:
    
      - Allow unions to be specified in pahole in the same fashion as structs
    
        $ pahole -C thread_union ../build/v5.1-rc4+/net/ipv4/tcp.o
        union thread_union {
                struct task_struct task __attribute__((__aligned__(64))); /* 0 11008 */
                long unsigned int          stack[2048];                   /* 0 16384 */
        };
        $
    
    - Infer __attribute__((__packed__)) when structs have no alignment holes
      and violate basic types (integer, longs, short integer) natural alignment
      requirements. Several heuristics are used to infer the __packed__
      attribute, see the changeset log for descriptions.
    
      $ pahole -F btf -C boot_e820_entry ../build/v5.1-rc4+/vmlinux
      struct boot_e820_entry {
              __u64             addr;     /*     0     8 */
              __u64             size;     /*     8     8 */
              __u32             type;     /*    16     4 */
    
    	/* size: 20, cachelines: 1, members: 3 */
    	/* last cacheline: 20 bytes */
      } __attribute__((__packed__));
      $
    
      $ pahole -F btf -C lzma_header ../build/v5.1-rc4+/vmlinux
      struct lzma_header {
              uint8_t                    pos;                  /*     0     1 */
              uint32_t                   dict_size;            /*     1     4 */
              uint64_t                   dst_size;             /*     5     8 */
    
              /* size: 13, cachelines: 1, members: 3 */
              /* last cacheline: 13 bytes */
      } __attribute__((__packed__));
    
    - Support DWARF5's DW_AT_alignment, which, together with the __packed__
      attribute inference algorithms produce output that, when compiled, should
      produce structures with layouts that match the original source code.
    
      See it in action with 'struct task_struct', which will also show some of the
      new information at the struct summary, at the end of the struct:
    
      $ pahole -C task_struct ../build/v5.1-rc4+/vmlinux | tail -19
      	/* --- cacheline 103 boundary (6592 bytes) --- */
      	struct vm_struct   * stack_vm_area;              /*  6592     8 */
      	refcount_t                 stack_refcount;       /*  6600     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	void *                     security;             /*  6608     8 */
    
      	/* XXX 40 bytes hole, try to pack */
    
      	/* --- cacheline 104 boundary (6656 bytes) --- */
      	struct thread_struct thread __attribute__((__aligned__(64))); /*  6656  4352 */
    
      	/* size: 11008, cachelines: 172, members: 207 */
      	/* sum members: 10902, holes: 16, sum holes: 98 */
      	/* sum bitfield members: 10 bits, bit holes: 2, sum bit holes: 54 bits */
      	/* paddings: 3, sum paddings: 14 */
      	/* forced alignments: 6, forced holes: 1, sum forced holes: 40 */
      } __attribute__((__aligned__(64)));
      $
    
    - Add a '--compile' option to 'pfunct' that produces compileable output for the
      function prototypes in an object file. There are still some bugs but the vast
      majority of the kernel single compilation unit files the ones produced from a
      single .c file are working, see the new 'fullcircle' utility that uses this
      feature.
    
      Example of it in action:
    
      $ pfunct --compile=static_key_false ../build/v5.1-rc4+/net/ipv4/tcp.o
      typedef _Bool bool;
      typedef struct {
      	int                        counter;              /*     0     4 */
    
      	/* size: 4, cachelines: 1, members: 1 */
      	/* last cacheline: 4 bytes */
      } atomic_t;
    
      struct jump_entry;
    
      struct static_key_mod;
    
      struct static_key {
      	atomic_t                   enabled;              /*     0     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	union {
      		long unsigned int  type;                 /*     8     8 */
      		struct jump_entry * entries;             /*     8     8 */
      		struct static_key_mod * next;            /*     8     8 */
      	};                                               /*     8     8 */
    
      	/* size: 16, cachelines: 1, members: 2 */
      	/* sum members: 12, holes: 1, sum holes: 4 */
      	/* last cacheline: 16 bytes */
      };
    
      bool static_key_false(struct static_key * key)
      {
      	return *(bool *)1;
      }
    
      $
    
    The generation of compilable code from the type information and its use in the
    new tool 'fullcircle, helps validate all the parts of this codebase, finding
    bugs that were lurking forever, go read the csets to find all sorts of curious
    C language features that are rarely seen, like unnamed zero sized bitfields and
    the way people have been using it over the years in a codebase like the linux
    kernel.
    
    Certainly there are several other features, changes and fixes that I forgot to
    mention! Now lemme release this version so that we can use it more extensively
    together with a recent patch merged for 5.2:
    
      [PATCH bpf-next] kbuild: add ability to generate BTF type info for vmlinux
    
    With it BTF will be always available for all the types of the kernel, which will
    open a pandora box of cool new features that are in the works, and, for people
    already using pahole, will greatly speed up its usage.
    
    Please try to alias it to use btf, i.e.
    
       alias pahole='pahole -F btf'
    
    Please report any problems you may find with this new version or with the BTF
    loader or any errors in the layout generated/pretty printed.
    
    Thanks to the fine BTF guys at Facebook for the patches and help in testing,
    fixing bugs and getting this out of the door, the stats for this release are:
    
          Changesets: 157
    
          113 Arnaldo Carvalho de Melo       Red Hat
           32 Andrii Nakryiko                Facebook
           10 Yonghong Song                  Facebook
            1 Martin Lau                     Facebook
            1 Domenico Andreoli
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/v1.13

    Here is a summary of changes for the 1.13 version of pahole and its friends:
    
    - BTF
    
      - Use of the recently introduced BTF deduplication algorithm present in the
        Linux kernel's libbpf library, which allows for all the types in a multi
        compile unit binary such as vmlinux to be compactly stored, without duplicates.
    
        E.g.: from roughly:
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .debug_info.*PROGBITS
          [63] .debug_info PROGBITS 0000000000000000 1d80be0 c3c18b9 00 0 0 1
        $
        195 MiB
    
        to:
    
        $ time pahole --btf_encode ../build/v5.1-rc4+/vmlinux
        real    0m19.168s
        user    0m17.707s         # On a Lenovo t480s (i7-8650U) SSD
        sys     0m1.337s
        $
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .BTF.*PROGBITS
          [78] .BTF        PROGBITS 0000000000000000 27b49f61 1e23c3 00 0 0 1
        $
        ~2 MiB
    
      - Introduce a 'btfdiff' utility that prints the output from DWARF and from
        BTF, comparing the pretty printed outputs, running it on various linux
        kernel images, such as an allyesconfig for ppc64.
    
        Running it on the above 5.1-rc4+ vmlinux:
    
          $ btfdiff ../build/v5.1-rc4+/vmlinux
          $
    
        No differences from the types generated from the DWARF ELF sections to the
        ones generated from the BTF ELF section.
    
      - Add a BTF loader, i.e. 'pahole -F btf' allows pretty printing of structs
        and unions in the same fashion as with DWARF info, and since BTF is way
        more compact, using it is much faster than using DWARF.
    
          $ cat ../build/v5.1-rc4+/vmlinux > /dev/null
          $ perf stat -e cycles pahole -F btf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F btf ../build/v5.1-rc4+/vmlinux':
    
                 229,712,692      cycles:u
                 0.063379597 seconds time elapsed
                 0.056265000 seconds user
                 0.006911000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F dwarf ../build/v5.1-rc4+/vmlinux':
    
              49,579,679,466      cycles:u
                13.063487352 seconds time elapsed
                12.612512000 seconds user
                 0.426226000 seconds sys
          $
    
    - Better union support:
    
      - Allow unions to be specified in pahole in the same fashion as structs
    
        $ pahole -C thread_union ../build/v5.1-rc4+/net/ipv4/tcp.o
        union thread_union {
                struct task_struct task __attribute__((__aligned__(64))); /* 0 11008 */
                long unsigned int          stack[2048];                   /* 0 16384 */
        };
        $
    
    - Infer __attribute__((__packed__)) when structs have no alignment holes
      and violate basic types (integer, longs, short integer) natural alignment
      requirements. Several heuristics are used to infer the __packed__
      attribute, see the changeset log for descriptions.
    
      $ pahole -F btf -C boot_e820_entry ../build/v5.1-rc4+/vmlinux
      struct boot_e820_entry {
              __u64             addr;     /*     0     8 */
              __u64             size;     /*     8     8 */
              __u32             type;     /*    16     4 */
    
    	/* size: 20, cachelines: 1, members: 3 */
    	/* last cacheline: 20 bytes */
      } __attribute__((__packed__));
      $
    
      $ pahole -F btf -C lzma_header ../build/v5.1-rc4+/vmlinux
      struct lzma_header {
              uint8_t                    pos;                  /*     0     1 */
              uint32_t                   dict_size;            /*     1     4 */
              uint64_t                   dst_size;             /*     5     8 */
    
              /* size: 13, cachelines: 1, members: 3 */
              /* last cacheline: 13 bytes */
      } __attribute__((__packed__));
    
    - Support DWARF5's DW_AT_alignment, which, together with the __packed__
      attribute inference algorithms produce output that, when compiled, should
      produce structures with layouts that match the original source code.
    
      See it in action with 'struct task_struct', which will also show some of the
      new information at the struct summary, at the end of the struct:
    
      $ pahole -C task_struct ../build/v5.1-rc4+/vmlinux | tail -19
      	/* --- cacheline 103 boundary (6592 bytes) --- */
      	struct vm_struct   * stack_vm_area;              /*  6592     8 */
      	refcount_t                 stack_refcount;       /*  6600     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	void *                     security;             /*  6608     8 */
    
      	/* XXX 40 bytes hole, try to pack */
    
      	/* --- cacheline 104 boundary (6656 bytes) --- */
      	struct thread_struct thread __attribute__((__aligned__(64))); /*  6656  4352 */
    
      	/* size: 11008, cachelines: 172, members: 207 */
      	/* sum members: 10902, holes: 16, sum holes: 98 */
      	/* sum bitfield members: 10 bits, bit holes: 2, sum bit holes: 54 bits */
      	/* paddings: 3, sum paddings: 14 */
      	/* forced alignments: 6, forced holes: 1, sum forced holes: 40 */
      } __attribute__((__aligned__(64)));
      $
    
    - Add a '--compile' option to 'pfunct' that produces compileable output for the
      function prototypes in an object file. There are still some bugs but the vast
      majority of the kernel single compilation unit files the ones produced from a
      single .c file are working, see the new 'fullcircle' utility that uses this
      feature.
    
      Example of it in action:
    
      $ pfunct --compile=static_key_false ../build/v5.1-rc4+/net/ipv4/tcp.o
      typedef _Bool bool;
      typedef struct {
      	int                        counter;              /*     0     4 */
    
      	/* size: 4, cachelines: 1, members: 1 */
      	/* last cacheline: 4 bytes */
      } atomic_t;
    
      struct jump_entry;
    
      struct static_key_mod;
    
      struct static_key {
      	atomic_t                   enabled;              /*     0     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	union {
      		long unsigned int  type;                 /*     8     8 */
      		struct jump_entry * entries;             /*     8     8 */
      		struct static_key_mod * next;            /*     8     8 */
      	};                                               /*     8     8 */
    
      	/* size: 16, cachelines: 1, members: 2 */
      	/* sum members: 12, holes: 1, sum holes: 4 */
      	/* last cacheline: 16 bytes */
      };
    
      bool static_key_false(struct static_key * key)
      {
      	return *(bool *)1;
      }
    
      $
    
    The generation of compilable code from the type information and its use in the
    new tool 'fullcircle, helps validate all the parts of this codebase, finding
    bugs that were lurking forever, go read the csets to find all sorts of curious
    C language features that are rarely seen, like unnamed zero sized bitfields and
    the way people have been using it over the years in a codebase like the linux
    kernel.
    
    Certainly there are several other features, changes and fixes that I forgot to
    mention! Now lemme release this version so that we can use it more extensively
    together with a recent patch merged for 5.2:
    
      [PATCH bpf-next] kbuild: add ability to generate BTF type info for vmlinux
    
    With it BTF will be always available for all the types of the kernel, which will
    open a pandora box of cool new features that are in the works, and, for people
    already using pahole, will greatly speed up its usage.
    
    Please try to alias it to use btf, i.e.
    
       alias pahole='pahole -F btf'
    
    Please report any problems you may find with this new version or with the BTF
    loader or any errors in the layout generated/pretty printed.
    
    Thanks to the fine BTF guys at Facebook for the patches and help in testing,
    fixing bugs and getting this out of the door, the stats for this release are:
    
          Changesets: 157
    
          113 Arnaldo Carvalho de Melo       Red Hat
           32 Andrii Nakryiko                Facebook
           10 Yonghong Song                  Facebook
            1 Martin Lau                     Facebook
            1 Domenico Andreoli
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • v1.13

    Here is a summary of changes for the 1.13 version of pahole and its friends:
    
    - BTF
    
      - Use of the recently introduced BTF deduplication algorithm present in the
        Linux kernel's libbpf library, which allows for all the types in a multi
        compile unit binary such as vmlinux to be compactly stored, without duplicates.
    
        E.g.: from roughly:
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .debug_info.*PROGBITS
          [63] .debug_info PROGBITS 0000000000000000 1d80be0 c3c18b9 00 0 0 1
        $
        195 MiB
    
        to:
    
        $ time pahole --btf_encode ../build/v5.1-rc4+/vmlinux
        real    0m19.168s
        user    0m17.707s         # On a Lenovo t480s (i7-8650U) SSD
        sys     0m1.337s
        $
    
        $ readelf -SW ../build/v5.1-rc4+/vmlinux | grep .BTF.*PROGBITS
          [78] .BTF        PROGBITS 0000000000000000 27b49f61 1e23c3 00 0 0 1
        $
        ~2 MiB
    
      - Introduce a 'btfdiff' utility that prints the output from DWARF and from
        BTF, comparing the pretty printed outputs, running it on various linux
        kernel images, such as an allyesconfig for ppc64.
    
        Running it on the above 5.1-rc4+ vmlinux:
    
          $ btfdiff ../build/v5.1-rc4+/vmlinux
          $
    
        No differences from the types generated from the DWARF ELF sections to the
        ones generated from the BTF ELF section.
    
      - Add a BTF loader, i.e. 'pahole -F btf' allows pretty printing of structs
        and unions in the same fashion as with DWARF info, and since BTF is way
        more compact, using it is much faster than using DWARF.
    
          $ cat ../build/v5.1-rc4+/vmlinux > /dev/null
          $ perf stat -e cycles pahole -F btf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F btf ../build/v5.1-rc4+/vmlinux':
    
                 229,712,692      cycles:u
                 0.063379597 seconds time elapsed
                 0.056265000 seconds user
                 0.006911000 seconds sys
    
          $ perf stat -e cycles pahole -F dwarf ../build/v5.1-rc4+/vmlinux  > /dev/null
    
           Performance counter stats for 'pahole -F dwarf ../build/v5.1-rc4+/vmlinux':
    
              49,579,679,466      cycles:u
                13.063487352 seconds time elapsed
                12.612512000 seconds user
                 0.426226000 seconds sys
          $
    
    - Better union support:
    
      - Allow unions to be specified in pahole in the same fashion as structs
    
        $ pahole -C thread_union ../build/v5.1-rc4+/net/ipv4/tcp.o
        union thread_union {
                struct task_struct task __attribute__((__aligned__(64))); /* 0 11008 */
                long unsigned int          stack[2048];                   /* 0 16384 */
        };
        $
    
    - Infer __attribute__((__packed__)) when structs have no alignment holes
      and violate basic types (integer, longs, short integer) natural alignment
      requirements. Several heuristics are used to infer the __packed__
      attribute, see the changeset log for descriptions.
    
      $ pahole -F btf -C boot_e820_entry ../build/v5.1-rc4+/vmlinux
      struct boot_e820_entry {
              __u64             addr;     /*     0     8 */
              __u64             size;     /*     8     8 */
              __u32             type;     /*    16     4 */
    
    	/* size: 20, cachelines: 1, members: 3 */
    	/* last cacheline: 20 bytes */
      } __attribute__((__packed__));
      $
    
      $ pahole -F btf -C lzma_header ../build/v5.1-rc4+/vmlinux
      struct lzma_header {
              uint8_t                    pos;                  /*     0     1 */
              uint32_t                   dict_size;            /*     1     4 */
              uint64_t                   dst_size;             /*     5     8 */
    
              /* size: 13, cachelines: 1, members: 3 */
              /* last cacheline: 13 bytes */
      } __attribute__((__packed__));
    
    - Support DWARF5's DW_AT_alignment, which, together with the __packed__
      attribute inference algorithms produce output that, when compiled, should
      produce structures with layouts that match the original source code.
    
      See it in action with 'struct task_struct', which will also show some of the
      new information at the struct summary, at the end of the struct:
    
      $ pahole -C task_struct ../build/v5.1-rc4+/vmlinux | tail -19
      	/* --- cacheline 103 boundary (6592 bytes) --- */
      	struct vm_struct   * stack_vm_area;              /*  6592     8 */
      	refcount_t                 stack_refcount;       /*  6600     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	void *                     security;             /*  6608     8 */
    
      	/* XXX 40 bytes hole, try to pack */
    
      	/* --- cacheline 104 boundary (6656 bytes) --- */
      	struct thread_struct thread __attribute__((__aligned__(64))); /*  6656  4352 */
    
      	/* size: 11008, cachelines: 172, members: 207 */
      	/* sum members: 10902, holes: 16, sum holes: 98 */
      	/* sum bitfield members: 10 bits, bit holes: 2, sum bit holes: 54 bits */
      	/* paddings: 3, sum paddings: 14 */
      	/* forced alignments: 6, forced holes: 1, sum forced holes: 40 */
      } __attribute__((__aligned__(64)));
      $
    
    - Add a '--compile' option to 'pfunct' that produces compileable output for the
      function prototypes in an object file. There are still some bugs but the vast
      majority of the kernel single compilation unit files the ones produced from a
      single .c file are working, see the new 'fullcircle' utility that uses this
      feature.
    
      Example of it in action:
    
      $ pfunct --compile=static_key_false ../build/v5.1-rc4+/net/ipv4/tcp.o
      typedef _Bool bool;
      typedef struct {
      	int                        counter;              /*     0     4 */
    
      	/* size: 4, cachelines: 1, members: 1 */
      	/* last cacheline: 4 bytes */
      } atomic_t;
    
      struct jump_entry;
    
      struct static_key_mod;
    
      struct static_key {
      	atomic_t                   enabled;              /*     0     4 */
    
      	/* XXX 4 bytes hole, try to pack */
    
      	union {
      		long unsigned int  type;                 /*     8     8 */
      		struct jump_entry * entries;             /*     8     8 */
      		struct static_key_mod * next;            /*     8     8 */
      	};                                               /*     8     8 */
    
      	/* size: 16, cachelines: 1, members: 2 */
      	/* sum members: 12, holes: 1, sum holes: 4 */
      	/* last cacheline: 16 bytes */
      };
    
      bool static_key_false(struct static_key * key)
      {
      	return *(bool *)1;
      }
    
      $
    
    The generation of compilable code from the type information and its use in the
    new tool 'fullcircle, helps validate all the parts of this codebase, finding
    bugs that were lurking forever, go read the csets to find all sorts of curious
    C language features that are rarely seen, like unnamed zero sized bitfields and
    the way people have been using it over the years in a codebase like the linux
    kernel.
    
    Certainly there are several other features, changes and fixes that I forgot to
    mention! Now lemme release this version so that we can use it more extensively
    together with a recent patch merged for 5.2:
    
      [PATCH bpf-next] kbuild: add ability to generate BTF type info for vmlinux
    
    With it BTF will be always available for all the types of the kernel, which will
    open a pandora box of cool new features that are in the works, and, for people
    already using pahole, will greatly speed up its usage.
    
    Please try to alias it to use btf, i.e.
    
       alias pahole='pahole -F btf'
    
    Please report any problems you may find with this new version or with the BTF
    loader or any errors in the layout generated/pretty printed.
    
    Thanks to the fine BTF guys at Facebook for the patches and help in testing,
    fixing bugs and getting this out of the door, the stats for this release are:
    
          Changesets: 157
    
          113 Arnaldo Carvalho de Melo       Red Hat
           32 Andrii Nakryiko                Facebook
           10 Yonghong Song                  Facebook
            1 Martin Lau                     Facebook
            1 Domenico Andreoli
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • debian/1.12-2

    1086e74c · Release 1.12-2 ·
    dwarves-dfsg Debian release 1.12-2
    
  • debian/1.12-1

    dwarves-dfsg Debian release 1.12-1
    
  • debian/1.10-2.1

    Debian release 1.10-2.1
  • debian/1.10-2

    Debian release 1.10-2
  • debian/1.10-1

    Debian release 1.10-1
  • acmel/1.12

    4a21c5c8 · v1.12 - New Release ·
    v1.12 August 2018
    
    - Add a BTF encoder (Martin KaFai Lau)
    
    	BTF (BPF Type Format) is the meta data format which describes
    the data types of BPF program/map.  Hence, it basically focus on the C
    programming language which the modern BPF is primary using.  The first
    use case is to provide a generic pretty print capability for a BPF map.
    
    	BTF has its root from CTF (Compact C-Type format).
    
    - Add Documentation on how to use the BTF encoder: (Arnaldo Carvalho de Melo)
    
    	Using the Linux 'perf' tools integration with BPF/llvm/clang to
    show how to generate an object file that then gets its DWARF info used
    to create a .BTF ELF section with this new BTF format. That augmented
    eBPF ELF object file is then loaded while 'perf ftrace -g *bpf*' is used
    to show the kernel BTF validation process.
    
    - Initial support for DW_TAG_partial_unit (Arnaldo Carvalho de Melo)
    
    	Just by treating these sections as DW_TAG_compile_unit, which is
    enough for the structs that don't contain cross-section type references
    to be correctly loaded and pretty-printed with pahole.
    
    	This doesn't affect the kernel or modules, where such DWARF
    compression techniques are not used so far. (Arnaldo Carvalho de Melo)
    
    - Print cacheline boundaries in multiple union members, (Arnaldo Carvalho de Melo)
    
    	We were showing it just on the first inner union member members,
    as if it was a struct, now we restart the cacheline boundaries when
    moving to print the next inner struct.
    
    	As an example, look at 'struct audit_context' where the only
    cacheline boundary printed for the following unnamed union was the first
    one, for the 'socketcall' struct member, now that cacheline boundary
    appears in each of the union member inner structs:
    
        struct audit_context {
        <SNIP>
                union {
                        struct {
                                int        nargs;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                long int   args[6];              /*   832    48 */
                        } socketcall;                            /*   824    56 */
                        struct {
                                kuid_t     uid;                  /*   824     4 */
                                kgid_t     gid;                  /*   828     4 */
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                umode_t    mode;                 /*   832     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                u32        osid;                 /*   836     4 */
                                int        has_perm;             /*   840     4 */
                                uid_t      perm_uid;             /*   844     4 */
                                gid_t      perm_gid;             /*   848     4 */
                                umode_t    perm_mode;            /*   852     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                long unsigned int qbytes;        /*   856     8 */
                        } ipc;                                   /*   824    40 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr mqstat;           /*   832    64 */
                        } mq_getsetattr;                         /*   824    72 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
                                int        sigev_signo;          /*   828     4 */
                        } mq_notify;                             /*   824     8 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                size_t     msg_len;              /*   832     8 */
                                unsigned int msg_prio;           /*   840     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                struct timespec64 abs_timeout;   /*   848    16 */
                        } mq_sendrecv;                           /*   824    40 */
                        struct {
                                int        oflag;                /*   824     4 */
                                umode_t    mode;                 /*   828     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr attr;             /*   832    64 */
                        } mq_open;                               /*   824    72 */
                        struct {
                                pid_t      pid;                  /*   824     4 */
                                struct audit_cap_data cap;       /*   828    32 */
                        } capset;                                /*   824    36 */
                        struct {
                                int        fd;                   /*   824     4 */
                                int        flags;                /*   828     4 */
                        } mmap;                                  /*   824     8 */
                        struct {
                                int        argc;                 /*   824     4 */
                        } execve;                                /*   824     4 */
                        struct {
                                char *     name;                 /*   824     8 */
                        } module;                                /*   824     8 */
                };                                               /*   824    72 */
                /* --- cacheline 14 boundary (896 bytes) --- */
                int                        fds[2];               /*   896     8 */
                struct audit_proctitle     proctitle;            /*   904    16 */
    
                /* size: 920, cachelines: 15, members: 46 */
                /* sum members: 912, holes: 2, sum holes: 8 */
                /* last cacheline: 24 bytes */
        };
    
    - Show where a struct was used, e.g.
    
          $ pahole -I vmlinux
        <SNIP>
          /* Used at: /home/acme/git/perf/init/main.c */
          /* <1f4a5> /home/acme/git/perf/arch/x86/include/asm/orc_types.h:85 */
          struct orc_entry {
                  s16                        sp_offset;            /*     0     2 */
                  s16                        bp_offset;            /*     2     2 */
         <SNIP>
    
    - Show offsets at union members (Arnaldo Carvalho de Melo, suggested by Matthew Wilcox):
    
    	In complex structs with multiple complex unions figuring out the
    offset for a given union member is difficult, as one needs to figure out
    the union, go to the end of it to see the offset.
    
        This way, for instance, the Linux kernel's 'struct page' shows now as:
    
        struct page {
                long unsigned int          flags;                /*     0     8 */
                union {
                        struct address_space * mapping;          /*     8     8 */
                        void *             s_mem;                /*     8     8 */
                        atomic_t           compound_mapcount;    /*     8     4 */
                };                                               /*     8     8 */
                union {
                        long unsigned int  index;                /*    16     8 */
                        void *             freelist;             /*    16     8 */
                };                                               /*    16     8 */
                union {
                        long unsigned int  counters;             /*    24     8 */
                        struct {
                                union {
                                        atomic_t _mapcount;      /*    24     4 */
                                        unsigned int active;     /*    24     4 */
                                        struct {
                                                unsigned int inuse:16; /*    24:16  4 */
                                                unsigned int objects:15; /*    24: 1  4 */
                                                unsigned int frozen:1; /*    24: 0  4 */
                                        };                       /*    24     4 */
                                        int units;               /*    24     4 */
                                };                               /*    24     4 */
                                atomic_t   _refcount;            /*    28     4 */
                        };                                       /*    24     8 */
                };                                               /*    24     8 */
                union {
                        struct list_head   lru;                  /*    32    16 */
                        struct dev_pagemap * pgmap;              /*    32     8 */
                        struct {
                                struct page * next;              /*    32     8 */
                                int        pages;                /*    40     4 */
                                int        pobjects;             /*    44     4 */
                        };                                       /*    32    16 */
                        struct callback_head callback_head;      /*    32    16 */
                        struct {
                                long unsigned int compound_head; /*    32     8 */
                                unsigned int compound_dtor;      /*    40     4 */
                                unsigned int compound_order;     /*    44     4 */
                        };                                       /*    32    16 */
                        struct {
                                long unsigned int __pad;         /*    32     8 */
                                pgtable_t  pmd_huge_pte;         /*    40     8 */
                        };                                       /*    32    16 */
                };                                               /*    32    16 */
                union {
                        long unsigned int  private;              /*    48     8 */
                        spinlock_t         ptl;                  /*    48     4 */
                        struct kmem_cache * slab_cache;          /*    48     8 */
                };                                               /*    48     8 */
                struct mem_cgroup *        mem_cgroup;           /*    56     8 */
    
                /* size: 64, cachelines: 1, members: 7 */
        };
    
    - Search and use running kernel vmlinux when no file is passed (Arnaldo Carvalho de Melo)
    
    	Now it is possible to use it just as:
    
        $ pahole -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0     8 */
                struct sk_buff *           prev;                 /*     8     8 */
                __u32                      qlen;                 /*    16     4 */
                spinlock_t                 lock;                 /*    20     4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    	This will look at /sys/kernel/notes, find the running kernel
    build-id, and then search the usual locations (vmlinux,
    /lib/modules/`uname -r`/build/vmlinux, the debuginfo package paths, etc)
    to find the matching vmlinux with the DWARF info to use. Build-ids are
    now ubiquitous, so this shortens a the most common binary used.
    
    - Document 'pahole --hex' in the man page (Arnaldo Carvalho de Melo)
    
    	This option shows offsets and sizes in hexadecimal, helping to
    correlate with reports using that notation.
    
    	E.g.:
    
        $ pahole --hex -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0   0x8 */
                struct sk_buff *           prev;                 /*   0x8   0x8 */
                __u32                      qlen;                 /*  0x10   0x4 */
                spinlock_t                 lock;                 /*  0x14   0x4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
    
  • upstream/1.12

    4a21c5c8 · v1.12 - New Release ·
    v1.12 August 2018
    
    - Add a BTF encoder (Martin KaFai Lau)
    
    	BTF (BPF Type Format) is the meta data format which describes
    the data types of BPF program/map.  Hence, it basically focus on the C
    programming language which the modern BPF is primary using.  The first
    use case is to provide a generic pretty print capability for a BPF map.
    
    	BTF has its root from CTF (Compact C-Type format).
    
    - Add Documentation on how to use the BTF encoder: (Arnaldo Carvalho de Melo)
    
    	Using the Linux 'perf' tools integration with BPF/llvm/clang to
    show how to generate an object file that then gets its DWARF info used
    to create a .BTF ELF section with this new BTF format. That augmented
    eBPF ELF object file is then loaded while 'perf ftrace -g *bpf*' is used
    to show the kernel BTF validation process.
    
    - Initial support for DW_TAG_partial_unit (Arnaldo Carvalho de Melo)
    
    	Just by treating these sections as DW_TAG_compile_unit, which is
    enough for the structs that don't contain cross-section type references
    to be correctly loaded and pretty-printed with pahole.
    
    	This doesn't affect the kernel or modules, where such DWARF
    compression techniques are not used so far. (Arnaldo Carvalho de Melo)
    
    - Print cacheline boundaries in multiple union members, (Arnaldo Carvalho de Melo)
    
    	We were showing it just on the first inner union member members,
    as if it was a struct, now we restart the cacheline boundaries when
    moving to print the next inner struct.
    
    	As an example, look at 'struct audit_context' where the only
    cacheline boundary printed for the following unnamed union was the first
    one, for the 'socketcall' struct member, now that cacheline boundary
    appears in each of the union member inner structs:
    
        struct audit_context {
        <SNIP>
                union {
                        struct {
                                int        nargs;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                long int   args[6];              /*   832    48 */
                        } socketcall;                            /*   824    56 */
                        struct {
                                kuid_t     uid;                  /*   824     4 */
                                kgid_t     gid;                  /*   828     4 */
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                umode_t    mode;                 /*   832     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                u32        osid;                 /*   836     4 */
                                int        has_perm;             /*   840     4 */
                                uid_t      perm_uid;             /*   844     4 */
                                gid_t      perm_gid;             /*   848     4 */
                                umode_t    perm_mode;            /*   852     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                long unsigned int qbytes;        /*   856     8 */
                        } ipc;                                   /*   824    40 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr mqstat;           /*   832    64 */
                        } mq_getsetattr;                         /*   824    72 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
                                int        sigev_signo;          /*   828     4 */
                        } mq_notify;                             /*   824     8 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                size_t     msg_len;              /*   832     8 */
                                unsigned int msg_prio;           /*   840     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                struct timespec64 abs_timeout;   /*   848    16 */
                        } mq_sendrecv;                           /*   824    40 */
                        struct {
                                int        oflag;                /*   824     4 */
                                umode_t    mode;                 /*   828     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr attr;             /*   832    64 */
                        } mq_open;                               /*   824    72 */
                        struct {
                                pid_t      pid;                  /*   824     4 */
                                struct audit_cap_data cap;       /*   828    32 */
                        } capset;                                /*   824    36 */
                        struct {
                                int        fd;                   /*   824     4 */
                                int        flags;                /*   828     4 */
                        } mmap;                                  /*   824     8 */
                        struct {
                                int        argc;                 /*   824     4 */
                        } execve;                                /*   824     4 */
                        struct {
                                char *     name;                 /*   824     8 */
                        } module;                                /*   824     8 */
                };                                               /*   824    72 */
                /* --- cacheline 14 boundary (896 bytes) --- */
                int                        fds[2];               /*   896     8 */
                struct audit_proctitle     proctitle;            /*   904    16 */
    
                /* size: 920, cachelines: 15, members: 46 */
                /* sum members: 912, holes: 2, sum holes: 8 */
                /* last cacheline: 24 bytes */
        };
    
    - Show where a struct was used, e.g.
    
          $ pahole -I vmlinux
        <SNIP>
          /* Used at: /home/acme/git/perf/init/main.c */
          /* <1f4a5> /home/acme/git/perf/arch/x86/include/asm/orc_types.h:85 */
          struct orc_entry {
                  s16                        sp_offset;            /*     0     2 */
                  s16                        bp_offset;            /*     2     2 */
         <SNIP>
    
    - Show offsets at union members (Arnaldo Carvalho de Melo, suggested by Matthew Wilcox):
    
    	In complex structs with multiple complex unions figuring out the
    offset for a given union member is difficult, as one needs to figure out
    the union, go to the end of it to see the offset.
    
        This way, for instance, the Linux kernel's 'struct page' shows now as:
    
        struct page {
                long unsigned int          flags;                /*     0     8 */
                union {
                        struct address_space * mapping;          /*     8     8 */
                        void *             s_mem;                /*     8     8 */
                        atomic_t           compound_mapcount;    /*     8     4 */
                };                                               /*     8     8 */
                union {
                        long unsigned int  index;                /*    16     8 */
                        void *             freelist;             /*    16     8 */
                };                                               /*    16     8 */
                union {
                        long unsigned int  counters;             /*    24     8 */
                        struct {
                                union {
                                        atomic_t _mapcount;      /*    24     4 */
                                        unsigned int active;     /*    24     4 */
                                        struct {
                                                unsigned int inuse:16; /*    24:16  4 */
                                                unsigned int objects:15; /*    24: 1  4 */
                                                unsigned int frozen:1; /*    24: 0  4 */
                                        };                       /*    24     4 */
                                        int units;               /*    24     4 */
                                };                               /*    24     4 */
                                atomic_t   _refcount;            /*    28     4 */
                        };                                       /*    24     8 */
                };                                               /*    24     8 */
                union {
                        struct list_head   lru;                  /*    32    16 */
                        struct dev_pagemap * pgmap;              /*    32     8 */
                        struct {
                                struct page * next;              /*    32     8 */
                                int        pages;                /*    40     4 */
                                int        pobjects;             /*    44     4 */
                        };                                       /*    32    16 */
                        struct callback_head callback_head;      /*    32    16 */
                        struct {
                                long unsigned int compound_head; /*    32     8 */
                                unsigned int compound_dtor;      /*    40     4 */
                                unsigned int compound_order;     /*    44     4 */
                        };                                       /*    32    16 */
                        struct {
                                long unsigned int __pad;         /*    32     8 */
                                pgtable_t  pmd_huge_pte;         /*    40     8 */
                        };                                       /*    32    16 */
                };                                               /*    32    16 */
                union {
                        long unsigned int  private;              /*    48     8 */
                        spinlock_t         ptl;                  /*    48     4 */
                        struct kmem_cache * slab_cache;          /*    48     8 */
                };                                               /*    48     8 */
                struct mem_cgroup *        mem_cgroup;           /*    56     8 */
    
                /* size: 64, cachelines: 1, members: 7 */
        };
    
    - Search and use running kernel vmlinux when no file is passed (Arnaldo Carvalho de Melo)
    
    	Now it is possible to use it just as:
    
        $ pahole -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0     8 */
                struct sk_buff *           prev;                 /*     8     8 */
                __u32                      qlen;                 /*    16     4 */
                spinlock_t                 lock;                 /*    20     4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    	This will look at /sys/kernel/notes, find the running kernel
    build-id, and then search the usual locations (vmlinux,
    /lib/modules/`uname -r`/build/vmlinux, the debuginfo package paths, etc)
    to find the matching vmlinux with the DWARF info to use. Build-ids are
    now ubiquitous, so this shortens a the most common binary used.
    
    - Document 'pahole --hex' in the man page (Arnaldo Carvalho de Melo)
    
    	This option shows offsets and sizes in hexadecimal, helping to
    correlate with reports using that notation.
    
    	E.g.:
    
        $ pahole --hex -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0   0x8 */
                struct sk_buff *           prev;                 /*   0x8   0x8 */
                __u32                      qlen;                 /*  0x10   0x4 */
                spinlock_t                 lock;                 /*  0x14   0x4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
    
  • upstream/v1.12

    4a21c5c8 · v1.12 - New Release ·
    v1.12 August 2018
    
    - Add a BTF encoder (Martin KaFai Lau)
    
    	BTF (BPF Type Format) is the meta data format which describes
    the data types of BPF program/map.  Hence, it basically focus on the C
    programming language which the modern BPF is primary using.  The first
    use case is to provide a generic pretty print capability for a BPF map.
    
    	BTF has its root from CTF (Compact C-Type format).
    
    - Add Documentation on how to use the BTF encoder: (Arnaldo Carvalho de Melo)
    
    	Using the Linux 'perf' tools integration with BPF/llvm/clang to
    show how to generate an object file that then gets its DWARF info used
    to create a .BTF ELF section with this new BTF format. That augmented
    eBPF ELF object file is then loaded while 'perf ftrace -g *bpf*' is used
    to show the kernel BTF validation process.
    
    - Initial support for DW_TAG_partial_unit (Arnaldo Carvalho de Melo)
    
    	Just by treating these sections as DW_TAG_compile_unit, which is
    enough for the structs that don't contain cross-section type references
    to be correctly loaded and pretty-printed with pahole.
    
    	This doesn't affect the kernel or modules, where such DWARF
    compression techniques are not used so far. (Arnaldo Carvalho de Melo)
    
    - Print cacheline boundaries in multiple union members, (Arnaldo Carvalho de Melo)
    
    	We were showing it just on the first inner union member members,
    as if it was a struct, now we restart the cacheline boundaries when
    moving to print the next inner struct.
    
    	As an example, look at 'struct audit_context' where the only
    cacheline boundary printed for the following unnamed union was the first
    one, for the 'socketcall' struct member, now that cacheline boundary
    appears in each of the union member inner structs:
    
        struct audit_context {
        <SNIP>
                union {
                        struct {
                                int        nargs;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                long int   args[6];              /*   832    48 */
                        } socketcall;                            /*   824    56 */
                        struct {
                                kuid_t     uid;                  /*   824     4 */
                                kgid_t     gid;                  /*   828     4 */
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                umode_t    mode;                 /*   832     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                u32        osid;                 /*   836     4 */
                                int        has_perm;             /*   840     4 */
                                uid_t      perm_uid;             /*   844     4 */
                                gid_t      perm_gid;             /*   848     4 */
                                umode_t    perm_mode;            /*   852     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                long unsigned int qbytes;        /*   856     8 */
                        } ipc;                                   /*   824    40 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr mqstat;           /*   832    64 */
                        } mq_getsetattr;                         /*   824    72 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
                                int        sigev_signo;          /*   828     4 */
                        } mq_notify;                             /*   824     8 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                size_t     msg_len;              /*   832     8 */
                                unsigned int msg_prio;           /*   840     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                struct timespec64 abs_timeout;   /*   848    16 */
                        } mq_sendrecv;                           /*   824    40 */
                        struct {
                                int        oflag;                /*   824     4 */
                                umode_t    mode;                 /*   828     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr attr;             /*   832    64 */
                        } mq_open;                               /*   824    72 */
                        struct {
                                pid_t      pid;                  /*   824     4 */
                                struct audit_cap_data cap;       /*   828    32 */
                        } capset;                                /*   824    36 */
                        struct {
                                int        fd;                   /*   824     4 */
                                int        flags;                /*   828     4 */
                        } mmap;                                  /*   824     8 */
                        struct {
                                int        argc;                 /*   824     4 */
                        } execve;                                /*   824     4 */
                        struct {
                                char *     name;                 /*   824     8 */
                        } module;                                /*   824     8 */
                };                                               /*   824    72 */
                /* --- cacheline 14 boundary (896 bytes) --- */
                int                        fds[2];               /*   896     8 */
                struct audit_proctitle     proctitle;            /*   904    16 */
    
                /* size: 920, cachelines: 15, members: 46 */
                /* sum members: 912, holes: 2, sum holes: 8 */
                /* last cacheline: 24 bytes */
        };
    
    - Show where a struct was used, e.g.
    
          $ pahole -I vmlinux
        <SNIP>
          /* Used at: /home/acme/git/perf/init/main.c */
          /* <1f4a5> /home/acme/git/perf/arch/x86/include/asm/orc_types.h:85 */
          struct orc_entry {
                  s16                        sp_offset;            /*     0     2 */
                  s16                        bp_offset;            /*     2     2 */
         <SNIP>
    
    - Show offsets at union members (Arnaldo Carvalho de Melo, suggested by Matthew Wilcox):
    
    	In complex structs with multiple complex unions figuring out the
    offset for a given union member is difficult, as one needs to figure out
    the union, go to the end of it to see the offset.
    
        This way, for instance, the Linux kernel's 'struct page' shows now as:
    
        struct page {
                long unsigned int          flags;                /*     0     8 */
                union {
                        struct address_space * mapping;          /*     8     8 */
                        void *             s_mem;                /*     8     8 */
                        atomic_t           compound_mapcount;    /*     8     4 */
                };                                               /*     8     8 */
                union {
                        long unsigned int  index;                /*    16     8 */
                        void *             freelist;             /*    16     8 */
                };                                               /*    16     8 */
                union {
                        long unsigned int  counters;             /*    24     8 */
                        struct {
                                union {
                                        atomic_t _mapcount;      /*    24     4 */
                                        unsigned int active;     /*    24     4 */
                                        struct {
                                                unsigned int inuse:16; /*    24:16  4 */
                                                unsigned int objects:15; /*    24: 1  4 */
                                                unsigned int frozen:1; /*    24: 0  4 */
                                        };                       /*    24     4 */
                                        int units;               /*    24     4 */
                                };                               /*    24     4 */
                                atomic_t   _refcount;            /*    28     4 */
                        };                                       /*    24     8 */
                };                                               /*    24     8 */
                union {
                        struct list_head   lru;                  /*    32    16 */
                        struct dev_pagemap * pgmap;              /*    32     8 */
                        struct {
                                struct page * next;              /*    32     8 */
                                int        pages;                /*    40     4 */
                                int        pobjects;             /*    44     4 */
                        };                                       /*    32    16 */
                        struct callback_head callback_head;      /*    32    16 */
                        struct {
                                long unsigned int compound_head; /*    32     8 */
                                unsigned int compound_dtor;      /*    40     4 */
                                unsigned int compound_order;     /*    44     4 */
                        };                                       /*    32    16 */
                        struct {
                                long unsigned int __pad;         /*    32     8 */
                                pgtable_t  pmd_huge_pte;         /*    40     8 */
                        };                                       /*    32    16 */
                };                                               /*    32    16 */
                union {
                        long unsigned int  private;              /*    48     8 */
                        spinlock_t         ptl;                  /*    48     4 */
                        struct kmem_cache * slab_cache;          /*    48     8 */
                };                                               /*    48     8 */
                struct mem_cgroup *        mem_cgroup;           /*    56     8 */
    
                /* size: 64, cachelines: 1, members: 7 */
        };
    
    - Search and use running kernel vmlinux when no file is passed (Arnaldo Carvalho de Melo)
    
    	Now it is possible to use it just as:
    
        $ pahole -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0     8 */
                struct sk_buff *           prev;                 /*     8     8 */
                __u32                      qlen;                 /*    16     4 */
                spinlock_t                 lock;                 /*    20     4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    	This will look at /sys/kernel/notes, find the running kernel
    build-id, and then search the usual locations (vmlinux,
    /lib/modules/`uname -r`/build/vmlinux, the debuginfo package paths, etc)
    to find the matching vmlinux with the DWARF info to use. Build-ids are
    now ubiquitous, so this shortens a the most common binary used.
    
    - Document 'pahole --hex' in the man page (Arnaldo Carvalho de Melo)
    
    	This option shows offsets and sizes in hexadecimal, helping to
    correlate with reports using that notation.
    
    	E.g.:
    
        $ pahole --hex -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0   0x8 */
                struct sk_buff *           prev;                 /*   0x8   0x8 */
                __u32                      qlen;                 /*  0x10   0x4 */
                spinlock_t                 lock;                 /*  0x14   0x4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
    
  • v1.12

    4a21c5c8 · v1.12 - New Release ·
    v1.12 August 2018
    
    - Add a BTF encoder (Martin KaFai Lau)
    
    	BTF (BPF Type Format) is the meta data format which describes
    the data types of BPF program/map.  Hence, it basically focus on the C
    programming language which the modern BPF is primary using.  The first
    use case is to provide a generic pretty print capability for a BPF map.
    
    	BTF has its root from CTF (Compact C-Type format).
    
    - Add Documentation on how to use the BTF encoder: (Arnaldo Carvalho de Melo)
    
    	Using the Linux 'perf' tools integration with BPF/llvm/clang to
    show how to generate an object file that then gets its DWARF info used
    to create a .BTF ELF section with this new BTF format. That augmented
    eBPF ELF object file is then loaded while 'perf ftrace -g *bpf*' is used
    to show the kernel BTF validation process.
    
    - Initial support for DW_TAG_partial_unit (Arnaldo Carvalho de Melo)
    
    	Just by treating these sections as DW_TAG_compile_unit, which is
    enough for the structs that don't contain cross-section type references
    to be correctly loaded and pretty-printed with pahole.
    
    	This doesn't affect the kernel or modules, where such DWARF
    compression techniques are not used so far. (Arnaldo Carvalho de Melo)
    
    - Print cacheline boundaries in multiple union members, (Arnaldo Carvalho de Melo)
    
    	We were showing it just on the first inner union member members,
    as if it was a struct, now we restart the cacheline boundaries when
    moving to print the next inner struct.
    
    	As an example, look at 'struct audit_context' where the only
    cacheline boundary printed for the following unnamed union was the first
    one, for the 'socketcall' struct member, now that cacheline boundary
    appears in each of the union member inner structs:
    
        struct audit_context {
        <SNIP>
                union {
                        struct {
                                int        nargs;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                long int   args[6];              /*   832    48 */
                        } socketcall;                            /*   824    56 */
                        struct {
                                kuid_t     uid;                  /*   824     4 */
                                kgid_t     gid;                  /*   828     4 */
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                umode_t    mode;                 /*   832     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                u32        osid;                 /*   836     4 */
                                int        has_perm;             /*   840     4 */
                                uid_t      perm_uid;             /*   844     4 */
                                gid_t      perm_gid;             /*   848     4 */
                                umode_t    perm_mode;            /*   852     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                long unsigned int qbytes;        /*   856     8 */
                        } ipc;                                   /*   824    40 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr mqstat;           /*   832    64 */
                        } mq_getsetattr;                         /*   824    72 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
                                int        sigev_signo;          /*   828     4 */
                        } mq_notify;                             /*   824     8 */
                        struct {
                                mqd_t      mqdes;                /*   824     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                size_t     msg_len;              /*   832     8 */
                                unsigned int msg_prio;           /*   840     4 */
    
                                /* XXX 4 bytes hole, try to pack */
    
                                struct timespec64 abs_timeout;   /*   848    16 */
                        } mq_sendrecv;                           /*   824    40 */
                        struct {
                                int        oflag;                /*   824     4 */
                                umode_t    mode;                 /*   828     2 */
    
                                /* XXX 2 bytes hole, try to pack */
    
                                /* --- cacheline 13 boundary (832 bytes) --- */
                                struct mq_attr attr;             /*   832    64 */
                        } mq_open;                               /*   824    72 */
                        struct {
                                pid_t      pid;                  /*   824     4 */
                                struct audit_cap_data cap;       /*   828    32 */
                        } capset;                                /*   824    36 */
                        struct {
                                int        fd;                   /*   824     4 */
                                int        flags;                /*   828     4 */
                        } mmap;                                  /*   824     8 */
                        struct {
                                int        argc;                 /*   824     4 */
                        } execve;                                /*   824     4 */
                        struct {
                                char *     name;                 /*   824     8 */
                        } module;                                /*   824     8 */
                };                                               /*   824    72 */
                /* --- cacheline 14 boundary (896 bytes) --- */
                int                        fds[2];               /*   896     8 */
                struct audit_proctitle     proctitle;            /*   904    16 */
    
                /* size: 920, cachelines: 15, members: 46 */
                /* sum members: 912, holes: 2, sum holes: 8 */
                /* last cacheline: 24 bytes */
        };
    
    - Show where a struct was used, e.g.
    
          $ pahole -I vmlinux
        <SNIP>
          /* Used at: /home/acme/git/perf/init/main.c */
          /* <1f4a5> /home/acme/git/perf/arch/x86/include/asm/orc_types.h:85 */
          struct orc_entry {
                  s16                        sp_offset;            /*     0     2 */
                  s16                        bp_offset;            /*     2     2 */
         <SNIP>
    
    - Show offsets at union members (Arnaldo Carvalho de Melo, suggested by Matthew Wilcox):
    
    	In complex structs with multiple complex unions figuring out the
    offset for a given union member is difficult, as one needs to figure out
    the union, go to the end of it to see the offset.
    
        This way, for instance, the Linux kernel's 'struct page' shows now as:
    
        struct page {
                long unsigned int          flags;                /*     0     8 */
                union {
                        struct address_space * mapping;          /*     8     8 */
                        void *             s_mem;                /*     8     8 */
                        atomic_t           compound_mapcount;    /*     8     4 */
                };                                               /*     8     8 */
                union {
                        long unsigned int  index;                /*    16     8 */
                        void *             freelist;             /*    16     8 */
                };                                               /*    16     8 */
                union {
                        long unsigned int  counters;             /*    24     8 */
                        struct {
                                union {
                                        atomic_t _mapcount;      /*    24     4 */
                                        unsigned int active;     /*    24     4 */
                                        struct {
                                                unsigned int inuse:16; /*    24:16  4 */
                                                unsigned int objects:15; /*    24: 1  4 */
                                                unsigned int frozen:1; /*    24: 0  4 */
                                        };                       /*    24     4 */
                                        int units;               /*    24     4 */
                                };                               /*    24     4 */
                                atomic_t   _refcount;            /*    28     4 */
                        };                                       /*    24     8 */
                };                                               /*    24     8 */
                union {
                        struct list_head   lru;                  /*    32    16 */
                        struct dev_pagemap * pgmap;              /*    32     8 */
                        struct {
                                struct page * next;              /*    32     8 */
                                int        pages;                /*    40     4 */
                                int        pobjects;             /*    44     4 */
                        };                                       /*    32    16 */
                        struct callback_head callback_head;      /*    32    16 */
                        struct {
                                long unsigned int compound_head; /*    32     8 */
                                unsigned int compound_dtor;      /*    40     4 */
                                unsigned int compound_order;     /*    44     4 */
                        };                                       /*    32    16 */
                        struct {
                                long unsigned int __pad;         /*    32     8 */
                                pgtable_t  pmd_huge_pte;         /*    40     8 */
                        };                                       /*    32    16 */
                };                                               /*    32    16 */
                union {
                        long unsigned int  private;              /*    48     8 */
                        spinlock_t         ptl;                  /*    48     4 */
                        struct kmem_cache * slab_cache;          /*    48     8 */
                };                                               /*    48     8 */
                struct mem_cgroup *        mem_cgroup;           /*    56     8 */
    
                /* size: 64, cachelines: 1, members: 7 */
        };
    
    - Search and use running kernel vmlinux when no file is passed (Arnaldo Carvalho de Melo)
    
    	Now it is possible to use it just as:
    
        $ pahole -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0     8 */
                struct sk_buff *           prev;                 /*     8     8 */
                __u32                      qlen;                 /*    16     4 */
                spinlock_t                 lock;                 /*    20     4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    	This will look at /sys/kernel/notes, find the running kernel
    build-id, and then search the usual locations (vmlinux,
    /lib/modules/`uname -r`/build/vmlinux, the debuginfo package paths, etc)
    to find the matching vmlinux with the DWARF info to use. Build-ids are
    now ubiquitous, so this shortens a the most common binary used.
    
    - Document 'pahole --hex' in the man page (Arnaldo Carvalho de Melo)
    
    	This option shows offsets and sizes in hexadecimal, helping to
    correlate with reports using that notation.
    
    	E.g.:
    
        $ pahole --hex -C sk_buff_head
        struct sk_buff_head {
                struct sk_buff *           next;                 /*     0   0x8 */
                struct sk_buff *           prev;                 /*   0x8   0x8 */
                __u32                      qlen;                 /*  0x10   0x4 */
                spinlock_t                 lock;                 /*  0x14   0x4 */
    
                /* size: 24, cachelines: 1, members: 4 */
                /* last cacheline: 24 bytes */
        };
        $
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
    
  • acmel/1.11

    4f34f234 · v1.11 - New Release ·
    v1.11
    
    Long time without a new release, this has been mostly bugfixing over the
    years, so push it out so that distros can get what they are used to, a
    new version.
    
    If you see this and want to help... Please try pahole and friends on
    non kernel objects and try to fix what you see breaking. For the kernel
    this has been surprisingly solid after all those years...
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/1.11

    4f34f234 · v1.11 - New Release ·
    v1.11
    
    Long time without a new release, this has been mostly bugfixing over the
    years, so push it out so that distros can get what they are used to, a
    new version.
    
    If you see this and want to help... Please try pahole and friends on
    non kernel objects and try to fix what you see breaking. For the kernel
    this has been surprisingly solid after all those years...
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • upstream/v1.11

    4f34f234 · v1.11 - New Release ·
    v1.11
    
    Long time without a new release, this has been mostly bugfixing over the
    years, so push it out so that distros can get what they are used to, a
    new version.
    
    If you see this and want to help... Please try pahole and friends on
    non kernel objects and try to fix what you see breaking. For the kernel
    this has been surprisingly solid after all those years...
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • v1.11

    4f34f234 · v1.11 - New Release ·
    v1.11
    
    Long time without a new release, this has been mostly bugfixing over the
    years, so push it out so that distros can get what they are used to, a
    new version.
    
    If you see this and want to help... Please try pahole and friends on
    non kernel objects and try to fix what you see breaking. For the kernel
    this has been surprisingly solid after all those years...
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    
  • acmel/1.10

    e887636d · v1.10 ·
  • upstream/1.10

    e887636d · v1.10 ·
  • upstream/v1.10

    e887636d · v1.10 ·