Commit Graph

1325 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo c65f2cf436 dwarves: Rename variable->location to ->scope
We'll use location in the DWARF sense, i.e. location lists, etc, i.e.
where is this variable? In a register? The stack? etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-09-26 16:45:25 -03:00
Yonghong Song 0d2511fd1d btf: Fix bitfield encoding
The btf bitfield encoding is broken.

For the following example:

  -bash-4.2$ cat t.c
  struct t {
     int a:2;
     int b:1;
     int :3;
     int c:1;
     int d;
     char e:1;
     char f:1;
     int g;
  };
  void test(struct t *t) {
     return;
  }
  -bash-4.2$ clang -S -g -emit-llvm t.c

The output for bpf "little and big" endian results with pahole dwarf2btf
conversion:

  -bash-4.2$ llc -march=bpfel -mattr=dwarfris -filetype=obj t.ll
  -bash-4.2$ pahole -JV t.o
  [1] PTR (anon) type_id=2
  [2] STRUCT t size=16 vlen=7
        a type_id=5 bits_offset=30
        b type_id=6 bits_offset=29
        c type_id=6 bits_offset=25
        d type_id=3 bits_offset=32
        e type_id=7 bits_offset=71
        f type_id=7 bits_offset=70
        g type_id=3 bits_offset=96
  [3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
  [4] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
  [5] INT int size=1 bit_offset=0 nr_bits=2 encoding=(none)
  [6] INT int size=1 bit_offset=0 nr_bits=1 encoding=(none)
  [7] INT char size=1 bit_offset=0 nr_bits=1 encoding=(none)
  -bash-4.2$ llc -march=bpfeb -mattr=dwarfris -filetype=obj t.ll
  -bash-4.2$ pahole -JV t.o
  [1] PTR (anon) type_id=2
  [2] STRUCT t size=16 vlen=7
        a type_id=5 bits_offset=0
        b type_id=6 bits_offset=2
        c type_id=6 bits_offset=6
        d type_id=3 bits_offset=32
        e type_id=7 bits_offset=64
        f type_id=7 bits_offset=65
        g type_id=3 bits_offset=96
  [3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
  [4] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
  [5] INT int size=1 bit_offset=0 nr_bits=2 encoding=(none)
  [6] INT int size=1 bit_offset=0 nr_bits=1 encoding=(none)
  [7] INT char size=1 bit_offset=0 nr_bits=1 encoding=(none)

The BTF struct member bits_offset counts bits from the beginning of the
containing entity regardless of endianness, similar to what
DW_AT_bit_offset from DWARF4 does. Such counting is equivalent to the
big endian conversion in the above.

But the little endian conversion is not correct since dwarf generates
DW_AT_bit_offset based on actual bit position in the little endian
architecture.  For example, for the above struct member "a", the dwarf
would generate DW_AT_bit_offset=30 for little endian, and
DW_AT_bit_offset=0 for big endian.

This patch fixed the little endian structure member bits_offset problem
with proper calculation based on dwarf attributes.

With the fix, we get:

  -bash-4.2$ llc -march=bpfel -mattr=dwarfris -filetype=obj t.ll
  -bash-4.2$ pahole -JV t.o
    [1] STRUCT t size=16 vlen=7
        a type_id=5 bits_offset=0
        b type_id=6 bits_offset=2
        c type_id=6 bits_offset=6
        d type_id=2 bits_offset=32
        e type_id=7 bits_offset=64
        f type_id=7 bits_offset=65
        g type_id=2 bits_offset=96
    [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
    [3] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
    [4] PTR (anon) type_id=1
    [5] INT int size=1 bit_offset=0 nr_bits=2 encoding=(none)
    [6] INT int size=1 bit_offset=0 nr_bits=1 encoding=(none)
    [7] INT char size=1 bit_offset=0 nr_bits=1 encoding=(none)
  -bash-4.2$ llc -march=bpfeb -mattr=dwarfris -filetype=obj t.ll
  -bash-4.2$ pahole -JV t.o
  [1] PTR (anon) type_id=2
  [2] STRUCT t size=16 vlen=7
        a type_id=5 bits_offset=0
        b type_id=6 bits_offset=2
        c type_id=6 bits_offset=6
        d type_id=3 bits_offset=32
        e type_id=7 bits_offset=64
        f type_id=7 bits_offset=65
        g type_id=3 bits_offset=96
  [3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
  [4] INT char size=1 bit_offset=0 nr_bits=8 encoding=(none)
  [5] INT int size=1 bit_offset=0 nr_bits=2 encoding=(none)
  [6] INT int size=1 bit_offset=0 nr_bits=1 encoding=(none)
  [7] INT char size=1 bit_offset=0 nr_bits=1 encoding=(none)
  -bash-4.2$

For both little endian and big endian, we have correct and
same bits_offset for struct members.

We could fix pos->bit_offset, but pos->bit_offset will be inconsistent
to pos->bitfield_offset in the meaning and pos->bitfield_offset is used
to print out pahole data structure:

  -bash-4.2$ llc -march=bpfel -mattr=dwarfris -filetype=obj t.ll
  -bash-4.2$ /bin/pahole t.o
  struct t {
        int                        a:2;                  /*     0:30  4 */
        int                        b:1;                  /*     0:29  4 */
        int                        c:1;                  /*     0:25  4 */
  .....

So this patch just made the change in btf specific routines.

Signed-off-by: Yonghong Song <yhs@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Cc: Alexei Starovoitov <ast@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-09-17 11:44:58 -03:00
Arnaldo Carvalho de Melo 92417082aa MANIFEST: Add missing COPYING file
That wasn't going into the tarballs generated when releasing new
versions.

Reported-by: Michal Schmidt <mschmidt@redhat.com>
Cc: Clark Williams <williams@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-09-11 11:22:41 -03:00
Yonghong Song eb6bd05766 dwarf_loader: Process DW_AT_count in DW_TAG_subrange_type
For array type, gcc and clang generates dwarf info with different tags.  For
example, with existing pahole,

  $ cat test.c
    int a[5][5];
  $ gcc -c -g test.c
  $ llvm-dwarfdump test.o
    ...
    0x0000001d:   DW_TAG_array_type
                  DW_AT_type    (0x0000003a "int")
                  DW_AT_sibling (0x00000033)

    0x00000026:     DW_TAG_subrange_type
                      DW_AT_type        (0x00000033 "long unsigned int")
                      DW_AT_upper_bound (0x04)

    0x0000002c:     DW_TAG_subrange_type
                      DW_AT_type        (0x00000033 "long unsigned int")
                      DW_AT_upper_bound (0x04)
  $ pahole -JV test.o
    [1] ARRAY (anon) type_id=3 index_type_id=3 nr_elems=25
    [2] INT long unsigned int size=8 bit_offset=0 nr_bits=64 encoding=(none)
    [3] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
  $ clang -c -g test.c
  $ llvm-dwarfdump test.o
    ...
    0x00000033:   DW_TAG_array_type
                    DW_AT_type  (0x00000045 "int")

    0x00000038:     DW_TAG_subrange_type
                      DW_AT_type        (0x0000004c "__ARRAY_SIZE_TYPE__")
                      DW_AT_count       (0x05)

    0x0000003e:     DW_TAG_subrange_type
                      DW_AT_type        (0x0000004c "__ARRAY_SIZE_TYPE__")
                      DW_AT_count       (0x05)
  $ pahole -JV test.o
    [1] ARRAY (anon) type_id=2 index_type_id=2 nr_elems=0
    [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
    [3] INT __ARRAY_SIZE_TYPE__ size=8 bit_offset=0 nr_bits=64 encoding=(none)

Current pahole processed DW_AT_upper_bound under DW_TAG_subrange_type to
get array range, but it did not process DW_AT_count so during pahole
dwarf2btf conversion, the flattened array size is 0.

This patch fixed the issue by processing DW_AT_count properly.
With the change, for clang generated test.o, pahole btf conversion output is:
  $ pahole -JV test.o
    [1] ARRAY (anon) type_id=2 index_type_id=2 nr_elems=25
    [2] INT int size=4 bit_offset=0 nr_bits=32 encoding=SIGNED
    [3] INT __ARRAY_SIZE_TYPE__ size=8 bit_offset=0 nr_bits=64 encoding=(none)

Committer testing:

Before:

  # pahole -C augmented_enter_connect_args augmented_syscalls.bpf.o
  struct augmented_enter_connect_args {
          struct syscall_enter_connect_args args;          /*     0    40 */
          char                       addr[0];              /*    40     0 */

          /* size: 56, cachelines: 1, members: 2 */
          /* padding: 16 */
          /* last cacheline: 56 bytes */
  };
  # file augmented_syscalls.bpf.o
  augmented_syscalls.bpf.o: ELF 64-bit LSB relocatable, *unknown arch 0xf7* version 1 (SYSV), with debug_info, not stripped
  #

After:

  # pahole -C augmented_enter_connect_args augmented_syscalls.bpf.o
  struct augmented_enter_connect_args {
	  struct syscall_enter_connect_args args;          /*     0    40 */
	  char                       addr[14];             /*    40    14 */

	  /* size: 56, cachelines: 1, members: 2 */
	  /* padding: 2 */
	  /* last cacheline: 56 bytes */
  };
  #

Signed-off-by: Yonghong Song <yhs@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Martin KaFai Lau <kafai@fb.com>
Cc: Okash Khawaja <osk@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-08-28 12:40:10 -03:00
Arnaldo Carvalho de Melo 4a21c5c8db v1.12 - New Release
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-08-16 16:15:27 -03:00
Arnaldo Carvalho de Melo 1ca2e351df README.btf: Add section on validating the .BTF section via the kernel
Run 'perf ftrace' to show *btf* functions called to load, validate and
put in place data structures with the .BTF ELF section contents.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-08-16 12:05:29 -03:00
Arnaldo Carvalho de Melo 9eda5e8163 README.btf: No need to use 'llvm.opts = -mattr=dwarfris' with elfutils >= 0.173
Updated elfutils to 0.173, using the fedora 28 packages and, as noted in
https://github.com/cilium/cilium/pull/5106/files ["bpf, doc: further
improvements on the BTF related section #5106"] there is no need to pass
the '-mattr=dwarfris' to llc to have DWARF sections correctly parsed by
tools like pahole.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-08-16 10:50:29 -03:00
Arnaldo Carvalho de Melo 7818af53f6 dwarves: Add a README.btf file with steps to test the BTF encoder
Using perf's integration to ease the whole process.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-08-15 17:43:43 -03:00
Arnaldo Carvalho de Melo f727c22191 dwarf_loader: Initial support for DW_TAG_partial_unit
This allows processing DW_TAG_partial_unit sections, which gets us from
no tags processed in files contained such tags to at least showing the
tags present in those sections.

Further work is required to support DW_TAG_compile_unit sections using
DW_TAG_imported_unit to import those DW_TAG_partial_unit sections, which
will be done by basically readding the contents of the
DW_TAG_partial_unit sections to the DW_TAG_compile_unit sections
importing them and then recoding as if all the tags in the partial units
were in the compile units.

This will make sure we have a contiguous series of types used in a
compile unit so that the converting routines to CTF and BTF can work
just as before.

On a fedora 27 system:

Before:

  $ pahole /usr/lib/debug/usr/lib64/libgtk-3.so.0.2200.19.debug
  die__process: DW_TAG_compile_unit or DW_TAG_type_unit expected got partial_unit!
  $

After:

  $ pahole /usr/lib/debug/usr/lib64/libgtk-3.so.0.2200.19.debug
  struct _GTimeVal {
          glong                      tv_sec;         /*     0     8 */
          glong                      tv_usec;        /*     8     8 */

          /* size: 16, cachelines: 1, members: 2 */
          /* last cacheline: 16 bytes */
  };
  struct _GError {
          GQuark                     domain;         /*     0     4 */
          gint                       code;           /*     4     4 */
          gchar *                    message;        /*     8     8 */

          /* size: 16, cachelines: 1, members: 3 */
          /* last cacheline: 16 bytes */
  };
  struct _GCond {
          gpointer                   p;              /*     0     8 */
          guint                      i[2];           /*     8     8 */

          /* size: 16, cachelines: 1, members: 2 */
          /* last cacheline: 16 bytes */
  };
<SNIP some more structs found in DW_TAG_partial unit sections...>
  struct _GSourceFuncs {
          gboolean                   (*prepare)(GSource *, gint *); /*     0     8 */
          gboolean                   (*check)(GSource *);  /*     8     8 */
          gboolean                   (*dispatch)(GSource *, GSourceFunc, gpointer); /*    16     8 */
          void                       (*finalize)(GSource *); /*    24     8 */
          GSourceFunc                closure_callback;     /*    32     8 */
          GSourceDummyMarshal        closure_marshal;      /*    40     8 */

          /* size: 48, cachelines: 1, members: 6 */
          /* last cacheline: 48 bytes */
  };
  struct _GThreadFunctions {
          GMutex *                   (*mutex_new)(void);   /*     0     8 */
          void                       (*mutex_lock)(GMutex *); /*     8     8 */
          gboolean                   (*mutex_trylock)(GMutex *)tag__recode_dwarf_type: couldn't find 0x74 type for 0x7fc (typedef)!
  tag__recode_dwarf_type: couldn't find 0x7e type for 0x829 (pointer_type)!
  tag__recode_dwarf_type: couldn't find 0x829 type for 0x844 (variable)!
  tag__recode_dwarf_type: couldn't find 0x7e type for 0x850 (variable)!
  tag__recode_dwarf_type: couldn't find 0x22 type for 0x85b (variable)!
  tag__recode_dwarf_type: couldn't find 0x22 type for 0x866 (variable)!
  tag__recode_dwarf_type: couldn't find 0x22 type for 0x871 (variable)!
  namespace__recode_dwarf_types: couldn't find 0x7fc type for 0x8a4 (member)!
  tag__recode_dwarf_type: couldn't find 0xfa type for 0x8e8 (volatile_type)!
  namespace__recode_dwarf_types: couldn't find 0x8b2 type for 0x90d (member)!
  tag__recode_dwarf_type: couldn't find 0x1b type for 0x941 (typedef)!
<SNIP>
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-08-13 16:07:23 -03:00
Arnaldo Carvalho de Melo e975ff247a dwarves_fprintf: Print cacheline boundaries in multiple union members
In 'struct audit_context' we have an union that have member structs that
straddles cacheline boundaries, the existing logic was showing those
cacheline boundaries only for the first struct in the union where that
straddling took place, all the subsequent structs where straddling also
takes place were not showing it, the struct:

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 */
			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 */

			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 */

			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 */

			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 */
};

With this fix:

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 */
};

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-07-28 14:25:30 -03:00
Martin KaFai Lau 68645f7fac btf: Add BTF support
This patch introduces BPF Type Format (BTF).

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.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-07-25 14:42:06 -03:00
Arnaldo Carvalho de Melo 81466af0d4 pahole: Show the file where a struct was used
To help with using just that object file, avoiding processing big files
such as vmlinux, 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 */
          unsigned int               sp_reg:4;             /*     4:28  4 */
          unsigned int               bp_reg:4;             /*     4:24  4 */
          unsigned int               type:2;               /*     4:22  4 */

          /* size: 6, cachelines: 1, members: 5 */
          /* padding: 65534 */
          /* bit_padding: 22 bits */
          /* last cacheline: 6 bytes */

          /* BRAIN FART ALERT! 6 != 8 + 0(holes), diff = -2 */
  };
<SNIP>

So I noticed that BFA, need to work on it, to make the testing process
faster, better not process vmlinux.o, instead, do:

  $ pahole -C orc_entry ${kernel_build_dir}/init/main.o

Much faster, as main.o is much smaller than the vmlinux file.

Now to fix the processing of 'struct orc_entry'.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-15 15:30:38 -03:00
Arnaldo Carvalho de Melo 2dd87be78b dwarves_fprintf: Show offsets at union members
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.

So just turn struct_member__fprintf() into class_member__fprintf() and
pass a 'union_member' boolean to share all the aspects of struct and
union members, just not advancing the offset when processing union
members.

This way, for instance, the Linux kernel's 'struct page' goes from:

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 */
};

To:

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 */
};

Suggested-by: Matthew Wilcox <willy@infradead.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-15 13:33:10 -03:00
Arnaldo Carvalho de Melo 66cf3983e1 README.DEBUG: Add an extra step to make the instructions cut'n'exec
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-14 14:15:54 -03:00
Arnaldo Carvalho de Melo 2a092d6145 dwarves: Fix cus__load_files() success return value
If we processed at least one file we should return 0 to mean success.

Fixes: 02a456f5f5 ("pahole: Search and use running kernel vmlinux when no file is passed")
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-12-14 14:14:56 -03:00
Arnaldo Carvalho de Melo 02a456f5f5 pahole: Search and use running kernel vmlinux when no file is passed
Seems like a nice shortcut for kernel hackers, and one that makes sure
the right vmlinux file is used, as it reads the running kernel build id
from /sys/kernel/notes and then searches the well known path for vmlinux
files:

vmlinux
/boot/vmlinux
/boot/vmlinux-4.14.0+
/usr/lib/debug/boot/vmlinux-`uname -r`
/lib/modules/`uname -r`/build/vmlinux
/usr/lib/debug/lib/modules/`uname -r`/vmlinux
/usr/lib/debug/boot/vmlinux-`uname -r`.debug

To find one with a matching build id (.notes ELF section, then
nhdr->n_type == NT_GNU_BUILD_ID), just like the Linux kernel 'perf
tools', where this code comes from, with some minor modifications to
cope with not having symbol_conf, symfs, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-11-24 11:24:16 -03:00
Arnaldo Carvalho de Melo 5f057919a0 man-pages: Add entry for --hex
Flavio needed this and found it only after some head scratching, add it.

Someone could help here by looking at other missing entries in the man
page, getting it in synch with 'pahole --help' ;-)

Reported-by: Flavio Leitner <fbl@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-09-05 10:13:06 -03:00
Arnaldo Carvalho de Melo 4f34f23413 v1.11 - New Release
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-06-28 16:03:46 -03:00
Arnaldo Carvalho de Melo 5a57eb0741 man-pages: Update URL to the dwarves paper
The ghostprotocols.net domain is busted for a while, point to the
more permanent OLS proceedings pdf hosted at kernel.org.

Reported-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2017-02-01 10:42:59 -03:00
Arnaldo Carvalho de Melo b52386d041 dwarves_fprintf: Find holes when expanding types
When --expand_types/-E is used we go on expanding internal types, and
when doing that for structs we were not looking for holes in them, only
on the main struct, fix it.

With that we can see these extra holes in a expanded Linux kernel's
'struct task_struct':

@@ -46,6 +46,9 @@
 			struct list_head * prev;                                         /*   176     8 */
 		} group_node; /*   168    16 */
 		unsigned int       on_rq;                                                /*   184     4 */
