Commit Graph

33 Commits

Author SHA1 Message Date
Arnaldo Carvalho de Melo b31090f722 [CLASSES]: Move more stuff to the lexblock namespace
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:51:42 -02:00
Arnaldo Carvalho de Melo 6a3cc448d1 [CLASSES]: Introduce struct lexblock
To represent DW_TAG_lexical_block, for now just group the lists of
labels, inline expansions and variables, struct function now has
the root of the tree as ->lexblock.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 16:38:47 -02:00
Arnaldo Carvalho de Melo 139cfd3318 [CLASSES]: Enhance function__print
Introducing function__print_body, that orders the tags in a function by the
souce code line where it was declared or inlined.

This finally takes advantage of the struct tag "superclass", more to come in
the form of lexical blocks and goto labels.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-20 15:43:39 -02:00
Arnaldo Carvalho de Melo 2d4c37208f [PFUNCT]: Introduce --cc_uninlined
I.e. the functions declared as inline but not inlined by the compiler
DW_AT_inline with DW_INL_declared_not_inlined value.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 19:08:37 -02:00
Arnaldo Carvalho de Melo 179e15d553 [PFUNCT]: Differentiate inlining cases
Following what is in the DWARF2 specs:

Name                          Meaning
-----------------------------------------------------------------------------
DW_INL_not_inlined            Not declared inline nor inlined by the compiler
DW_INL_inlined                Not declared inline but inlined by the compiler
DW_INL_declared_not_inlined   Declared inline but not inlined by the compiler
DW_INL_declared_inlined       Declared inline and inlined by the compiler

Take advantae of this and use it in a new pfunct option: --cc_inlined, to
show which functions were of the DW_INL_inlined type.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 19:02:55 -02:00
Arnaldo Carvalho de Melo bff3938037 [CLASSES]: Introduce struct function & struct parameter
And helper routines, so as to separate DW_TAG_subprogram from
the type tags (DW_TAG_structure_type, basic_type, etc).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 14:33:48 -02:00
Arnaldo Carvalho de Melo 5afa478d8d [CLASSES]: Introduce struct tag
This should have been done from the start: all DW_TAG_s will be represented by
structs that has as its first member a struct tag, so that we can fully
represent the DWARF information, following csets will take continue the
restructuring.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-18 11:54:02 -02:00
Arnaldo Carvalho de Melo 47845f0f9b [PFUNCT]: Implement --externals
That uses the DW_AT_external attribute, that tells if the DW_TAG_subprogram
(a function) is visible externally.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-17 23:43:08 -02:00
Arnaldo Carvalho de Melo d3b9b9bfcf [CLASSES]: Add backpointer to class in inline_expansion
And several assorted tidy-ups.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-13 00:31:48 -02:00
Arnaldo Carvalho de Melo 9490088ae0 [CLASSES]: Use the struct cu backpointer
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-12 17:33:37 -02:00
Arnaldo Carvalho de Melo 0f5548a55f [CODIFF]: New tool
1. build, save the object
2. change it, build
3. do the diff!

[acme@newtoy net-2.6.20]$ codiff /tmp/ipv6.ko.before /tmp/ipv6.ko.after | head -22
/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/af_inet6.c:
 inet6_init              |  +50
 inet6_create            |  -15
 inet6_getname           |  +13
 inet6_sk_rebuild_header |   +5
4 functions changed, 68 bytes added, 15 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/anycast.c:
 ipv6_sock_ac_join |   +7
1 function changed, 7 bytes added

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/ip6_output.c:
 ip6_output2             |  +14
 ip6_sk_dst_lookup       |   -2
 ip6_push_pending_frames |   +5
 ip6_xmit                |   +4
 ip6_forward             |   +1
 ip6_nd_hdr              |  +13
6 functions changed, 37 bytes added, 2 bytes removed

/pub/scm/linux/kernel/git/acme/net-2.6.20/net/ipv6/addrconf.c:
 ipv6_rcv_saddr_equal |  +16
[acme@newtoy net-2.6.20]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-11 16:31:04 -02:00
Arnaldo Carvalho de Melo e45f877489 [MAKEFILE]: Use -Wall
And fix the warnings generated.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-11 14:15:50 -02:00
Arnaldo Carvalho de Melo b4b2f83057 [PFUNCT]: Tidy up --total_inline_stats column headers
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-10 21:08:42 -02:00
Arnaldo Carvalho de Melo 51c81fb099 [CLASSES]: namespace cleanups: just rename the classes__ with cu__
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 15:46:45 -02:00
Arnaldo Carvalho de Melo 4f0c9ef164 [CLASSES]: Introduce struct variable
To represent DW_TAG_variable, for now all the variables in all the lexical
blocks, in addition to the top level function variables are in this list, next
step is to add support for DW_TAG_lexical_block, with support for nesting, and
to associate variables to the right place, be it the function itself (first,
implicit lexical block) or to the lexical blocks they belong too, this will be
useful for calculating stack usage.

