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>
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>
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>
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>
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>
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>
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>
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>
So that we don't have to do all the code emission inside ctracer.c, add
a Makefile too that uses the kernel rpm files shipped by your distro to
easily build a module for your workstation, see README.ctracer, that was
updated to describe the steps needed to have ctracer running in your
machine.
Now to polish the relay code.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
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>
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>
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>
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>
I should have done this since day one, but was lazy, now somebody complained
on my blog and I thought it was time to bite this bullet, hopefully will be
helpful for people interested in helping improve these tools, as the comments
are useful for understanding the other dwarves too.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
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>
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>