Commit Graph

423 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo 7fc7148be7 core: Fix thinko in type__find_first_biggest_size_base_type_member
ctracer was segfaulting due to this problem.

Reported-by: Breno Leitão <leitao@linux.vnet.ibm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-02 13:33:05 -03:00
Arnaldo Carvalho de Melo c93fff6743 core: Add variable__name to struct debug_fmt_ops
Same reason as for function__name

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-02 12:40:33 -03:00
Arnaldo Carvalho de Melo ea4ff04f8e core: class__vtable_fprintf should use function__name
Same reason as for last commit.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-02 12:10:33 -03:00
Arnaldo Carvalho de Melo d5d45ab5af core: cu__find_function_by_name must use function__name()
And not compare by string_t, as now it may not be on the global strings table,
so we have to give a chance to the underlying debug format to translate that to
a string for us.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-02 12:07:53 -03:00
Arnaldo Carvalho de Melo 0837979e09 core: function__name in CTF gets the name from .strtab
That is done by adding some new struct debug_fmt_ops methods:

->function__name()

This one, if specified, will be called by function__name(), giving a chance to
formats such as CTF to get this from some other place than the global strings
table. CTF does this by storing GElf_Sym->st_name in function->name, and by
providing a dfops->function__name() that uses function->name as an index into
the .strtab ELF section.

->cu__delete()

This is needed because we can't anymore call ctf__delete at the end of
ctf__load_file, as we will need at least the .strstab ELF section to be
available till we're done with the cu, i.e. till we call cu__delete(), that now
calls dfops->cu__delete() if it is available.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-02 11:46:26 -03:00
Arnaldo Carvalho de Melo 6b4aec4a73 core: Rename cu_orig_info to debug_fmt_ops
There are more things that should be handled differently, such as function
names coming from the .strtab ELF section instead of from the global strings_t
table.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-02 11:12:02 -03:00
Arnaldo Carvalho de Melo db741ee3fc core: Hasta la vista cu__for_each_tag
build/libdwarves.so.1.0.0:
 1 function changed, 169 bytes removed, diff: -169

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-04-01 13:49:58 -03:00
Arnaldo Carvalho de Melo 2d8700009b pfunct: Introduce --no_parm_names
Because CTF doesn't encodes the names of the parameters and I want to
test the upcoming CTF function section code in ctftwdiff.

$ pfunct -V pahole > /tmp/before
$ pfunct --no_parm_names -V pahole > /tmp/after
$ diff -u /tmp/before /tmp/after | tail -3
-struct structure * structure__new(strings_t name);
+struct structure * structure__new(strings_t);
 /* definitions: 1 */
$

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-30 21:47:59 -03:00
Arnaldo Carvalho de Melo 51ea39717f core: Add destructors for the function and lexblock classes
And also export the namespace destructor.

The tag__delete destructor now also uses these new destructors.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-25 14:54:02 -03:00
Arnaldo Carvalho de Melo 4024ccee40 tag: Make tag__delete call the right destructors for non-trivial types
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-25 13:06:29 -03:00
Arnaldo Carvalho de Melo fe27f41973 enumerator: Introduce enumerator__delete
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-25 12:17:50 -03:00
Arnaldo Carvalho de Melo 6d66c9ae6b type: Introduce type__delete
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-25 12:00:30 -03:00
Arnaldo Carvalho de Melo 0e29fc9912 ftype: Introduce ftype__delete
To delete all the members added so far in the loaders in case memory is scarce.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-25 11:40:05 -03:00
Arnaldo Carvalho de Melo 4bdead6876 core: Add a per object file functions_table
CTF will need this distinction in that it handles functions differently, using
data in the ELF symbol table.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-24 20:12:59 -03:00
Arnaldo Carvalho de Melo a386913705 core: function__tag_fprintf should check if the alias name is NULL
Only seen in some C++ inline expansion cases. Will appear as "(null)" in the
rendered source code.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-24 19:05:25 -03:00
Arnaldo Carvalho de Melo 4848eef743 core: Rename {cus,dwarf,ctf}__load to {cus,dwarf,ctf}__load_file
Because we already use ctf__load in libctf.c, rename the others to
disambiguate, and also as there are the __load_dir and __load_files
it looks more consistent.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-24 16:48:41 -03:00
Arnaldo Carvalho de Melo d6d845f0d7 core: Handle GCC support for vector instructions
So after the next patch, when dwarf_loader will use this new core
functionality, it recognizes:

908 typedef int __m64 __attribute__ ((__vector_size__ (8))); size: 8
909 int         array __attribute__ ((__vector_size__ (8))); size: 8
910 int         array __attribute__ ((__vector_size__ (4))); size: 4
911 short int   array __attribute__ ((__vector_size__ (2))); size: 2
912 char        array __attribute__ ((__vector_size__ (1))); size: 1

