2003-03-03 21:06:36

by Jörn Engel

[permalink] [raw]
Subject: [PATCH] add checkstack Makefile target

On Thu, 20 February 2003 08:54:55 -0800, Linus Torvalds wrote:
>
> A sorted list of bad stack users (more than 256 bytes) in my default build
> follows. Anybody can create their own with something like
>
> objdump -d linux/vmlinux |
> grep 'sub.*$0x...,.*esp' |
> awk '{ print $9,$1 }' |
> sort > bigstack
>
> and a script to look up the addresses.

Since Linus didn't give us the script, I had to try it myself. The
result is likely ugly and inefficient, but it works for i386 and ppc
(actually crosscompiling for ppc).

This patch is against vanilla 2.4.20, but should apply to -pre5 as
well. Shouldn't be too hard to port to 2.5.x either, but I don't need
it there yet.

J?rn

--
This above all: to thine own self be true.
-- Shakespeare


diff -Naur foo/linux-2.4.20/arch/i386/Makefile linux-2.4.20/arch/i386/Makefile
--- foo/linux-2.4.20/arch/i386/Makefile Fri Nov 29 00:53:09 2002
+++ linux-2.4.20/arch/i386/Makefile Mon Mar 3 21:38:36 2003
@@ -139,9 +139,18 @@
@$(MAKEBOOT) BOOTIMAGE=bzImage install

archclean:
+ $(RM) $(TOPDIR)/scripts/checkstack_i386.pl
@$(MAKEBOOT) clean

archmrproper:

archdep:
@$(MAKEBOOT) dep
+
+$(TOPDIR)/scripts/checkstack_i386.pl: $(TOPDIR)/scripts/checkstack.pl
+ (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_i386.pl)
+
+checkstack: vmlinux $(TOPDIR)/scripts/checkstack_i386.pl
+ $(OBJDUMP) -d vmlinux | \
+ grep 'sub.*$0x...,.*esp' | \
+ $(TOPDIR)/scripts/checkstack_i386.pl
diff -Naur foo/linux-2.4.20/arch/ppc/Makefile linux-2.4.20/arch/ppc/Makefile
--- foo/linux-2.4.20/arch/ppc/Makefile Fri Nov 29 00:53:11 2002
+++ linux-2.4.20/arch/ppc/Makefile Mon Mar 3 21:38:52 2003
@@ -108,6 +108,7 @@
cp -f arch/ppc/configs/$(@:config=defconfig) arch/ppc/defconfig

archclean:
+ $(RM) $(TOPDIR)/scripts/checkstack_ppc.pl
rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks}
@$(MAKEBOOT) clean

@@ -115,3 +116,11 @@

archdep: scripts/mkdep
$(MAKEBOOT) fastdep
+
+$(TOPDIR)/scripts/checkstack_ppc.pl: $(TOPDIR)/scripts/checkstack.pl
+ (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_ppc.pl)
+
+checkstack: vmlinux $(TOPDIR)/scripts/checkstack_ppc.pl
+ $(OBJDUMP) -d vmlinux | \
+ grep 'stwu.*r1,-.\{3,\}(r1)' | \
+ $(TOPDIR)/scripts/checkstack_ppc.pl
diff -Naur foo/linux-2.4.20/scripts/checkstack.pl linux-2.4.20/scripts/checkstack.pl
--- foo/linux-2.4.20/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.4.20/scripts/checkstack.pl Mon Mar 3 20:46:52 2003
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Usage for ppc:
+# powerpc-linux-objdump -d vmlinux | \
+# grep 'stwu.*r1,-.\{3,\}(r1)' | \
+# stackcheck_ppc.pl
+
+{
+ (my $arch = $0) =~ s/.*checkstack_(.+)\.pl$/\1/;
+ if ($arch =~ /^i386$/) {
+ $get_code = 'get_code_i386 "@_"';
+ $bysize = 'bysize_i386 "@_"';
+ } elsif ($arch =~ /^ppc$/) {
+ $get_code = 'get_code_ppc "@_"';
+ $bysize = 'bysize_ppc "@_"';
+ } else {
+ $get_code = "exit";
+ $bysize = "exit";
+ }
+}
+
+sub get_intro($) {
+ my $line = $_[0];
+
+ (my $addr = $line) =~ s/^([0-9a-f]{8}).*/0x\1/;
+ chomp($addr);
+
+ my $ksymoops = `ksymoops -v vmlinux -m System.map -K -L -O -A $addr | \
+ tail -2 | head -1`;
+ (my $func = $ksymoops) =~ s/^Adhoc [0-9a-f]{8} (<.*>)/\1/;
+ chomp($func);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ return $intro
+}
+
+sub get_code_ppc {
+ (my $code = shift) =~ s/.*(stwu.*)/\1/;
+ chomp($code);
+ return $code
+}
+
+sub bysize_ppc {
+ ($asize = $a) =~ s/.*r1,-([0-9]+)\(r1\)/\1/;
+ ($bsize = $b) =~ s/.*r1,-([0-9]+)\(r1\)/\1/;
+ $bsize <=> $asize
+}
+
+sub get_code_i386 {
+ (my $code = shift) =~ s/.*(sub.*)/\1/;
+ chomp($code);
+ return $code
+}
+
+sub bysize_i386 {
+ $a cmp $b
+}
+
+sub get_code($) {
+ eval $get_code
+}
+
+sub bysize($) {
+ eval $bysize
+}
+
+#
+# main()
+#
+$i = 5;
+while (defined($line = <STDIN>)
+ && $i-- > 0
+ ) {
+
+ my $intro = get_intro($line);
+ my $code = get_code($line);
+
+ $stack[@stack] = "$intro $code";
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i\n");
+}


2003-03-04 06:55:40

