Commit Graph

205 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo 161c6712f4 [LIB]: Handle --help, -?, --usage in with_executable_option()
Ugh, what a hack, have to fix this properly somehow.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-05-08 12:11:04 -03:00
Arnaldo Carvalho de Melo b8eb5eb214 [LIB]: Make with_executable_option handle "--executable" and "-?e?"
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-08 11:38:06 -03:00
Arnaldo Carvalho de Melo 04b27f7012 [LIB]: Don't use argp_parse to discover if -e has to be inserted in argv
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-08 11:29:23 -03:00
Arnaldo Carvalho de Melo fbb50fc851 [LIB]: Move class__reorganize & friends to a new lib: libdwarves_reorganize
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-07 00:30:02 -03:00
Arnaldo Carvalho de Melo 05351ece16 [LIB]: Move the __emit functions to a separate library, libdwarves_emit
To isolate functionality only used in utilities such as ctracer.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-06 14:50:28 -03:00
Eugene Teo 93183ec9ee [PAHOLE]: Added an option -r to use rel_offset when printing inner structs
By default, pahole will display the offsets of the inner struct members from
the top level struct. If the user wants to focus on some inner structs, just
call the tool with the -r option to use relative offset instead of the base
offset.

Signed-off-by: Eugene Teo <eteo@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-02 16:14:20 -03:00
Arnaldo Carvalho de Melo 224ba634ee [LIB]: Make ftype__fprintf_parms optionally indent parameters
One per line.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-30 16:37:18 -03:00
Arnaldo Carvalho de Melo ccb9ff1b29 [LIB]: Introduce ftype__fprintf_parms
So that we can print just the list of arguments.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-30 16:26:29 -03:00
Arnaldo Carvalho de Melo 5d1513d035 [LIB]: Print the inline expansion sizes when printing a function
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-30 16:10:54 -03:00
Arnaldo Carvalho de Melo c3381fbd08 [LIB]: Add missing newline in cus__emit_typedef_definitions
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-28 16:58:03 -03:00
Arnaldo Carvalho de Melo 210921279a [LIB]: Fix problem introduced by the conf_fprintf work
type__emit needs to use .emit_stats = 1 or emit the ';', do the former.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-28 16:49:10 -03:00
Arnaldo Carvalho de Melo 262a5d24ea [LIB]: Introduce conf_fprintf
So that we can go on adding more config knobs without requiring adding new
parameters to lots of functions.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-28 16:13:35 -03:00
Arnaldo Carvalho de Melo 711d96943a [LIB]: Use a base_offset when printing inner structs
That way we can have the offsets from the top level struct. If the user wants
to focus some inner struct, just call the tool again specifying the inner
struct name.

Perhaps this is not so clear, shoot me, erm, no, an example should help. Look
at the member offsets (first column in the comment after each member), before
and after:

before:

acme@filo pahole]$ pahole -C tcp_sock --expand_types examples/net
/* <12a> examples/expand.c:18 */
struct tcp_sock {
	struct inet_sock {
		struct sock {
			int        protocol;     /*     0     4 */
			struct spinlock {
				int magic;       /*     0     4 */
				int counter;     /*     4     4 */
			} sklock; /*     4     8 */
			int        b;            /*    12     4 */
			int        c;            /*    16     4 */
		} sk; /*     0    20 */
		long int           daddr;        /*    20     4 */
	} inet; /*     0    24 */
	long int                   cwnd;         /*    24     4 */
	struct spinlock {
		int                magic;        /*     0     4 */
		int                counter;      /*     4     4 */
	} lock; /*    28     8 */
}; /* size: 36, cachelines: 1 */
   /* last cacheline: 36 bytes */

After:

acme@filo pahole]$ pahole -C tcp_sock --expand_types examples/net
/* <12a> examples/expand.c:18 */
struct tcp_sock {
	struct inet_sock {
		struct sock {
			int        protocol;     /*     0     4 */
			struct spinlock {
				int magic;       /*     4     4 */
				int counter;     /*     8     4 */
			} sklock; /*     4     8 */
			int        b;            /*    12     4 */
			int        c;            /*    16     4 */
		} sk; /*     0    20 */
		long int           daddr;        /*    20     4 */
	} inet; /*     0    24 */
	long int                   cwnd;         /*    24     4 */
	struct spinlock {
		int                magic;        /*    28     4 */
		int                counter;      /*    32     4 */
	} lock; /*    28     8 */
}; /* size: 36, cachelines: 1 */
   /* last cacheline: 36 bytes */

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-28 10:01:54 -03:00
Arnaldo Carvalho de Melo 55dd0a7efa [LIB]: Move variable to inside only scope that uses it
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-28 09:07:35 -03:00
Arnaldo Carvalho de Melo f85781d5b9 [LIB]: Allow of not specifying -e
cus__loadfl will just insert the -e and pass it up to dwfl_standard_argp.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-24 16:09:34 -03:00
Arnaldo Carvalho de Melo 5df74480e4 [LIB]: Detect adjacent bitfields and avoid, for now, moving the first ones
See the comment in the cset for further information.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-03 08:21:26 -03:00
Arnaldo Carvalho de Melo 757765a779 [LIB]: Disable some code in class__find_next_bit_hole_of_size
See the comment in the cset.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-03 08:00:04 -03:00
Arnaldo Carvalho de Melo 983fef74b2 [LIB]: Initialize bitfield_head to NULL in class__demote_bitfields
For the cases where the first member in a struct is part of a bitfield.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-02 19:41:09 -03:00
Arnaldo Carvalho de Melo 9a2f107820 [LIB]: Fix some more reorganize bugs
1. if the first member is a bitfield, we have to have set current_bitfield_size to 0
   prior to entering the loop.

