Commit Graph

359 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo
ef45383d22 [LIB] lexblock: Show the lexblock low_pc info as offsets from the function where they appear
__wsum csum_partial_copy_to_user(const void  * src, void * dst, int len, __wsum isum, int * errp);
{ /* low_pc=0xffffffff8128ed37 */
        { /* csum_partial_copy_to_user+0x11 */
                long unsigned int flag;                               //    76
                long unsigned int roksum;                             //    76
                current_thread_info(void); /* size=9, low_pc=0xffffffff8128ed4b */ //    76
        } /* lexblock size=32 */
        { /* csum_partial_copy_to_user+0x49 */
                __u16 val16;                                          //    83
                add32_with_carry(unsigned int a,
                                unsigned int b); /* size=8, low_pc=0xffffffff8128ed83 */ //    84
                { /* csum_partial_copy_to_user+0x54 */
                        int __pu_err;                                 //    86
                } /* lexblock size=5 */
        } /* lexblock size=35 */
}/* size: 149 */
/* definitions: 1 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-31 14:00:44 -03:00
Arnaldo Carvalho de Melo
86bf6e680b [LIB] lexblock: make lexblock__fprintf show non zero high/low pcs
pfunct -TVi on a x86_64 vmlinux:

__wsum csum_partial_copy_to_user(const void  * src, void * dst, int len, __wsum isum, int * errp);
{ /* low_pc=0xffffffff8128ed37 */
        { /* low_pc=0xffffffff8128ed48 */
                long unsigned int flag;                               //    76
                long unsigned int roksum;                             //    76
                current_thread_info(void); /* size=9, low_pc=0xffffffff8128ed4b */ //    76
        } /* high_pc=0xffffffff8128ed68 */
        { /* low_pc=0xffffffff8128ed80 */
                __u16 val16;                                          //    83
                add32_with_carry(unsigned int a,
                                unsigned int b); /* size=8, low_pc=0xffffffff8128ed83 */ //    84
                { /* low_pc=0xffffffff8128ed8b */
                        int __pu_err;                                 //    86
                } /* high_pc=0xffffffff8128ed90 */
        } /* high_pc=0xffffffff8128eda3 */
} /* high_pc=0xffffffff8128edcc *//* size: 149 */

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-31 13:25:22 -03:00
Arnaldo Carvalho de Melo
f4f8e0e16d [LIB]: First stab at supporting vtables
Will just print the vtable as a comment on classes with vtables.

But we have to support multiple vtables when multiple inheritance exists.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-08 20:57:23 -03:00
Arnaldo Carvalho de Melo
9c92fc59fb [LIB]: Add vtable_entry to struct function
To support the DW_AT_vtable_elem_location attribute.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-08 20:35:49 -03:00
Arnaldo Carvalho de Melo
c7f3b5d812 [LIB]: attr_offset should receive the attr name to search for
So that we can also look for offset expressions other than DW_AT_data_member_location.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-08 20:33:56 -03:00
Arnaldo Carvalho de Melo
0883a936d5 [LIB]: Support DW_OP_constu in dwarf_expr
So that we can handle DW_AT_vtable_elem_location, that is also an offset expression.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-08 20:32:34 -03:00
Arnaldo Carvalho de Melo
ce516fb0cf [LIB]: Support DW_AT_MIPS_linkage_name
Another C++ specific case:

-       class TypeTemplate ByName(const string  &, size_t);
+       class TypeTemplate ByName(const string  &, size_t); /* linkage=_ZN4ROOT6Reflex12TypeTemplate6ByNameERKSsj */

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-08 19:47:26 -03:00
Arnaldo Carvalho de Melo
d6471b435b [LIB]: Make function__fprintf handle the member virtuality
More C++ support. Now we print "virtual" before DW_TAG_subprogram DW_TAG_member
tags that have a DW_AT_virtuality attribute of and DW_VIRTUALITY_pure_virtual or
DW_VIRTUALITY_virtual and " = 0" after the DW_VIRTUALITY_pure_virtual ones.