The above output was obtained using pdwtags.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-23 16:56:57 -03:00
Arnaldo Carvalho de Melo 09edf84b74 tag: tag__follow_typedef doesn't change self, make it const
That will allow it to be used in other places were we forward self and it is
const.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-23 16:30:20 -03:00
Arnaldo Carvalho de Melo 790019678d dwarves: Fixup the flat_arrays code
To deal with cases such as this:

$ pahole -C tun_filter drivers/net/tun.o
struct tun_filter {
	__u16           flags;         /*   0  2 */
	__u16           count;         /*   2  2 */
	__u8            addr[0][6];    /*   4  0 */

	/* size: 4, cachelines: 1, members: 3 */
	/* last cacheline: 4 bytes */
};
$ pahole --flat_arrays -C tun_filter drivers/net/tun.o
struct tun_filter {
	__u16           flags;         /*   0  2 */
	__u16           count;         /*   2  2 */
	__u8            addr[0];       /*   4  0 */

	/* size: 4, cachelines: 1, members: 3 */
	/* last cacheline: 4 bytes */
};
$

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-20 14:05:01 -03:00
Arnaldo Carvalho de Melo aff24d3517 base_type: floats are 32 bits
Gee, I guess I was nuts when thinking int was dependent on the arch
word-size.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-20 13:38:03 -03:00
Arnaldo Carvalho de Melo 6454e1dc8b enumeration: Allow sharing the enumerators
Nasty trick, but works and should be properly documented in the sources
and here:

If struct namespace.shared_tags is 1, we actually are reusing the list
of enumerators in another namespace, so we shouldn't delete them, for
that list_for_each_tag now means more for each _unshared_ tag, so that
cu__delete doesn't visits it, double freeing enumerator tags.

type__for_each_enumerator knows that and only for enums we'll set this
->shared_tags bit to 1, so we should be safe...

Disgusting? send me a patch, but without increasing memory or processing
footprints, please ;-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-20 12:53:43 -03:00
Arnaldo Carvalho de Melo 57127d45fc pahole: Introduce --flat_array
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>
2009-03-20 10:29:50 -03:00
Arnaldo Carvalho de Melo 6564699144 base_type: Add "float" to base_type_name_to_size_table
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-19 21:52:01 -03:00
Arnaldo Carvalho de Melo 45255ec6b6 pahole: Add --format_path/-F to specify a list of formats to try
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>
2009-03-19 12:19:37 -03:00
Arnaldo Carvalho de Melo 347e70f4d8 cus: Allow passing a debugging format path to cus__load
So that the user can specify what is the order it wants for decodind, as
we can have several debugging formats encoded in different ELF sections.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-19 12:13:00 -03:00
Arnaldo Carvalho de Melo eb0284c619 enumeration: type->size for enumerations is in bits, not in bytes
I have to normalize this so that we don't have this special case, but
since we can have enum bitfields....

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-18 23:01:32 -03:00
Arnaldo Carvalho de Melo bcf24ef40f base_type__name_to_size: Complain when not finding the requested type name
Fragile interface, but its the best I have for now.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-18 22:49:33 -03:00
Arnaldo Carvalho de Melo 7397fab08e base_type_name_to_size: Add "long double long double"
Looks like a stupid glitch, but lets leave this for later for now.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-18 22:47:48 -03:00
Arnaldo Carvalho de Melo da37c56c26 cu: Add a filename member
Will later be used when generating the CTF info, be it in a separate
file, be it on a new ELF section inserted into this filename.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-18 22:35:54 -03:00
Arnaldo Carvalho de Melo 140712f06a cu: Rename cu__find_{type,tag}_by_id to cu__{type,tag}
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>
2009-03-18 12:17:07 -03:00
Arnaldo Carvalho de Melo dfdfcbbb5c cu: Introduce cu__find_enumeration_by_sname_and_size
Needed for reencoding DWARF bitfields, where we need to create a new
enum that has a bitfield_size bits size.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-18 11:52:29 -03:00
Arnaldo Carvalho de Melo 83e389677e base_type: Move base_type__name_to_size from the ctf loader to the core
Will be used in more parts.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-18 11:48:40 -03:00
Arnaldo Carvalho de Melo 61219b0c3b class_member: cache the byte size of the member
This is the full byte size of the type or the bitfield it is in.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-17 14:31:18 -03:00
Arnaldo Carvalho de Melo 93eefc6cfb class_member: cache byte_size
This will help us in the next csets when we need to know both the full
size of the base_type used in an bitfield _and_ the size in bits of the
bitfield member.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-17 13:57:40 -03:00
Arnaldo Carvalho de Melo ef6c1c63d6 dwarves: Rename the class_member bitfields size and offset members
Because we will need the "bit_offset" and "bit_size" names when converting the
representation of offset and size everywhere to be in bits, not bytes.

