Finally we can use the Elf file already opened in dwarf_load, call
cu__for_each_cached_symtab_entry to iterate over the symtab entries,
this iterator will first call dwfl_module_getsymtab, that will do the
relocation that will allow us to go from the symtab address to the one
in the DWARF DW_TAG_subprogram tag DW_AT_low_pc attribute.
And voila, for a relatively complex single unit Linux kernel object
file, kernel/sched.o, we go from:
Just DWARF (gcc -g):
$ ls -la kernel/sched.o
1979011 kernel/sched.o
Then we run this to encode the CTF section:
$ pahole -Z kernel/sched.o
And get a file with both DWARF and CTF ELF sections:
$ ls -la kernel/sched.o
2019848 kernel/sched.o
We still need to encode the "OBJECTS", i.e. variables, but this
gets us from 1979011 (just DWARF) to:
$ strip--strip-debug kernel/sched.o
$ ls -la kernel/sched.o
-rw-rw-r-- 1 acme acme 507008 2009-03-30 23:01 kernel/sched.o
25% of the original size.
Of course we don't have inline expansion information, parameter names,
goto labels, etc, but should be good enough for most use cases.
See, without DWARF data, if we ask for it to use DWARF, nothing will be
printed, if we don't speficy the format, it will try first DWARF, it
will not find anything, it will try CTF:
$ pahole -F dwarf kernel/sched.o
$ pahole -C seq_operations kernel/sched.o
struct seq_operations {
void * (*start)(struct seq_file *, loff_t *); /* 0 8 */
void (*stop)(struct seq_file *, void *); /* 8 8 */
void * (*next)(struct seq_file *, void *, loff_t *); /* 16 8 */
int (*show)(struct seq_file *, void *); /* 24 8 */
/* size: 32, cachelines: 1, members: 4 */
/* last cacheline: 32 bytes */
};
$ $ pfunct -Vi -f schedule kernel/sched.o
void schedule(void);
{ /* low_pc=0xe01 */
}/* size: 83 */
$
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
It should free ->filename and only close the file and call
elf_end if it was opened at ctf__new.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
And ditch the iterate calling a function interface. I'm trying to get rid of
that in the core (cu__for_each+callback+filter, etc) because doit it
explicitely, like in the kernel, where you have a foo__for_each_bar and do the
filtering directly and process the data, if the processing is simple, right in
the body of the loop, instead of having to go back and forth thru functions.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
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>
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>
Too DWARF specific and wasn't working since I implemented type recoding and
removed the Dwarf_Off from struct tag.
To achieve the same result one can use --show_decl_info that also shows the
dwarf offset, since it needs to keep the DWARF specific line number and file
and then use a text editor to find the offset.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Moving more CTF only stuff out of the dwarves land and into something that can
be more easily stolen by other projects not interested in funny named stuff
such as pahole.
This also will help with encoding, as we will normally be recoding data from
DWARF, so the ELF file will be available and we will just add a new section to
it.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
The ctf_loader.c file should be a direct counterpart to dwarf_loader,
that is, it should have just use what is in libctf to decode the CTF
sections and convert it to the core format in dwarves.[ch].
Also introduce a ctf__string32 for the very common idiom:
ctf_string(ctf__get32(sp->ctf, &tp->base.ctf_name), sp);
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
We will need this when encoding the CTF functions section. Things like lookup
a function by its address when converting from a DW_TAG_subprogram to a CTF
function, for instance.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
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>
So now 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>
With this a "make allyesconfig" on a 2.6.29-rc8 Linux kernel build left 16
cases flagged by ctfdwdiff, 8 unique ones, out of 6209 single-cu (compile unit)
.o files.
But what this clearly shows is that we really need to detect if a struct is
packed, and wether it is naturally packed or if __attribute__ packed was used,
that way we will have more clues as to if a enum is packed or if the whole
struct where it is used as a type for a/several member(s) is packed.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
As we will show them on the first level. This is yet another thing
required to properly compare te result of "pahole -F ctf foo" with the
output of "pahole -F dwarf foo", as there is no support, that I know of,
for namespacing in ctf.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>