vtables are next.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-08 14:55:15 -03:00
Arnaldo Carvalho de Melo
84fac64313 [LIB]: Honor conf.suppress_comments in one more case
class__fprintf_cacheline_boundary should only be called if
conf_suppress_comments is not set.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-07 14:48:40 -03:00
Arnaldo Carvalho de Melo
39a6eba82a [LIB]: Introduce suppress_offset_comment in conf_fprintf
And use it when expandind pointer types (using --expand_pointer).

This has to be done because the offset comments make no sense when expanding a
pointer.

Will be used as well in pahole --quiet.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-07 14:41:41 -03:00
Arnaldo Carvalho de Melo
d653039ef4 [LIB]: Add conf->expand_pointers
So that we can expand pointer types, useful for ABI signature checking. And to
fully browse a type, when using --expand_types is also of interest.

I have yet to disable printing the offsets when expanding pointers, where the
information is not useful at all, for now just ignore it, it gets back to a
sane state in the next field, after the pointer type expansion.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-04 20:36:28 -03:00
Arnaldo Carvalho de Melo
96fe1bf804 [LIB]: Reorganize type__fprintf to have just one exit point
Will be used by the upcoming expand_pointer algorithm.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-01 20:46:59 -03:00
Arnaldo Carvalho de Melo
59099b3481 [LIB]: Make array_type__fprintf use type__fprintf
This way it can handle arrays of anonymous structs.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-07-01 20:04:19 -03:00
Arnaldo Carvalho de Melo
0b3969bdb4 [LIB]: Introduce conf_fprintf.suppress_comments
pahole will use it in the --quiet mode.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-06-22 16:51:31 -03:00
Arnaldo Carvalho de Melo
949e8c4f14 [PAHOLE]: Implement --quiet
For now it just suppresses the struct statistics at the end of the output, but
will also suppress the comments about holes.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-06-22 16:43:29 -03:00
Arnaldo Carvalho de Melo
59e957f8f9 [LIB]: Introduce {function,ftype}__for_each_parameter
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-06-12 15:01:23 -03:00
Arnaldo Carvalho de Melo
9486197977 [LIB]: Introduce tag__is_{enumeration,union,namespace}
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-31 02:21:36 -03:00
Arnaldo Carvalho de Melo
cf124f1636 [LIB]: Introduce tag__is_struct() for a common idiom
And also to get this less, ho-hum, DWARF specific.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-31 01:53:01 -03:00
Arnaldo Carvalho de Melo
48a1d89ec0 [LIB]: Introduce conf_fprintf.no_semicolon
To indicate wheter the semicolon should be supressed. Useful for
prototype/function emission, etc.

Also move the struct stats to be inside its body, to simplify tag__fprintf,
that now looks at conf.no_semicolon after calling the tag type specific
__fprintf method.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-31 01:39:44 -03:00
Arnaldo Carvalho de Melo
281955d800 [LIB]: Add the show_only_data_members field to struct conf_fprintf
So that tools can specify if they are interested in printing just the members
that use space in the class layout (DW_TAG_inheritance, DW_TAG_member) and not
things like constructors, private type definitions, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-30 11:36:54 -03:00
Arnaldo Carvalho de Melo
1554f95d81 [LIB]: Check for unhandled DW_OP_ operations in the DW_AT_data_member_location attr
So far we only handle DW_OP_plus_uconst, the simplest of them all, but now
'public virtual' base classes are appearing in these tools radar, so, to make
it clear that we don't support it spit a warning message to stderr and return
UINT64_MAX so that in the report it is clearly seen. C++ support still needs
more work, simple as that :)

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-29 18:11:45 -03:00
Arnaldo Carvalho de Melo
493ce2132f [LIB]: Look at inheritance entries in class__find_holes
We need to, if not when there is no data members the padding will be
miscalculated.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-29 14:24:50 -03:00
Arnaldo Carvalho de Melo
911375f5c5 [LIB]: Introduce type__for_each_data_member
So that we traverse just the data members, mostly in the reorganize code, where
we can't care less where is that the compiler put the base classes in the
layout since we can't influence how the compiler does this, it has only to
respect the layout we specify for the data members.

