Commit Graph

13 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo cdd088c05c btfdiff: Suppress alignment tags with BTF as well as with DWARF
Now that the alignment attributes are being inferred from BTF we need to
suppress it in btfdiff, as we can't infer for some cases, like when the
field is naturally aligned.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-10-28 09:37:26 -03:00
Arnaldo Carvalho de Melo dd13708f2f btfdiff: Use multithreaded DWARF loading
Quite a few cases of types with the same name, will add a
--exclude-types option to filter those, and study BTF dedup to see what
it does in this case.

  $ btfdiff vmlinux
  --- /tmp/btfdiff.dwarf.BgsYYn	2021-07-06 17:03:07.471814114 -0300
  +++ /tmp/btfdiff.btf.Ene2Ug	2021-07-06 17:03:07.714819609 -0300
  @@ -23627,12 +23627,15 @@ struct deadline_data {
   };
   struct debug_buffer {
   	ssize_t                    (*fill_func)(struct debug_buffer *); /*     0     8 */
  -	struct ohci_hcd *          ohci;                 /*     8     8 */
  +	struct usb_bus *           bus;                  /*     8     8 */
   	struct mutex               mutex;                /*    16    32 */
   	size_t                     count;                /*    48     8 */
  -	char *                     page;                 /*    56     8 */
  +	char *                     output_buf;           /*    56     8 */
  +	/* --- cacheline 1 boundary (64 bytes) --- */
  +	size_t                     alloc_size;           /*    64     8 */

  -	/* size: 64, cachelines: 1, members: 5 */
  +	/* size: 72, cachelines: 2, members: 6 */
  +	/* last cacheline: 8 bytes */
   };
   struct debug_reply_data {
   	struct ethnl_reply_data    base;                 /*     0     8 */
  @@ -47930,11 +47933,12 @@ struct intel_community {
   	/* last cacheline: 32 bytes */
   };
   struct intel_community_context {
  -	u32 *                      intmask;              /*     0     8 */
  -	u32 *                      hostown;              /*     8     8 */
  +	unsigned int               intr_lines[16];       /*     0    64 */
  +	/* --- cacheline 1 boundary (64 bytes) --- */
  +	u32                        saved_intmask;        /*    64     4 */

  -	/* size: 16, cachelines: 1, members: 2 */
  -	/* last cacheline: 16 bytes */
  +	/* size: 68, cachelines: 2, members: 2 */
  +	/* last cacheline: 4 bytes */
   };
   struct intel_early_ops {
   	resource_size_t            (*stolen_size)(int, int, int); /*     0     8 */
  @@ -52600,64 +52604,19 @@ struct irqtime {
   	/* size: 24, cachelines: 1, members: 4 */
   	/* last cacheline: 24 bytes */
   };
  -struct irte {
  -	union {
  -		struct {
  -			__u64      present:1;            /*     0: 0  8 */
  -			__u64      fpd:1;                /*     0: 1  8 */
  -			__u64      __res0:6;             /*     0: 2  8 */
  -			__u64      avail:4;              /*     0: 8  8 */
  -			__u64      __res1:3;             /*     0:12  8 */
  -			__u64      pst:1;                /*     0:15  8 */
  -			__u64      vector:8;             /*     0:16  8 */
  -			__u64      __res2:40;            /*     0:24  8 */
  -		};                                       /*     0     8 */
  -		struct {
  -			__u64      r_present:1;          /*     0: 0  8 */
  -			__u64      r_fpd:1;              /*     0: 1  8 */
  -			__u64      dst_mode:1;           /*     0: 2  8 */
  -			__u64      redir_hint:1;         /*     0: 3  8 */
  -			__u64      trigger_mode:1;       /*     0: 4  8 */
  -			__u64      dlvry_mode:3;         /*     0: 5  8 */
  -			__u64      r_avail:4;            /*     0: 8  8 */
  -			__u64      r_res0:4;             /*     0:12  8 */
  -			__u64      r_vector:8;           /*     0:16  8 */
  -			__u64      r_res1:8;             /*     0:24  8 */
  -			__u64      dest_id:32;           /*     0:32  8 */
  -		};                                       /*     0     8 */
  -		struct {
  -			__u64      p_present:1;          /*     0: 0  8 */
  -			__u64      p_fpd:1;              /*     0: 1  8 */
  -			__u64      p_res0:6;             /*     0: 2  8 */
  -			__u64      p_avail:4;            /*     0: 8  8 */
  -			__u64      p_res1:2;             /*     0:12  8 */
  -			__u64      p_urgent:1;           /*     0:14  8 */
  -			__u64      p_pst:1;              /*     0:15  8 */
  -			__u64      p_vector:8;           /*     0:16  8 */
  -			__u64      p_res2:14;            /*     0:24  8 */
  -			__u64      pda_l:26;             /*     0:38  8 */
  -		};                                       /*     0     8 */
  -		__u64              low;                  /*     0     8 */
  -	};                                               /*     0     8 */
  -	union {
  -		struct {
  -			__u64      sid:16;               /*     8: 0  8 */
  -			__u64      sq:2;                 /*     8:16  8 */
  -			__u64      svt:2;                /*     8:18  8 */
  -			__u64      __res3:44;            /*     8:20  8 */
  -		};                                       /*     8     8 */
  -		struct {
  -			__u64      p_sid:16;             /*     8: 0  8 */
  -			__u64      p_sq:2;               /*     8:16  8 */
  -			__u64      p_svt:2;              /*     8:18  8 */
  -			__u64      p_res3:12;            /*     8:20  8 */
  -			__u64      pda_h:32;             /*     8:32  8 */
  -		};                                       /*     8     8 */
  -		__u64              high;                 /*     8     8 */
  -	};                                               /*     8     8 */
  -
  -	/* size: 16, cachelines: 1, members: 2 */
  -	/* last cacheline: 16 bytes */
  +union irte {
  +	u32                        val;                /*     0     4 */
  +	struct {
  +		u32                valid:1;            /*     0: 0  4 */
  +		u32                no_fault:1;         /*     0: 1  4 */
  +		u32                int_type:3;         /*     0: 2  4 */
  +		u32                rq_eoi:1;           /*     0: 5  4 */
  +		u32                dm:1;               /*     0: 6  4 */
  +		u32                rsvd_1:1;           /*     0: 7  4 */
  +		u32                destination:8;      /*     0: 8  4 */
  +		u32                vector:8;           /*     0:16  4 */
  +		u32                rsvd_2:8;           /*     0:24  4 */
  +	} fields;                                      /*     0     4 */
   };
   struct irte_ga {
   	union irte_ga_lo           lo;                   /*     0     8 */
  @@ -66862,12 +66821,13 @@ struct netlbl_domhsh_tbl {
   	/* last cacheline: 16 bytes */
   };
   struct netlbl_domhsh_walk_arg {
  -	struct netlbl_audit *      audit_info;           /*     0     8 */
  -	u32                        doi;                  /*     8     4 */
  +	struct netlink_callback *  nl_cb;                /*     0     8 */
  +	struct sk_buff *           skb;                  /*     8     8 */
  +	u32                        seq;                  /*    16     4 */

  -	/* size: 16, cachelines: 1, members: 2 */
  +	/* size: 24, cachelines: 1, members: 3 */
   	/* padding: 4 */
  -	/* last cacheline: 16 bytes */
  +	/* last cacheline: 24 bytes */
   };
   struct netlbl_dommap_def {
   	u32                        type;                 /*     0     4 */
  @@ -72907,20 +72867,16 @@ struct pci_raw_ops {
   	/* last cacheline: 16 bytes */
   };
   struct pci_root_info {
  -	struct list_head           list;                 /*     0    16 */
  -	char                       name[12];             /*    16    12 */
  -
  -	/* XXX 4 bytes hole, try to pack */
  -
  -	struct list_head           resources;            /*    32    16 */
  -	struct resource            busn;                 /*    48    64 */
  -	/* --- cacheline 1 boundary (64 bytes) was 48 bytes ago --- */
  -	int                        node;                 /*   112     4 */
  -	int                        link;                 /*   116     4 */
  +	struct acpi_pci_root_info  common;               /*     0    56 */
  +	struct pci_sysdata         sd;                   /*    56    40 */
  +	/* --- cacheline 1 boundary (64 bytes) was 32 bytes ago --- */
  +	bool                       mcfg_added;           /*    96     1 */
  +	u8                         start_bus;            /*    97     1 */
  +	u8                         end_bus;              /*    98     1 */

  -	/* size: 120, cachelines: 2, members: 6 */
  -	/* sum members: 116, holes: 1, sum holes: 4 */
  -	/* last cacheline: 56 bytes */
  +	/* size: 104, cachelines: 2, members: 5 */
  +	/* padding: 5 */
  +	/* last cacheline: 40 bytes */
   };
   struct pci_root_res {
   	struct list_head           list;                 /*     0    16 */
  @@ -76415,25 +76371,66 @@ struct pmc_dev {

   	/* XXX 4 bytes hole, try to pack */

  -	void *                     regmap;               /*     8     8 */
  +	void *                     regbase;              /*     8     8 */
   	const struct pmc_reg_map  * map;                 /*    16     8 */
   	struct dentry *            dbgfs_dir;            /*    24     8 */
  -	bool                       init;                 /*    32     1 */
  +	int                        pmc_xram_read_bit;    /*    32     4 */

  -	/* size: 40, cachelines: 1, members: 5 */
  -	/* sum members: 29, holes: 1, sum holes: 4 */
  -	/* padding: 7 */
  -	/* last cacheline: 40 bytes */
  +	/* XXX 4 bytes hole, try to pack */
  +
  +	struct mutex               lock;                 /*    40    32 */
  +	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
  +	bool                       check_counters;       /*    72     1 */
  +
  +	/* XXX 7 bytes hole, try to pack */
  +
  +	u64                        pc10_counter;         /*    80     8 */
  +	u64                        s0ix_counter;         /*    88     8 */
  +	int                        num_lpm_modes;        /*    96     4 */
  +	int                        lpm_en_modes[8];      /*   100    32 */
  +
  +	/* XXX 4 bytes hole, try to pack */
  +
  +	/* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
  +	u32 *                      lpm_req_regs;         /*   136     8 */
  +
  +	/* size: 144, cachelines: 3, members: 12 */
  +	/* sum members: 125, holes: 4, sum holes: 19 */
  +	/* last cacheline: 16 bytes */
   };
   struct pmc_reg_map {
  -	const struct pmc_bit_map  * d3_sts_0;            /*     0     8 */
  -	const struct pmc_bit_map  * d3_sts_1;            /*     8     8 */
  -	const struct pmc_bit_map  * func_dis;            /*    16     8 */
  -	const struct pmc_bit_map  * func_dis_2;          /*    24     8 */
  -	const struct pmc_bit_map  * pss;                 /*    32     8 */
  +	const struct pmc_bit_map  * * pfear_sts;         /*     0     8 */
  +	const struct pmc_bit_map  * mphy_sts;            /*     8     8 */
  +	const struct pmc_bit_map  * pll_sts;             /*    16     8 */
  +	const struct pmc_bit_map  * * slps0_dbg_maps;    /*    24     8 */
  +	const struct pmc_bit_map  * ltr_show_sts;        /*    32     8 */
  +	const struct pmc_bit_map  * msr_sts;             /*    40     8 */
  +	const struct pmc_bit_map  * * lpm_sts;           /*    48     8 */
  +	const u32                  slp_s0_offset;        /*    56     4 */
  +	const int                  slp_s0_res_counter_step; /*    60     4 */
  +	/* --- cacheline 1 boundary (64 bytes) --- */
  +	const u32                  ltr_ignore_offset;    /*    64     4 */
  +	const int                  regmap_length;        /*    68     4 */
  +	const u32                  ppfear0_offset;       /*    72     4 */
  +	const int                  ppfear_buckets;       /*    76     4 */
  +	const u32                  pm_cfg_offset;        /*    80     4 */
  +	const int                  pm_read_disable_bit;  /*    84     4 */
  +	const u32                  slps0_dbg_offset;     /*    88     4 */
  +	const u32                  ltr_ignore_max;       /*    92     4 */
  +	const u32                  pm_vric1_offset;      /*    96     4 */
  +	const int                  lpm_num_maps;         /*   100     4 */
  +	const int                  lpm_res_counter_step_x2; /*   104     4 */
  +	const u32                  lpm_sts_latch_en_offset; /*   108     4 */
  +	const u32                  lpm_en_offset;        /*   112     4 */
  +	const u32                  lpm_priority_offset;  /*   116     4 */
  +	const u32                  lpm_residency_offset; /*   120     4 */
  +	const u32                  lpm_status_offset;    /*   124     4 */
  +	/* --- cacheline 2 boundary (128 bytes) --- */
  +	const u32                  lpm_live_status_offset; /*   128     4 */
  +	const u32                  etr3_offset;          /*   132     4 */

  -	/* size: 40, cachelines: 1, members: 5 */
  -	/* last cacheline: 40 bytes */
  +	/* size: 136, cachelines: 3, members: 27 */
  +	/* last cacheline: 8 bytes */
   };
   struct pmic_table {
   	int                        address;              /*     0     4 */
  @@ -114574,12 +114571,18 @@ struct urb {
   	/* last cacheline: 56 bytes */
   };
   struct urb_priv {
  -	int                        num_tds;              /*     0     4 */
  -	int                        num_tds_done;         /*     4     4 */
  -	struct xhci_td             td[];                 /*     8     0 */
  +	struct ed *                ed;                   /*     0     8 */
  +	u16                        length;               /*     8     2 */
  +	u16                        td_cnt;               /*    10     2 */

  -	/* size: 8, cachelines: 1, members: 3 */
  -	/* last cacheline: 8 bytes */
  +	/* XXX 4 bytes hole, try to pack */
  +
  +	struct list_head           pending;              /*    16    16 */
  +	struct td *                td[];                 /*    32     0 */
  +
  +	/* size: 32, cachelines: 1, members: 5 */
  +	/* sum members: 28, holes: 1, sum holes: 4 */
  +	/* last cacheline: 32 bytes */
   };
   struct usb2_lpm_parameters {
   	unsigned int               besl;                 /*     0     4 */
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:41:13 -03:00
Arnaldo Carvalho de Melo f95f783849 btfdiff: Use --sort for pretty printing from both BTF and DWARF
$ btfdiff vmlinux
  $

As expected, no change, both sort to the same output, now lets add
--jobs to the DWARF case.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-08-12 09:41:13 -03:00
Arnaldo Carvalho de Melo da9d70a16f btfdiff: Support diffing DWARF vs detached BTF
I.e.:

  $ rm -f vmlinux.btf ; pahole -j vmlinux.btf vmlinux && btfdiff vmlinux vmlinux.btf

Is much more robust in making sure we really generated new BTF from
the DWARF in a ELF file and that the detached BTF produces the same
output as the original DWARF.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2021-06-08 10:08:22 -03:00
Arnaldo Carvalho de Melo 92a4118812 v1.13: New release
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-16 16:13:19 -03:00
Arnaldo Carvalho de Melo 9a4d719304 fprintf: Allow suppressing the inferred __attribute__((__packed__))
We use things like DW_AT_alignment, so not all of those attributes are
inferred by formats like BTF that lack that info, allow suppressing the
output and make btfdiff ask for both DWARF and BTF output to have this
suppressed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-15 15:01:53 -03:00
Arnaldo Carvalho de Melo ec935ee422 fprintf: Allow suppressing the output of force paddings at the end of structs
Things like 'struct timex' in the linux kernel led to this output:

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-15 14:45:29 -03:00
Arnaldo Carvalho de Melo 52d1c75ea4 btfdiff: Use --suppress_aligned_attribute with -F dwarf
Now that we collect DWARF5's DW_AT_alignent, btdiff shows, for instance:

  $ btfdiff examples/tcp.o
  <SNIP>
  @@ -13450,7 +13450,7 @@ struct ip6_flowlabel {
   	struct in6_addr            dst;                  /*    16    16 */
   	struct ipv6_txoptions *    opt;                  /*    32     8 */
   	long unsigned int          linger;               /*    40     8 */
  -	struct callback_head       rcu __attribute__((__aligned__(8)); /*    48    16 */
  +	struct callback_head       rcu;                  /*    48    16 */
   	/* --- cacheline 1 boundary (64 bytes) --- */
   	u8                         share;                /*    64     1 */

  @@ -13616,7 +13616,7 @@ struct fib6_node {
   	__u16                      fn_flags;             /*    42     2 */
   	int                        fn_sernum;            /*    44     4 */
   	struct fib6_info *         rr_ptr;               /*    48     8 */
  -	struct callback_head       rcu __attribute__((__aligned__(8)); /*    56    16 */
  +	struct callback_head       rcu;                  /*    56    16 */

   	/* size: 72, cachelines: 2, members: 10 */
   	/* last cacheline: 8 bytes */
  $

So ask for those attributes to be suppressed when comparing BTF and
DWARF output.

Cc: Alexei Starovoitov <ast@fb.com>
Cc: Andrii Nakryiko <andriin@fb.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Wielaard <mark@klomp.org>
Cc: Yonghong Song <yhs@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-04-03 18:10:16 -03:00
Andrii Nakryiko 6bcf0bd703 btfdiff: Support specifying custom pahole location
During development it's convenient to be able to specify custom location
of pahole binary, built locally.

E.g.:

  $ PAHOLE=~/local/pahole/build/pahole ./btfdiff /tmp/vmlinux4

Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@fb.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-02-22 18:06:27 -03:00
Arnaldo Carvalho de Melo 88028b5d0c btfdiff: Use --show_private_classes with DWARF
In DWARF we have the information if a struct/class is defined only
inside another struct/class or in a function, and then we consider those
to be 'private classes', requiring the use of --show_private_classes to
see those when asking for all structs.

That is not the case with BTF, that doesn't have that info and thus
shows all structs, private or not.

So, to compare the outputs in btfdiff we need to ask for
--show_private_classes when printing from DWARF.

With the Linux kernel vmlinux file the only private structure noticed
when not using this option, i.e. the only private class, as 'struct
sun_disklabel', defined in the block/partitions/sun.c file, inside the
'sun_partition' function.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-02-19 11:04:44 -03:00
Arnaldo Carvalho de Melo 5148be53dc btfdiff: Rename tmp files to contain the format used
So that one can comment the 'rm' line at the end to look at the files
further.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-02-18 11:05:29 -03:00
Arnaldo Carvalho de Melo 278b64c3ee btfdiff: Use diff's -p option to show the struct/union
To help in looking up the change and figure out its reason.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-01-17 10:07:13 -03:00
Arnaldo Carvalho de Melo 06e364bc62 btfdiff: Add utility to compare pahole output produced from DWARF and BTF
$ btfdiff
  Usage: btfdiff <filename_with_BTF_and_DWARF_info>
  $ btfdiff ~/git/build/v4.20-rc5+/net/ipv4/tcp.o
  --- /tmp/btfdiff.LRlcgc	2019-01-11 13:55:16.808989679 -0300
  +++ /tmp/btfdiff.SHuCev	2019-01-11 13:55:16.819989781 -0300
  @@ -585,11 +585,17 @@
   	__u16                      vesapm_off;           /*    48     2 */
   	__u16                      pages;                /*    50     2 */
   	__u16                      vesa_attributes;      /*    52     2 */
  -	__u32                      capabilities;         /*    54     4 */
  -	__u32                      ext_lfb_base;         /*    58     4 */
  +	__u32                      capabilities;         /*    52     4 */
  +	__u32                      ext_lfb_base;         /*    56     4 */
  +
  +	/* XXX 2 bytes hole, try to pack */
  +
   	__u8                       _reserved[2];         /*    62     2 */

   	/* size: 64, cachelines: 1, members: 36 */
  +	/* sum members: 60, holes: 1, sum holes: 2 */
  +
  +	/* BRAIN FART ALERT! 64 != 60 + 2(holes), diff = 2 */
   };
   struct apm_bios_info {
   	__u16                      version;              /*     0     2 */
  <SNIP>
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2019-01-11 13:54:22 -03:00