by Muli Ben-Yehuda

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Mon, Mar 03, 2003 at 10:16:47PM +0100, J?rn Engel wrote:
> On Thu, 20 February 2003 08:54:55 -0800, Linus Torvalds wrote:
> >
> > A sorted list of bad stack users (more than 256 bytes) in my default build
> > follows. Anybody can create their own with something like
> >
> > objdump -d linux/vmlinux |
> > grep 'sub.*$0x...,.*esp' |
> > awk '{ print $9,$1 }' |
> > sort > bigstack
> >
> > and a script to look up the addresses.
>
> Since Linus didn't give us the script, I had to try it myself. The
> result is likely ugly and inefficient, but it works for i386 and ppc
> (actually crosscompiling for ppc).

Keith Owens has such a script, and even posted it here a time or
three. You can find it (and various other near scripts) at
http://www.kernelnewbies.org/scripts/. As for making a Makefile
target, nice idea, but probably 2.5 material.
--
Muli Ben-Yehuda
http://www.mulix.org


Attachments:
(No filename) (899.00 B)
(No filename) (189.00 B)
Download all attachments

2003-03-04 07:14:14

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Tue, 4 March 2003 09:03:04 +0200, Muli Ben-Yehuda wrote:
>
> Keith Owens has such a script, and even posted it here a time or
> three. You can find it (and various other near scripts) at
> http://www.kernelnewbies.org/scripts/.

Good point!
Comparing both, there are some points in my favor though:
- Works for ppc as well, other platforms should be simple.
- Works for cross-compiling out of the box.
- More readable. :)

> As for making a Makefile target, nice idea, but probably 2.5 material.

Probably, yes. I'll port it later today.

J?rn

--
"Security vulnerabilities are here to stay."
-- Scott Culp, Manager of the Microsoft Security Response Center, 2001

2003-03-04 10:12:07

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

Added Keith to cc

On Tue, 4 March 2003 08:24:43 +0100, J?rn Engel wrote:
> On Tue, 4 March 2003 09:03:04 +0200, Muli Ben-Yehuda wrote:
> >
> > Keith Owens has such a script, and even posted it here a time or
> > three. You can find it (and various other near scripts) at
> > http://www.kernelnewbies.org/scripts/.
>
> Good point!
> Comparing both, there are some points in my favor though:
> - Works for ppc as well, other platforms should be simple.
> - Works for cross-compiling out of the box.
> - More readable. :)
- Linus output is nicer.

Con:
- Keith is _much_ faster. 14s vs. 200s on some test kernel.

Tough call. How much does speed matter for something like this?

Still, the patch was updated a little.

J?rn

--
Geld macht nicht gl?cklich.
Gl?ck macht nicht satt.

diff -Naur foo/linux-2.4.20/arch/i386/Makefile linux-2.4.20/arch/i386/Makefile
--- foo/linux-2.4.20/arch/i386/Makefile Fri Nov 29 00:53:09 2002
+++ linux-2.4.20/arch/i386/Makefile Mon Mar 3 21:38:36 2003
@@ -139,9 +139,18 @@
@$(MAKEBOOT) BOOTIMAGE=bzImage install

archclean:
+ $(RM) $(TOPDIR)/scripts/checkstack_i386.pl
@$(MAKEBOOT) clean

archmrproper:

archdep:
@$(MAKEBOOT) dep
+
+$(TOPDIR)/scripts/checkstack_i386.pl: $(TOPDIR)/scripts/checkstack.pl
+ (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_i386.pl)
+
+checkstack: vmlinux $(TOPDIR)/scripts/checkstack_i386.pl
+ $(OBJDUMP) -d vmlinux | \
+ grep 'sub.*$0x...,.*esp' | \
+ $(TOPDIR)/scripts/checkstack_i386.pl
diff -Naur foo/linux-2.4.20/arch/ppc/Makefile linux-2.4.20/arch/ppc/Makefile
--- foo/linux-2.4.20/arch/ppc/Makefile Fri Nov 29 00:53:11 2002
+++ linux-2.4.20/arch/ppc/Makefile Mon Mar 3 21:38:52 2003
@@ -108,6 +108,7 @@
cp -f arch/ppc/configs/$(@:config=defconfig) arch/ppc/defconfig

archclean:
+ $(RM) $(TOPDIR)/scripts/checkstack_ppc.pl
rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks}
@$(MAKEBOOT) clean

@@ -115,3 +116,11 @@