At the same time we will keep bitfield_size and bitfield_offset when we convert
from DWARF to CTF and will calculate them when loading CTF, so that the
conversion of the algorithms in dwarves_reorganize, that have all sorts of
subtle issues, can be left for later.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-17 11:43:17 -03:00
Arnaldo Carvalho de Melo b9a9b048d4 dwarves: Don't double free vtable entries
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-14 22:40:56 -03:00
Arnaldo Carvalho de Melo 865e259012 dwarves: the variable abstract_origin is resolved at load time too
It makes no sense to try to lookup the abstract_origin (a Dwarf_Off)
after we recode the types just after load.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-14 15:19:33 -03:00
Arnaldo Carvalho de Melo 80374a4e27 dwarves: Remove some unused functions
Namely cus__find_function_by_name and cus__find_tag_by_id.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-14 14:52:30 -03:00
Arnaldo Carvalho de Melo 4d44276d85 coding style: remove trailing whitespaces, etc
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>
2009-03-14 13:50:36 -03:00
Arnaldo Carvalho de Melo 839ab493c9 dwarves: Introduce cu__find_base_type_by_sname_and_size
From cu__find_base_type_by_name_and_size, so that one can do a string_t
based lookup.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-14 13:36:45 -03:00
Arnaldo Carvalho de Melo 489e3b585c dwarves: Introduce cu__find_struct_by_sname
Out of cu__find_struct_by_name so that we can do a string__find
once and lookup the string id on multiple cus.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-13 14:57:53 -03:00
Arnaldo Carvalho de Melo 991c6a3ebb dwarves: Rename cus__loadfl with cus__load_files
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>
2009-03-13 10:49:01 -03:00
Arnaldo Carvalho de Melo ade3f44269 dwarves: Ditch old cus__load and cus__load_filename
Not used anymore now that cus__loadfl is sanitized. Now we can even
remove the fl (historically comes from libdwfl, when we used to pass an
argp, argh!).

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-13 09:31:48 -03:00
Arnaldo Carvalho de Melo 152277f667 dwarves: cu__find_struct_by_name should set id for non declarations
Bug introduced recently, fixed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-12 20:34:07 -03:00
Arnaldo Carvalho de Melo 8cc4949b00 dwarves: Add destructors
So that at program exit we can verify, using tools, that no memory was
leaked.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-11 12:31:17 -03:00
Arnaldo Carvalho de Melo 250dded466 dwarf: separate dwarf_tag from tag
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>
2009-03-09 14:43:47 -03:00
Arnaldo Carvalho de Melo 822f8b675e dwarves: Introduce cu__for_all_tags
To visit all parms, lexblocks, namespaces, i.e. not just the top level
tags listed in cu->tags.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-08 10:36:24 -03:00
Arnaldo Carvalho de Melo 702485234a dwarves: replace high_pc by size in struct lex_block
So that we can save 8 bytes in lexblock and in function instances:

$ codiff /tmp/libdwarves.so.1.0.0 build/libdwarves.so.1.0.0
/home/acme/git/pahole/dwarves.c:
  struct lexblock               |   -8
  struct function               |   -8
 2 structs changed
  cu__account_inline_expansions |   -3
  lexblock__fprintf             |  -26
  function__fprintf_stats       |   -4
  function__size                |  -18
 4 functions changed, 51 bytes removed, diff: -51

/home/acme/git/pahole/dwarf_loader.c:
 2 structs changed
  lexblock__init  |  +20
 1 function changed, 20 bytes added, diff: +20