2. If sizeof(last member) == 0, don't try to move it

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-04-02 10:50:49 -03:00
Arnaldo Carvalho de Melo a27a17088f [LIB]: Fill holes by moving members from the tail to after the hole
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 13:32:02 -03:00
Arnaldo Carvalho de Melo 286d96c520 [LIB]: Avoid moving the next member to after the current member
Confusing huh? Think about ____cacheline_aligned_in_smp, and you'll get the
idea, look at this patch inline comment to understand the issue.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 12:07:09 -03:00
Arnaldo Carvalho de Melo 46d3c408f0 [LIB]: Members bigger than cu->addr_size should be aligned by cu->addr_size
E.g. in struct net_device when moving sysfs_groups[3] to after reg_state,
sizeof(sisfs_groups[3]) is 24 and the hole found after some reorganizing after
reg_state is 80 bytes, so align it just after reg_state, not 8 bytes after it.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 11:36:21 -03:00
Arnaldo Carvalho de Melo bf6ee86eae [LIB]: Use class__find_holes more frequently
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 10:33:36 -03:00
Arnaldo Carvalho de Melo 2626f863c1 [LIB]: Call class__find_holes in class__reorganize
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 10:10:50 -03:00
Arnaldo Carvalho de Melo ef79438fc2 [LIB]: Find base types of 8 bytes on 32 and 64 bits
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 09:44:53 -03:00
Arnaldo Carvalho de Melo 416f00a81b [LIB]: Emit comment about moving to the padding in class__move_member only if in verbose mode
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 09:30:21 -03:00
Arnaldo Carvalho de Melo df2a515d4f [LIB]: Allow passing a NULL argp to cus__loadfl
For tools such as pdwtags, that don't have any further options.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-30 13:54:14 -03:00
Arnaldo Carvalho de Melo 26ea852c17 [LIB]: Moving to libdwfl
Now there is a cus__loadfl function that receives the tool argp tables and uses
libdwfl to process the DWARF info, with this RELA objects such as .o and .ko
files in a Linux kernel build are supported, and all the other goodies that
come from using libdwfl, such as separate debuginfo files, etc come as a bonus.

Now to convert the tools, pahole being the first, that already works well using
cus__loadfl().

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-30 13:22:28 -03:00
Arnaldo Carvalho de Melo 0dcc856a7f [LIB]: Emit a warning when the compiler gets the byte_offset (seemingly) wrong
[acme@filo examples]$ pahole -a mpg_audio_frame_t
/* <14f> /home/acme/git/pahole/examples/mpg_audio_frame_t.c:4 */
typedef struct {
        uint16_t     frame_sync;           /*     0     2 */
        uint8_t      layer;                /*     2     1 */

        /* WARNING: DWARF offset=0, real offset=3 */

        uint32_t     mpeg25_bit:1;         /*     0     4 */
        uint32_t     lsf_bit:1;            /*     0     4 */
        uint32_t     bitrate_idx:4;        /*     0     4 */
<SNIP>

So gcc combined a uint16_t + a uint8_t + the first entries in the uint32_t
bitfield that could fit in the 8 bits after the first two fields but haven't
updated the size of the bitfield (4) and wrote 0 as the offset, warn about such
inconsistencies.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-29 11:25:02 -03:00
Arnaldo Carvalho de Melo 27ac8cec6c [LIB]: Only check if it is a cacheline boundary when the offset changes
So that we print the boundary after the last member in a bitfield.

Spotted by Matthew Wilcox.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-28 13:21:27 -03:00
Arnaldo Carvalho de Melo c87d8d831a [ALL]: Emit better diagnostic messages
[acme@mica pahole]$ pahole lala
pahole: Permission denied
[acme@mica pahole]$ pahole foo
pahole: No such file or directory
[acme@mica pahole]$ pahole ctracer.c
pahole: couldn't load DWARF info from ctracer.c
[acme@mica pahole]$

Thanks to Matthew Wilcox for noticing how lame it was :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-28 12:54:46 -03:00
Arnaldo Carvalho de Melo 7bd8fb3c43 [LIB]: Fix compiler warnings on 64bits
Mostly related to size_t, Dwarf_Off -> (unsigned long long), etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-28 11:38:32 -03:00
Arnaldo Carvalho de Melo 0895c23b46 [LIB]: Be a bit more paranoid about types not found in type__fprintf
Instead of just segfaulting on these extreme cases.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-26 23:00:56 -03:00
Arnaldo Carvalho de Melo 723c27b3e0 [LIB]: Expand typedefs in the expand_types mode
[acme@filo pahole]$ cat examples/expand_typedefs.c
<SNIP>
typedef struct {
	int a, b, c;
} inner;

static struct outer {
        int q, b;
        inner m;
} foo;
<SNIP>
[acme@filo pahole]$ pahole --expand_types examples/expand_typedefs
/* <158> /home/acme/git/pahole/examples/expand_typedefs.c:7 */
struct outer {
	int          q;                 /*     0     4 */
	int          b;                 /*     4     4 */
	/* typedef inner */ struct {
		int  a;                 /*     0     4 */
		int  b;                 /*     4     4 */
		int  c;                 /*     8     4 */
	} m;                            /*     8    12 */
}; /* size: 20, cachelines: 1 */
   /* last cacheline: 20 bytes */
   /* definitions: 1 */
[acme@filo pahole]$

For now it does all typedef expansions, which in at least the base types may be
a bit too much, e.g. u32 -> unsigned long int, lets see if somebody complains,
perhaps even myself 8) If that is the case we can add yet another command line
option to specify that such base type expansions should be filtered out, making
the expand_types parameter be flag mask, not just a boolean as it is today.