So, with what we have now pfunct can do this:

[acme@newtoy guinea_pig-2.6]$ pfunct --variables net/ipv4/built-in.o tcp_v4_remember_stamp
/* net/ipv4/tcp_ipv4.c:1197 */
int tcp_v4_remember_stamp(struct sock * sk);

{
        /* variables in tcp_v4_remember_stamp: */
        struct inet_sock * inet;
        struct tcp_sock * tp;
        struct rtable * rt;
        struct inet_peer * peer;
        int release_it;
}
[acme@newtoy guinea_pig-2.6]$

That is already useful when you don't have the sources, huh? :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-05 01:31:41 -02:00
Arnaldo Carvalho de Melo dd482c5983 [PFUNCT]: Print the average size of inline expansions
Its just totsz / nrexp, i.e. total size of expansions divided by the number of
expansions found, but helps in analising the data.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-04 17:34:20 -03:00
Arnaldo Carvalho de Melo d731cb8674 [PFUNCT]: Add some missing getopt entries
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-04 00:11:04 -03:00
Arnaldo Carvalho de Melo 784968cca1 [PFUNCT]: Add a header with the columns names
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 19:47:07 -03:00
Arnaldo Carvalho de Melo 05ca190f25 [PFUNCT]: Introduce --total_inline_stats
Top 10 inline functions expanded more than once by sum of its expansions,
columns are (name, nr expansions, sum of expansions, nr source files where
expansions ocurred):

[acme@newtoy guinea_pig-2.6]$ pfunct --total_inline_stats ../../acme/OUTPUT/qemu/net-2.6/vmlinux | grep -v ': 1 ' | sort -k3 -nr | head -10
get_current                        676   5732 155
xfrm_selector_match                  6   4778   2
__memcpy                           177   4326  89
kmalloc                            185   3991 119
__constant_c_memset                113   3556  69
__constant_c_and_count_memset      225   3161 156
prefetch                           333   2915 101
__ext3_journal_dirty_metadata       44   2810   6
skb_put                             34   2650  27
module_put                          80   2613  42
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 16:14:25 -03:00
Arnaldo Carvalho de Melo 2124d4f375 [PFUNCT]: Improve --cu_inline_expansions_stats
Now it shows the number that each of the inline functions were expanded in an
object file:

Top 10 inline functions expanded more than once in kernel/sched.o, by total
size of inline expansions:

[acme@newtoy guinea_pig-2.6]$ pfunct --cu_inline_expansions_stats kernel/sched.o | sort -k3 -nr | grep -v ': 1 ' | head -11
kernel/sched.c: 318 10217
get_current: 38 325
finish_task_switch: 2 238
normal_prio: 2 167
__cpus_and: 14 164
find_process_by_pid: 6 152
current_thread_info: 21 149
sched_find_first_bit: 2 148
update_cpu_clock: 2 140
task_rq_unlock: 14 137
variable_test_bit: 14 121
[acme@newtoy guinea_pig-2.6]$

Now we have these options:

[acme@newtoy guinea_pig-2.6]$ pfunct --help
usage: pfunct [options] <file_name> {<function_name>}
 where:
   -c, --class=<class>               functions that have <class> pointer parameters
   -g, --goto_labels                 show number of goto labels
   -i, --show_inline_expansions      show inline expansions
   -C, --cu_inline_expansions_stats  show CU inline expansions stats
   -s, --sizes                       show size of functions
   -N, --function_name_len           show size of functions
   -p, --nr_parameters               show number or parameters
   -S, --variables                   show number of variables
   -V, --verbose                     be verbose
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 15:22:12 -03:00
Arnaldo Carvalho de Melo dcfe27a7ef [PFUNCT]: Do per CU inline statistics
Top five object files (CU, Compilation Unit) per number of inline expansions,
vmlinux being dissected is one built for QEMU, most things as modules, that
are not being taken into account as we're only looking at vmlinux:

[acme@newtoy guinea_pig-2.6]$ pfunct -C ../../acme/OUTPUT/qemu/net-2.6/vmlinux | sort -k2 -nr | head -5 | cut -c40-
net/ipv4/tcp_input.c: 274 20655
fs/buffer.c: 272 4597
kernel/sched.c: 214 3549
kernel/signal.c: 196 2730
fs/ext3/inode.c: 191 7961
[acme@newtoy guinea_pig-2.6]$

Top five object files (CU, Compilation Unit) per total size of inline expansions:

[acme@newtoy guinea_pig-2.6]$ pfunct -C ../../acme/OUTPUT/qemu/net-2.6/vmlinux | sort -k3 -nr | head -5 | cut -c40-
net/ipv4/tcp_input.c: 274 20655
net/xfrm/xfrm_policy.c: 173 11511
kernel/module.c: 95 10826
drivers/char/vt.c: 91 10050
net/xfrm/xfrm_user.c: 150 9682
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 14:38:43 -03:00
Arnaldo Carvalho de Melo a42afe1acf [CLASSES]: Add support for DW_TAG_inlined_subroutine
Output of pfunct using this information (all for a make allyesconfig build):

Top 5 functions by size of inlined functions in net/ipv4:

[acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k3 -nr | head -5
ip_route_input: 19 7086
tcp_ack: 33 6415
do_ip_vs_set_ctl: 23 4193
q931_help: 8 3822
ip_defrag: 19 3318
[acme@newtoy guinea_pig-2.6]$

And by number of inline expansions:

[acme@newtoy guinea_pig-2.6]$ pfunct -I net/ipv4/built-in.o | sort -k2 -nr | head -5
dump_packet: 35 905
tcp_v4_rcv: 34 1773
tcp_recvmsg: 34 928
tcp_ack: 33 6415
tcp_rcv_established: 31 1195
[acme@newtoy guinea_pig-2.6]$

And the list of expansions on a specific function:

[acme@newtoy guinea_pig-2.6]$ pfunct -i net/ipv4/built-in.o tcp_v4_rcv
/* net/ipv4/tcp_ipv4.c:1054 */
int tcp_v4_rcv(struct sk_buff * skb);
/* size: 2189, variables: 8, goto labels: 6, inline expansions: 34 (1773 bytes) */

/* inline expansions in tcp_v4_rcv:
current_thread_info: 8
pskb_may_pull: 36
pskb_may_pull: 29
tcp_v4_checksum_init: 139
__fswab32: 2
__fswab32: 2
inet_iif: 12
__inet_lookup: 292
__fswab16: 20
inet_ehashfn: 25
inet_ehash_bucket: 18
prefetch: 4
prefetch: 4
prefetch: 4
sock_hold: 4
xfrm4_policy_check: 59
nf_reset: 66
sk_filter: 135
__skb_trim: 20
get_softnet_dma: 68
tcp_prequeue: 257
sk_add_backlog: 40
sock_put: 27
xfrm4_policy_check: 46
tcp_checksum_complete: 29
current_thread_info: 8
sock_put: 20
xfrm4_policy_check: 50
tcp_checksum_complete: 29
current_thread_info: 8
inet_iif: 9
inet_lookup_listener: 36
inet_twsk_put: 114
tcp_v4_timewait_ack: 153
*/
[acme@newtoy guinea_pig-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-03 12:41:19 -03:00
Arnaldo Carvalho de Melo 97385598a6 [CLASSES]: Use strdup for the ->name members
Reducing the memory footprint, but more has to be done, such as to take
advantage of the strings table when handling indirect strings.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-02 13:48:35 -03:00
Arnaldo Carvalho de Melo 683428ee16 [PFUNCT]: Add missing 'else'
And update the --help output.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-01 18:08:54 -03:00
Arnaldo Carvalho de Melo 800429032e [PFUNCT]: Implement --function_name_len
[acme@newtoy net-2.6]$ pfunct --function_name_len vmlinux | sort -k 2 -nr | head -5
attribute_container_add_class_device_adapter: 44
wait_for_completion_interruptible_timeout: 41
sparse_memory_present_with_active_regions: 41
attribute_container_classdev_to_container: 41
percpu_pagelist_fraction_sysctl_handler: 39
[acme@newtoy net-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-01 10:42:18 -03:00
Arnaldo Carvalho de Melo 09bb5df8aa [PFUNCT]: Implement --nr_parameters
[acme@newtoy net-2.6]$ pfunct --nr_parameters vmlinux | sort -k 2 -nr | head -5
__ide_add_setting: 13
ide_add_setting: 12
fib_dump_info: 12
__blockdev_direct_IO: 10
vma_merge: 9
[acme@newtoy net-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-01 10:34:42 -03:00
Arnaldo Carvalho de Melo 4a6117a912 [PFUNCT]: Introduce --help
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-01 10:29:31 -03:00
Arnaldo Carvalho de Melo eff5348081 Handle the DW_TAG_variable and DW_TAG_label tags, now we can do:
[acme@newtoy net-2.6]$ pfunct --variables vmlinux | sort -k 2 -nr | head -5
do_task_stat: 29
load_elf_binary: 28
elf_core_dump: 23
ext3_new_blocks: 21
sys_unshare: 19
[acme@newtoy net-2.6]$

And:

[acme@newtoy net-2.6]$ pfunct --goto_labels vmlinux | sort -k 2 -nr | head -5
copy_process: 16
sys_unshare: 10
device_add: 9
class_device_add: 8
tcp_sendmsg: 7
[acme@newtoy net-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-11-01 10:18:01 -03:00
Arnaldo Carvalho de Melo 5aaca80de6 [CLASSES]: Rework the find_by routines
So that we can find all the cus for some specific class
(cus__find_class_by_name), or traverse all the CUs (cus__for_each_cu),
etc.

Now we don't look at just the first CU in multi-CU files (vmlinux, etc).

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-31 17:23:16 -03:00
Arnaldo Carvalho de Melo 0ca9826e36 Introduce struct cu, i.e. a per compilation unit struct that holds the list of
types for each CU, for now when working on multi-CU files (vmlinux, any binary
with more than one object file linked) we look only at the first CU when
looking for a specific class or function name, this will be fixed in the
upcoming csets, but doesn't affect the case when we don't specify a class or
function name, where all the CU's are traversed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-31 16:12:42 -03:00
Arnaldo Carvalho de Melo 8f1d76d93a [PFUNCT]: Implement --size in pfunct
[acme@newtoy net-2.6]$ pfunct --size net/ipv4/netfilter/ip_conntrack.ko | sort -k 2 -nr | head -5
tcp_packet: 3349
ip_conntrack_in: 1146
icmp_error: 874
ip_conntrack_expect_related: 804
__ip_conntrack_confirm: 586
[acme@newtoy net-2.6]$

'nuff said :-)

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-30 15:15:09 -03:00
Arnaldo Carvalho de Melo 3dfd363868 Add getopt support in pfunct, options implemented should be self explaining,
except for --classes, that asks that all non-inlined functions that receive as
one of its parameter a pointer to the specified class be printed, just the name
if --verbose is not used, or its complete prototype and where it is in the
source code:

[acme@newtoy net-2.6]$ pfunct --verbose --class=inode fs/ext3/built-in.o
/* /pub/scm/linux/kernel/git/acme/net-2.6/fs/ext3/balloc.c 606 */
void ext3_free_blocks(handle_t * handle, struct inode * inode, ext3_fsblk_t block, long unsigned int count);

/* /pub/scm/linux/kernel/git/acme/net-2.6/fs/ext3/balloc.c 1404 */
ext3_fsblk_t ext3_new_blocks(handle_t * handle, struct inode * inode, ext3_fsblk_t goal, long unsigned int * count, int * errp);

/* /pub/scm/linux/kernel/git/acme/net-2.6/fs/ext3/balloc.c 1668 */
ext3_fsblk_t ext3_new_block(handle_t * handle, struct inode * inode, ext3_fsblk_t goal, int * errp);

/* /pub/scm/linux/kernel/git/acme/net-2.6/fs/ext3/balloc.c 346 */
void ext3_init_block_alloc_info(struct inode * inode);

/* /pub/scm/linux/kernel/git/acme/net-2.6/fs/ext3/balloc.c 388 */
void ext3_discard_reservation(struct inode * inode);

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-29 00:41:48 -03:00
Arnaldo Carvalho de Melo e038f068b1 New dwarf: pfunct, see it in action:
[acme@newtoy net-2.6]$ pfunct ~acme/work/atag/atag | grep LRMI
void * LRMI_alloc_real(int size);
void LRMI_free_real(void * m);
int LRMI_init(void);
void set_regs(struct LRMI_regs * r);
void get_regs(struct LRMI_regs * r);
int LRMI_call(struct LRMI_regs * r);
int LRMI_int(int i, struct LRMI_regs * r);
[acme@newtoy net-2.6]$

[acme@newtoy net-2.6]$ pfunct kernel/sched.o task_running
int task_running(struct rq * rq, struct task_struct * p);
[acme@newtoy net-2.6]$

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
2006-10-28 19:07:45 -03:00