Well, it may well be the case that the order of the ancestor classes in the
class declaration can influence this, but I haven't checked.

Yes, another C++ism :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-29 14:06:33 -03:00
Arnaldo Carvalho de Melo
3b869e96f8 [LIB]: list__find_tag_by_id should look in union's namespace too
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-29 12:41:25 -03:00
Arnaldo Carvalho de Melo
aa91264ea0 [LIB]: cu__find_parameter_by_id should look inside namespaces too
This is simplified by introducing list__find_tag_by_id. I guess in the end the
right thing is to use a hashtable to find the ids. Trying to have specialized
find_foo_by_id functions instead of having just one that traverses _all_ the
tags is becoming less of a performance advantage as struct class now has
namespaces, i.e. functions can be inside structs and to find abstract_origin,
specification, etc references we have to traverse most of the tree anyway...

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-26 17:53:40 -03:00
Arnaldo Carvalho de Melo
5824b679d5 [LIB]: Make cu__find_parameter_by_id return a struct tag
For consistency with the other find_foo_by_id routines.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-26 16:15:27 -03:00
Arnaldo Carvalho de Melo
904b882c62 [LIB]: Fix breakage introduced when supporting DW_AT_specification in structs
Heck, anonymous structs are nothing new, things like:

typedef struct {
	int bar;
} baz;

Are ugly, but valid. So if ->name is NULL and ->specification is 0, its an
anonymous struct, don't go looking for dwarf offset 0, that is "void", not
something a DW_AT_specification is supposed to point to 8)

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-26 15:47:39 -03:00
Arnaldo Carvalho de Melo
c15d8d700c [LIB]: Introduce tag__id_not_found
tag__type_not_found was incorrectly being used for cases where we were
searching things like abstract_origin and specification, not tag->type, so add
this variant, make tag__type_not_found use id and fix the callers.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-26 15:40:52 -03:00
Arnaldo Carvalho de Melo
fdcd10fa3f [LIB]: Handle void in typedef__fprintf
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-26 14:50:51 -03:00
Arnaldo Carvalho de Melo
90d6202e3c [LIB]: Support DW_TAG_imported_declaration
Basic support, as according to the DWARF3 standard there are other cases that
we don't support yet, such as "using ::foo" with an alias, i.e. in the
namespace that is importing the imported declaration is aliased to some other
name.

But for the test cases, common case, its enough.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-26 12:39:16 -03:00
Arnaldo Carvalho de Melo
33b92cbd4f [LIB]: Support DW_TAG_imported_module
The "using namespace" line in:

namespace __gnu_debug {
	using namespace __gnu_debug_def;
};

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-26 10:54:27 -03:00
Arnaldo Carvalho de Melo
b776154f74 [LIB]: Comment the DW_TAG_inheritance tags in class__fprintf output
So that it looks more like a compilable representation.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-25 21:45:30 -03:00
Arnaldo Carvalho de Melo
9d6ac7737b [LIB]: Print class member accessibility in class__fprintf
Now we see the "private:\n" etc, everytime the accessibility is changed from
one member to the next.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-25 17:33:49 -03:00
Arnaldo Carvalho de Melo
ed927ac7cd [LIB]: Introduce tag__accessibility()
Helper to check if the tag has accessibility info, returning one of
"protected", "private", "public" or NULL if there is no accessibility info.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-25 17:02:05 -03:00
Arnaldo Carvalho de Melo
eba595f958 [LIB]: Add accessibility and virtuality members to struct function
Will be used in the following csets, where we'll print the accessibility
info in C++ classes.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-25 16:42:49 -03:00
Arnaldo Carvalho de Melo
9e48067e92 [LIB]: Some stopgap hacks on DW_TAG_inheritance + DW_AT_virtuality == DW_VIRTUALITY_virtual
The offsets doesn't make sense, /me lazy right now to look at untangling the
expressions in the DW_AT_data_member_location.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 19:11:53 -03:00
Arnaldo Carvalho de Melo
e59b1ebb05 [LIB]: Support DW_AT_specification in DW_TAG_structure_type tags
C++ uses this, and to cache the result of the lookup at type__name time we need
to pass the cu to class__name and type__name. Big fallout because of that :-\