To see a more complete output look at:

http://oops.ghostprotocols.net:81/acme/dwarves/vmlinux-pahole-expand_types-typedef_unfolding.txt

Suggested by Jeff Muizelaar.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-26 22:57:38 -03:00
Arnaldo Carvalho de Melo d415382909 [LIB]: Rename all the variables used to account the number of bytes printed in __fprintf routines
For consistency

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 12:28:02 -02:00
Arnaldo Carvalho de Melo 5a420cc24e [LIB]: Make tag__fprintf return the number of bytes printed
For consistency with all the other __fprintf routines.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 12:03:47 -02:00
Arnaldo Carvalho de Melo c3103abfef [LIB]: Rename function__print_stats to function__fprintf_stats, for consistency
Also make it return the number of bytes printed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 12:01:01 -02:00
Arnaldo Carvalho de Melo 640d1d5e53 [LIB]: Rename function__print to function__fprintf, for consistency
Also make it return the number of bytes printed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 11:58:28 -02:00
Arnaldo Carvalho de Melo d5a0c78a4c [LIB]: Rename lexblock__print to lexblock__fprintf, for consistency
Also make it return the number of bytes printed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 11:56:16 -02:00
Arnaldo Carvalho de Melo 6b1f439074 [LIB]: Rename typedef__print to typedef__fprintf, for consistency
And also make it return the number of bytes printed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 11:46:49 -02:00
Arnaldo Carvalho de Melo 02d70cca53 [LIB]: Rename tag__print_decl_info to tag__fprintf_decl_info
Also for consistency

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 11:42:33 -02:00
Arnaldo Carvalho de Melo 70f9135467 [LIB]: Rename tag__print to tag__fprintf, for consistency
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 11:40:51 -02:00
Arnaldo Carvalho de Melo f411354f05 [LIB]: Convert the __snprintf routines to __fprintf semantics
So that we get rid of all the buffer limits, if we need to format into strings
we can use string streams, like we're doing now in just one case, tag__name for
DW_TAG_subroutine_type, that is bogus as it is, as we need to have the name of
the type inside the type declaration (void (*type_name)(parameters)) and not
after (void (*)(parameters) type_name)), but leave this for an upcoming cset.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-15 11:36:49 -02:00
Arnaldo Carvalho de Melo dabcb982df [LIB]: Bigger name_spacing when expanding types
To better align the comments with the offset and member size on the right.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-11 21:58:05 -02:00
Arnaldo Carvalho de Melo d37f41df58 [LIB]: Pass a FILE pointer to the cus__emit routines
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-02 12:52:46 -02:00
Davi Arnaut 4ab3403e3b [LIB]: Add initial support for DW_AT_location, in variables
And use it in a new tool, pglobal, that shows global variables and functions.