build/libdwarves.so.1.0.0:
 5 functions changed, 20 bytes added, 51 bytes removed, diff: -31

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-07 17:37:33 -03:00
Arnaldo Carvalho de Melo 20464ba7f0 dwarves: Reduce the size of some data structures
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-07 16:45:09 -03:00
Arnaldo Carvalho de Melo c550aea11c pahole, lib: Do more strings__find + integer comparisions
Replacing strcmp calls

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 12:41:29 -03:00
Arnaldo Carvalho de Melo b902f563b3 dwarves: find holes when adding a fresh compile unit
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>
2009-03-06 11:48:33 -03:00
Arnaldo Carvalho de Melo 9fadbfffba dwarves: use tag__is_function in the tools
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 11:14:26 -03:00
Arnaldo Carvalho de Melo fa82c1b623 dwarves: remove now unused 'cu' argument to {type,class}__name
And also make then pure functions.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-06 10:57:41 -03:00
Arnaldo Carvalho de Melo a2289d0606 dwarves: Ditch parameter__type and simplify parameter__name
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>
2009-03-06 09:27:40 -03:00
Arnaldo Carvalho de Melo c178f4698d dwarves: Remove some more DWARF details from the core
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>
2009-03-05 20:40:54 -03:00
Arnaldo Carvalho de Melo f2a3b9afbc dwarves: Print arrays in tag__fprintf too
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-05 13:49:30 -03:00
Arnaldo Carvalho de Melo 913aee45fc dwarves: Use hlist for the hashtables
Reducing the struct cu footprint by 4 Kb.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-03 22:24:05 -03:00
Arnaldo Carvalho de Melo 3f4e4457e2 dwarves: Add DW_TAG_ptr_to_member_type to tag__is_tag_type
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-03 15:12:29 -03:00
Arnaldo Carvalho de Melo 72eba67214 dwarves: Move hashtags__find out of cu__find_tag_by_id
Will be used by cu__find_type_by_id too.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-03 13:48:07 -03:00
Arnaldo Carvalho de Melo e710cca6bf dwarves: Introduce cu__hash
So that we can then decide in what hashtable we will add it, and this
also paves the way for a type array that will help us in reducing the
size of struct tag by removing the id field.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-03 13:37:57 -03:00
Arnaldo Carvalho de Melo 415b9d1e28 dwarves: Introduce tag__has_namespace
This open coded sequence appears two times already, with more to come.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-03 09:38:27 -03:00
Arnaldo Carvalho de Melo 659611ee2f dwarves: Implement cu__find_base_type_by_name_and_size
Needed for CTF, where we can have many base types with name "unsigned",
but with different bit sizes, to implement bitfields.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-03-02 12:22:37 -03:00
Arnaldo Carvalho de Melo 56be29c649 all: Add the --version
Using the argp tricks.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2009-02-13 10:57:23 -02:00
Arnaldo Carvalho de Melo 138cc4739c dwarves: Don't pass argp to dwarf_loadfl
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>
2009-02-09 21:43:56 -02:00
Arnaldo Carvalho de Melo f890ae7cc1 loaders: Process argp only once
This is still ugly, as the processing of argp was done on the loader so
that we can use the libdwfl argp processing, doing the tool argp
processing as a child. But then when we find out that there is no DWARF
info we fall back to another debugging format, with CTF being the only
other one supported as of now.

I used this scheme as when developing the CTF decoder and using pahole
on a binary with both CTF and DWARF info I would like to get the CTF
processed first.

So we still need some good refactoring here to get this sorted out in a
way that the user can specify the order of decoding, and perhaps even
ask for decoding _both_ and comparing if the results are the same, i.e.
if the (potentially subset of) information decoded from the first (that
may have less information: CTF) is the same as decoded from the second
(DWARF, more verbose).

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-12-01 13:47:52 -02:00
Arnaldo Carvalho de Melo 212b994ab5 strings: Introduce the strings class
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>
2008-10-02 14:34:42 -03:00
Arnaldo Carvalho de Melo 964c6b0666 dwarves_emit: Adopt type_emissions
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-10-01 12:51:58 -03:00
Arnaldo Carvalho de Melo efa997ed40 dwarves: Remove type_emissions fields from cus
Now only when one wants to emit this struct is needed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-10-01 12:47:42 -03:00
Arnaldo Carvalho de Melo c3f6f8b79f dwarves_emit: Introduce type_emissions
We may want to work on just one object file, not on a multi cu.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-10-01 11:26:51 -03:00
Arnaldo Carvalho de Melo 0614c1d53e dwarves: Introduce tag__is_typedef()
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-09-30 14:21:03 -03:00
Arnaldo Carvalho de Melo 51bcb5f9e5 dwarves: Introduce function__prototype
Basically a wrapper for ftype__fprintf(&function__proto, ...) for the
cases we want the prototype rendered to a buffer, not to a file.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-07-30 18:33:33 -04:00
Arnaldo Carvalho de Melo 33ba723280 dwarves: handle the empty base optimization trick
Thanks to Dennis Lubert for bringing this to my attention, now tons of BRAIN
FART ALERTs are gone.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-07-04 12:09:28 -03:00
Arnaldo Carvalho de Melo ad635812a0 dwarves: Print the number of members in class__fprintf
Example:

struct foo {
	void xxx(class foo *); /* linkage=_ZN4tonk3foo3xxxEv */

	/* size: 1, cachelines: 1, members: 0 */
	/* padding: 1 */
	/* last cacheline: 1 bytes */
};

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-07-03 14:44:03 -03:00
Arnaldo Carvalho de Melo 5488b1dbde [DWARVES]: Check if any cu was found
Reported-by: Diego 'Flameeyes' Pettenò <flameeyes@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-05-12 15:25:45 -03:00
Arnaldo Carvalho de Melo f71ee6d306 [DWARVES]: Add support to DW_TAG_ptr_to_member_type
Another C++ism:

- regtest/before/libQtGui.so.4.3.4.debug.pahole -A.c  2008-04-21 16:09:30.000000000 -0300
+ regtest/after/libQtGui.so.4.3.4.debug.pahole -A.c   2008-04-21 17:25:17.000000000 -0300
@@ -115443,7 +115443,7 @@

        void init(classQGridLayoutPrivate *); /* linkage=_ZN18QGridLayoutPrivate4initEv */

