3 # Check the stack usage of functions
5 # Copyright Joern Engel <joern@wh.fh-wedel.de>
6 # Inspired by Linus Torvalds
7 # Original idea maybe from Keith Owens
10 # objdump -d vmlinux | checkstack.pl <arch>
12 # find <moduledir> -name "*.o" | while read M; do
13 # objdump -d $M | perl ~/checkstack.pl <arch> | \
14 # sed "s/^/`basename $M`: /" ; done | \
15 # awk '/esp/ { print $5, $2, $4 }' | sort -nr
17 # TODO : Port to all architectures (one regex per arch)
22 # $re is used for three matches:
23 # $& (whole re) matches the complete objdump line with the stack growth
24 # $1 (first bracket) matches the code that will be displayed in the output
25 # $2 (second bracket) matches the size of the stack growth
27 # use anything else and feel the pain ;)
30 $x = "[0-9a-f]"; # hex character
31 $xs = "[0-9a-f ]"; # hex character or space
32 if ($arch =~ /^i[3456]86$/) {
33 #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
34 $re = qr/^.*(sub/s\$(0x$x{3,5}),\%esp)$/o;
35 } elsif ($arch =~ /^ia64$/) {
37 $re = qr/.*(adds/sr12=-($x{3,5}),r12)/o;
38 } elsif ($arch =~ /^ppc$/) {
39 #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
40 $re = qr/.*(stwu/sr1,-($x{3,5})\(r1\))/o;
41 } elsif ($arch =~ /^s390x?$/) {
42 # 11160: a7 fb ff 60 aghi %r15,-160
43 $re = qr/.*(ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}))/o;
45 print("wrong or unknown architecture\n");
51 ($asize = $a) =~ s/$re/\2/;
52 ($bsize = $b) =~ s/$re/\2/;
59 $funcre = qr/^$x* \<(.*)\>:$/;
60 while ($line = <STDIN>) {
61 if ($line =~ m/$funcre/) {
62 ($func = $line) =~ s/$funcre/\1/;
66 if ($line =~ m/$re/) {
67 (my $addr = $line) =~ s/^($xs{8}).*/0x\1/o;
70 my $intro = "$addr $func:";
71 my $padlen = 56 - length($intro);
76 (my $code = $line) =~ s/$re/\1/;
78 $stack[@stack] = "$intro $code";
82 @sortedstack = sort bysize @stack;
84 foreach $i (@sortedstack) {
89 http://sourceforge.net/projects/ext2resize/
90 http://www-mddsp.enel.ucalgary.ca/People/adilger/