To load directory trees, looking for files with a specified glob mask, calling
cus__load() on the ones that match and optionally recursively searching for
more matches in subdirectories.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
So that we can extract bits from one and combine it bits from other instances,
like we'll do in ctracer, where we want to have a cus instance just to get the
kprobes definitions and forward declarations but not handle the methods in it.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
For the ranges cases we store the lowest low_pc (in the first range) and the
highest high_pc (in the last range).
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This is part of a cleanup process were I'm revisiting the types used for
the various abstractions, using the correct libdw.h types.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
So that we can build a module that doesn't uses #includes to get these
definitions.
More work to be done for enums, etc, but this already is enough for
ctracer to handle tracing the sk_buff methods in vmlinux.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
In struct cus, that will be used when rebuilding class definitions for
enums, struct pointers, struct definitions, etc, in ctracer for a start.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Some rework is needed to make class_member__names and parameter__names to share
more code, but there are things like bitfields that are exclusive to
class_member entries, etc.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
So that tools can mark it as being processed already, such as when ctracer
needs to emit forward declarations for types in function parameters or return
types.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
So that we can load many object files, that is what the next csets will
do, to recursively look for files with debug info in a build tree, such
as the kernel one.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
For cases where the compiler doesn't emits the whole struct definition for
things like base classes that don't have any of its members acessed, just the
ones in its descendants.
Will be used to avoid emiting hole anottations, since we don't have the
size of these classes we can't say if its smaller than the space allocated
by the compiler.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This new function searches the first member before the one being traversed that
has a bit hole (or byte_hole, I've just normalised it on bits to make it
generic) that can be used to combine with the class_member at hand to possibly
kill a hole, possibly because for now it doesn't guarantees that moving the
member being traversed to just after the hole after the member returned by
class__find_bit_hole will indeed reduce the struct size, but its a good first
stab, next csets should provide a member to start from so that we can try to
find other holes after the one that proved not enough to reduce the struct
size.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
To simplify the callsites and make implementing the same thing on the other
dwarves (prefcnt, pfunct, etc) easy.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
To represent DW_TAG_lexical_block, for now just group the lists of
labels, inline expansions and variables, struct function now has
the root of the tree as ->lexblock.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Introducing function__print_body, that orders the tags in a function by the
souce code line where it was declared or inlined.
This finally takes advantage of the struct tag "superclass", more to come in
the form of lexical blocks and goto labels.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Following what is in the DWARF2 specs:
Name Meaning
-----------------------------------------------------------------------------
DW_INL_not_inlined Not declared inline nor inlined by the compiler
DW_INL_inlined Not declared inline but inlined by the compiler
DW_INL_declared_not_inlined Declared inline but not inlined by the compiler
DW_INL_declared_inlined Declared inline and inlined by the compiler
Take advantae of this and use it in a new pfunct option: --cc_inlined, to
show which functions were of the DW_INL_inlined type.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
And helper routines, so as to separate DW_TAG_subprogram from
the type tags (DW_TAG_structure_type, basic_type, etc).
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This should have been done from the start: all DW_TAG_s will be represented by
structs that has as its first member a struct tag, so that we can fully
represent the DWARF information, following csets will take continue the
restructuring.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
That uses the DW_AT_external attribute, that tells if the DW_TAG_subprogram
(a function) is visible externally.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This fixes a problem with codiff usage of the ->class_to_diff member, as we
were looking at a different CU than the one intended, so we'd have to have a
pointer to the CU associated with ->class_to_diff, heck, its time to have this
backpointer :-)
Now to audit the rest of the code to look for simplifications since we now have
this backpointer and thus don't need to pass CU pointers around.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
[acme@newtoy examples]$ cat struct.c
static struct foo {
char a:2;
unsigned int b;
unsigned long c;
unsigned long d;
unsigned long e;
} bar;
int main(int argc, char *argv[])
{
printf("%d", bar.a);
}
[acme@newtoy examples]$
Then change "a:2" to "a:4":
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | +0
a:2;
from: char /* 0(6) 1(2) */
to: char /* 0(4) 1(4) */
1 struct changed
Now, on top of that move a after b:
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | +0
a:2;
from: char /* 0(6) 1(2) */
to: char /* 4(4) 1(4) */
b;
from: unsigned int /* 4(0) 4(0) */
to: unsigned int /* 0(0) 4(0) */
1 struct changed
[acme@newtoy examples]$
Move it back a to before b and change the type of e without changing its size,
i.e. from unsigned long to long:
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | +0
a:2;
from: char /* 0(6) 1(2) */
to: char /* 0(4) 1(4) */
e;
from: long unsigned int /* 16(0) 4(0) */
to: long int /* 16(0) 4(0) */
1 struct changed
[acme@newtoy examples]$
Now on top of this lets delete the c member:
[acme@newtoy examples]$ codiff -V old_struct new_struct
struct.c:
struct foo | -4
nr_members: -1
-long unsigned int c; /* 8 4 */
a:2;
from: char /* 0(6) 1(2) */
to: char /* 0(4) 1(4) */
d;
from: long unsigned int /* 12(0) 4(0) */
to: long unsigned int /* 8(0) 4(0) */
e;
from: long unsigned int /* 16(0) 4(0) */
to: long int /* 12(0) 4(0) */
1 struct changed
[acme@newtoy examples]$
WOW, many changes, what an ABI breakage, no? :-)
It started as:
[acme@newtoy examples]$ pahole old_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
char a:2; /* 0 1 */
/* XXX 3 bytes hole, try to pack */
unsigned int b; /* 4 4 */
long unsigned int c; /* 8 4 */
long unsigned int d; /* 12 4 */
long unsigned int e; /* 16 4 */
}; /* size: 20, sum members: 17, holes: 1, sum holes: 3 */
And ended up as:
[acme@newtoy examples]$ pahole new_struct foo
/* /home/acme/pahole/examples/struct.c:3 */
struct foo {
char a:4; /* 0 1 */
/* XXX 3 bytes hole, try to pack */
unsigned int b; /* 4 4 */
long unsigned int d; /* 8 4 */
long int e; /* 12 4 */
}; /* size: 16, sum members: 13, holes: 1, sum holes: 3 */
[acme@newtoy examples]$
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
First step:
Show if struct members were removed or added:
[acme@newtoy net-2.6.20]$ codiff -sV /tmp/ipv6.ko.before /tmp/ipv6.ko.after
<SNIP>
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/tcp_ipv6.c:
struct inet_sock | -4
nr_members: -1
struct inet_connection_sock | -4
struct tcp_sock | -4
struct tcp6_sock | -4
4 structs changed
<SNIP>
Oh, so struct inet_sock must be one of the members of the other structs that
haven't had changes in its number of members? Yes, this is the case :-)
Now lets see _which_ members were removed, added or had its type changed
causing a reduction in the struct size.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>