-       class QSize findSize(const classQGridLayoutPrivate  *, <ERROR>, int, int); /* linkage=_ZNK18QGridLayoutPrivate8findSizeEM13QLayoutStructiii */
+       class QSize findSize(const classQGridLayoutPrivate  *, int QLayoutStruct::*, int, int); /* linkage=_ZNK18QGridLayoutPrivate8findSizeEM13QLayoutStructiii */

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-04-21 17:28:06 -03:00
Arnaldo Carvalho de Melo 23a8c85ae8 [DWARVES]: Normalise the reporting of IDs not found
By inlining them in the output when possible, that way we get context on where
the problem is, etc.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-04-21 15:57:34 -03:00
Arnaldo Carvalho de Melo 0dc85894dd [DWARVES]: Fix ftype__fprintf_parms goto label
If we don't find the type it should spill an <ERROR>, not print 'void'.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-04-21 13:09:26 -03:00
Arnaldo Carvalho de Melo 4ab5153b8a [DWARVES]: Handle DW_TAG_class_type
Basically the same as DW_TAG_structure_type.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-04-20 22:12:03 -03:00
Arnaldo Carvalho de Melo fb809733cc [DWARVES]: Introduce tag__assert_search_result
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>
2008-04-20 18:56:36 -03:00
Arnaldo Carvalho de Melo e288817933 [DWARVES]: Check if ancestor classes were found in class__fprintf
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-04-19 12:12:13 -03:00
Arnaldo Carvalho de Melo f8c943bfe5 [DWARVES] base_type: store the size in bits
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>
2008-03-04 18:38:21 -03:00
Arnaldo Carvalho de Melo 2dfa5fe6ea [DWARVES]: Initial CTF support
Using a library written by David S. Miller.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-03-04 15:37:02 -03:00
Arnaldo Carvalho de Melo 03a653048e [DWARVES]: Check if type was found for members in union__fprintf
As we already do in class__fprintf.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-03-04 12:44:40 -03:00
Arnaldo Carvalho de Melo b3489e14eb [DWARVES]: Move all the DWARF specific loading routines to dwarf_loader.c
In libdwarves.so well continue using DW_TAG_ entries and types for now, but its
becoming non-DWARF specific as will be demonstrated with the introduction of
ctf_loader.c in the upcoming csets.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-03-03 13:50:44 -03:00
Felipe Kellermann 414595651d [DWARVES] Fixes a FIXME relating to a missing elf (libdw) symbol check.
Signed-off-by: Felipe Kellermann <felipek@socksarmor.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-02-12 21:08:49 -02:00
Hagen Paul Pfeifer 030f1871aa [DWARVES]: define memdup() static
memdup() is only referenced from dwarves.c. This patch defines them
static. Further symbol hiding can be accomplished via GCC attributes:

Signed-off-by: Hagen Paul Pfeifer <hagen@jauu.net>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-02-11 22:08:29 -02:00
Arnaldo Carvalho de Melo c83d935a4f [DWARVES]: Use a hash table for the tags in a CU
Almost halves the time spent on processing a x86_64 vmlinux. Good, we
have features, now lets have performance ;-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-02-11 11:47:17 -02:00
Arnaldo Carvalho de Melo 11282eafb4 [DWARVES]: Another fix for DW_TAG_base_type entries without DW_AT_name
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-02-01 20:00:07 -02:00
Arnaldo Carvalho de Melo 0a9cbf6ef6 [DWARVES]: Allow passing NULL as self to cu__find_
It will return NULL, this will be useful for codiff to use /dev/null as one of
the files being compared. And if you look for something in NULL, you better
get NULL, seems like a useful convention, huh?

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-31 10:03:54 -02:00
Arnaldo Carvalho de Melo 9a47906767 [DWARVES]: Find holes in inner, nameless structs
Long standing bug, fixed!

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-14 21:46:25 -02:00
Arnaldo Carvalho de Melo a1abd424a5 [DWARVES]: Adopt tag__follow_typedef from pahole
Useful for other cases, such as class__fixup_alignment in dwarves_reorganize.c.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-14 21:36:30 -02:00
Arnaldo Carvalho de Melo a2eb3ea774 [DWARVES]: Add some destructors: tag, cu, namespace
To be used later.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-14 20:04:57 -02:00
Arnaldo Carvalho de Melo 48f5b0d824 [DWARVES]: Introduce cu__same_build_id
So that we can speed up codiff when just some object files changed in a
multi-cu file.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-14 15:39:41 -02:00
Arnaldo Carvalho de Melo 0e09769bb4 [DWARVES]: Don't search in empty structs
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-13 16:04:09 -02:00
Arnaldo Carvalho de Melo b32024f7f6 [DWARVES]: Follow const and volatile tags to its ultimate types
In type__find_first_biggest_size_base_type_member.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-13 15:42:33 -02:00
Arnaldo Carvalho de Melo 2a6382f143 [DWARVES]: Introduce type__find_first_biggest_size_base_type_member
What a mouthful ;-) To be used in finding the most aligned member in a non-packed
type, i.e. one that originally wasn't __attribute__((packed)).

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-13 15:18:39 -02:00
Arnaldo Carvalho de Melo 2c58da36fa [PAHOLE]: Check if types of struct and union members were already resized
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-12 15:25:12 -02:00
Arnaldo Carvalho de Melo 5d4405bf90 [DWARVES]: build id support requires a recent elfutils package
That is not present in stable distros, where people trying the dwarves, for
now, should just disable build id support in this awkward way till I find out
how to do it properly using cmake.