archdep: scripts/mkdep
$(MAKEBOOT) fastdep
+
+$(TOPDIR)/scripts/checkstack_ppc.pl: $(TOPDIR)/scripts/checkstack.pl
+ (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_ppc.pl)
+
+checkstack: vmlinux $(TOPDIR)/scripts/checkstack_ppc.pl
+ $(OBJDUMP) -d vmlinux | \
+ grep 'stwu.*r1,-.\{3,\}(r1)' | \
+ $(TOPDIR)/scripts/checkstack_ppc.pl
diff -Naur foo/linux-2.4.20/scripts/checkstack.pl linux-2.4.20/scripts/checkstack.pl
--- foo/linux-2.4.20/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.4.20/scripts/checkstack.pl Tue Mar 4 11:07:23 2003
@@ -0,0 +1,105 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <[email protected]>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+#
+# Usage for ppc:
+# ln -s stackcheck.pl stackcheck_ppc.pl
+# powerpc-linux-objdump -d vmlinux | \
+# grep 'stwu.*r1,-.\{3,\}(r1)' | \
+# stackcheck_ppc.pl
+
+# check for arch
+{
+ (my $arch = $0) =~ s/.*checkstack_(.+)\.pl$/\1/;
+ if ($arch =~ /^i386$/) {
+ $get_code = 'get_code_i386 "@_"';
+ $bysize = 'bysize_i386 "@_"';
+ } elsif ($arch =~ /^ppc$/) {
+ $get_code = 'get_code_ppc "@_"';
+ $bysize = 'bysize_ppc "@_"';
+ } else {
+ print "wrong or unknown architecture";
+ exit
+ }
+}
+
+# arch-independent: address and function name
+sub get_intro($) {
+ my $line = $_[0];
+
+ (my $addr = $line) =~ s/^([0-9a-f]{8}).*/0x\1/;
+ chomp($addr);
+
+ my $ksymoops = `ksymoops -v vmlinux -m System.map -K -L -O -A $addr | \
+ tail -2 | head -1`;
+ (my $func = $ksymoops) =~ s/^Adhoc [0-9a-f]{8} (<.*>)/\1/;
+ chomp($func);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ return $intro
+}
+
+# arch-specific: code and comparison
+
+#c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+sub get_code_ppc {
+ (my $code = shift) =~ s/.*(stwu.*)/\1/;
+ chomp($code);
+ return $code
+}
+
+sub bysize_ppc {
+ ($asize = $a) =~ s/.*r1,-([0-9]+)\(r1\)/\1/;
+ ($bsize = $b) =~ s/.*r1,-([0-9]+)\(r1\)/\1/;
+ $bsize <=> $asize
+}
+
+#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+sub get_code_i386 {
+ (my $code = shift) =~ s/.*(sub.*)/\1/;
+ chomp($code);
+ return $code
+}
+
+sub bysize_i386 {
+ ($asize = $a) =~ s/.*sub.*\$0x([0-9]+),\%esp/\1/;
+ ($bsize = $b) =~ s/.*sub.*\$0x([0-9]+),\%esp/\1/;
+ $a cmp $b
+}
+
+sub get_code($) {
+ eval $get_code
+}
+
+sub bysize($) {
+ eval $bysize
+}
+
+#
+# main()
+#
+$i = 5;
+while (defined($line = <STDIN>)
+ #&& $i-- > 0
+ ) {
+
+ my $intro = get_intro($line);
+ my $code = get_code($line);
+
+ $stack[@stack] = "$intro $code";
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i\n");
+}

2003-03-04 10:47:10

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

This is the checkstack patch for 2.5.63 vanilla.
Again, it works for i386 and ppc and is slow like hell.

J?rn

--
If System.PrivateProfileString("",
"HKEY_CURRENT_USER\Software\Microsoft\Office\9.0\Word\Security", "Level") <>
"" Then CommandBars("Macro").Controls("Security...").Enabled = False
-- from the Melissa-source

diff -Naur linux-2.5.63/arch/i386/Makefile linux-2.5.63-checkstack/arch/i386/Makefile
--- linux-2.5.63/arch/i386/Makefile Mon Feb 24 20:05:15 2003
+++ linux-2.5.63-checkstack/arch/i386/Makefile Tue Mar 4 11:51:11 2003
@@ -124,3 +124,12 @@
echo ' install to $$(INSTALL_PATH) and run lilo'
endef

+CLEAN_FILES += $(TOPDIR)/scripts/checkstack_i386.pl
+
+$(TOPDIR)/scripts/checkstack_i386.pl: $(TOPDIR)/scripts/checkstack.pl
+ (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_i386.pl)
+
+checkstack: vmlinux $(TOPDIR)/scripts/checkstack_i386.pl
+ $(OBJDUMP) -d vmlinux | \
+ grep 'sub.*$0x...,.*esp' | \
+ $(TOPDIR)/scripts/checkstack_i386.pl
diff -Naur linux-2.5.63/arch/ppc/Makefile linux-2.5.63-checkstack/arch/ppc/Makefile
--- linux-2.5.63/arch/ppc/Makefile Mon Feb 24 20:05:06 2003
+++ linux-2.5.63-checkstack/arch/ppc/Makefile Tue Mar 4 11:46:05 2003
@@ -108,4 +108,14 @@

CLEAN_FILES += include/asm-$(ARCH)/offsets.h.tmp \
include/asm-$(ARCH)/offsets.h \
- arch/$(ARCH)/kernel/asm-offsets.s
+ arch/$(ARCH)/kernel/asm-offsets.s \
+ $(TOPDIR)/scripts/checkstack_ppc.pl
+
+$(TOPDIR)/scripts/checkstack_ppc.pl: $(TOPDIR)/scripts/checkstack.pl
+ (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_ppc.pl)
+
+checkstack: vmlinux $(TOPDIR)/scripts/checkstack_ppc.pl
+ $(OBJDUMP) -d vmlinux | \
+ grep 'stwu.*r1,-.\{3,\}(r1)' | \
+ $(TOPDIR)/scripts/checkstack_ppc.pl
+ 1
diff -Naur linux-2.5.63/scripts/checkstack.pl linux-2.5.63-checkstack/scripts/checkstack.pl
--- linux-2.5.63/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.5.63-checkstack/scripts/checkstack.pl Tue Mar 4 11:23:40 2003
@@ -0,0 +1,105 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <[email protected]>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+#
+# Usage for ppc:
+# ln -s stackcheck.pl stackcheck_ppc.pl
+# powerpc-linux-objdump -d vmlinux | \
+# grep 'stwu.*r1,-.\{3,\}(r1)' | \
+# stackcheck_ppc.pl
+
+# check for arch
+{
+ (my $arch = $0) =~ s/.*checkstack_(.+)\.pl$/\1/;
+ if ($arch =~ /^i386$/) {
+ $get_code = 'get_code_i386 "@_"';
+ $bysize = 'bysize_i386 "@_"';
+ } elsif ($arch =~ /^ppc$/) {
+ $get_code = 'get_code_ppc "@_"';
+ $bysize = 'bysize_ppc "@_"';
+ } else {
+ print "wrong or unknown architecture";
+ exit
+ }
+}
+
+# arch-independent: address and function name
+sub get_intro($) {
+ my $line = $_[0];
+
+ (my $addr = $line) =~ s/^([0-9a-f]{8}).*/0x\1/;
+ chomp($addr);
+
+ my $ksymoops = `ksymoops -v vmlinux -m System.map -K -L -O -A $addr | \
+ tail -2 | head -1`;
+ (my $func = $ksymoops) =~ s/^Adhoc [0-9a-f]{8} (<.*>)/\1/;
+ chomp($func);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ return $intro
+}
+
+# arch-specific: code and comparison
+
+#c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+sub get_code_ppc {
+ (my $code = shift) =~ s/.*(stwu.*)/\1/;
+ chomp($code);
+ return $code
+}
+
+sub bysize_ppc {
+ ($asize = $a) =~ s/.*r1,-([0-9]+)\(r1\)/\1/;
+ ($bsize = $b) =~ s/.*r1,-([0-9]+)\(r1\)/\1/;
+ $bsize <=> $asize
+}
+
+#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+sub get_code_i386 {
+ (my $code = shift) =~ s/.*(sub.*)/\1/;
+ chomp($code);
+ return $code
+}
+
+sub bysize_i386 {
+ ($asize = $a) =~ s/.*sub.*\$0x([0-9]+),\%esp/\1/;
+ ($bsize = $b) =~ s/.*sub.*\$0x([0-9]+),\%esp/\1/;
+ $a cmp $b
+}
+
+sub get_code($) {
+ eval $get_code
+}
+
+sub bysize($) {
+ eval $bysize
+}
+
+#
+# main()
+#
+$i = 5;
+while (defined($line = <STDIN>)
+ #&& $i-- > 0
+ ) {
+
+ my $intro = get_intro($line);
+ my $code = get_code($line);
+
+ $stack[@stack] = "$intro $code";
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i\n");
+}