But now the output is mucho embelished by the humongous strings representing
C++ templates.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 18:45:34 -03:00
Arnaldo Carvalho de Melo
ad24e0a00c [LIB]: Introduce cus__find_tag_by_id
Using it in the --dwarf_offset/-O new pahole command line option, useful in
debugging. Prints the tag in the dwarf offset supplied.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 17:41:16 -03:00
Arnaldo Carvalho de Melo
106a78fd08 [LIB]: Print DW_TAG_inheritance together with DW_TAG_member entries
In class__fprintf, at least this can help till we get proper DW_TAG_inheritance
layout printing, that is right now blocked by lack of knowledge about
DW_AT_data_member_location DWARF expression parsing for non const expressions.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 14:11:33 -03:00
Arnaldo Carvalho de Melo
5463bc5419 [LIB]: Support DW_AT_accessibility and DW_AT_virtuality
So that in DW_TAG_inheritance we can should "virtual", "virtual public", etc.

This has yet to be supported for normal class members, constructors, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 13:57:08 -03:00
Arnaldo Carvalho de Melo
25c2b7a095 [LIB]: Handle DW_TAG_inheritance in class__fprintf
Printing things like:

class foo : bar, baz, bada {
<SNIP>
};

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 13:38:13 -03:00
Arnaldo Carvalho de Melo
ec2c921b05 [LIB]: Introduce namespace__fprintf
Use pdwtags, that prints all the tags, pahole has to be changed to traverse
namespaces looking for structs.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 13:18:38 -03:00
Arnaldo Carvalho de Melo
37204266b1 [LIB]: Allow specifying in conf_fprintf if the decl info is to be printed
By default it is not, was getting too much in the way with the namespace support.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 12:45:45 -03:00
Arnaldo Carvalho de Melo
8562640b58 [LIB]: Rename type__find_tag_by_id to namespace__find_tag_by_id
Go down the rabbit hole baby, oops, the namespace hole that is. Now we find
types inside namespaces. Off to implement namespace__fprintf so that we can see
more brunnetes and blondes out of the DWARF encoding 8)

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 12:40:43 -03:00
Arnaldo Carvalho de Melo
32cad958cd [LIB]: Initial support for namespace
We still don't search for tags inside namespaces, next cset...

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 12:30:33 -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
2b480348e9 [LIB]: Make class__fprintf print non DW_TAG_member entries
Such as types within types and class methods. This greatly improves support for
C++. Next improvements will be supporting DW_TAG_namespace and properly
supporting DW_TAG_inheritance.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-24 00:16:23 -03:00
Arnaldo Carvalho de Melo
a1e75c91e2 [LIB]: Properly nest types within types
Now we need add support to scope type pretty-printing.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-23 23:19:35 -03:00
Arnaldo Carvalho de Melo
2f7f49b107 [LIB]: Put infrastructure for type scoping in place
Now it is possible to have types defined inside types.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-23 22:38:29 -03:00
Arnaldo Carvalho de Melo
e905635260 [LIB]: Introduce type__last_member
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-23 22:10:50 -03:00
Arnaldo Carvalho de Melo
c0cbf4fa94 [LIB]: Introduce type__for_each_member
Will be useful to show that the intent is to traverse just the DW_TAG_member
entries in the type list. Right now there are both DW_TAG_inheritance and
DW_TAG_member entries in the ->members type list. But there will be many more
tags, like enumerations, classes, etc, that are defined inside classes, a C++
feature. This will also help with DW_TAG_namespace support.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-05-23 21:43:01 -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
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
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