+
+		/* XXX 4 bytes hole, try to pack */
+
 		/* --- cacheline 3 boundary (192 bytes) --- */
 		/* typedef u64 */ long long unsigned int exec_start;                     /*   192     8 */
 		/* typedef u64 */ long long unsigned int sum_exec_runtime;               /*   200     8 */
@@ -86,9 +89,15 @@
 		} statistics; /*   232   216 */
 		/* --- cacheline 7 boundary (448 bytes) --- */
 		int                depth;                                                /*   448     4 */
+
+		/* XXX 4 bytes hole, try to pack */
+
 		struct sched_entity * parent;                                            /*   456     8 */
 		struct cfs_rq *    cfs_rq;                                               /*   464     8 */
 		struct cfs_rq *    my_q;                                                 /*   472     8 */
+
+		/* XXX 32 bytes hole, try to pack */
+
 		/* --- cacheline 8 boundary (512 bytes) --- */
 		struct sched_avg {
 			/* typedef u64 */ long long unsigned int last_update_time;       /*   512     8 */
@@ -153,6 +162,9 @@
 			struct hrtimer_clock_base * base;                                /*   768     8 */
 			/* typedef u8 */ unsigned char state;                            /*   776     1 */
 			/* typedef u8 */ unsigned char is_rel;                           /*   777     1 */
+
+			/* XXX 2 bytes hole, try to pack */
+
 			int        start_pid;                                            /*   780     4 */
 			void *     start_site;                                           /*   784     8 */
 			char       start_comm[16];                                       /*   792    16 */
@@ -197,6 +209,9 @@
 	} tasks; /*   912    16 */
 	struct plist_node {
 		int                prio;                                                 /*   928     4 */
+
+		/* XXX 4 bytes hole, try to pack */
+
 		struct list_head {
 			struct list_head * next;                                         /*   936     8 */
 			struct list_head * prev;                                         /*   944     8 */
@@ -258,12 +273,18 @@
 				/* typedef u32 */ unsigned int val;                      /*  1136     4 */
 				/* typedef u32 */ unsigned int flags;                    /*  1140     4 */
 				/* typedef u32 */ unsigned int bitset;                   /*  1144     4 */
+
+				/* XXX 4 bytes hole, try to pack */
+
 				/* --- cacheline 18 boundary (1152 bytes) --- */
 				/* typedef u64 */ long long unsigned int time;           /*  1152     8 */
 				u32 * uaddr2;                                            /*  1160     8 */
 			} futex;                                                         /*          40 */
 			struct {
 				/* typedef clockid_t -> __kernel_clockid_t */ int clockid; /*  1128     4 */
+
+				/* XXX 4 bytes hole, try to pack */
+
 				struct timespec * rmtp;                                  /*  1136     8 */
 				struct compat_timespec * compat_rmtp;                    /*  1144     8 */
 				/* typedef u64 */ long long unsigned int expires;        /*  1152     8 */
@@ -426,6 +447,9 @@
 	unsigned int               sessionid;                                            /*  1804     4 */
 	struct seccomp {
 		int                mode;                                                 /*  1808     4 */
+
+		/* XXX 4 bytes hole, try to pack */
+
 		struct seccomp_filter * filter;                                          /*  1816     8 */
 	} seccomp; /*  1808    16 */
 	/* typedef u32 */ unsigned int               parent_exec_id;                     /*  1824     4 */
@@ -602,6 +626,9 @@
 		long unsigned int  backtrace[12];                                        /*  2472    96 */
 		/* --- cacheline 40 boundary (2560 bytes) was 8 bytes ago --- */
 		unsigned int       count;                                                /*  2568     4 */
+
+		/* XXX 4 bytes hole, try to pack */
+
 		long unsigned int  time;                                                 /*  2576     8 */
 		long unsigned int  max;                                                  /*  2584     8 */
 	} latency_record[32]; /*  2472  3840 */
@@ -686,12 +713,18 @@
 		long unsigned int * io_bitmap_ptr;                                       /*  6600     8 */
 		long unsigned int  iopl;                                                 /*  6608     8 */
 		unsigned int       io_bitmap_max;                                        /*  6616     4 */
+
+		/* XXX 36 bytes hole, try to pack */
+
 		/* --- cacheline 104 boundary (6656 bytes) --- */
 		struct fpu {
 			unsigned int last_cpu;                                           /*  6656     4 */
 			unsigned char fpstate_active;                                    /*  6660     1 */
 			unsigned char fpregs_active;                                     /*  6661     1 */
 			unsigned char counter;                                           /*  6662     1 */
+
+			/* XXX 57 bytes hole, try to pack */
+
 			/* --- cacheline 105 boundary (6720 bytes) --- */
 			union fpregs_state {
 				struct fregs_state {
@@ -751,6 +784,9 @@
 					/* typedef u8 */ unsigned char no_update;        /*  6831     1 */
 					/* typedef u8 */ unsigned char rm;               /*  6832     1 */
 					/* typedef u8 */ unsigned char alimit;           /*  6833     1 */
+
+					/* XXX 6 bytes hole, try to pack */
+
 					struct math_emu_info * info;                     /*  6840     8 */
 					/* typedef u32 */ unsigned int entry_eip;        /*  6848     4 */
 				} soft; /*         136 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-06-30 16:30:28 -03:00
Arnaldo Carvalho de Melo 103e89bb25 dwarves_fprintf: Find holes on structs embedded in other structs
Take 'struct task_struct' in the Linux kernel, these fields:

        /* --- cacheline 2 boundary (128 bytes) --- */
        struct sched_entity        se;                   /*   128   448 */

        /* XXX last struct has 24 bytes of padding */

        /* --- cacheline 9 boundary (576 bytes) --- */
        struct sched_rt_entity     rt;                   /*   576    48 */

The sched_entity struct has 24 bytes of padding, and that info would
only appear when printing 'struct task_struct' if class__find_holes()
had previously been run on 'struct sched_entity' which wasn't always the
case, make sure that happens.

This results in this extra stat being printed for 'struct task_struct':

	/* paddings: 4, sum paddings: 38 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-06-30 16:18:11 -03:00
Arnaldo Carvalho de Melo ab97c07a7e dwarves_fprintf: Fixup cacheline boundary printing on expanded structs
A diff for 'pahole -EC task_struct vmlinux' should clarify what this fixes:

  [acme@jouet linux]$ diff -u /tmp/before.c /tmp/after.c | head -30
  --- /tmp/before.c	2016-06-29 17:00:38.082647281 -0300
  +++ /tmp/a.c	2016-06-29 17:03:36.913124779 -0300
  @@ -43,8 +43,8 @@
 			struct list_head * prev;                                         /*   176     8 */
 		} group_node; /*   168    16 */
 		unsigned int       on_rq;                                                /*   184     4 */
  +		/* --- cacheline 3 boundary (192 bytes) --- */
 		/* typedef u64 */ long long unsigned int exec_start;                     /*   192     8 */
  -		/* --- cacheline 1 boundary (64 bytes) was 4 bytes ago --- */
 		/* typedef u64 */ long long unsigned int sum_exec_runtime;               /*   200     8 */
 		/* typedef u64 */ long long unsigned int vruntime;                       /*   208     8 */
 		/* typedef u64 */ long long unsigned int prev_sum_exec_runtime;          /*   216     8 */
  @@ -53,40 +53,40 @@
 			/* typedef u64 */ long long unsigned int wait_start;             /*   232     8 */
 			/* typedef u64 */ long long unsigned int wait_max;               /*   240     8 */
 			/* typedef u64 */ long long unsigned int wait_count;             /*   248     8 */
  +			/* --- cacheline 4 boundary (256 bytes) --- */
 			/* typedef u64 */ long long unsigned int wait_sum;               /*   256     8 */
 			/* typedef u64 */ long long unsigned int iowait_count;           /*   264     8 */
 			/* typedef u64 */ long long unsigned int iowait_sum;             /*   272     8 */
 			/* typedef u64 */ long long unsigned int sleep_start;            /*   280     8 */
 			/* typedef u64 */ long long unsigned int sleep_max;              /*   288     8 */
  -			/* --- cacheline 1 boundary (64 bytes) --- */
 			/* typedef s64 */ long long int sum_sleep_runtime;               /*   296     8 */
 			/* typedef u64 */ long long unsigned int block_start;            /*   304     8 */
 			/* typedef u64 */ long long unsigned int block_max;              /*   312     8 */
  +			/* --- cacheline 5 boundary (320 bytes) --- */
 			/* typedef u64 */ long long unsigned int exec_max;               /*   320     8 */
 			/* typedef u64 */ long long unsigned int slice_max;              /*   328     8 */
 			/* typedef u64 */ long long unsigned int nr_migrations_cold;     /*   336     8 */
  [acme@jouet linux]$

I.e. the boundary detection was being reset at each expanded struct, do the math globally,
using the member offset, that was already done globally and correctly.

Reported-and-Tested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-06-29 17:27:51 -03:00
Arnaldo Carvalho de Melo 046ad67af3 dwarves_fprintf: Shorten class__fprintf() sig
That conf_fprintf can be elided as it is always NULL for the root call,
i.e. only when expanding types is that it will be called recursively.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-06-29 16:19:20 -03:00
Arnaldo Carvalho de Melo 44130bf70e dwarves: Update e-mail address
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-06-28 14:24:41 -03:00
Arnaldo Carvalho de Melo 327757975b dwarf_loader: Add URL for template tags description
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-19 10:31:21 -03:00
Arnaldo Carvalho de Melo f4d5e21fd1 dwarf_loader: Tidy up template tags usage
We need to get it under some ifdefs to avoid breaking the build in
distros where these tags are not defined.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-19 10:28:59 -03:00
Arnaldo Carvalho de Melo e12bf99999 dwarf_loader: Do not hash unsupported tags
This causes a segfault:

    at /home/teuf/freesoftware/pahole/dwarf_loader.c:141
    at /home/teuf/freesoftware/pahole/dwarf_loader.c:170
    cu=0x66bc70) at /home/teuf/freesoftware/pahole/dwarf_loader.c:1535
    at /home/teuf/freesoftware/pahole/dwarf_loader.c:1552
    fn=0x7ffff79cd160 <__FUNCTION__.8133> "die__process_class")
    at /home/teuf/freesoftware/pahole/dwarf_loader.c:1593
    at /home/teuf/freesoftware/pahole/dwarf_loader.c:1288

