Commit Graph

195 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo d105a5eb6c [PAHOLE]: Reorganize bitfields
This cset also does a fixup for cases where the compiler keeps the type
specified by the programmer for a bitfield but uses less space to combine with
the next, non-bitfield member, these cases can be caught using plain pahole and
will appear with this comment:

        /* --- cacheline 1 boundary (64 bytes) --- */
        int          bitfield1:1;   /* 64 4 */
        int          bitfield2:1;   /* 64 4 */

        /* XXX 14 bits hole, try to pack */
        /* Bitfield WARNING: DWARF size=4, real size=2 */

        short int    d;             /* 66 2 */

The fixup is done prior to reorganizing the fields.

Now an example of this code in action:

[acme@filo examples]$ cat swiss_cheese.c
<SNIP>
struct cheese {
        char  id;
        short number;
        char  name[52];
        int   a:1;
        int   b;
        int   bitfield1:1;
        int   bitfield2:1;
        short d;
        short e;
        short last:5;
};
<SNIP>
[acme@filo examples]$

Lets look at the layout:

[acme@filo examples]$ pahole swiss_cheese cheese
/* <11b> /home/acme/git/pahole/examples/swiss_cheese.c:3 */
struct cheese {
        char        id;             /*  0  1 */

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

        short int   number;         /*  2  2 */
        char        name[52];       /*  4 52 */
        int         a:1;            /* 56  4 */

        /* XXX 31 bits hole, try to pack */

        int         b;              /* 60  4 */
        /* --- cacheline 1 boundary (64 bytes) --- */
        int         bitfield1:1;    /* 64  4 */
        int         bitfield2:1;    /* 64  4 */

        /* XXX 14 bits hole, try to pack */
        /* Bitfield WARNING: DWARF size=4, real size=2 */

        short int   d;              /* 66  2 */
        short int   e;              /* 68  2 */
        short int   last:5;         /* 70  2 */
}; /* size: 72, cachelines: 2 */
   /* sum members: 71, holes: 1, sum holes: 1 */
   /* bit holes: 2, sum bit holes: 45 bits */
   /* bit_padding: 11 bits */
   /* last cacheline: 8 bytes */
[acme@filo examples]$

Full of holes, has bit padding and uses more than one 64 bytes cacheline.

Now lets ask pahole to reorganize it:

[acme@filo examples]$ pahole --reorganize --verbose swiss_cheese cheese
/* Demoting bitfield ('a' ... 'a') from 'int' to 'unsigned char' */
/* Demoting bitfield ('bitfield1' ... 'bitfield2') from 'short unsigned int' to 'unsigned char' */
/* Demoting bitfield ('last') from 'short int' to 'unsigned char' */
/* Moving 'bitfield2:1' from after 'bitfield1' to after 'a:1' */
/* Moving 'bitfield1:1' from after 'b' to after 'bitfield2:1' */
/* Moving 'last:5' from after 'e' to after 'bitfield1:1' */
/* Moving bitfield('a' ... 'last') from after 'name' to after 'id' */
/* Moving 'e' from after 'd' to after 'b' */

/* <11b> /home/acme/git/pahole/examples/swiss_cheese.c:3 */
struct cheese {
        char                       id;                   /*     0     1 */
        unsigned char              a:1;                  /*     1     1 */
        unsigned char              bitfield2:1;          /*     1     1 */
        unsigned char              bitfield1:1;          /*     1     1 */
        unsigned char              last:5;               /*     1     1 */
        short int                  number;               /*     2     2 */
        char                       name[52];             /*     4    52 */
        int                        b;                    /*    56     4 */
        short int                  e;                    /*    60     2 */
        short int                  d;                    /*    62     2 */
        /* --- cacheline 1 boundary (64 bytes) --- */
}; /* size: 64, cachelines: 1 */
   /* saved 8 bytes and 1 cacheline! */
[acme@filo examples]$