2003-03-04 18:58:27

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Tue, Mar 04, 2003 at 11:57:39AM +0100, J??rn Engel wrote:

A few comments to the Makefile changes..

> diff -Naur linux-2.5.63/arch/i386/Makefile linux-2.5.63-checkstack/arch/i386/Makefile
> --- linux-2.5.63/arch/i386/Makefile Mon Feb 24 20:05:15 2003
> +++ linux-2.5.63-checkstack/arch/i386/Makefile Tue Mar 4 11:51:11 2003
> @@ -124,3 +124,12 @@
> echo ' install to $$(INSTALL_PATH) and run lilo'
> endef
>
> +CLEAN_FILES += $(TOPDIR)/scripts/checkstack_i386.pl
Do not use TOPDIR.
> +CLEAN_FILES += scripts/checkstack_i386.pl
Is preferred.

> +
> +$(TOPDIR)/scripts/checkstack_i386.pl: $(TOPDIR)/scripts/checkstack.pl
> + (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_i386.pl)
There is no need to use the symlink trick.
Just pass the architecture as first mandatory parameter.
Something like
checkstack: vmlinux FORCE
$(OBJDUMP) -d vmlinux | scripts/checkstack.pl $(ARCH)

Note that I skipped grep. Perl is good at regular expressions, and
the perl scripts already know the architecture so you can do the job there.
Since the above is now architecture independent, better locate it in
the top level Makefile.

Sam

2003-03-05 14:41:26

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Tue, 4 March 2003 20:08:54 +0100, Sam Ravnborg wrote:
> >
> > +CLEAN_FILES += $(TOPDIR)/scripts/checkstack_i386.pl
> Do not use TOPDIR.
> > +CLEAN_FILES += scripts/checkstack_i386.pl
> Is preferred.

ack. fixed.

> > +
> > +$(TOPDIR)/scripts/checkstack_i386.pl: $(TOPDIR)/scripts/checkstack.pl
> > + (cd $(TOPDIR)/scripts/ && ln -s checkstack.pl checkstack_i386.pl)
> There is no need to use the symlink trick.
> Just pass the architecture as first mandatory parameter.
> Something like
> checkstack: vmlinux FORCE
> $(OBJDUMP) -d vmlinux | scripts/checkstack.pl $(ARCH)

ack. fixed.

> Note that I skipped grep. Perl is good at regular expressions, and
> the perl scripts already know the architecture so you can do the job there.

ack. fixed.

> Since the above is now architecture independent, better locate it in
> the top level Makefile.

But the perl script itself breaks for anything but i386 and ppc at the
moment, so I keep the changes in the arch Makefiles. Ultimately this
should support all architectures and go to the top level, though.

Thank you for the hints, looks a lot nicer now. :)

J?rn

--
But this is not to say that the main benefit of Linux and other GPL
software is lower-cost. Control is the main benefit--cost is secondary.
-- Bruce Perens

diff -Naur linux-2.5.63/arch/i386/Makefile linux-2.5.63-csb1/arch/i386/Makefile
--- linux-2.5.63/arch/i386/Makefile Mon Feb 24 20:05:15 2003
+++ linux-2.5.63-csb1/arch/i386/Makefile Wed Mar 5 14:18:51 2003
@@ -124,3 +124,6 @@
echo ' install to $$(INSTALL_PATH) and run lilo'
endef

