2020-05-08 11:13:12

by Maninder Singh

[permalink] [raw]
Subject: [PATCH v2 1/4] scripts/checkstack.pl: don't display $dre as different entity

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


2020-05-08 11:13:17

by Maninder Singh

[permalink] [raw]
Subject: [PATCH v2 3/4] scripts/checkstack.pl: add arm push handling for stack usage

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

2020-05-08 11:13:41

by Maninder Singh

[permalink] [raw]
Subject: [PATCH v2 4/4] scripts/checkstack.pl: fix arm sp regex

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

2020-05-08 11:15:22

by Maninder Singh

[permalink] [raw]
Subject: [PATCH v2 2/4] scripts/checkstack.pl: Add argument to print stacks greather than value.

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

2020-05-09 07:45:53

by Masahiro Yamada

[permalink] [raw]
Subject: Re: [PATCH v2 1/4] scripts/checkstack.pl: don't display $dre as different entity

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