Instant karma, it gets completely packed, and look ma, no
__attribute__((packed)) :-)

With this struct task_struct in the linux kernel is shrunk by 12 bytes, there
is more 4 bytes to save with another technique that involves not combining
holes, but using the last single hole to fill it with members at the tail of
the struct.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-01 10:51:16 -02:00
Arnaldo Carvalho de Melo 8e236f4ca3 [PAHOLE]: Combine bitfields and demote the ones that have more bits than needed
This allows us to save 4 more bytes in struct task_struct, for instance, now we
need to combine whole bitfields with other fields if some bitfield has a size
less than sizeof(void *) and there is a suitable hole.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-30 16:55:19 -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 9b0edcc982 [PAHOLE]: Fix alignment of options descriptions in --help
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-29 11:18:46 -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 c9bd654d3b [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.

Damn, I had commited just dwarves.c, here is the dwarves.h and pahole.c bits.

Signed-off-by: Davi Arnaut <davi@haxent.com.br>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-28 11:07:22 -02:00
Arnaldo Carvalho de Melo 2705bba815 [PAHOLE]: Fix the usage info, its a class name not a function name
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-01-27 19:46:35 -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 03530985c1 [PAHOLE]: Introduce --nr_methods
To show how many non inline functions receive as a parameter each of the structs
in a project, example:

[acme@newtoy ctracer_example]$ pahole --nr_methods vmlinux | sort -k2 -nr | head -5
file: 526
inode: 479
sk_buff: 386
sock: 383
dentry: 295
[acme@newtoy ctracer_example]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-13 13:59:32 -02:00
Arnaldo Carvalho de Melo 04d65d98ff [PAHOLE]: Add a verbose command line option
For now it just affects showing differences in definitions of structs with the
same name found in different object files, that could be a real problem but
could as well be just a namespace colision not affecting the project's build
process as they were be local to specific objects.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-11 22:11:31 -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
Arnaldo Carvalho de Melo 8062d1a874 [CLASSES]: Make struct class and enumeration share more thru struct type
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-09 10:00:47 -02:00
Arnaldo Carvalho de Melo 5deeded578 [CLASSES]: Introduce struct type
Out of struct typedef_tag, that now becomes the superclass of struct class, and
that also will be for struct enumeration, struct union_type and then finally
for struct struct_type, when struct class finally dies.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-07 12:30:58 -02:00
Arnaldo Carvalho de Melo 6165ac5ba6 [CLASSES]: Reduce the space needed to represent a DW_TAG_typedef
By having its own class, struct typedef_tag.

As it, as structs, unions and enums have a common part, the node and visited
fields, required when emitting its definitions there is an opportunity for
consolidation, that will be explored when adding the specific classes for
DW_TAG_enumeration & DW_TAG_union.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-06 15:17:58 -02:00
Arnaldo Carvalho de Melo b11c508509 [CLASSES]: Remove cu field from struct class
Same reason as for the previous structs were the same change was made.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-04 01:41:11 -02:00
Arnaldo Carvalho de Melo bed9378b42 [CLASSES]: Use just one list for classes (structs, unions, etc) and functions
Almost mirroring the DWARF on-disk linkage on memory, more to come before
getting over these simplification refactorings.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2007-01-03 21:29:24 -02:00
Arnaldo Carvalho de Melo bbf3f8d95e [CLASSES]: Become struct tag centric
So far struct class was being used as the main data structure, switch to struct
tag, that already was the top of the tag hierarchy, being a struct class
ancestor, so reflect that and stop using struct class as the catch all class,
as a started DW_TAG_array_type tags are now represented by a new class, struct
array_type, reducing the size of struct class and reducing DW__TAG_array_type
instance memory usage.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-29 15:28:58 -02:00
Arnaldo Carvalho de Melo 43de2d269f [CLASSES]: Use ISO C99 integer types more comprehensively
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-28 11:18:43 -02:00
Arnaldo Carvalho de Melo 95578b7694 [CLASSES]: Shrink struct class_member
[acme@newtoy pahole]$ codiff build/libclasses.so.orig build/libclasses.so
/home/acme/pahole/classes.c:
  struct class_member |  -16
 1 struct changed
  class_member__new   |   +6
  class_member__names |   +5
  class_member__print |   -9
  class__find_holes   |  -37
  class__print_struct |  -22
  cu__process_class   |   +1
 6 functions changed, 12 bytes added, 68 bytes removed
[acme@newtoy pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-28 10:09:18 -02:00
Arnaldo Carvalho de Melo b0e2c51ec8 [CLASSES]: Allow struct cus instances to share a list of defs and fwd_decls
So that we can extract bits from one and combine it bits from other instances,
like we'll do in ctracer, where we want to have a cus instance just to get the
kprobes definitions and forward declarations but not handle the methods in it.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-27 14:39:37 -02:00
Arnaldo Carvalho de Melo 66ef6a39ba [CLASSES]: Add optional prefix and suffix parameters to class__print
That will be used when typedefs are being emitted, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-23 18:09:47 -02:00
Arnaldo Carvalho de Melo 3e7e387ddb [CLASSES]: Move passing the object file name from cus__new to cus__load
So that we can load many object files, that is what the next csets will
do, to recursively look for files with debug info in a build tree, such
as the kernel one.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 12:35:45 -02:00
KOVACS Krisztian f35522a09f [PAHOLE]: Fix copy'n'paste error on usage()
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-20 09:41:25 -02:00
Arnaldo Carvalho de Melo 9b12f89fa9 [PAHOLE]: Ditch the opt enum, use a formatter pointer
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-18 16:27:14 -02:00
Arnaldo Carvalho de Melo e87d958939 [PAHOLE]: Check structure definitions in multi-object files
An example to illustrate the kind of checks done:

[acme@newtoy multi-cu]$ cat a.c

struct foo {
	int	a;
	char	b;
};

void a_foo_print(struct foo *f)
{
	printf("f.a=%d\n", f->a);
}

[acme@newtoy multi-cu]$ cat main.c
struct foo {
	int	a;
	char	b;
	char	c;
};

extern void a_foo_print(struct foo *f);

int main(void)
{
	struct foo f = { .a = 10, };
	a_foo_print(&f);
	return 0;
}

[acme@newtoy multi-cu]$ cc -g -c a.c -o a.o
[acme@newtoy multi-cu]$ cc -g -c main.c -o main.o
[acme@newtoy multi-cu]$ cc a.o main.o -o m
[acme@newtoy multi-cu]$ pahole m
class: foo
first: a.c
current: main.c
nr_members: 2 != 3
padding: 3 != 2

[acme@newtoy multi-cu]$

Gotcha? In the above case this inconsistency wouldn't cause problems, as the
'c' member doesn't makes the struct bigger, it uses the padding, but what if we
inverted the members 'a' and 'b'?

Upcoming csets will check if the type and order of the members are the same,
should help in some complex projects where people insist on using #ifdefs in
struct definitions.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-18 11:05:07 -02:00
Arnaldo Carvalho de Melo afb41b16f9 [PAHOLE]: Improve multi-CU processing
Simplifying options processing by using just pair of cu and class iterators and
using the list we were building just for --total_structure_stats for all
options, this way we don't print multiple times structures that are defined in
more than one object file when processing a multi-object file.

With this in place all the options will check if a struct definition in one
object file somehow doesn't matches the same struct definition in some other
object file, more checks will be put in place in the upcoming csets.

And, to show that this besides simplifying reduces the code size, lets use
codiff:

[acme@newtoy pahole]$ codiff build/pahole.before build/pahole
/home/acme/pahole/pahole.c:
  structures__add | -143
  class__filter   | +147
  main            | -263
 3 functions changed, 147 bytes added, 406 bytes removed
[acme@newtoy pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-18 10:47:39 -02:00
Arnaldo Carvalho de Melo cb883f6a8f [PAHOLE]: First stab at implementing --packable
That is to find structs that have combinable holes, trying to pack the struct
by suggesting a move, for now it just prints structs that have holes that can
be combined, but these hints are not guaranteed to generate struct size
reductions, more has to be done and that involves understanding the alignment
rules that depend on the arch being 32 or 64 bits, but it at least reduces the
number of packing candidates.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 16:14:15 -02:00
Arnaldo Carvalho de Melo c5a4d29825 [PAHOLE]: Introduce --bit_holes
So that we can see only the structs that have more than the specified number of
bit holes.

Can be combined with --holes to see structs that have bit and byte holes.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-07 13:08:20 -02:00
Bernhard Fischer c9be4684fe [PAHOLE]: make some functions static
These are currently only used by pahole and would live in classes otherwise.

Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:58:27 -02:00
Bernhard Fischer a35aa33be8 [PAHOLE]: trim some superfluous whitespace
No object-code changes.

Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:56:47 -02:00
Bernhard Fischer 10b1299dea [PAHOLE]: save a few bytes on-disk
Merge option parsing variables into one opts variable.

   text    data     bss     dec     hex filename
  25006     660      44   25710    646e pahole.orig
  24974     660      44   25678    644e pahole

Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-05 14:55:31 -02:00
Arnaldo Carvalho de Melo 1347cff6d9 [PAHOLE]: Make --holes require an argument
The minimum number of holes that a struct must have for it to be
reported, to help in combining holes.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-02 12:51:59 -02:00
Arnaldo Carvalho de Melo d5620cc7fd [PAHOLE]: Implement --decl_exclude
pahole -D /pub/scm/linux/kernel/git/acme/net-2.6.20/include/net/ \
	  ../OUTPUT/qemu/net-2.6.20/net/ipv4/tcp.o

Will exclude all the classes that were defined in files in the
/pub/scm/linux/kernel/git/acme/net-2.6.20/include/net/ directory, note that its
a prefix, not a directory, so one could as well pass
/pub/scm/linux/kernel/git/acme/net-2.6.20/include/net/tcp_ to exclude just the
files in the include/net directory and that start with 'tcp_'.

Now I think I implemented what Bernard wanted, and that is useful for me
as well, of course :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-01 00:08:10 -02:00
Arnaldo Carvalho de Melo 5c777371cd [CLASSES]: Make cu__for_each_class receive a filter
Same semantic as in the cus__for_each_cu filter.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-12-01 00:00:24 -02:00
Arnaldo Carvalho de Melo e5a400d01f [CLASSES]: Make cus__for_each_cu receive an optional filter
To simplify the callsites and make implementing the same thing on the other
dwarves (prefcnt, pfunct, etc) easy.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:48:34 -02:00
Arnaldo Carvalho de Melo 512cb6fce5 [PAHOLE]: Implement --cu_exclude
Doesn't make that much sense for structs, because of the usual includes hell in
most projects, but makes sense for pfunct, so implement it now and later move
it to classes.c.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:36:55 -02:00
Arnaldo Carvalho de Melo a9adcc2349 [PAHOLE]: Add 'class__' prefix to exclude_prefix{_len}
As we'll have cu__exclude_prefix{_len} too.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:23:41 -02:00
Arnaldo Carvalho de Melo 5631a94760 [PAHOLE]: Introduce class__filter()
That checks for constraints, the first one being a exclude prefix, and is used
by all the iterators.

Additional constraints can be things like specifying prefixes for compilation
unit names, i.e. "show me only the object files which name starts with
net/ipv4/", etc.

Initial patch provided by Bernhard Fischer, who also had the --exclude idea.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 23:12:21 -02:00
Arnaldo Carvalho de Melo f428efa335 [pahole]: reimplement --class_name_len
I somehow deleted this functionality at some point, spotted by Bernhard
Fischer.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 19:35:29 -02:00
Bernhard Fischer 23785f65b7 [pahole]: typo in help text
Correct short option for nr_members in help text.

Signed-off-by: Bernhard Fischer <rep.nop@aon.at>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-30 19:03:59 -02:00
Arnaldo Carvalho de Melo fceec841ca [PAHOLE]: Implement --holes to show only the structs with holes
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-27 15:54:02 -02:00
Arnaldo Carvalho de Melo 5afa478d8d [CLASSES]: Introduce struct tag
This should have been done from the start: all DW_TAG_s will be represented by
structs that has as its first member a struct tag, so that we can fully
represent the DWARF information, following csets will take continue the
restructuring.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 11:54:02 -02:00
Arnaldo Carvalho de Melo 7ebee113cc [PAHOLE]: Check if we found the struct before calling class__is_struct
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-14 13:30:15 -02:00
Arnaldo Carvalho de Melo 9490088ae0 [CLASSES]: Use the struct cu backpointer
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 17:33:37 -02:00
Arnaldo Carvalho de Melo 0f5548a55f [CODIFF]: New tool
1. build, save the object
2. change it, build
3. do the diff!

[acme@newtoy net-2.6.20]$ codiff /tmp/ipv6.ko.before /tmp/ipv6.ko.after | head -22
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/af_inet6.c:
 inet6_init              |  +50
 inet6_create            |  -15
 inet6_getname           |  +13
 inet6_sk_rebuild_header |   +5
4 functions changed, 68 bytes added, 15 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/anycast.c:
 ipv6_sock_ac_join |   +7
1 function changed, 7 bytes added

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/ip6_output.c:
 ip6_output2             |  +14
 ip6_sk_dst_lookup       |   -2
 ip6_push_pending_frames |   +5
 ip6_xmit                |   +4
 ip6_forward             |   +1
 ip6_nd_hdr              |  +13
6 functions changed, 37 bytes added, 2 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/addrconf.c:
 ipv6_rcv_saddr_equal |  +16
[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-11 16:31:04 -02:00
Arnaldo Carvalho de Melo e45f877489 [MAKEFILE]: Use -Wall
And fix the warnings generated.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-11 14:15:50 -02:00
Arnaldo Carvalho de Melo 51c81fb099 [CLASSES]: namespace cleanups: just rename the classes__ with cu__
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 15:46:45 -02:00
Arnaldo Carvalho de Melo 633dd33a05 [PAHOLE]: Print cacheline boundaries
Cacheline size defaults to 32, sample output changing the default to 64 bytes:

pahole --cacheline=64 ../../acme/OUTPUT/qemu/net-2.6/net/ipv4/tcp.o inode

/* /pub/scm/linux/kernel/git/acme/net-2.6/include/linux/dcache.h:86 */
struct inode {
        struct hlist_node          i_hash;               /*     0     8 */
        struct list_head           i_list;               /*     8     8 */
        struct list_head           i_sb_list;            /*    16     8 */
        struct list_head           i_dentry;             /*    24     8 */
        long unsigned int          i_ino;                /*    32     4 */
        atomic_t                   i_count;              /*    36     4 */
        umode_t                    i_mode;               /*    40     2 */

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

        unsigned int               i_nlink;              /*    44     4 */
        uid_t                      i_uid;                /*    48     4 */
        gid_t                      i_gid;                /*    52     4 */
        dev_t                      i_rdev;               /*    56     4 */
        loff_t                     i_size;               /*    60     8 */
        struct timespec            i_atime;              /*    68     8 */
        struct timespec            i_mtime;              /*    76     8 */
        struct timespec            i_ctime;              /*    84     8 */
        unsigned int               i_blkbits;            /*    92     4 */
        long unsigned int          i_version;            /*    96     4 */
        blkcnt_t                   i_blocks;             /*   100     4 */
        short unsigned int         i_bytes;              /*   104     2 */
        spinlock_t                 i_lock;               /*   106     0 */

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

        struct mutex               i_mutex;              /*   108    24 */
        /* ---------- cacheline 2 boundary ---------- */
        struct rw_semaphore        i_alloc_sem;          /*   132    12 */
        struct inode_operations *  i_op;                 /*   144     4 */
        const struct file_operations  * i_fop;                /*   148     4 */
        struct super_block *       i_sb;                 /*   152     4 */
        struct file_lock *         i_flock;              /*   156     4 */
        struct address_space *     i_mapping;            /*   160     4 */
        struct address_space       i_data;               /*   164    72 */
        struct list_head           i_devices;            /*   236     8 */
        union                      ;                     /*   244     4 */
        int                        i_cindex;             /*   248     4 */
        __u32                      i_generation;         /*   252     4 */
        long unsigned int          i_dnotify_mask;       /*   256     4 */
        /* ---------- cacheline 4 boundary ---------- */
        struct dnotify_struct *    i_dnotify;            /*   260     4 */
        struct list_head           inotify_watches;      /*   264     8 */
        struct mutex               inotify_mutex;        /*   272    24 */
        long unsigned int          i_state;              /*   296     4 */
        long unsigned int          dirtied_when;         /*   300     4 */
        unsigned int               i_flags;              /*   304     4 */
        atomic_t                   i_writecount;         /*   308     4 */
        void *                     i_private;            /*   312     4 */
}; /* size: 316, sum members: 312, holes: 2, sum holes: 4 */

Has to be improved to show the other cacheline boundaries, that may be buried
into a included struct or union.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 15:34:54 -02:00
Arnaldo Carvalho de Melo 34b5f29576 [PAHOLE]: Add basic support for typedefs
[acme@newtoy guinea_pig-2.6]$ pahole mm/slab.o kmem_cache_t | head -6
/* include/linux/slab.h:12 */
struct kmem_cache {
        struct array_cache *array[8];    /*  0  32 */
        unsigned int        batchcount;  /* 32   4 */
        unsigned int        limit;       /* 36   4 */
        unsigned int        shared;      /* 40   4 */
[acme@newtoy guinea_pig-2.6]$ pahole --sizes fs/ext3/built-in.o | grep typedef | head -5
typedef pgd_t:struct(): 4 0
typedef pgprot_t:struct(): 4 0
typedef cpumask_t:struct(): 4 0
typedef mm_segment_t:struct(): 4 0
typedef raw_spinlock_t:struct(): 4 0
[acme@newtoy guinea_pig-2.6]$ pahole fs/ext3/built-in.o pgd_t
/* include/asm/page.h:57 */
struct  {
        long unsigned int          pgd;                  /*     0     4 */
}; /* size: 4 */

[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 02:17:19 -02:00
Arnaldo Carvalho de Melo 1ec7e4aa18 [PAHOLE]: Dwarf trivia: show number of files that include a struct
[acme@newtoy guinea_pig-2.6]$ pahole -t ../../acme/OUTPUT/qemu/net-2.6/vmlinux | sort -k2 -nr | head -5
list_head                          468
__wait_queue_head                  466
timespec                           466
rw_semaphore                       466
plist_head                         466
[acme@newtoy guinea_pig-2.6]$

Which leads to another, more non-trivia question, what if a struct
definition is included but there are no references to this function?

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 20:24:37 -03:00
Arnaldo Carvalho de Melo 6b82eae556 [PAHOLE]: getopt support
With some of the options in pfunct, such as:

[acme@newtoy guinea_pig-2.6]$ pahole --sizes kernel/sched.o | sort -k2 -nr | head -5
pglist_data: 3456
task_struct: 2704
rq: 2480
mmu_gather: 2040
zone: 1664
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-02 13:47:37 -03:00
Arnaldo Carvalho de Melo 5aaca80de6 [CLASSES]: Rework the find_by routines
So that we can find all the cus for some specific class
(cus__find_class_by_name), or traverse all the CUs (cus__for_each_cu),
etc.

Now we don't look at just the first CU in multi-CU files (vmlinux, etc).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-31 17:23:16 -03:00
Arnaldo Carvalho de Melo 0ca9826e36 Introduce struct cu, i.e. a per compilation unit struct that holds the list of
types for each CU, for now when working on multi-CU files (vmlinux, any binary
with more than one object file linked) we look only at the first CU when
looking for a specific class or function name, this will be fixed in the
upcoming csets, but doesn't affect the case when we don't specify a class or
function name, where all the CU's are traversed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-31 16:12:42 -03:00
Arnaldo Carvalho de Melo 35e87417f9 Move the classes methods out of pahole.c and into classes.c,
that will be used by other new dwarves 8)

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 18:22:42 -03:00
Arnaldo Carvalho de Melo f4cc126c11 Separate finding the holes from printing the class, so that we are able to
print just the structs with holes, that indeed is what we do now if no class
name is passed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 18:10:47 -03:00
Arnaldo Carvalho de Melo 01f021b2a7 Prefix the functions that create the classes list with "classes__",
in preparation to moving them to a library.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 14:16:29 -03:00
Arnaldo Carvalho de Melo 06672633cb Move the top level dwarf traversal of the CUs to a new function,
classes__load().

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 14:08:46 -03:00
Arnaldo Carvalho de Melo 13ec307479 Move the global 'bf' buffer to the only place still using it.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 13:51:34 -03:00
Arnaldo Carvalho de Melo 3593eb45a6 Move the class and class_member structs to a new header file,
classes.h.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 13:45:59 -03:00
Arnaldo Carvalho de Melo 5c3d14ac09 Renane class__print to class__print_struct and make class__print
call it if the class ->tag is DW_TAG_structure_type, and do a basic
print for the other tags.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 13:37:20 -03:00
Arnaldo Carvalho de Melo 7f5ce05961 Initialize struct class->name in the constructor if no name was
informed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 13:16:59 -03:00
Arnaldo Carvalho de Melo 23cc5e41cb Get the file and line where the classes were declared and use it
in the printout.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 09:52:08 -03:00
Arnaldo Carvalho de Melo 98295e3fd2 Improve attr_numeric to handle more form types, convering DW_AT_type,
etc, so ditch attr_type().

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-27 17:51:18 -03:00
Arnaldo Carvalho de Melo 7dbb993d8b Rename attr_unsigned to attr_numeric, simplifying it to not require a
Dwarf_Attribute to work on, as we just return a integer and it handles more
than just unsigned ints.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-27 15:04:18 -03:00
Arnaldo Carvalho de Melo 0c707643d7 Print the number of holes
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-26 03:31:58 -03:00
Arnaldo Carvalho de Melo d36e7147f0 Stop using libdwarf from SGI, use the one in elfutils instead, the code got
much cleaner and now uses what seems to be a better maintained DWARF library
that hopefully works well on 64bit platforms, well see.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-26 03:06:32 -03:00
Arnaldo Carvalho de Melo e5e7c6fc8b Initialize nr_entries in class__new
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 15:21:34 -03:00
Arnaldo Carvalho de Melo 17025a38f2 Handle multi CU (Compile Unit) files, like vmlinux :-)
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 14:33:59 -03:00
Arnaldo Carvalho de Melo aac0259cc0 Use return for consistency in main.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 14:03:44 -03:00
Arnaldo Carvalho de Melo 3acc236241 Support void pointers, i.e. DW_TAG_pointer_type with no DW_AT_type.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 13:47:54 -03:00
Arnaldo Carvalho de Melo 4881c2f0d2 Add a .gitignore file
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 13:32:07 -03:00
Arnaldo Carvalho de Melo 134120b796 Ditch the program_name variable, use "pahole" directly
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 13:29:38 -03:00
Arnaldo Carvalho de Melo e01a32fddc Remove leftover check_error variable.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 13:20:18 -03:00
Arnaldo Carvalho de Melo 2338691b42 Show the sum of the members sizeof only if there are holes, and if so print the
sum of all holes too.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 13:18:43 -03:00
Arnaldo Carvalho de Melo 031b291d9a Add a copyright notice.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 12:49:47 -03:00
Arnaldo Carvalho de Melo 51a8d81527 bitfields, ugh, if you have, say:
struct foo {
        char    c:1;
        int     b:1;
        short   a:1;
};

the first byte_size for the first member (c) will be 1, as the "type"
is char, but the compiler combines all of them into a single 4 byte
bitfield, and the '4' only appear when the bit field has type int, in
the above case on the second member.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 12:46:26 -03:00
Arnaldo Carvalho de Melo 96ef1165ae Add support for enum printing.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 12:42:53 -03:00
Arnaldo Carvalho de Melo a4e260fc1a Grr, another fix for bitfields, this time for a sequence of
bitfields, i.e. the offset changes from one bitfield to another.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 12:14:27 -03:00
Arnaldo Carvalho de Melo e45d94f9de Fix bitfield accounting, as I was assuming that the first field would be
at the 0 offset, but its not, so just look if the last member was in a
bitfield.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 12:01:18 -03:00
Arnaldo Carvalho de Melo d4c95e9b49 Remove more dead code, we don't use the srcfile table.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 02:55:36 -03:00
Arnaldo Carvalho de Melo 9b15e948e4 Remove dead code
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 02:42:57 -03:00
Arnaldo Carvalho de Melo 23971435ad Fix the struct declaration case.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 02:37:21 -03:00
Arnaldo Carvalho de Melo e748ac69c3 Print the diff when the sum of the member sizeofs + the sum of the
holes is not equal to the size of the struct:

struct task_struct {
<SNIP>
}; /* sizeof struct: 1312, sum sizeof members: 1279 */

/* BRAIN FART ALERT! 1312 != 1279 + 25(holes), diff = 8 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 01:18:15 -03:00
Arnaldo Carvalho de Melo 99dd25f7f6 More output layout changes, this time for the elusive task_struct
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 01:04:26 -03:00
Arnaldo Carvalho de Melo f517a01b6e Support DW_TAG_volatile_type and DW_TAG_const_type.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 00:54:57 -03:00
Arnaldo Carvalho de Melo 668aec0284 Cosmetic, output layout tidyup to have struct sock output perfect,
its our supermodel 8)

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 00:40:06 -03:00
Arnaldo Carvalho de Melo 034dafb614 Handle the case where DW_TAG_subroutine_type has no DW_AT_type, meaning
it doesn't have a return value, i.e. it "returns" void.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 00:27:29 -03:00
Arnaldo Carvalho de Melo 3e4d70ad47 Support bitfields, still not checking if there are bits available at
the end of it.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-25 00:18:05 -03:00
Arnaldo Carvalho de Melo d07bbf65fc Just some output layout changes.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-24 23:28:37 -03:00
Arnaldo Carvalho de Melo cc701e54a3 Check if the sum of the struct member sizeofs plus the sum of all the holes
found is equal to the sizeof of the structure and emit a "BRAIN FART ALERT!" if
this assertion fails, good news is that no such brain farts ocurred so far :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-24 23:09:46 -03:00
Arnaldo Carvalho de Melo 00a86e1267 For now don't print the "nameless structs", aka "typedef struct { } foo".
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-24 22:45:43 -03:00
Arnaldo Carvalho de Melo 1bbfd30eea Basic function pointer support, parameter list will come next, using a struct
class instance for the DW_TAG_subroutine_type tag and class->members for the
list of DW_TAG_formal_parameter, if any.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-24 22:43:33 -03:00
Arnaldo Carvalho de Melo 7246a223a2 Add support for arrays
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-24 22:02:51 -03:00
Arnaldo Carvalho de Melo 038d806873 Repository creation.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-24 20:42:39 -03:00