currently script prints stack usage for functions
in two ways:($re and $dre)
dre breaks sorting mechanism.
0xffffa00011f26f88 sunxi_mux_clk_setup.isra.0 [vmlinux]:Dynamic (0x140)
..
0xffffa00011f27210 sunxi_divs_clk_setup [vmlinux]: Dynamic (0x1d0)
so we can print it in decimal only.
Also address before function name is changed to function
start address rather than stack consumption address.
Because in next patch, arm has two ways to use stack
which can be clubbed and printed in one function only.
All symbols whose stack by adding(re and dre) is greater than
100, will be printed.
0xffffa00011f2720c0 sunxi_divs_clk_setup [vmlinux]: 464
...
0xffffa00011f26f840 sunxi_mux_clk_setup.isra.0 [vmlinux]:320
Co-developed-by: Vaneet Narang <[email protected]>
Signed-off-by: Vaneet Narang <[email protected]>
Signed-off-by: Maninder Singh <[email protected]>
---
v1: https://lkml.org/lkml/2020/4/30/530
v2: review comments by Masahiro Yamada incorporated
scripts/checkstack.pl | 54 +++++++++++++++++++++++++--------------------------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 371bd17..6957108 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -109,11 +109,30 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
#
# main()
#
-my ($func, $file, $lastslash);
+my ($func, $file, $lastslash, $total_size, $addr, $intro);
+
+$total_size = 0;
while (my $line = <STDIN>) {
if ($line =~ m/$funcre/) {
$func = $1;
+ next if $line !~ m/^($xs*)/;
+ if ($total_size > 100) {
+ push @stack, "$intro$total_size\n";
+ }
+
+ $addr = $1;
+ $addr =~ s/ /0/g;
+ $addr = "0x$addr";
+
+ $intro = "$addr $func [$file]:";
+ my $padlen = 56 - length($intro);
+ while ($padlen > 0) {
+ $intro .= ' ';
+ $padlen -= 8;
+ }
+
+ $total_size = 0;
}
elsif ($line =~ m/(.*):\s*file format/) {
$file = $1;
@@ -134,37 +153,18 @@ while (my $line = <STDIN>) {
}
next if ($size > 0x10000000);
- next if $line !~ m/^($xs*)/;
- my $addr = $1;
- $addr =~ s/ /0/g;
- $addr = "0x$addr";
-
- my $intro = "$addr $func [$file]:";
- my $padlen = 56 - length($intro);
- while ($padlen > 0) {
- $intro .= ' ';
- $padlen -= 8;
- }
- next if ($size < 100);
- push @stack, "$intro$size\n";
+ $total_size += $size;
}
elsif (defined $dre && $line =~ m/$dre/) {
- my $size = "Dynamic ($1)";
-
- next if $line !~ m/^($xs*)/;
- my $addr = $1;
- $addr =~ s/ /0/g;
- $addr = "0x$addr";
+ my $size = $1;
- my $intro = "$addr $func [$file]:";
- my $padlen = 56 - length($intro);
- while ($padlen > 0) {
- $intro .= ' ';
- $padlen -= 8;
- }
- push @stack, "$intro$size\n";
+ $size = hex($size) if ($size =~ /^0x/);
+ $total_size += $size;
}
}
+if ($total_size > 100) {
+ push @stack, "$intro$total_size\n";
+}
# Sort output by size (last field)
print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
--
1.9.1
To count stack usage of push {*, fp, ip, lr, pc} instruction in ARM,
if FRAME POINTER is enabled.
e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
c01f0d50 <Y>:
c01f0d44: e1a0c00d mov ip, sp
c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
c01f0d4c: e24cb004 sub fp, ip, #4
c01f0d50: e24dd094 sub sp, sp, #448 ; 0x1C0
$ cat dump | scripts/checkstack.pl arm
0xc01f0d50 Y []: 448
added subroutine frame work for this.
After change:
0xc01f0d500 Y []: 492
Co-developed-by: Vaneet Narang <[email protected]>
Signed-off-by: Vaneet Narang <[email protected]>
Signed-off-by: Maninder Singh <[email protected]>
---
scripts/checkstack.pl | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index bc23cc7..bc07e19 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -34,8 +34,10 @@ use strict;
# $& (whole re) matches the complete objdump line with the stack growth
# $1 (first bracket) matches the dynamic amount of the stack growth
#
+# $sub: subroutine for special handling to check stack usage.
+#
# use anything else and feel the pain ;)
-my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack);
+my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack);
{
my $arch = shift;
if ($arch eq "") {
@@ -59,6 +61,7 @@ my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack);
} elsif ($arch eq 'arm') {
#c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
$re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
+ $sub = \&arm_push_handling;
} elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) {
#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
# or
@@ -112,6 +115,24 @@ my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack);
}
#
+# To count stack usage of push {*, fp, ip, lr, pc} instruction in ARM,
+# if FRAME POINTER is enabled.
+# e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+#
+sub arm_push_handling {
+ my $regex = qr/.*push.*fp, ip, lr, pc}/o;
+ my $size = 0;
+ my $line_arg = shift;
+
+ if ($line_arg =~ m/$regex/) {
+ $size = $line_arg =~ tr/,//;
+ $size = ($size + 1) * 4;
+ }
+
+ return $size;
+}
+
+#
# main()
#
my ($func, $file, $lastslash, $total_size, $addr, $intro);
@@ -166,6 +187,11 @@ while (my $line = <STDIN>) {
$size = hex($size) if ($size =~ /^0x/);
$total_size += $size;
}
+ elsif (defined $sub) {
+ my $size = &$sub($line);
+
+ $total_size += $size;
+ }
}
if ($total_size > $min_stack) {
push @stack, "$intro$total_size\n";
--
1.9.1
if objdump has below entries;
c01ed608 <X>:
c01ed614: e24ddff7 sub sp, sp, #120 ; 0x78
c01f0d50 <Y>:
c01f0d50: e24dd094 sub sp, sp, #140 ; 0x8c
scripts fails to read stack usage.
so making regex $re for ARM similar to aarch64
Co-developed-by: Vaneet Narang <[email protected]>
Signed-off-by: Vaneet Narang <[email protected]>
Signed-off-by: Maninder Singh <[email protected]>
---
scripts/checkstack.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index bc07e19..d2c3858 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -60,7 +60,7 @@ my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack);
$dre = qr/^.*sub.*sp, sp, #(0x$x{1,8})/o;
} elsif ($arch eq 'arm') {
#c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64
- $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
+ $re = qr/.*sub.*sp, sp, #([0-9]{1,4})/o;
$sub = \&arm_push_handling;
} elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) {
#c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp
--
1.9.1
Add arguments support to print stacks which are greater than
argument value only.
Co-developed-by: Vaneet Narang <[email protected]>
Signed-off-by: Vaneet Narang <[email protected]>
Signed-off-by: Maninder Singh <[email protected]>
---
scripts/checkstack.pl | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index 6957108..bc23cc7 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -35,7 +35,7 @@ use strict;
# $1 (first bracket) matches the dynamic amount of the stack growth
#
# use anything else and feel the pain ;)
-my (@stack, $re, $dre, $x, $xs, $funcre);
+my (@stack, $re, $dre, $x, $xs, $funcre, $min_stack);
{
my $arch = shift;
if ($arch eq "") {
@@ -43,6 +43,11 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
chomp($arch);
}
+ $min_stack = shift;
+ if ($min_stack eq "" || $min_stack !~ /^\d+$/) {
+ $min_stack = 100;
+ }
+
$x = "[0-9a-f]"; # hex character
$xs = "[0-9a-f ]"; # hex character or space
$funcre = qr/^$x* <(.*)>:$/;
@@ -117,7 +122,7 @@ while (my $line = <STDIN>) {
if ($line =~ m/$funcre/) {
$func = $1;
next if $line !~ m/^($xs*)/;
- if ($total_size > 100) {
+ if ($total_size > $min_stack) {
push @stack, "$intro$total_size\n";
}
@@ -162,7 +167,7 @@ while (my $line = <STDIN>) {
$total_size += $size;
}
}
-if ($total_size > 100) {
+if ($total_size > $min_stack) {
push @stack, "$intro$total_size\n";
}
--
1.9.1
On Fri, May 8, 2020 at 8:10 PM Maninder Singh <[email protected]> wrote:
>
> currently script prints stack usage for functions
> in two ways:($re and $dre)
>
> dre breaks sorting mechanism.
> 0xffffa00011f26f88 sunxi_mux_clk_setup.isra.0 [vmlinux]:Dynamic (0x140)
> ..
> 0xffffa00011f27210 sunxi_divs_clk_setup [vmlinux]: Dynamic (0x1d0)
>
> so we can print it in decimal only.
>
> Also address before function name is changed to function
> start address rather than stack consumption address.
> Because in next patch, arm has two ways to use stack
> which can be clubbed and printed in one function only.
>
> All symbols whose stack by adding(re and dre) is greater than
> 100, will be printed.
>
> 0xffffa00011f2720c0 sunxi_divs_clk_setup [vmlinux]: 464
> ...
> 0xffffa00011f26f840 sunxi_mux_clk_setup.isra.0 [vmlinux]:320
>
> Co-developed-by: Vaneet Narang <[email protected]>
> Signed-off-by: Vaneet Narang <[email protected]>
> Signed-off-by: Maninder Singh <[email protected]>
> ---
All applied to linux-kbuild. Thanks.
> v1: https://lkml.org/lkml/2020/4/30/530
> v2: review comments by Masahiro Yamada incorporated
>
> scripts/checkstack.pl | 54 +++++++++++++++++++++++++--------------------------
> 1 file changed, 27 insertions(+), 27 deletions(-)
>
> diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
> index 371bd17..6957108 100755
> --- a/scripts/checkstack.pl
> +++ b/scripts/checkstack.pl
> @@ -109,11 +109,30 @@ my (@stack, $re, $dre, $x, $xs, $funcre);
> #
> # main()
> #
> -my ($func, $file, $lastslash);
> +my ($func, $file, $lastslash, $total_size, $addr, $intro);
> +
> +$total_size = 0;
>
> while (my $line = <STDIN>) {
> if ($line =~ m/$funcre/) {
> $func = $1;
> + next if $line !~ m/^($xs*)/;
> + if ($total_size > 100) {
> + push @stack, "$intro$total_size\n";
> + }
> +
> + $addr = $1;
> + $addr =~ s/ /0/g;
> + $addr = "0x$addr";
> +
> + $intro = "$addr $func [$file]:";
> + my $padlen = 56 - length($intro);
> + while ($padlen > 0) {
> + $intro .= ' ';
> + $padlen -= 8;
> + }
> +
> + $total_size = 0;
> }
> elsif ($line =~ m/(.*):\s*file format/) {
> $file = $1;
> @@ -134,37 +153,18 @@ while (my $line = <STDIN>) {
> }
> next if ($size > 0x10000000);
>
> - next if $line !~ m/^($xs*)/;
> - my $addr = $1;
> - $addr =~ s/ /0/g;
> - $addr = "0x$addr";
> -
> - my $intro = "$addr $func [$file]:";
> - my $padlen = 56 - length($intro);
> - while ($padlen > 0) {
> - $intro .= ' ';
> - $padlen -= 8;
> - }
> - next if ($size < 100);
> - push @stack, "$intro$size\n";
> + $total_size += $size;
> }
> elsif (defined $dre && $line =~ m/$dre/) {
> - my $size = "Dynamic ($1)";
> -
> - next if $line !~ m/^($xs*)/;
> - my $addr = $1;
> - $addr =~ s/ /0/g;
> - $addr = "0x$addr";
> + my $size = $1;
>
> - my $intro = "$addr $func [$file]:";
> - my $padlen = 56 - length($intro);
> - while ($padlen > 0) {
> - $intro .= ' ';
> - $padlen -= 8;
> - }
> - push @stack, "$intro$size\n";
> + $size = hex($size) if ($size =~ /^0x/);
> + $total_size += $size;
> }
> }
> +if ($total_size > 100) {
> + push @stack, "$intro$total_size\n";
> +}
>
> # Sort output by size (last field)
> print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
> --
> 1.9.1
>
--
Best Regards
Masahiro Yamada