Signed-off-by: Davi Arnaut <davi@haxent.com.br>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-02 11:56:53 -02:00
Arnaldo Carvalho de Melo dfccef66dd [LIB]: Use list_for_each_entry_safe in class__delete
As we're deleting the members.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-01 15:54:42 -02:00
Arnaldo Carvalho de Melo e4ad9bb2e8 [LIB]: Optionally pass a new name for the class in class__clone
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-01 14:09:48 -02:00
Arnaldo Carvalho de Melo aab506fdcc [LIB]: Pass a FILE pointer to the __print routines
So that in tools like ctracer we can print to a file, most of the tools just
pass stdout, keeping the previous behaviour.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-01 13:50:28 -02:00
Arnaldo Carvalho de Melo 67119ea1a3 [LIB]: Move class__reorganize and friends from pahole to libdwarves
Will be used in ctracer to create a struct subset with just the types for which
we have "collectors", i.e. functions that reduce complex types to base types
that will be put in the mini-struct, that will be as tightly packed as it can
be.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-01 13:17:41 -02:00
Arnaldo Carvalho de Melo 5d300c135e [LIB]: Export class__print
Will be used by pahole --show_reorg_steps

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-01 11:51:38 -02:00
Arnaldo Carvalho de Melo ac4fe37f72 [LIB]: Introduce cu__find_base_type_by_name
Will be used by the bitfield reorganizer in pahole.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-30 16:53:01 -02:00
Arnaldo Carvalho de Melo 4a4b75e75a [PAHOLE]: Introduce --reorganize
Reorganizes structs with holes as non disruptively as possible to combine
holes, possibly reducing the struct size.

It doesn't yet combines bit holes, but will.

And will suggest type demotion in the bitfields case i.e. if there is a integer
(4) bytes bitfield that could fit on an short int bitfield or on a char
bitfield, it'll do just that 8)

Examples are available at:

http://oops.ghostprotocols.net:81/acme/dwarves/pahole--reorganize-ide-core-struct-hwif_s.pahole.txt
http://oops.ghostprotocols.net:81/acme/dwarves/pahole--reorganize-sched-struct-task_struct.pahole.txt
http://oops.ghostprotocols.net:81/acme/dwarves/pahole--reorganize-serial-struct-jsm_channel.pahole.txt

Also look at a more detailed description at my blog:

http://oops.ghostprotocols.net:81/blog/?p=49

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-30 13:32:55 -02:00
Arnaldo Carvalho de Melo 2de67fcaf4 [PAHOLE]: Implement type expansion
What is in a struct...

[acme@filo pahole]$ pahole net/ipv6/tcp_ipv6.o delayed_work
/* <2bc9> /home/acme/git/linux-2.6/include/linux/workqueue.h:37 */
struct delayed_work {
        struct work_struct         work;                 /*     0    16 */
        struct timer_list          timer;                /*    16    24 */
}; /* size: 40, cachelines: 1 */
   /* last cacheline: 40 bytes */
[acme@filo pahole]$

Oh, but what if we want to unfold all the structs?

lo pahole]$ pahole --expand_types /home/acme/git/OUTPUT/qemu/linux-2.6/net/ipv6/tcp_ipv6.o delayed_work
/* <2bc9> /home/acme/git/linux-2.6/include/linux/workqueue.h:37 */
struct delayed_work {
        struct work_struct {
                atomic_long_t      data;                 /*   0   4 */
                struct list_head {
                        struct list_head * next;         /*   0   4 */
                        struct list_head * prev;         /*   4   4 */
                } entry;				 /*   4   8 */
                work_func_t        func;                 /*  12   4 */
        } work;						 /*   0  16 */
        struct timer_list {
                struct list_head {
                        struct list_head * next;         /*   0   4 */
                        struct list_head * prev;         /*   4   4 */
                } entry; /*     0     8 */
                long unsigned int  expires;              /*   8   4 */
                void               (*function)(long unsigned int); /*    12     4 */
                long unsigned int  data;                 /*  16   4 */
                struct tvec_t_base_s * base;             /*  20   4 */
        } timer; /*    16    24 */
}; /* size: 40, cachelines: 1 */
   /* last cacheline: 40 bytes */
[acme@filo pahole]$

Quick hack, as we already had all the needed infrastructure due to anonymous struct
printing inside structs/unions, now for the curious, if you have the kernel-debuginfo
package installed in your FC6 machine:

[acme@filo pahole]$ pahole --expand_types /usr/lib/debug/lib/modules/2.6.19-1.2895.fc6/kernel/net/ipv6/ipv6.ko.debug tcp6_sock

Try struct task_struct too 8-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-29 13:12:23 -02:00
Arnaldo Carvalho de Melo f426dc12f2 [LIB]: Print a comment after struct members with padding
/* <9fec83> /home/acme/git/linux-2.6/include/linux/sysdev.h:40 */
struct sysdev_class_attribute {
        struct attribute attr;                 /*     0    12 */

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