We're not supposed to hash those unsupported tags, so just check for it and
avoid hashing.

Reported-by: Christophe Fergeau <cfergeau@redhat.com>
Cc: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-19 10:23:11 -03:00
Arnaldo Carvalho de Melo 3afcfbec9e dwarf_loader: Add DW_TAG_GNU_formal_parameter_pack stub in process_function
Template support is a big TODO entry...

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-19 10:21:17 -03:00
Arnaldo Carvalho de Melo 55d9b20dba dwarf_loader: Ignore DW_TAG_dwarf_procedure when processing functions
We have no use for these location expressions yet...

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-19 10:09:06 -03:00
Arnaldo Carvalho de Melo 45618c7ec1 dwarf_loader: Initial support for DW_TAG_unspecified_type
Still need to check what to fprintf for this, but at least have it in
the type lists so that we can find it.

Reported-by: Christophe Fergeau <cfergeau@redhat.com>
Cc: Dodji Seketeli <dodji@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-17 10:05:34 -03:00
Arnaldo Carvalho de Melo 658a238b98 dwarf_loader: Stop emitting warnings about DW_TAG_call_site
No tool in this suite has any use for that, so just leave the comments
and pointers to the documentation for these tags and stop bothering the
user.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-06 15:20:16 -03:00
Arnaldo Carvalho de Melo 0fbb39291d dwarf_loader: Add support for DW_TAG_restrict_type
I.e. supporting the 'restrict' keyword, emitted by recent compilers:

  [acme@jouet pahole]$ pfunct -P ~/bin/perf |& grep -w restrict
  inline int vprintf(const char  * restrict  __fmt, struct __va_list_tag * __ap);
  inline size_t fread(void * restrict  __ptr, size_t __size, size_t __n, FILE * restrict  __stream);
  inline int vfprintf(FILE * restrict  __stream, const char  * restrict  __fmt, struct __va_list_tag * __ap);
  inline int vasprintf(char * * restrict  __ptr, const char  * restrict  __fmt, struct __va_list_tag * __ap);
  inline char * realpath(const char  * restrict  __name, char * restrict  __resolved);
  inline ssize_t readlink(const char  * restrict  __path, char * restrict  __buf, size_t __len);
  inline char * strcat(char * restrict  __dest, const char  * restrict  __src);
  inline char * fgets(char * restrict  __s, int __n, FILE * restrict  __stream);
  inline int snprintf(char * restrict  __s, size_t __n, const char  * restrict  __fmt, ...);
  inline int sprintf(char * restrict  __s, const char  * restrict  __fmt, ...);
  inline char * strcpy(char * restrict  __dest, const char  * restrict  __src);
  inline int asprintf(char * * restrict  __ptr, const char  * restrict  __fmt, ...);
  inline char * strncpy(char * restrict  __dest, const char  * restrict  __src, size_t __len);
  inline int fprintf(FILE * restrict  __stream, const char  * restrict  __fmt, ...);
  inline int vsnprintf(char * restrict  __s, size_t __n, const char  * restrict  __fmt, struct __va_list_tag * __ap);
  inline int printf(const char  * restrict  __fmt, ...);
  [acme@jouet pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-05-06 15:02:17 -03:00
Arnaldo Carvalho de Melo 9df42c6826 dwarves: Initial support for rvalue_reference_type
Need to read more on http://www.artima.com/cppsource/rvalue.html, but
handling it mostly like DW_TAG_typedef so that at least references to it
are resolved, we can get its byte size, etc.

FIXME: look at the vtable parameters, some are resolving to "(null)".

Reported-by: Benjamin Kosnik <bkoz@redhat.com>
Reported-by: Mark Wieelard <mjw@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=962571
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 16:37:48 -03:00
Arnaldo Carvalho de Melo 8af5ccd86d dwarves: Use cus__fprintf_load_files_err() in the remaining tools
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 14:29:57 -03:00
Arnaldo Carvalho de Melo 10515a7c4d dwarves: Introduce cus__fprintf_load_files_err()
Out of code in pdwtags and pahole, will be used in the other tools.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 14:25:58 -03:00
Arnaldo Carvalho de Melo 0e64636350 pahole: Show more informative message when errno is properly set on error
$ cat foo
  cat: foo: No such file or directory

Before:

  $ pahole foo
  pahole: No debugging information found

After:

  $ pahole foo
  pahole: foo: No such file or directory

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 12:59:37 -03:00
Arnaldo Carvalho de Melo 2566cc2c87 pdwtags: Show proper error messages for files it can't handle
Before it would print no message, only update its exit status, now:

  $ cat foo
  cat: foo: No such file or directory
  $ pdwtags foo
  pdwtags: foo: No such file or directory
  $ pdwtags /dev/null
  ctf__new: cannot get elf header.
  pdwtags: /dev/null: Invalid argument
  $

Reported-by: Eric Blake <eblake@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=949034
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 12:29:38 -03:00
Arnaldo Carvalho de Melo 9f3f67e786 dwarves: Fix cus__load_files() error return
Silly bug, it was trying to return a negative index stating what file
had problems in the provided array, but if the first had problems it was
return -0, duh, fix it by returning the first as 1, etc.

With this, calling 'pdwtags non-existent-file' would return no errors
via $?.

Next csets will provide proper error messages, using what is in errno
and this index to tell what file has problems.

Reported-by: Eric Blake <eblake@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=949034
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 12:24:38 -03:00
Arnaldo Carvalho de Melo ae3a2720c3 dutil: Add ____ilog2_NaN declaration to silence compiler warning
To deal with unrepresentable constant logarithms we end up causing a
build error, provide the declaration so that the compiler shut up.

Taken, as the other related code, from the Linux kernel sources.

For reference, the warning:

  [ 40%] Building C object CMakeFiles/dwarves_reorganize.dir/dwarves_reorganize.o
  /home/acme/git/pahole/dwarves_reorganize.c: In function ‘class__demote_bitfields’:
  /home/acme/git/pahole/dwarves_reorganize.c:536:168: warning: implicit declaration of function ‘____ilog2_NaN’ [-Wimplicit-function-declaration]

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2016-03-15 11:42:16 -03:00
Arnaldo Carvalho de Melo 0b81b5ad47 Update version in CMakeLists.txt
The current release is v1.10, but CMakeLists.txt had just v1.9, fix it.

Reported-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-11-20 12:19:06 -03:00
Arnaldo Carvalho de Melo 79536f4f95 cmake: Use INTERFACE_LINK_LIBRARIES
LINK_INTERFACE_LIBRARIES was deprecated.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-09-16 11:31:40 -03:00
Arnaldo Carvalho de Melo 1decb1bc4a dwarf_loader: Check cu__find_type_by_ref result
In class_member__dwarf_recode_bitfield, making it more robust, as
now we're in the process of supporting DW_TAG_partial_unit, where
some types seem to be in some ther unit and thus not being found
at the moment.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-06-05 15:10:39 -03:00
Arnaldo Carvalho de Melo 956343d05a Add instructions on how to build with debug info
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2015-06-02 16:04:04 -03:00
Arnaldo Carvalho de Melo e71353c3fa dwarf_loader: Ignore DW_TAG_dwarf_procedure
It just about having a location expression that is referenced by other
tags to save space, since we don't have use for loc exprs so far, just
ignore it instead of spamming the user with "tag not supported"
warnings.

First seen on binaries generated by gcc 4.9

Reported-by: Diego Elio Pettenò <flameeyes@flameeyes.eu>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2014-11-19 18:15:26 -03:00
Arnaldo Carvalho de Melo 1896959072 dwarves_fprintf: Add the missing GNU_ suffix to DWARF_TAG_ created by the GNU project
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2014-11-19 18:07:50 -03:00
Arnaldo Carvalho de Melo d973b1d5da dwarf_fprintf: Handle DW_TAG_GNU_call_site{_parameter}
Reported-by: Diego Elio Pettenò <flameeyes@flameeyes.eu>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2014-11-19 18:06:41 -03:00
Arnaldo Carvalho de Melo c23eab4b12 dwarf_loader: Print unknown tags as an hex number
So that we can look up at /usr/include/dwarf.h for new tags, like.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2014-11-19 17:51:11 -03:00
Mark Wielaard 943a0de067 dwarves_fprintf: DW_TAG_mutable_type doesn't exist.
DW_TAG_mutable_type was a mistake in an early DWARFv3 draft and was
removed in the final version.

http://dwarfstd.org/ShowIssue.php?issue=050223.1

Signed-off-by: Mark Wielaard <mjw@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2014-07-03 12:34:48 -03:00
Masatake YAMATO a8e562a157 dwarf_loader: Use obstack_zalloc when allocating tag
obstack_alloc was used in __tag__alloc to allocate tag object. As the
result some fields of the tag object are not initialized.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2014-07-03 12:32:16 -03:00
Arnaldo Carvalho de Melo fd3838ae9a dwarves: Stop using 'self'
As Thomas Gleixner wisely pointed out, using 'self' is stoopid, it
doesn't convey useful information, so use sensible names

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2014-01-06 16:46:50 -03:00