Commit Graph

128 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo de9aa81358 [PAHOLE]: Consolidate conf_fprintf code
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 17:18:32 -03:00
Arnaldo Carvalho de Melo 80454cb7fd [PAHOLE]: Set show_decl_info if --verbose is passed
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 12:47:11 -03:00
Arnaldo Carvalho de Melo 9bf0fda9b0 [LIB]: Introduce struct namespace
For now its just the direct ancestor of struct type. But it will exists by
itself, to represent the DW_TAG_namespace DWARF tag, that is how the C++
'namespace' (and other languages too, heck, I'd love to get my hands on a
binary with DWARF info built from, say, ADA source code, objectiveC... COBOL!
:-P).

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 12:16:59 -03:00
Arnaldo Carvalho de Melo 230d9310aa [LIB]: Introduce type__name()
This is in preparation for the introduction of struct namespace, that will be
struct type ancestor.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 11:56:12 -03:00
Arnaldo Carvalho de Melo 3377190195 [PAHOLE]: Introduce --separator/-t
[acme@filo pahole]$ pahole -t, --packable examples/ipv6.ko.debug.x86-64 | sort -t, -k2 -n | tail
inode,1008,1000,8
hh_cache,256,128,128
proto,8512,8504,8
super_block,1184,1168,16
task_struct,3776,3704,72
module,8832,8800,32
pglist_data,10752,10744,8
zone,1536,1352,184
net_device,1664,1208,456
softnet_data,1920,1792,128
[acme@filo pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-23 16:26:39 -03:00
Arnaldo Carvalho de Melo 776f5a6418 [PAHOLE]: Use a common separator in the formatters
For now its a tab, will be configurable in the next cset.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-23 16:15:21 -03:00
Arnaldo Carvalho de Melo 7401af38db [LIB]: Introduce class__has_hole_ge()
That returns if the class has a hole greater or equal to the size specified.

Pahole now has a --hole_size_ge command line option to use it.

Example on a linux kernel built for x86_64 where we list the structs that have
holes bigger than 32 bytes, that provides an approximation of structs with
____cacheline_aligned_in_smp annotated members:

[acme@filo pahole]$ pahole --hole_size_ge 32 examples/vmlinux-x86_64
inet_hashinfo
rcu_ctrlblk
hh_cache
net_device
files_struct
module
zone

For instance, look at struct zone clever use of such construct:

_pad1_ is defined with ZONE_PADDING(_pad1_), that is:

/* <40e> /home/acme/git/net-2.6.22/include/linux/mmzone.h:179 */
struct zone {
	long unsigned int          pages_min;            /*     0     8 */
	long unsigned int          pages_low;            /*     8     8 */
	long unsigned int          pages_high;           /*    16     8 */
	long unsigned int          lowmem_reserve[3];    /*    24    24 */
	int                        node;                 /*    48     4 */

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

	long unsigned int          min_unmapped_pages;   /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	long unsigned int          min_slab_pages;       /*    64     8 */
	struct per_cpu_pageset *   pageset[255];         /*    72  2040 */
	/* --- cacheline 33 boundary (2112 bytes) --- */
	spinlock_t                 lock;                 /*  2112     4 */

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

	struct free_area           free_area[11];        /*  2120   264 */

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

	/* --- cacheline 38 boundary (2432 bytes) --- */
	struct zone_padding        _pad1_;               /*  2432     0 */
	spinlock_t                 lru_lock;             /*  2432     4 */

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

	struct list_head           active_list;          /*  2440    16 */
	struct list_head           inactive_list;        /*  2456    16 */
	long unsigned int          nr_scan_active;       /*  2472     8 */
	long unsigned int          nr_scan_inactive;     /*  2480     8 */
	long unsigned int          pages_scanned;        /*  2488     8 */
	/* --- cacheline 39 boundary (2496 bytes) --- */
	int                        all_unreclaimable;    /*  2496     4 */
	atomic_t                   reclaim_in_progress;  /*  2500     4 */
	atomic_long_t              vm_stat[20];          /*  2504   160 */
	/* --- cacheline 41 boundary (2624 bytes) was 40 bytes ago --- */
	int                        prev_priority;        /*  2664     4 */

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

	/* --- cacheline 42 boundary (2688 bytes) --- */
	struct zone_padding        _pad2_;               /*  2688     0 */
	wait_queue_head_t *        wait_table;           /*  2688     8 */
	long unsigned int          wait_table_hash_nr_entries; /*  2696     8 */
	long unsigned int          wait_table_bits;      /*  2704     8 */
	struct pglist_data *       zone_pgdat;           /*  2712     8 */
	long unsigned int          zone_start_pfn;       /*  2720     8 */
	long unsigned int          spanned_pages;        /*  2728     8 */
	long unsigned int          present_pages;        /*  2736     8 */
	const char  *              name;                 /*  2744     8 */
	/* --- cacheline 43 boundary (2752 bytes) --- */
}; /* size: 2752, cachelines: 43 */
   /* sum members: 2672, holes: 5, sum holes: 80 */
   /* definitions: 933 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-11 13:32:53 -03:00
Arnaldo Carvalho de Melo f314f4f896 [PAHOLE]: Introduce --recursive
For now only affects the --contains output.

Example showing the structs that include struct list_head in a linux kernel module:

[acme@filo pahole]$ pahole --recursive --contains list_head examples/ipv6.ko.debug.x86-64
inet_protosw
proto
sock_iocb
key_type
msg_queue
msg_msg
nf_hook_ops
softnet_data
net_device
  softnet_data
dma_device
dma_client
dma_chan
class_device
  net_device
    softnet_data
  dma_chan
class
klist_node
  device_driver
  device
klist
  device_driver
  bus_type
  device
file_system_type
nfs_lock_info
file_lock
block_device
address_space
  inode
dquot
mem_dqinfo
super_block
inode
signal_struct
page
kioctx
file
kiocb
work_struct
  delayed_work
    kioctx
timer_list
  ifmcaddr6
  inet6_dev
  inet6_ifaddr
  neigh_table
  neighbour
  net_device
    softnet_data
  sock
    inet_sock
  delayed_work
    kioctx
plist_head
  task_struct
sigpending
  signal_struct
  task_struct
user_struct
device
dev_pm_info
  device
mutex_waiter
mutex
  seq_file
  block_device
  quota_info
    super_block
  dquot
  super_block
  inode
zone
per_cpu_pages
free_area
kset
  bus_type
  subsystem
    class
    bus_type
__wait_queue_head
__wait_queue
rw_semaphore
  quota_info
    super_block
  super_block
  inode
  key
  blocking_notifier_head
    bus_type
  subsystem
    class
    bus_type
  mm_struct
dentry
vm_area_struct
kobject
  class_device
    net_device
      softnet_data
    dma_chan
  device_driver
  module_kobject
    module
  device
  kset
    bus_type
    subsystem
      class
      bus_type
lock_class
module
mm_struct
task_struct

Handling in multi-cu objects is not very precise, as the same struct has
different dwarf offsets (id) in each CU. A mitigation for this problem will be
provided with the --cu_list and --cu_name upcoming options, where one will be
able to get a list of the object files in a, for instance, linux kernel .ko
module and also to specify a cu name to be the only to be considered when
processing multi-cu files (again, such as .ko linux kernel modules).

This ends up being also useful to generate a reverse class hierarchy :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-10 19:11:51 -03:00
Arnaldo Carvalho de Melo eaf77f1e5a [LIB]: Introduce type__nr_members_of_type
First user is pahole, that now has a --contains CLASS_NAME option, that will
show which classes contains CLASS_NAME, i.e.:

struct foo {
	struct bar baz;
	int i;
};

on an object file called with '--contains bar' will produce:

foo

if --verbose is used it will tell the number of CLASS_NAME members, so, in the
above example:

foo:1

Next thing will be a --recursive flag, that will show all the structs that
contains CLASS_NAME and the ones that contains the ones which contains and...
:-)

Useful to evaluate the impact that increasing or decreasing the size of some
important struct will have on the whole project that uses the struct.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-10 15:28:00 -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
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 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 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 bd4e74162c [PAHOLE]: Handle typedef'ed anonymous structs in --reorganize
In fact in any place that uses -a.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-04 14:44:56 -03:00
Arnaldo Carvalho de Melo e8926e6bc0 [PAHOLE]: Make -x work with anonymous structs
Just look for a typedef that points to the anonymous struct, if it matches
the -x prefix, exclude it.

[acme@filo pahole]$ pahole -PAae examples/anonymous_struct_typedef
/home/acme/git/pahole/examples/anonymous_struct_typedef.c:12    12     8     4
teste_t                             12     8     4
[acme@filo pahole]$ pahole -x teste -PAae examples/anonymous_struct_typedef
/home/acme/git/pahole/examples/anonymous_struct_typedef.c:12    12     8     4
[acme@filo pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-04 14:21:41 -03:00
Arnaldo Carvalho de Melo 6ddeeb3b90 [PAHOLE]: For real anonymous structs print file:line where was defined
For example, the inner, anonymous struct here:

struct {
        int d;
        int z;
        struct {
                short a;
                int  b;
                char  c;
        };
} biba = { .d = 2, };

[acme@filo pahole]$ pahole --packable --anon_include --nested_anon_include -e examples/anonymous_struct_typedef
/home/acme/git/pahole/examples/anonymous_struct_typedef.c:12    12     8     4
teste_t                             12     8     4
[acme@filo pahole]$

The long options can be shortened to -PAae :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-04 14:11:40 -03:00
Arnaldo Carvalho de Melo a62ebae88b [PAHOLE]: Look for a typedef pointing to anonymous structs in --packable
Problem reported by Diego 'Flameeyes' Pettenò. Thanks!

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-04 13:59:54 -03:00
Arnaldo Carvalho de Melo 786ef46234 [TOOLS]: Give "-e FILE", the basic way of using most tools, more visibility
Suggested by: Jeff Muizelaar.

And it was wrong in the sense that the help was like:

--executable|-e FILE <SNIP lots of other options> FILE

So now its a bit redundant, like:

--executable|-e FILE <SNIP lots of other options> -e FILE

But as this is the most common usage pattern, give it more visibility.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-04 08:29:21 -03:00
Arnaldo Carvalho de Melo f3c4f527f7 [PAHOLE]: Rework the output of pahole --packable
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-03 09:11:06 -03:00
Arnaldo Carvalho de Melo 1ec66565a1 [PAHOLE]: Change the output of --packable to show orig size, new size and the diff
[acme@filo pahole]$ pahole --packable -e examples/dccp.ko.x86_64 | sort -k5 -nr | head -5
net_device: 1664 -> 1448: 216
module: 16960 -> 16848: 112
hh_cache: 192 -> 80: 112
zone: 2752 -> 2672: 80
softnet_data: 1792 -> 1728: 64
[acme@filo pahole]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-02 10:12:09 -03:00
Arnaldo Carvalho de Melo 57ff4ea736 [PAHOLE] In --packable show just the savings when not in verbose mode
Example:

[acme@filo pahole]$ pahole -P -e examples/dccp.ko.x86_64 | sort -k2 -nr | head -20
hh_cache: 112
softnet_data: 64
task_struct: 56
net_device: 56
module: 32
inet_hashinfo: 32
zone: 24
device: 24
thread_struct: 16
super_block: 16
mm_struct: 16
dccp_sock: 16
block_device: 16
socket: 8
signal_struct: 8
sighand_struct: 8
rt6_info: 8
proto: 8
pglist_data: 8
nf_bridge_info: 8
[acme@filo pahole]$

Some may well be false positives or gcc DWARF emitter artifacts, checking...

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 10:03:04 -03:00
Arnaldo Carvalho de Melo 57fce1596b [PAHOLE]: Use class__reorganize in class__packable
A more brute force approach: create a clone, reorganize it, if the resulting
size is less than the cloned class, it is packable.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-04-01 09:31:35 -03:00
Arnaldo Carvalho de Melo 61609b4364 [PAHOLE]: Use cus__loadfl, i.e. libdwfl
Now we have:

[acme@filo pahole]$ pahole --help
Usage: pahole [OPTION...] [FILE] {[CLASS]}

  -a, --anon_include         include anonymous classes
  -A, --nested_anon_include  include nested (inside other structs) anonymous
                             classes
  -B, --bit_holes=NR_HOLES   Show only structs at least NR_HOLES bit holes
  -c, --cacheline_size=SIZE  set cacheline size to SIZE
  -D, --decl_exclude=PREFIX  exclude classes declared in files with PREFIX
  -E, --expand_types         expand class members
  -H, --holes=NR_HOLES       show only structs at least NR_HOLES holes
  -m, --nr_methods           show number of methods
  -n, --nr_members           show number of members
  -N, --class_name_len       show size of classes
  -P, --packable             show only structs that has holes that can be
                             packed
  -R, --reorganize           reorg struct trying to kill holes
  -s, --sizes                show size of classes
  -S, --show_reorg_steps     show the struct layout at each reorganization step

  -t, --nr_definitions       show how many times struct was defined
  -V, --verbose              be verbose
  -x, --exclude=PREFIX       exclude PREFIXed classes
  -X, --cu_exclude=PREFIX    exclude PREFIXed compilation units

 Input Selection:
      --debuginfo-path=PATH  Search path for separate debuginfo files
  -e, --executable=FILE      Find addresses in FILE
  -k, --kernel               Find addresses in the running kernel
  -K, --offline-kernel[=RELEASE]   Kernel with all modules
  -M, --linux-process-map=FILE   Find addresses in files mapped as read from
                             FILE in Linux /proc/PID/maps format
  -p, --pid=PID              Find addresses in files mapped into process PID

  -?, --help                 Give this help list
      --usage                Give a short usage message

Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-30 13:25:51 -03:00
Arnaldo Carvalho de Melo 5f1ba48d5e [PAHOLE]: Convert to argp
Paving the way to move from libdw to libdwfl.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-03-30 10:07:01 -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 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 f6888f029a [PAHOLE]: Honor --expand_types when the class is specified too
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-11 00:55:54 -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 f221465b68 [PAHOLE]: Introduce --show_reorg_steps
To show how the struct looks like after each member reorganization, should help
with debugging when something looks like a bad decision.

An example is provided at:

http://oops.ghostprotocols.net:81/acme/dwarves/pahole--reorganize--verbose--show_reorg_steps_example.txt

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-02-01 12:27:43 -02:00
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