Or you can get so annoyed to the point of submitting a patch to fix this ;-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2008-01-10 12:10:51 -02:00
Arnaldo Carvalho de Melo 5bc698ab1b [DUTIL]: Move __unused definition to dutil.h
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-16 14:47:59 -02:00
Arnaldo Carvalho de Melo c4ee21aa12 [DWARVES]: Kill some warnings by turning ident variables to int
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-08 01:56:03 -02:00
Arnaldo Carvalho de Melo 114b534f32 [DWARVES]: Check if a bitfield that was combined with a previous field is at the end of the struct
This was found on an old openbsd kernel image that Leonardo Chiquito built
enabling DWARF instead of the default, STABS debugging format 8)

Just this struct has this characteristic:

struct ricoh_is410_window_data {
        struct scsi_window_data    window_data;          /*     0    48 */
        u_int8_t                   res1;                 /*    48     1 */
        u_int8_t                   res2;                 /*    49     1 */

        /* Bitfield combined with previous fields */

        u_int                      mrif:1;               /*    48:15  4 */
        u_int                      filtering:3;          /*    48:12  4 */
        u_int                      gamma_id:4;           /*    48: 8  4 */

        /* size: 52, cachelines: 1 */
        /* bit_padding: 24 bits */
        /* last cacheline: 52 bytes */
};

Now there are no BRAIN FART ALERT!s when paholing openbsd, yay!

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-08 01:46:53 -02:00
Arnaldo Carvalho de Melo b55ede8af2 [DWARVES]: Handle having a bitfield starting at the same offset as a non-bitfield
One more BRAIN FART ALERT! hits the dust.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-08 01:39:29 -02:00
Arnaldo Carvalho de Melo dcb2563bfe [DWARVES]: Fix class__fprintf wrt bitfields combined with previous/next small fields
Lots of BRAIN FART ALERT!s removed!

There is still a problem in class__find_holes where we don't catch bitfields
that are combined with previous fields where the byte offset for the bitfield
is the same as the previous field. This happens when the compiler combines a
bitfield with real byte size > 1 just after a one or two bytes field that is at
an alignment boundary.

Will fix later.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-07 19:27:52 -02:00
Arnaldo Carvalho de Melo 7953ff3ed3 [DWARVES]: Mark the end of bitfields in class__find_holes
To ease some algorithms where we have to find the transition from
one bitfield to another.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-07 19:24:59 -02:00
Arnaldo Carvalho de Melo 68be38bddd [DWARVES]: Properly find holes in bitfields
Make class__find_holes understand that when a byte offset goes backward it is
because the compiler is "combining" small bitfields with previous fields, and
using from the end of the combined bitfield + small fields. This made your
head hurt, huh? One example:

struct usb_bus {
	struct device *            controller;           /*     0     8 */
	int                        busnum;               /*     8     4 */

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

	char *                     bus_name;             /*    16     8 */
	u8                         uses_dma;             /*    24     1 */
	u8                         otg_port;             /*    25     1 */

	/* Bitfield combined with previous fields */

	unsigned int               is_b_host:1;          /*    24:15  4 */
	unsigned int               b_hnp_enable:1;       /*    24:14  4 */

	/* XXX 14 bits hole, try to pack */

	int                        devnum_next;          /*    28     4 */
	struct usb_devmap          devmap;               /*    32    16 */
<SNIP>
};

See? is_b_host:1 .. b_hnp_enable:1 makes a bitfield of just two bits.

The programmer decided to make this a 'unsigned int' bitfield, so taking 4 bytes.

And placed this "4" bytes bitfield just after two fields of one byte.

The compiler put the "4" bytes bitfield "in the same place" as the "uses_dma"
field, but its really not clobbering it neither "otg_port", as it allocates it
from (offset 24 + sizeof(unsigned int) - 1), backwards.

So at the end there is a, now correctly calculated, 14 bits hole, and that
matches the bit offset used for the last field, that is "14", as offsets for
bits and bytes starts at zero, all is explained now.

One last thing is that since we actually have 14 bits we in fact have a one
byte hole + a 6 bits hole, but that should be clear (haha) for those looking
for holes :-)

Nah, just run pahole reorganize on this beast and you'll have (for the complete
structure, with the <SNIP> part back in:

struct usb_bus {
	struct device *            controller;           /*     0     8 */
	int                        busnum;               /*     8     4 */
	unsigned char              is_b_host:1;          /*    12:247  1 */
	unsigned char              b_hnp_enable:1;       /*    12:246  1 */