        ssize_t          (*show)(struct sysdev_class *, char *); /*    12     4 */
        ssize_t          (*store)(struct sysdev_class *, const char  *, size_t); /*    16     4 */
}; /* size: 20, cachelines: 1 */
   /* paddings: 1, sum paddings: 2 */
   /* last cacheline: 20 bytes */
   /* definitions: 1 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-29 12:43:49 -02:00
Arnaldo Carvalho de Melo 01b8a495c4 [LIB]: Show the number of paddings as well, not just the sum
In the Linux kernel there were no cases of more than one member
struct with paddings.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-29 12:01:15 -02:00
Arnaldo Carvalho de Melo b5baabcd16 [ALL]: Fixup warnings
Using export CFLAGS="-Wall -Wfatal-errors -Wformat=2 -Wsequence-point -Wextra
-Wno-parentheses -g", suggested by Davi Arnault, amazing how cruft piles up
when one is not looking ;)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-29 10:42:03 -02:00
Davi Arnaut a7b22b8f2c [LIB]: Show the sum of paddings in structs within a struct
Commiter note:

Idea and initial patch by Davi Arnaut, I fixed it to do the right thing,
to understand why this is useful, nothing better than an example:

/* <bd92a0> /home/acme/git/linux-2.6/include/net/xfrm.h:242 */
struct xfrm_tmpl {
        struct xfrm_id             id;                   /*     0    24 */
        xfrm_address_t             saddr;                /*    24    16 */
        short unsigned int         encap_family;         /*    40     2 */

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

        __u32                      reqid;                /*    44     4 */
        __u8                       mode;                 /*    48     1 */
        __u8                       share;                /*    49     1 */
        __u8                       optional;             /*    50     1 */

        /* XXX 1 byte hole, try to pack */

        __u32                      aalgos;               /*    52     4 */
        __u32                      ealgos;               /*    56     4 */
        __u32                      calgos;               /*    60     4 */
        /* --- cacheline 1 boundary (64 bytes) --- */
}; /* size: 64, cachelines: 1 */
   /* sum members: 61, holes: 2, sum holes: 3 */
   /* sum padding: 3 */
   /* definitions: 22 */

"sum padding" here means there is some member that is a struct and this struct
has paddings: struct xfrm_id:

/* <bd78b6> /home/acme/git/linux-2.6/include/linux/xfrm.h:24 */
struct xfrm_id {
	xfrm_address_t             daddr;                /*     0    16 */
	__be32                     spi;                  /*    16     4 */
	__u8                       proto;                /*    20     1 */
}; /* size: 24, cachelines: 1 */
   /* padding: 3 */
   /* last cacheline: 24 bytes */
   /* definitions: 22 */

Signed-off-by: Davi Arnaut <davi@haxent.com.br>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-29 00:16:33 -02:00
Davi Arnaut 9241301511 [PAHOLE]: Handle anonymous structs
Some are just typedefs, others are inside structs and in some cases its
useful to see the statistics for them, so add two new cmd line options:

-a, --anon_include        include anonymous classes\
-A, --nested_anon_include include nested (inside other structs) anonymous classes

Commiter note: I've reworked several aspects of the patch, but mostly to
give better names for the new find_first_typedef_of_type function, adding
a clarifying comment and introducing --nested_anon_include so that we
can select just the typedef'ed anonymous structs.

Signed-off-by: Davi Arnaut <davi@haxent.com.br>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-28 02:18:34 -02:00
Arnaldo Carvalho de Melo c49f2c9634 [LIB]: Add orphan DW_TAG_formal_parameter tags to the lexblock where it appears
Previously it was being added to the CU tag list.