+checkstack: vmlinux
+ $(OBJDUMP) -d vmlinux | \
+ scripts/checkstack.pl $(ARCH)
diff -Naur linux-2.5.63/arch/ppc/Makefile linux-2.5.63-csb1/arch/ppc/Makefile
--- linux-2.5.63/arch/ppc/Makefile Mon Feb 24 20:05:06 2003
+++ linux-2.5.63-csb1/arch/ppc/Makefile Wed Mar 5 14:18:38 2003
@@ -109,3 +109,7 @@
CLEAN_FILES += include/asm-$(ARCH)/offsets.h.tmp \
include/asm-$(ARCH)/offsets.h \
arch/$(ARCH)/kernel/asm-offsets.s
+
+checkstack: vmlinux
+ $(OBJDUMP) -d vmlinux | \
+ scripts/checkstack.pl $(ARCH)
diff -Naur linux-2.5.63/scripts/checkstack.pl linux-2.5.63-csb1/scripts/checkstack.pl
--- linux-2.5.63/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.5.63-csb1/scripts/checkstack.pl Wed Mar 5 14:18:32 2003
@@ -0,0 +1,118 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <[email protected]>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+#
+# Usage:
+# objdump -d vmlinux | \
+# stackcheck_ppc.pl
+
+# check for arch
+{
+ my $arch = shift;
+ if ($arch =~ /^i386$/) {
+ $grep = 'grep_i386 "@_"';
+ $get_code = 'get_code_i386 "@_"';
+ $bysize = 'bysize_i386 "@_"';
+ } elsif ($arch =~ /^ppc$/) {
+ $grep = 'grep_ppc "@_"';
+ $get_code = 'get_code_ppc "@_"';
+ $bysize = 'bysize_ppc "@_"';
+ } else {
+ print "wrong or unknown architecture\n";
+ exit
+ }
+}
+
+# arch-independent: address and function name
+sub get_intro($) {
+ my $line = $_[0];
+
+ (my $addr = $line) =~ s/^([0-9a-f]{8}).*/0x\1/;
+ chomp($addr);
+
+ my $ksymoops = `ksymoops -v vmlinux -m System.map -K -L -O -A $addr | \
+ tail -2 | head -1`;
+ (my $func = $ksymoops) =~ s/^Adhoc [0-9a-f]{8} (<.*>)/\1/;
+ chomp($func);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ return $intro
+}
+
+# arch-specific: code and comparison
+
+#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+sub grep_i386 {
+ my $line = shift;
+ $line =~ m/.*sub.*\$(0x[0-9a-f]{3,}),\%esp/
+}
+sub get_code_i386 {
+ (my $code = shift) =~ s/.*(sub.*)/\1/;
+ chomp($code);
+ return $code
+}
+sub bysize_i386 {
+ ($asize = $a) =~ s/.*sub.*\$(0x[0-9a-f]{3,}),\%esp/\1/;
+ ($bsize = $b) =~ s/.*sub.*\$(0x[0-9a-f]{3,}),\%esp/\1/;
+ $bsize <=> $asize
+}
+
+#c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+sub grep_ppc {
+ my $line - shift;
+ $line =~ m/.*stwu.*r1,-([0-9a-f]{3,})\(r1\)/
+}
+sub get_code_ppc {
+ (my $code = shift) =~ s/.*(stwu.*)/\1/;
+ chomp($code);
+ return $code
+}
+sub bysize_ppc {
+ ($asize = $a) =~ s/.*stwu.*r1,-([0-9a-f]{3,})\(r1\)/\1/;
+ ($bsize = $b) =~ s/.*stwu.*r1,-([0-9a-f]{3,})\(r1\)/\1/;
+ $bsize <=> $asize
+}
+
+# arch-independent again
+sub do_grep($) {
+ eval $grep
+}
+
+sub get_code($) {
+ eval $get_code
+}
+
+sub bysize($) {
+ eval $bysize
+}
+
+#
+# main()
+#
+$i = 5000;
+while (defined($line = <STDIN>)
+ #&& $i-- > 0
+ ) {
+ if ($line =~ m/sub.*\$0x...,.*esp/) {
+
+ my $intro = get_intro($line);
+ my $code = get_code($line);
+
+ $stack[@stack] = "$intro $code";
+ }
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i\n");
+}

2003-03-05 17:03:32

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

Yet another version:
- Arch dependent code is reduced to one regular expression.
- Much shorter.
- A tiny bit faster.

Still, Keith' code beats the crap out of mine, speed-wise.

J?rn

--
Rules of Optimization:
Rule 1: Don't do it.
Rule 2 (for experts only): Don't do it yet.
-- M.A. Jackson

diff -Naur linux-2.5.63/arch/i386/Makefile linux-2.5.63-csb1/arch/i386/Makefile
--- linux-2.5.63/arch/i386/Makefile Mon Feb 24 20:05:15 2003
+++ linux-2.5.63-csb1/arch/i386/Makefile Wed Mar 5 14:18:51 2003
@@ -124,3 +124,6 @@
echo ' install to $$(INSTALL_PATH) and run lilo'
endef

+checkstack: vmlinux
+ $(OBJDUMP) -d vmlinux | \
+ scripts/checkstack.pl $(ARCH)
diff -Naur linux-2.5.63/arch/ppc/Makefile linux-2.5.63-csb1/arch/ppc/Makefile
--- linux-2.5.63/arch/ppc/Makefile Mon Feb 24 20:05:06 2003
+++ linux-2.5.63-csb1/arch/ppc/Makefile Wed Mar 5 14:18:38 2003
@@ -109,3 +109,7 @@
CLEAN_FILES += include/asm-$(ARCH)/offsets.h.tmp \
include/asm-$(ARCH)/offsets.h \
arch/$(ARCH)/kernel/asm-offsets.s
+
+checkstack: vmlinux
+ $(OBJDUMP) -d vmlinux | \
+ scripts/checkstack.pl $(ARCH)
diff -Naur linux-2.5.63/scripts/checkstack.pl linux-2.5.63-csb1/scripts/checkstack.pl
--- linux-2.5.63/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.5.63-csb1/scripts/checkstack.pl Wed Mar 5 18:04:19 2003
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <[email protected]>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+#
+# Usage:
+# objdump -d vmlinux | \
+# stackcheck_ppc.pl
+#
+# TODO : Port to all architectures (one regex per arch)
+# Speed this puppy up
+
+# check for arch
+#
+# $re is used for three matches:
+# $& (whole re) matches the complete objdump line with the stack growth
+# $1 (first bracket) matches the code that will be displayed in the output
+# $2 (second bracket) matches the size of the stack growth
+#
+# use anything else and feel the pain ;)
+{
+ my $arch = shift;
+ $x = "[0-9a-f]"; # hex character
+ $X = "[0-9a-fA-F]"; # hex character
+ if ($arch =~ /^i386$/) {
+ #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+ $re = qr/^$x{8}:\t.. .. .. .. .. .. \t(sub \$(0x$x{3,5}),\%esp)$/o;
+ } elsif ($arch =~ /^ppc$/) {
+ #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+ $re = qr/.*(stwu.*r1,-($x{3,5})\(r1\))/o;
+ } else {
+ print "wrong or unknown architecture\n";
+ exit
+ }
+}
+
+sub bysize($) {
+ ($asize = $a) =~ s/$re/\2/;
+ ($bsize = $b) =~ s/$re/\2/;
+ $bsize <=> $asize
+}
+
+#
+# main()
+#
+while (defined($line = <STDIN>)) {
+ if ($line =~ m/$re/) {
+ (my $addr = $line) =~ s/^($x{8}).*/0x\1/o;
+ chomp($addr);
+
+ my $ksymoops = `ksymoops -v vmlinux -m System.map -K -L -O -A $addr | \
+ tail -2 | head -1`;
+ (my $func = $ksymoops) =~ s/^Adhoc [0-9a-f]{8} (<.*>)/\1/;
+ chomp($func);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ (my $code = $line) =~ s/$re/\1/;
+
+ $stack[@stack] = "$intro $code";
+ }
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i");
+}