	/* XXX 6 bits hole, try to pack */

	u8                         otg_port;             /*    13     1 */
	u8                         uses_dma;             /*    14     1 */

	/* XXX 1 byte hole, try to pack */

	char *                     bus_name;             /*    16     8 */
	int                        bandwidth_isoc_reqs;  /*    24     4 */
	int                        devnum_next;          /*    28     4 */
	struct usb_devmap          devmap;               /*    32    16 */
	struct usb_device *        root_hub;             /*    48     8 */
	struct list_head           bus_list;             /*    56    16 */
	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
	int                        bandwidth_allocated;  /*    72     4 */
	int                        bandwidth_int_reqs;   /*    76     4 */
	struct dentry *            usbfs_dentry;         /*    80     8 */
	struct class_device *      class_dev;            /*    88     8 */
	struct mon_bus *           mon_bus;              /*    96     8 */
	int                        monitored;            /*   104     4 */

	/* size: 112, cachelines: 2 */
	/* sum members: 107, holes: 1, sum holes: 1 */
	/* bit holes: 1, sum bit holes: 6 bits */
	/* padding: 4 */
	/* last cacheline: 48 bytes */
};   /* saved 8 bytes! */

And we save 8 bytes and reduce the previous complexity. Hey, but look at those
bit offsets at is_b_host and b_hnp_enable... damn, exposing the bit offsets I
just exposed another bug, that is: the reorganization code is not fixing up the
bit offsets, one more for the TODO list, nah, just compile it and pass the
results back to the dwarves and we get:

struct usb_bus {
	struct device *            controller;           /*     0     8 */
	int                        busnum;               /*     8     4 */
	unsigned char              is_b_host:1;          /*    12: 7  1 */
	unsigned char              b_hnp_enable:1;       /*    12: 6  1 */

	/* XXX 6 bits hole, try to pack */

	u8                         otg_port;             /*    13     1 */
	u8                         uses_dma;             /*    14     1 */

	/* XXX 1 byte hole, try to pack */

	char *                     bus_name;             /*    16     8 */
	int                        bandwidth_isoc_reqs;  /*    24     4 */
	int                        devnum_next;          /*    28     4 */
	struct usb_devmap          devmap;               /*    32    16 */
	struct usb_device *        root_hub;             /*    48     8 */
	struct list_head           bus_list;             /*    56    16 */
	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
	int                        bandwidth_allocated;  /*    72     4 */
	int                        bandwidth_int_reqs;   /*    76     4 */
	struct dentry *            usbfs_dentry;         /*    80     8 */
	struct class_device *      class_dev;            /*    88     8 */
	struct mon_bus *           mon_bus;              /*    96     8 */
	int                        monitored;            /*   104     4 */

	/* size: 112, cachelines: 2 */
	/* sum members: 107, holes: 1, sum holes: 1 */
	/* bit holes: 1, sum bit holes: 6 bits */
	/* padding: 4 */
	/* last cacheline: 48 bytes */
};

See? this time gcc fixed up things for us and even agreed on the reorganization
the dwarves did! 8-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-07 15:03:27 -02:00
Arnaldo Carvalho de Melo 31d20380cc [DWARVES]: Print the bit offset too
Helps understanding how bitfields really work, and after all it is just
confusing, not wrong.

See this one:

struct usb_bus {
	struct device *      controller;       /*   0     8 */
	int                  busnum;           /*   8     4 */

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

	char *               bus_name;         /*  16     8 */
	u8                   uses_dma;         /*  24     1 */
	u8                   otg_port;         /*  25     1 */

	/* WARNING: DWARF offset=24, real offset=26 */

	unsigned int         is_b_host:1;      /*  24:15  4 */
	unsigned int         b_hnp_enable:1;   /*  24:14  4 */

	/* XXX 30 bits hole, try to pack */

	int                  devnum_next;      /*  28     4 */
<SNIP>
};

So the bitfield _really_ is at offset 24 and the "WARNING:" above is just
pahole not understanding how it works, i.e. it starts at 24 and since the
bitfield has a 'unsigned int' as its base type it goes from 24 to 27, the
offsets start at the end, i.e. from byte 27 back to byte 27, but as only two
bits are used, it puts bit padding at the end, at bit offset 0, that is the
last bit in byte 27 and uses the first bits of byte 26 at bit offset 14 and 15.

Now to make libdwarves finally understand this convention.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-07 14:12:35 -02:00
Arnaldo Carvalho de Melo 07e0974f2c [DWARVES]: Add sanity check when calculating size from DWARF offsets
This struct, from the linux kernel:

