Now ctracer manages vmlinux at least for struct sk_buff, more to come as tests
are made with other classes (structs).
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>
Not struct class_member, that was not much of a problem, as the
initial layout is the same (struct tag).
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>
In cu_emit_kprobes_table_iterator we were defining the jprobes[] table for each
object file, do it surrounding the cu__for_each_cu call.
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>
A class tracer, it looks for non-inline functions that receive as one of its
parameters a pointer to the specified "class" (a struct) and will generate a
kprobes kernel module, see the whole sequence in the README.ctracer file.
Next steps involve supporting kretprobes, inserting kprobes at each inline
"method" expansion, using relayfs, and eventually uprobes to make this useful
for userspace as well.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
An example to illustrate the kind of checks done:
[acme@newtoy multi-cu]$ cat a.c
struct foo {
int a;
char b;
};
void a_foo_print(struct foo *f)
{
printf("f.a=%d\n", f->a);
}
[acme@newtoy multi-cu]$ cat main.c
struct foo {
int a;
char b;
char c;
};
extern void a_foo_print(struct foo *f);
int main(void)
{
struct foo f = { .a = 10, };
a_foo_print(&f);
return 0;
}
[acme@newtoy multi-cu]$ cc -g -c a.c -o a.o
[acme@newtoy multi-cu]$ cc -g -c main.c -o main.o
[acme@newtoy multi-cu]$ cc a.o main.o -o m
[acme@newtoy multi-cu]$ pahole m
class: foo
first: a.c
current: main.c
nr_members: 2 != 3
padding: 3 != 2
[acme@newtoy multi-cu]$
Gotcha? In the above case this inconsistency wouldn't cause problems, as the
'c' member doesn't makes the struct bigger, it uses the padding, but what if we
inverted the members 'a' and 'b'?
Upcoming csets will check if the type and order of the members are the same,
should help in some complex projects where people insist on using #ifdefs in
struct definitions.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Simplifying options processing by using just pair of cu and class iterators and
using the list we were building just for --total_structure_stats for all
options, this way we don't print multiple times structures that are defined in
more than one object file when processing a multi-object file.
With this in place all the options will check if a struct definition in one
object file somehow doesn't matches the same struct definition in some other
object file, more checks will be put in place in the upcoming csets.
And, to show that this besides simplifying reduces the code size, lets use
codiff:
[acme@newtoy pahole]$ codiff build/pahole.before build/pahole
/home/acme/pahole/pahole.c:
structures__add | -143
class__filter | +147
main | -263
3 functions changed, 147 bytes added, 406 bytes removed
[acme@newtoy pahole]$
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
We should check if we're in a new byte offset, i.e. the previous bitfield is
gone, now it works well when two bitfields are found one after the other, like
in struct sk_buff.
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>
So that languages such as C++ can have its inheritance concepts
covered, example:
[acme@newtoy examples]$ pahole qsettings.o QSettingsPrivate
/* io/qsettings_p.h:159 */
class QSettingsPrivate {
class QObjectPrivate; /* ancestor class */ /* 0 0 */
/* XXX 56 bytes hole, try to pack */
/* --- cacheline 1 boundary (32 bytes) was 24 bytes ago --- */
class QStack<QSettingsGroup> groupStack; /* 56 4 */
class QString groupPrefix; /* 60 4 */
/* --- cacheline 2 boundary (64 bytes) --- */
int spec; /* 64 4 */
bool fallbacks; /* 68 1 */
bool pendingChanges; /* 69 1 */
/* XXX 2 bytes hole, try to pack */
enum Status status; /* 72 4 */
}; /* size: 76, cachelines: 3 */
/* sum members: 18, holes: 2, sum holes: 58 */
/* last cacheline: 12 bytes */
Nevermind about the "/* XXX 56 bytes hole, try to pack */" and sizeof(class
QObjectPrivate) being zero, its just gcc compressing the DWARF tags avoiding
including definitions that are not used in this specific object file, i.e.
there are not accesses to 'class QObjectPrivate' members.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
We want just DW_TAG_structure_type classes, but for now there are
enums, C++ inline classes, etc, have to fix this later.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
That is to find structs that have combinable holes, trying to pack the struct
by suggesting a move, for now it just prints structs that have holes that can
be combined, but these hints are not guaranteed to generate struct size
reductions, more has to be done and that involves understanding the alignment
rules that depend on the arch being 32 or 64 bits, but it at least reduces the
number of packing candidates.
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
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>