Too DWARF specific and wasn't working since I implemented type recoding and
removed the Dwarf_Off from struct tag.
To achieve the same result one can use --show_decl_info that also shows the
dwarf offset, since it needs to keep the DWARF specific line number and file
and then use a text editor to find the offset.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
As we will show them on the first level. This is yet another thing
required to properly compare te result of "pahole -F ctf foo" with the
output of "pahole -F dwarf foo", as there is no support, that I know of,
for namespacing in ctf.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
By default pahole doesn't prints structs/classes that are only defined
inside functions, so add a knob to aks for that.
This is for the benefit of ctfdwdiff, as in CTF we don't have
expressiveness to tell that a struct is only defined inside a function,
its all in the global table.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
CTF doesn't have support for multiple array dimensions, so it flattens
the arrays.
This caused a large number of false positives in ctfdwdiff, so introduce
this conf_fprintf option, use it in pahole and ctfdwdiff.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
For a file with just DWARF info:
$ pahole -F ctf build/pahole
$
But if we ask that it also try dwarf:
$ pahole -F ctf,dwarf build/pahole | head -2
struct _IO_FILE {
int _flags; /* 0 4 */
$
Useful when testing the new CTF support in these tools, as we'll be able to,
from the DWARF info in objects, generate the CTF equivalent and add to the same
object, then run pahole -A -F ctf, pahole -A -F dwarf and compare the outputs.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
"pahole -Z foo" will create foo.SUNW_ctf, that if objcopy
--add-section'ed to the right word-sized object will work, sans VARARGS,
that will get fixed soon (as in, probably, tomorrow).
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
To shorten the name and to reflect the fact that we're no longer
"finding" a type, but merely accessing an array with a bounds check in
this function.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Amazing how many crept up over time, should have set the
execute bit of .git/hooks/pre-commit already, duh.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
So that we can, for instance, go from:
[acme@doppio pahole]$ time pahole -C sk_buff
/usr/lib/debug/lib/modules/2.6.27.19-170.2.35.fc10.x86_64/vmlinux | head
-3
struct sk_buff {
struct sk_buff * next; /* 0 8 */
struct sk_buff * prev; /* 8 8 */
real 0m11.071s
user 0m10.627s
sys 0m0.359s
[acme@doppio pahole]$
To a mere:
[acme@doppio pahole]$ time pahole -C sk_buff
/usr/lib/debug/lib/modules/2.6.27.19-170.2.35.fc10.x86_64/vmlinux | head
-3
struct sk_buff {
struct sk_buff * next; /* 0 8 */
struct sk_buff * prev; /* 8 8 */
real 0m1.464s
user 0m1.431s
sys 0m0.016s
[acme@doppio pahole]$
And also results go appearing much quicker for other options, etc.
The other tools will be converted too, but the old way of working will
always be there, as it is possible that we may need all the types in
memory for some future tool.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Also introducing cus__load, that load just one file.
The new cus__load_files routine now iterates thru the provided array
calling cus__load for each, and that in turn will try first dwarf__load,
and if that fail, i.e. if no DWARF info is found, call ctf__load.
This now allows loading DWARF _and_ CTF files at the same time. This
will be useful in the future when we, from DWARF generate CTF and at the
same time do a codiff, comparing the freshly generated CTF file with the
DWARF it came from.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
So that, when not needing the DWARF info, the apps can tell that at load
time, and then the dwarf loader can just free all the dwarf_tags
allocated, reducing memory usage.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
To take advantage of cache effects and to avoid calling cu__find_holes
more than once on the same struct.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
parameter__type was needed because the abstract_origin resolution was
done later, now it is at dwarf recode time, and for debugging formats
that don't have this crap, never. So it now can use the same idiom as
other tags: foo->tag.type.
parameter__name still exists because the tools still want a string
returned, but for some what they want is indeed the string_t, so that
when looking for a particular string it can be done as an string__find
for the key + integer comparision instead of doing a costlier strcmp.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Had to be a big sweeping change, but the regression tests shows just
improvements :-)
Now we stop using an id in struct tag, only storing the type, that now
uses 16 bits only, as CTF does.
Each format loader has to go on adding the types to the core, that
figures out if it is a tag that can be on the tag->type field
(tag__is_tag_type).
Formats that already have the types separated and in sequence, such as
CTF, just ask the core to insert in the types_table directly with its
original ID.
For DWARF, we ask the core to put it on the table, in sequence, and return the
index, that is then stashed with the DWARF specific info (original id, type,
decl_line, etc) and hashed by the original id. Later we recode everything,
looking up via the original type, getting the small_id to put on the tag->type.
The underlying debugging info not needed by the core is stashed in tag->priv,
and the DWARF loader now just allocates sizeof(struct dwarf_tag) at the end of
the core tag and points it there, and makes that info available thru
cu->orig_info. In the future we can ask, when loading a cu, that this info be
trown away, so that we reduce the memory footprint for big multi-cu files such
as the Linux kernel.
There is also a routine to ask for inserting a NULL, as we still have
bugs in the CTF decoding and thus some entries are being lost, to avoid
using an undefined pointer when traversing the types_table the ctf
loader puts a NULL there via cu__table_nullify_type_entry() and then
cu__for_each_type skips those.
There is some more cleanups for leftovers that I avoided cleaning to
reduce this changeset.
And also while doing this I saw that enums can appear without any
enumerators and that an array with DW_TAG_GNU_vector is actually a
different tag, encoded this way till we get to DWARF4 ;-)
So now we don't have to lookup on a hash table looking for DWARF
offsets, we can do the more sensible thing of just indexing the
types_tags array.
Now to do some cleanups and try to get the per cu encoder done. Then
order all the cus per number of type entries, pick the one with more,
then go on merging/recoding the types of the others and putting the
parent linkage in place.
Just to show the extent of the changes:
$ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0
/home/acme/git/pahole/dwarves.c:
struct cu | -4048
struct tag | -32
struct ptr_to_member_type | -32
struct namespace | -32
struct type | -32
struct class | -32
struct base_type | -32
struct array_type | -32
struct class_member | -32
struct lexblock | -32
struct ftype | -32
struct function | -64
struct parameter | -32
struct variable | -32
struct inline_expansion | -32
struct label | -32
struct enumerator | -32
17 structs changed
tag__follow_typedef | +3
tag__fprintf_decl_info | +25
array_type__fprintf | +6
type__name | -126
type__find_first_biggest_size_base_type_member | -3
typedef__fprintf | +16
imported_declaration__fprintf | +6
imported_module__fprintf | +3
cu__new | +26
cu__delete | +26
hashtags__hash | -65
hash_64 | -124
hlist_add_head | -78
hashtags__find | -157
cu__hash | -80
cu__add_tag | +20
tag__prefix | -3
cu__find_tag_by_id | -2
cu__find_type_by_id | -3
cu__find_first_typedef_of_type | +38
cu__find_base_type_by_name | +68
cu__find_base_type_by_name_and_size | +72
cu__find_struct_by_name | +59
cus__find_struct_by_name | +8
cus__find_tag_by_id | +5
cus__find_cu_by_name | -6
lexblock__find_tag_by_id | -173
cu__find_variable_by_id | -197
list__find_tag_by_id | -308
cu__find_parameter_by_id | -60
tag__ptr_name | +6
tag__name | +15
variable__type | +13
variable__name | +7
class_member__size | +6
parameter__name | -119
tag__parameter | -14
parameter__type | -143
type__fprintf | -29
union__fprintf | +6
class__add_vtable_entry | -9
type__add_member | -6
type__clone_members | -3
enumeration__add | -6
function__name | -156
ftype__has_parm_of_type | -39
class__find_holes | -27
class__has_hole_ge | -3
type__nr_members_of_type | +3
lexblock__account_inline_expansions | +3
cu__account_inline_expansions | -18
ftype__fprintf_parms | +46
function__tag_fprintf | +24
lexblock__fprintf | -6
ftype__fprintf | +3
function__fprintf_stats | -18
function__size | -6
class__vtable_fprintf | -11
class__fprintf | -21
tag__fprintf | -35
60 functions changed, 513 bytes added, 2054 bytes removed, diff: -1541
/home/acme/git/pahole/ctf_loader.c:
struct ctf_short_type | +0
14 structs changed
type__init | -14
type__new | -9
class__new | -12
create_new_base_type | -7
create_new_base_type_float | -7
create_new_array | -8
create_new_subroutine_type | -9
create_full_members | -18
create_short_members | -18
create_new_class | +1
create_new_union | +1
create_new_enumeration | -19
create_new_forward_decl | -2
create_new_typedef | +3
create_new_tag | -5
load_types | +16
class__fixup_ctf_bitfields | -3
17 functions changed, 21 bytes added, 131 bytes removed, diff: -110
/home/acme/git/pahole/dwarf_loader.c:
17 structs changed
zalloc | -56
tag__init | +3
array_type__new | +20
type__init | -24
class_member__new | +46
inline_expansion__new | +12
class__new | +81
lexblock__init | +19
function__new | +43
die__create_new_array | +20
die__create_new_parameter | +4
die__create_new_label | +4
die__create_new_subroutine_type | +113
die__create_new_enumeration | -21
die__process_class | +79
die__process_namespace | +76
die__create_new_inline_expansion | +4
die__process_function | +147
__die__process_tag | +34
die__process_unit | +56
die__process | +90
21 functions changed, 851 bytes added, 101 bytes removed, diff: +750
/home/acme/git/pahole/dwarves.c:
struct ptr_table | +16
struct cu_orig_info | +32
2 structs changed
tag__decl_line | +68
tag__decl_file | +70
tag__orig_id | +71
ptr_table__init | +46
ptr_table__exit | +37
ptr_table__add | +183
ptr_table__add_with_id | +165
ptr_table__entry | +64
cu__table_add_tag | +171
cu__table_nullify_type_entry | +38
10 functions changed, 913 bytes added, diff: +913
/home/acme/git/pahole/ctf_loader.c:
2 structs changed
tag__alloc | +52
1 function changed, 52 bytes added, diff: +52
/home/acme/git/pahole/dwarf_loader.c:
struct dwarf_tag | +48
struct dwarf_cu | +4104
4 structs changed
dwarf_cu__init | +83
hashtags__hash | +61
hash_64 | +124
hlist_add_head | +78
hashtags__find | +161
cu__hash | +95
tag__is_tag_type | +171
tag__is_type | +85
tag__is_union | +28
tag__is_struct | +57
tag__is_typedef | +28
tag__is_enumeration | +28
dwarf_cu__find_tag_by_id | +56
dwarf_cu__find_type_by_id | +63
tag__alloc | +114
__tag__print_type_not_found | +108
namespace__recode_dwarf_types | +346
tag__namespace | +14
tag__has_namespace | +86
tag__is_namespace | +28
type__recode_dwarf_specification | +182
tag__type | +14
__tag__print_abstract_origin_not_found | +105
ftype__recode_dwarf_types | +322
tag__ftype | +14
tag__parameter | +14
lexblock__recode_dwarf_types | +736
tag__lexblock | +14
tag__label | +14
tag__recode_dwarf_type | +766
tag__ptr_to_member_type | +14
cu__recode_dwarf_types_table | +88
cu__recode_dwarf_types | +48
dwarf_tag__decl_file | +77
strings__ptr | +33
dwarf_tag__decl_line | +59
dwarf_tag__orig_id | +59
dwarf_tag__orig_type | +59
38 functions changed, 4432 bytes added, diff: +4432
build/libdwarves.so.1.0.0:
147 functions changed, 6782 bytes added, 2286 bytes removed, diff: +4496
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Now we just pass a NULL terminated array of filenames, since we got rid
of that ugly -e insertion hack.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
So that they appear on the output in the same order as they
come from the original debugging info.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
And make the dwarves use it, so that we can remove duplicate strings in
a multi-CU file (vmlinux anyone?) and have it ready for insertion in a
compressed DWARF format with just the types, or better, CTF or some new
compressed debugging info format.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
While pahole allows you to exclude classes with a specified prefix (using
--exclude), it doesn't appear to be able to do the opposite - only show classes
with a specific prefix. I found I needed this for my own use of it, so here is
a patch to add this functionality.
Signed-off-by: Dave Rigby <davidr@transitive.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
For correctly created and completely parsed debugging information the type will
always be found, but as we still need to parse more tags and expecting
debugging information to be always correctly built is not sane... sprinkle some
asserts.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This is trying to get CTF friendly, where bitfields are not stored in the
equivalent to the DW_TAG_member dwarf TAG, but on "base types" with bit sizes
different than the real in the DWARF sense, base types (char, long, etc).
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This will print which object files have a struct definition, i.e. not just a
forward declaration.
There are many cases in the Linux kernel where just a fwd decl would suffice or outright
unneeded includes that end up bloating the DWARF sessions and consequently making everybody
suffer with humongous kernel-debuginfo packages.
More automation is needed here, this time something like sparse seems to be
needed to check what is that a header file "provides" and what is that the C
files "requires", doing some depsolving to discover unneeded Requires, i.e.
include directives and some that are required but are only satisfied
indirectly, which is a recipe for problems down the line.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Found in at least a file (tcp_ipv6.c in the Linux kernel) built with gcc
version 4.3.0 20080130 (Red Hat 4.3.0-0.7).
Which seems to be in violation with DWARF3, but better be defensive and handle
that.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>