struct usb_bus {
        struct device *            controller;           /*     0     8 */
        int                        busnum;               /*     8     4 */
        char *                     bus_name;             /*    16     8 */
        u8                         uses_dma;             /*    24     1 */
        u8                         otg_port;             /*    25     1 */
        unsigned int               is_b_host:1;          /*    24     4 */
        unsigned int               b_hnp_enable:1;       /*    24     4 */
        int                        devnum_next;          /*    28     4 */
        struct usb_devmap          devmap;               /*    32    16 */
        struct usb_device *        root_hub;             /*    48     8 */
        struct list_head           bus_list;             /*    56    16 */
        int                        bandwidth_allocated;  /*    72     4 */
        int                        bandwidth_int_reqs;   /*    76     4 */
        int                        bandwidth_isoc_reqs;  /*    80     4 */
        struct dentry *            usbfs_dentry;         /*    88     8 */
        struct class_device *      class_dev;            /*    96     8 */
        struct mon_bus *           mon_bus;              /*   104     8 */
        int                        monitored;            /*   112     4 */
};

Generates seemingly wrong DWARF when compiled with GCC:

struct usb_bus {
	struct device *            controller;           /*     0     8 */
	int                        busnum;               /*     8     4 */

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

	char *                     bus_name;             /*    16     8 */
	u8                         uses_dma;             /*    24     1 */
	u8                         otg_port;             /*    25     1 */

	/* WARNING: DWARF offset=24, real offset=26 */

	unsigned int               is_b_host:1;          /*    24     4 */
	unsigned int               b_hnp_enable:1;       /*    24     4 */

	/* XXX 30 bits hole, try to pack */

	int                        devnum_next;          /*    28     4 */
	struct usb_devmap          devmap;               /*    32    16 */
	struct usb_device *        root_hub;             /*    48     8 */
	struct list_head           bus_list;             /*    56    16 */
	/* --- cacheline 1 boundary (64 bytes) was 10 bytes ago --- */
	int                        bandwidth_allocated;  /*    72     4 */
	int                        bandwidth_int_reqs;   /*    76     4 */
	int                        bandwidth_isoc_reqs;  /*    80     4 */

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

	struct dentry *            usbfs_dentry;         /*    88     8 */
	struct class_device *      class_dev;            /*    96     8 */
	struct mon_bus *           mon_bus;              /*   104     8 */
	int                        monitored;            /*   112     4 */

	/* size: 120, cachelines: 2 */
	/* sum members: 110, holes: 2, sum holes: 8 */
	/* bit holes: 1, sum bit holes: 30 bits */
	/* padding: 4 */
	/* last cacheline: 56 bytes */

	/* BRAIN FART ALERT! 120 != 110 + 8(holes), diff = 2 */

};

Look at the offset for the first entry in the bitfield (is_b_host), the
compiler said in the DWARF info that it was at offset 25, when in fact it is at
offset 26 as can be seen when looking at the generated assembly code.

This previously was confusing libdwarves, as it uses subtracts the last offset
from the current offset to see what was the size the compiler really allocated
to then check if it is equal to the size of the previous entry, so as to detect
alignment holes.

The offsets are uint32_t, so cast both to int64_t when doing the calculation,
the existing code already deals with negative numbers that result in this
patologic case.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-12-06 21:59:42 -02:00
Arnaldo Carvalho de Melo 5a58b1dfef [DWARVES]: Use dwfl_getdwarf in cus__loadfl to get the buildid
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-11-24 00:28:15 -02:00
Arnaldo Carvalho de Melo 515738edee [DWARVES]: Initialize tool_node on function__new
In ctracer we can find a function that receives as one of its arguments a
pointer to the target class and also a pointer to an alias or pointer class,
so we have to check if the function was already added to one of these lists:

class methods list
class aliases list
class pointer list

To avoid corrupting one of them by trying to add the function to multiple
lists.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-11-17 11:11:33 -02:00
Arnaldo Carvalho de Melo 6c7a1721ec [DWARVES]: Tell cu__find_struct_by_name if struct declarations are wanted
When we are looking for members of some type in all CUs it may be that in
some CU we don't have the full type, but just a declaration.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-11-16 18:16:56 -02:00
Arnaldo Carvalho de Melo 0284699d63 [DWARVES]: Add missing semicolon to anonymous struct union members
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2007-11-11 17:30:43 -02:00
Arnaldo Carvalho de Melo bb9bb96c5b [DWARVES]: Replace misplaced putchar with fputc in class__fprintf
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-11-10 16:27:24 -02:00
Arnaldo Carvalho de Melo 09b28d519e [DWARVES]: Cast Dwarf_Off to unsigned long long
To kill compiler warnings.

Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-11-10 15:56:30 -02:00
Eduardo Habkost 15c6f261b6 [CMAKE] Define _GNU_SOURCE on CMakeLists.txt
The latest elfutils-libelf headers won't compile without _LARGEFILE64_SOURCE
(that is implied by _GNU_SOURCE).

Some .c files don't have a #define _GNU_SOURCE line. Instead of adding the line
to all .c files, define it globally on CMakeLists.txt.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
2007-10-26 13:21:31 -02:00
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