This also fixes a problem in cu__find_parameter_by_id where the second test in
the loop was actually outside the loop due to lack of {}.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-26 00:29:53 -02:00
Arnaldo Carvalho de Melo 2aa6ef9a0f [LIB]: Use dwarf_dieoffset where we were using dwarf_cuoffset
Better, to match the readelf (binutils) and eu-readelf (elfutils) tools,
that on multi CU blobs is the way to go.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-25 16:24:09 -02:00
Davi Arnaut 4e93019433 [LIB]: Add missing { in typedef__print
That was preventing the correct printing of anonymous struct typedefs.

Signed-off-by: Davi Arnaut <davi@haxent.com.br>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-25 10:31:36 -02:00
Arnaldo Carvalho de Melo a4856181a7 [LIB]: Emit typedefs of typedef arrays
Such as this one, when using ctracer to trace struct task_struct methods:

  --- ctracer_methods.c.before	2007-01-24 09:20:30.000000000 -0200
  +++ ctracer_methods.c	2007-01-24 09:38:35.000000000 -0200
  @@ -759,7 +759,8 @@
   	.entry = (kprobe_opcode_t *)jprobe_entry__release_thread,
   };

  -typedef elf_greg_t elf_gregset_t;
  +typedef long unsigned int elf_greg_t;
  +typedef elf_greg_t elf_gregset_t[17];

   static int jprobe_entry__dump_task_regs(struct task_struct * tsk, elf_gregset_t * regs)
   {

Code impact:

[acme@filo pahole]$ codiff build/libdwarves.so.before build/libdwarves.so
/home/acme/git/pahole/dwarves.c:
  typedef__print                | +154
    cus__emit_typedef_definitions |  +27
     2 functions changed, 181 bytes added
     [acme@filo pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-24 09:41:46 -02:00
Arnaldo Carvalho de Melo 68d64b2930 [LIB]: Detect typedef loops
Recheck if the typedef was emitted as part of the emission of its target, as
there are cases, like wait_queue_t in the Linux kernel, that is against struct
__wait_queue, that has a wait_queue_func_t member, a function typedef that has
as one of its parameters a... wait_queue_t, that will thus be emitted before
the function typedef, making a no go to redefine the typedef after struct
__wait_queue.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-24 09:10:26 -02:00
Arnaldo Carvalho de Melo 4c2ef6007f [LIB]: Fix emission of arrays of structs, unions, etc
And it even shrinks the lib a bit :-)

[acme@filo pahole]$ codiff build/libdwarves.so.before build/libdwarves.so
/home/acme/git/pahole/dwarves.c:
  cus__emit_tag_definitions |  -68
   1 function changed, 68 bytes removed
   [acme@filo pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-24 08:58:50 -02:00
Arnaldo Carvalho de Melo 30165f5c63 [LIB]: Don't return struct declarations in cu__find_struct_by_name
Find the real thing instead.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-23 16:25:24 -02:00
Arnaldo Carvalho de Melo 812406d9fb [LIB]: Use sysconf to get the L1 cacheline size
As suggested by Ulrich Drepper.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-01-18 21:41:25 -02:00
Arnaldo Carvalho de Melo e3786105c0 [LIB]: Handle void typedefs
Oh the horror, found in a proprietary kernel module:

typedef void * PVOID;

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-16 12:19:06 -02:00
Arnaldo Carvalho de Melo 1750958111 [LIB]: Separate emission of definitions in a type from the emission of the type itself
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-16 12:11:35 -02:00
Arnaldo Carvalho de Melo 14863f943e [LIB]: Remove the prefix tag for enum functions
Now the functions that call cus__emit_enumeration_definitions should call
tag__print_decl_info, so that if it is a typedef we can just print "typedef ",
then call the enum printing routines.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-15 12:15:59 -02:00
Arnaldo Carvalho de Melo 36c4c5a386 [LIB]: Handle union typedefs
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-15 11:21:39 -02:00
Arnaldo Carvalho de Melo 8f8a691a6a [LIB]: Handle enum typedefs
Using 'ctracer vmlinux pci_dev' without and with this cset:

  --- ctracer.c.old 2007-01-15 10:45:45.000000000 -0200
  +++ ctracer.c	  2007-01-15 10:45:57.000000000 -0200
  @@ -2175,7 +2175,28 @@
   struct hwgroup_s;
   struct proc_dir_entry;
   typedef int (ide_ack_intr_t)(struct hwif_s *);
  -typedef enum  hwif_chipset_t;
  +/* <a710> /pub/scm/linux/kernel/git/acme/linux-2.6/include/linux/ide.h:199 */
  +typedef enum {
  +	ide_unknown = 0,
  +	ide_generic = 1,
  +	ide_pci = 2,
  +	ide_cmd640 = 3,
  +	ide_dtc2278 = 4,
  +	ide_ali14xx = 5,
  +	ide_qd65xx = 6,
  +	ide_umc8672 = 7,
  +	ide_ht6560b = 8,
  +	ide_rz1000 = 9,
  +	ide_trm290 = 10,
  +	ide_cmd646 = 11,
  +	ide_cy82c693 = 12,
  +	ide_4drives = 13,
  +	ide_pmac = 14,
  +	ide_etrax100 = 15,
  +	ide_acorn = 16,
  +	ide_au1xxx = 17,
  +	ide_forced = 18,
  +} hwif_chipset_t;
   struct device;

 /* <a796> /pub/scm/linux/kernel/git/acme/linux-2.6/include/linux/ide.h:211 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-15 10:51:07 -02:00
Arnaldo Carvalho de Melo 37d19a9320 [LIB]: Emit definitions for structs in typedefs
I.e. things like

typedef struct foo bar;

will emit the definition for struct foo before emitting the above line.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-15 10:39:23 -02:00
Arnaldo Carvalho de Melo 348fdc8d1a [LIB]: Avoid emitting top level unnamed unions and structs
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-15 10:34:13 -02:00
Arnaldo Carvalho de Melo 9a413e60a3 [LIB]: Fix stupid if + switch case
Where the 'if' should be just one of of the cases in the 'switch', and guess
what:

This:

  diff --git a/dwarves.c b/dwarves.c
  index c0ae7c8..34f29a1 100644
  --- a/dwarves.c
  +++ b/dwarves.c
  @@ -2580,10 +2580,10 @@ static int cus__emit_typedef_definitions
   	}
   	type = cu__find_tag_by_id(cu, tdef->type);

  -	if (type->tag == DW_TAG_typedef)
  -		cus__emit_typedef_definitions(self, cu, type);
  -
   	switch (type->tag) {
  +	case DW_TAG_typedef:
  +		cus__emit_typedef_definitions(self, cu, type);
  +		break;
   	case DW_TAG_pointer_type:
   		ptr_type = cu__find_tag_by_id(cu, type->type);
   		if (ptr_type->tag != DW_TAG_subroutine_type)

Results in this:

[acme@newtoy pahole]$ codiff -V build/libdwarves.so.orig build/libdwarves.so
/home/acme/pahole/dwarves.c:
  cus__emit_typedef_definitions |  -18 # 466 -> 448
 1 function changed, 18 bytes removed
[acme@newtoy pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 16:22:53 -02:00
Arnaldo Carvalho de Melo 9b0f2584fe [LIB]: Minor class_member__snprintf cleanup
Size of generated code doesn't changes.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 16:14:45 -02:00
Arnaldo Carvalho de Melo 45f5c5f8e3 [LIB]: switches are cheaper, step 2
[acme@newtoy pahole]$ codiff -V build/libdwarves.so.orig build/libdwarves.so
/home/acme/pahole/dwarves.c:
  class_member__snprintf |  -45 # 1126 -> 1081
 1 function changed, 45 bytes removed
[acme@newtoy pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 16:12:41 -02:00
Arnaldo Carvalho de Melo 59bddf5928 [LIB]: switches are cheaper
[acme@newtoy pahole]$ codiff -V build/libdwarves.so.orig build/libdwarves.so
/home/acme/pahole/dwarves.c:
  tag__name |  -63 # 982 -> 919
 1 function changed, 63 bytes removed
[acme@newtoy pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 16:04:21 -02:00
Arnaldo Carvalho de Melo 003a38d2b0 [LIB]: Emit a ';' after unions in cus__emit_type_definitions
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 15:56:27 -02:00
Arnaldo Carvalho de Melo 0bf740a74c [LIB]: Make cus__emit_fwd_decl handle unions
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 14:27:08 -02:00
Arnaldo Carvalho de Melo 3a9ceb41ee [LIB]: Rename cus__emit_struct_definitions to cus__emit_type_definitions
To make it handle unions too.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 14:19:34 -02:00
Arnaldo Carvalho de Melo 7e57db18d7 [LIB]: Add support for DW_AT_specification in DW_TAG_subprogram
C++ feature, we have to look for the id, then abstract_origin and then
specification.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 11:37:41 -02:00
Arnaldo Carvalho de Melo 5dcd02daa3 [LIB]: Print the cu offset in tag__print_decl_info
To locate the entry in the readelf output when looking for problems.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 10:58:58 -02:00
Arnaldo Carvalho de Melo f6718f5721 [LIB]: Export lexblock__print
tag__print on a DW_TAG_subprogram tag prints just the function prototype,
without the ending ";\", so if a user wants to print the whole function its
just a matter of calling tag__print + lexblock__(tag__function(tag), cu,
indent).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 10:57:19 -02:00
Arnaldo Carvalho de Melo 777a21fad0 [LIB]: Replace ntabs with indent, for consistency
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 10:40:33 -02:00
Arnaldo Carvalho de Melo aa961db9b9 [LIB]: Reintroduce union__print, this time being called by tag__print
And will be used by a new dwarf, that is about to be merged.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 18:00:32 -02:00
Arnaldo Carvalho de Melo de345d7d29 [LIB]: Leave to the callers of enumeration__print to add or not the ; and newline
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 17:40:12 -02:00
Arnaldo Carvalho de Melo ef329ecd49 [LIB]: Leave to callers of typedef__print to add or not the ; and newline
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 17:23:14 -02:00
Arnaldo Carvalho de Melo 49ca9c8a0b [LIB]: Make ftype__snprintf check for types not found
Again, due to some tags not being collected in the C++ case.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:34:53 -02:00
Arnaldo Carvalho de Melo ed2d124a0e [LIB]: Make typedef__print check if the type was not found
This should not happen, but right now happens as we don't support all the C++
tags, so some types are not being collected when inside DW_TAG_namespace dies.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:29:53 -02:00
Arnaldo Carvalho de Melo 16c0586602 [LIB]: Make all callers of function__print use tag__print instead
And since there are no external users now, just unexport it, ditto
for tag__print_decl_info.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:25:20 -02:00
Arnaldo Carvalho de Melo 907831071f [LIB]: Make tag__print support DW_TAG_subprogram
Calling function__print.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:19:13 -02:00
Arnaldo Carvalho de Melo 26747d0053 [LIB]: Don't print the decl info in function__print
Its up to its callers, that will be moot soon as tag__print will call
function__print and as it already prints the decl info it'll be just a matter
of making all the function__print callers call tag__print instead and then
function__print will be unexported.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:17:53 -02:00
Arnaldo Carvalho de Melo df1832ac4f [LIB]: Introduce tag__print_decl_info
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:11:37 -02:00
Arnaldo Carvalho de Melo c1f96237b3 [LIB]: Remove unused variables in function__print
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:03:38 -02:00
Arnaldo Carvalho de Melo 3fe4f09a27 [LIB]: Move the stats printing bits out of function__print
Moving them to a new function, function__print_stats.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 16:00:07 -02:00
Arnaldo Carvalho de Melo d385563a53 [LIB]: Make the function methods return and receive a struct tag
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 15:47:26 -02:00
Arnaldo Carvalho de Melo 458e7d6867 [LIB]: Call enumeration__print in tag__print
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 15:24:41 -02:00
Arnaldo Carvalho de Melo 18703f8d3c [LIB]: Call typedef__print in tag__print
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 15:13:38 -02:00
Arnaldo Carvalho de Melo bc58353565 [LIB]: Pass prefix and suffix to class__snprintf in class__print
Fixing a regression introduced when doing the class__snprintf introduction out
of class__print, namely this one:

--- ctracer_sock.c.old  2007-01-12 14:57:56.000000000 -0200
+++ ctracer.c   2007-01-12 15:00:21.000000000 -0200
@@ -1668,7 +1668,7 @@
 };

   /* /pub/scm/linux/kernel/git/acme/linux-2.6/include/linux/fs.h:1050 */
  -struct {
  +typedef struct {
          size_t              written;     /*     0     4 */
          size_t              count;       /*     4     4 */
          union {
  @@ -1676,7 +1676,7 @@
                  void *      data;        /*           4 */
          } arg;                           /*     8     4 */
          int                 error;       /*    12     4 */
  -}; /* size: 16, cachelines: 1 */
  +} read_descriptor_t; /* size: 16, cachelines: 1 */
      /* last cacheline: 16 bytes */

   typedef int (*sk_read_actor_t)(read_descriptor_t *, struct sk_buff *, unsigned int, size_t);

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 15:03:59 -02:00
Arnaldo Carvalho de Melo 0661f26f9f [LIB]: Call cus__emit_ftype_definitions for DW_TAG_subroutine_type in cus__emit_tag_definitions
Thus emitting definitions/forward declarations for the types of function
pointers, not just for the return type of the function pointer.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 14:39:26 -02:00
Arnaldo Carvalho de Melo 0905197862 [LIB]: Create typedef__print out of cus__emit_typedef_definitions
This way cus__emit_typedef_definitions first looks for definitions in the
typedef that will be emitted, emits those definitions, then prints the typedef.

With this it'll be possible to make tag__print to print typedefs, when we know
that the definitions it needs were already previously emitted/printed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 13:04:05 -02:00
Arnaldo Carvalho de Melo a1f5422656 [LIB]: Add support for DW_TAG_reference_type
One more C++ feature supported:

[acme@newtoy examples]$ pahole qsettings.o QConfFileSettingsPrivate
/* io/qsettings_p.h:233 */
struct QConfFileSettingsPrivate {
        struct QSettingsPrivate (null);               /*     0    76 */
        /* --- cacheline 2 boundary (64 bytes) was 12 bytes ago --- */
        class QConfFile *       confFiles[4];         /*    76    16 */
        enum Format             format;               /*    92     4 */
        /* --- cacheline 3 boundary (96 bytes) --- */
        bool                    (*readFunc)(class QIODevice &, class QMap<QString,QVariant> &); /*    96     4 */
        bool                    (*writeFunc)(class QIODevice &, const class QMap<QString,QVariant>  &); /*   100     4 */
        struct QString          extension;            /*   104     4 */
        >>>ERROR: type for caseSensitivity not found!
}; /* size: 112, cachelines: 4 */
   /* padding: 5 */
   /* last cacheline: 16 bytes */

/* BRAIN FART ALERT! 112 != 108 + 0(holes), diff = 4 */

[acme@newtoy examples]$

Now to see the problem with caseSensitivity type, probably was defined inside
some DW_TAG_namespace, that is not yet supported.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-12 11:06:59 -02:00
Arnaldo Carvalho de Melo 0ad467a321 [LIB]: Replace type not found asserts by an error message
So that we can continue and see what was the problem, investigate using readelf
-wi and proceed to fix it, normally its just references to not yet supported
tags, so far the ones I know are not supported are DW_TAG_reference_type &
DW_TAG_namespace, i.e. tags not present in the C language, only on C++ and
other object oriented routines with such concepts.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-11 23:09:06 -02:00
Arnaldo Carvalho de Melo 30b6aa2f73 [LIB]: Rename classes.[ch] to dwarves.[ch]
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-11 16:07:05 -02:00