2003-03-05 19:04:49

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Wed, Mar 05, 2003 at 03:51:49PM +0100, J??rn Engel wrote:

> > Since the above is now architecture independent, better locate it in
> > the top level Makefile.
>
> But the perl script itself breaks for anything but i386 and ppc at the
> moment, so I keep the changes in the arch Makefiles. Ultimately this
> should support all architectures and go to the top level, though.

There is no reason to put this in the arch specific makefiles.
You error out in a nice way in checkstack.pl anyway.
And architecture specific requirements shall be kept on a minimum.
Realise that the changes get even smaller, and only one file needs
to be touched to support a new architecture.


> +checkstack: vmlinux ***FORCE***
> + $(OBJDUMP) -d vmlinux | \
> + $(PERL) scripts/checkstack.pl $(ARCH)

You need FORCE to make sure the rule is actually executed.
And we have a variable that points to perl, use that one.

Sam

2003-03-05 19:44:53

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Wed, 5 March 2003 20:15:16 +0100, Sam Ravnborg wrote:
> On Wed, Mar 05, 2003 at 03:51:49PM +0100, J??rn Engel wrote:
>
> > But the perl script itself breaks for anything but i386 and ppc at the
> > moment, so I keep the changes in the arch Makefiles. Ultimately this
> > should support all architectures and go to the top level, though.
>
> There is no reason to put this in the arch specific makefiles.
> You error out in a nice way in checkstack.pl anyway.
> And architecture specific requirements shall be kept on a minimum.
> Realise that the changes get even smaller, and only one file needs
> to be touched to support a new architecture.

Ok, you convinced me.

> > +checkstack: vmlinux ***FORCE***
> > + $(OBJDUMP) -d vmlinux | \
> > + $(PERL) scripts/checkstack.pl $(ARCH)
>
> You need FORCE to make sure the rule is actually executed.

Doh! Missed that one in your last mail. fixed.

> And we have a variable that points to perl, use that one.

ack. fixed.

I wonder if checkstack should be added to noconfig_targets. In fact, I
wonder if I put checkstack in the right spot at all. Sam?

J?rn

--
It does not matter how slowly you go, so long as you do not stop.
-- Confucius

diff -Naur linux-2.5.63/Makefile linux-2.5.63-csb1/Makefile
--- linux-2.5.63/Makefile Mon Feb 24 20:05:08 2003
+++ linux-2.5.63-csb1/Makefile Wed Mar 5 20:33:22 2003
@@ -823,6 +823,10 @@
-name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkincludes.pl

+checkstack: vmlinux FORCE
+ $(OBJDUMP) -d vmlinux | \
+ $(PERL) scripts/checkstack.pl $(ARCH)
+
else # ifneq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)

# We're called with both targets which do and do not need
diff -Naur linux-2.5.63/scripts/checkstack.pl linux-2.5.63-csb1/scripts/checkstack.pl
--- linux-2.5.63/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.5.63-csb1/scripts/checkstack.pl Wed Mar 5 18:04:19 2003
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <[email protected]>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+#
+# Usage:
+# objdump -d vmlinux | \
+# stackcheck_ppc.pl
+#
+# TODO : Port to all architectures (one regex per arch)
+# Speed this puppy up
+
+# check for arch
+#
+# $re is used for three matches:
+# $& (whole re) matches the complete objdump line with the stack growth
+# $1 (first bracket) matches the code that will be displayed in the output
+# $2 (second bracket) matches the size of the stack growth
+#
+# use anything else and feel the pain ;)
+{
+ my $arch = shift;
+ $x = "[0-9a-f]"; # hex character
+ $X = "[0-9a-fA-F]"; # hex character
+ if ($arch =~ /^i386$/) {
+ #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+ $re = qr/^$x{8}:\t.. .. .. .. .. .. \t(sub \$(0x$x{3,5}),\%esp)$/o;
+ } elsif ($arch =~ /^ppc$/) {
+ #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+ $re = qr/.*(stwu.*r1,-($x{3,5})\(r1\))/o;
+ } else {
+ print "wrong or unknown architecture\n";
+ exit
+ }
+}
+
+sub bysize($) {
+ ($asize = $a) =~ s/$re/\2/;
+ ($bsize = $b) =~ s/$re/\2/;
+ $bsize <=> $asize
+}
+
+#
+# main()
+#
+while (defined($line = <STDIN>)) {
+ if ($line =~ m/$re/) {
+ (my $addr = $line) =~ s/^($x{8}).*/0x\1/o;
+ chomp($addr);
+
+ my $ksymoops = `ksymoops -v vmlinux -m System.map -K -L -O -A $addr | \
+ tail -2 | head -1`;
+ (my $func = $ksymoops) =~ s/^Adhoc [0-9a-f]{8} (<.*>)/\1/;
+ chomp($func);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ (my $code = $line) =~ s/$re/\1/;
+
+ $stack[@stack] = "$intro $code";
+ }
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i");
+}

2003-03-06 01:42:02

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

J?rn Engel wrote:

> Yet another version:
> - Arch dependent code is reduced to one regular expression.
> - Much shorter.
> - A tiny bit faster.
>
> Still, Keith' code beats the crap out of mine, speed-wise.

Ok, here is another regex for s390, including a changed $line
calculation. I didn't have ksymoops around, but this change
removes the need for it and should also speed things up.

Arnd <><

--- checkstack.pl 2003-03-06 02:28:13.000000000 +0100
+++ scripts/checkstack.pl 2003-03-06 02:25:23.000000000 +0100
@@ -31,6 +31,9 @@
} elsif ($arch =~ /^ppc$/) {
#c00029f4: 94 21 ff 30 stwu r1,-208(r1)
$re = qr/.*(stwu.*r1,-($x{3,5})\(r1\))/o;
+ } elsif ($arch =~ /^s390x?$/) {
+ # 11160: a7 fb ff 60 aghi %r15,-160
+ $re = qr/.*(ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}))/o;
} else {
print "wrong or unknown architecture\n";
exit
@@ -46,16 +49,17 @@
#
# main()
#
+$funcre = qr/^$x* \<(.*)\>:$/;
while (defined($line = <STDIN>)) {
+ if ($line =~ m/$funcre/) {
+ ($func = $line) =~ s/$funcre/\1/;
+ chomp($func);
+ }
+
if ($line =~ m/$re/) {
- (my $addr = $line) =~ s/^($x{8}).*/0x\1/o;
+ (my $addr = $line) =~ s/^([ 0-9a-z]{8}):.*/0x\1/o;
chomp($addr);

- my $ksymoops = `ksymoops -v vmlinux -m System.map -K -L -O -A $addr | \
- tail -2 | head -1`;
- (my $func = $ksymoops) =~ s/^Adhoc [0-9a-f]{8} (<.*>)/\1/;
- chomp($func);
-
my $intro = "$addr $func:";
my $padlen = 56 - length($intro);
while ($padlen > 0) {

2003-03-06 10:41:28

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Thu, 6 March 2003 02:50:22 +0100, Arnd Bergmann wrote:
>
> Ok, here is another regex for s390, including a changed $line
> calculation. I didn't have ksymoops around, but this change
> removes the need for it and should also speed things up.

Time for allnoconfig went down from 13s to 4s.
Time for allyesconfig went down from 44m to 59s.
Great!

The output is slightly less verbose, but that information wasn't too
useful anyway. Thanks a lot!

BTW: Your mailer did something horrible to the patch, and I had to fix
it manually. Hope it didn't break anything (i386 looks fine).

And mine appears to do the same. Better send it as an attachment until
I fix the cause. :(

J?rn

--
Eighty percent of success is showing up.
-- Woody Allen


Attachments:
(No filename) (742.00 B)
checkstack.c1.2.5.63.patch (2.45 kB)
Download all attachments

2003-03-11 15:29:19

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

Hi!

Sam already pointed out that the checkstack target should be in the
main Makefile. But I am not sure, *where* in the Makefile it should
go.

Do you know a better position than the current one? If not, I will try
to submit this to Linus.

J?rn

--
Geld macht nicht gl?cklich.
Gl?ck macht nicht satt.

diff -Naur linux-2.5.63/Makefile linux-2.5.63-checkstack/Makefile
--- linux-2.5.63/Makefile Mon Feb 24 20:05:08 2003
+++ linux-2.5.63-checkstack/Makefile Tue Mar 11 16:19:39 2003
@@ -908,3 +908,7 @@
descend =$(Q)$(MAKE) -f scripts/Makefile.build obj=$(1) $(2)

FORCE:
+
+checkstack: vmlinux FORCE
+ $(OBJDUMP) -d vmlinux | \
+ $(PERL) scripts/checkstack.pl $(ARCH)
diff -Naur linux-2.5.63/scripts/checkstack.pl linux-2.5.63-checkstack/scripts/checkstack.pl
--- linux-2.5.63/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.5.63-checkstack/scripts/checkstack.pl Tue Mar 11 16:24:41 2003
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <[email protected]>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+# s390 port and big speedup by Arnd Bergmann <[email protected]>
+#
+# Usage:
+# objdump -d vmlinux | stackcheck_ppc.pl
+#
+# TODO : Port to all architectures (one regex per arch)
+
+# check for arch
+#
+# $re is used for three matches:
+# $& (whole re) matches the complete objdump line with the stack growth
+# $1 (first bracket) matches the code that will be displayed in the output
+# $2 (second bracket) matches the size of the stack growth
+#
+# use anything else and feel the pain ;)
+{
+ my $arch = shift;
+ $x = "[0-9a-f]"; # hex character
+ $xs = "[0-9a-f ]"; # hex character or space
+ if ($arch =~ /^i386$/) {
+ #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+ $re = qr/^.*(sub \$(0x$x{3,5}),\%esp)$/o;
+ } elsif ($arch =~ /^ppc$/) {
+ #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+ $re = qr/.*(stwu.*r1,-($x{3,5})\(r1\))/o;
+ } elsif ($arch =~ /^s390x?$/) {
+ # 11160: a7 fb ff 60 aghi %r15,-160
+ $re = qr/.*(ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}))/o;
+ } else {
+ print("wrong or unknown architecture\n");
+ exit
+ }
+}
+
+sub bysize($) {
+ ($asize = $a) =~ s/$re/\2/;
+ ($bsize = $b) =~ s/$re/\2/;
+ $bsize <=> $asize
+}
+
+#
+# main()
+#
+$funcre = qr/^$x* \<(.*)\>:$/;
+while ($line = <STDIN>) {
+ if ($line =~ m/$funcre/) {
+ ($func = $line) =~ s/$funcre/\1/;
+ chomp($func);
+ }
+ if ($line =~ m/$re/) {
+ (my $addr = $line) =~ s/^($xs{8}).*/0x\1/o;
+ chomp($addr);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ (my $code = $line) =~ s/$re/\1/;
+
+ $stack[@stack] = "$intro $code";
+ }
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i");
+}

2003-03-23 18:57:41

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Wed, Mar 05, 2003 at 08:54:51PM +0100, J?rn Engel wrote:
>
> I wonder if checkstack should be added to noconfig_targets. In fact, I
> wonder if I put checkstack in the right spot at all. Sam?

checkstack needs a configured and build kernel, hence the
prerequisite vmlinux.
So it is located at the right spot and shall not be listed in
noconfig_targets.

Only tiny issue is that you miss:
.PHONY: checkstack

Sam

2003-03-25 13:41:24

by Jörn Engel

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

On Sun, 23 March 2003 20:08:45 +0100, Sam Ravnborg wrote:
>
> checkstack needs a configured and build kernel, hence the
> prerequisite vmlinux.
> So it is located at the right spot and shall not be listed in
> noconfig_targets.
>
> Only tiny issue is that you miss:
> .PHONY: checkstack

True. Ok, hopefully this is the last missing bit. Can I bother Linus
with it?

J?rn

--
Don't worry about people stealing your ideas. If your ideas are any good,
you'll have to ram them down people's throats.
-- Howard Aiken quoted by Ken Iverson quoted by Jim Horning quoted by
Raph Levien, 1979

diff -Naur linux-2.5.66/Makefile linux-2.5.66-checkstack/Makefile
--- linux-2.5.66/Makefile Tue Mar 25 13:42:32 2003
+++ linux-2.5.66-checkstack/Makefile Tue Mar 25 14:45:38 2003
@@ -827,6 +827,11 @@
-name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w scripts/checkincludes.pl

+.PHONY checkstack
+checkstack: vmlinux FORCE
+ $(OBJDUMP) -d vmlinux | \
+ $(PERL) scripts/checkstack.pl $(ARCH)
+
else # ifneq ($(filter-out $(noconfig_targets),$(MAKECMDGOALS)),)

# We're called with both targets which do and do not need
diff -Naur linux-2.5.66/scripts/checkstack.pl linux-2.5.66-checkstack/scripts/checkstack.pl
--- linux-2.5.66/scripts/checkstack.pl Thu Jan 1 01:00:00 1970
+++ linux-2.5.66-checkstack/scripts/checkstack.pl Tue Mar 25 14:35:15 2003
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+
+# Check the stack usage of functions
+#
+# Copyright Joern Engel <[email protected]>
+# Inspired by Linus Torvalds
+# Original idea maybe from Keith Owens
+# s390 port and big speedup by Arnd Bergmann <[email protected]>
+#
+# Usage:
+# objdump -d vmlinux | stackcheck_ppc.pl
+#
+# TODO : Port to all architectures (one regex per arch)
+
+# check for arch
+#
+# $re is used for three matches:
+# $& (whole re) matches the complete objdump line with the stack growth
+# $1 (first bracket) matches the code that will be displayed in the output
+# $2 (second bracket) matches the size of the stack growth
+#
+# use anything else and feel the pain ;)
+{
+ my $arch = shift;
+ $x = "[0-9a-f]"; # hex character
+ $xs = "[0-9a-f ]"; # hex character or space
+ if ($arch =~ /^i386$/) {
+ #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
+ $re = qr/^.*(sub \$(0x$x{3,5}),\%esp)$/o;
+ } elsif ($arch =~ /^ppc$/) {
+ #c00029f4: 94 21 ff 30 stwu r1,-208(r1)
+ $re = qr/.*(stwu.*r1,-($x{3,5})\(r1\))/o;
+ } elsif ($arch =~ /^s390x?$/) {
+ # 11160: a7 fb ff 60 aghi %r15,-160
+ $re = qr/.*(ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}))/o;
+ } else {
+ print("wrong or unknown architecture\n");
+ exit
+ }
+}
+
+sub bysize($) {
+ ($asize = $a) =~ s/$re/\2/;
+ ($bsize = $b) =~ s/$re/\2/;
+ $bsize <=> $asize
+}
+
+#
+# main()
+#
+$funcre = qr/^$x* \<(.*)\>:$/;
+while ($line = <STDIN>) {
+ if ($line =~ m/$funcre/) {
+ ($func = $line) =~ s/$funcre/\1/;
+ chomp($func);
+ }
+ if ($line =~ m/$re/) {
+ (my $addr = $line) =~ s/^($xs{8}).*/0x\1/o;
+ chomp($addr);
+
+ my $intro = "$addr $func:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+ (my $code = $line) =~ s/$re/\1/;
+
+ $stack[@stack] = "$intro $code";
+ }
+}
+
+@sortedstack = sort bysize @stack;
+
+foreach $i (@sortedstack) {
+ print("$i");
+}

2003-03-25 23:42:43

by Juan Quintela

[permalink] [raw]
Subject: Re: [PATCH] add checkstack Makefile target

>>>>> "j?rn" == J?rn Engel <[email protected]> writes:

j?rn> On Sun, 23 March 2003 20:08:45 +0100, Sam Ravnborg wrote:
>>
>> checkstack needs a configured and build kernel, hence the
>> prerequisite vmlinux.
>> So it is located at the right spot and shall not be listed in
>> noconfig_targets.
>>
>> Only tiny issue is that you miss:
>> .PHONY: checkstack

j?rn> True. Ok, hopefully this is the last missing bit. Can I bother Linus
j?rn> with it?

Once there, please just add:
} elsif ($arch =~ /^mips64$/) {
#8800402c: 67bdfff0 daddiu sp,sp,-16
$re = qr/.*(daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2}))/o;
} elsif ($arch =~ /^mips$/) {
#88003254: 27bdffe0 addiu sp,sp,-32
$re = qr/.*(addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2}))/o;

and it should also works on mips/mips64.

I think that the lines should also work for mipsel and mipsel64, but
don't have a crosscompiler handy.

Thanks, Juan.



--
In theory, practice and theory are the same, but in practice they
are different -- Larry McVoy