diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2019-01-17 22:21:53 +0100 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2019-01-17 22:59:45 +0100 |
commit | f59739a66361367c29aa1c68600b91ff2212d5f7 (patch) | |
tree | f6cdd816a358dab98087d27edb9d808ec1d05044 | |
parent | fe7ae562e5d0121d1c5f4d3ba1ec4117c7bbaab8 (diff) | |
download | busybox-w32-f59739a66361367c29aa1c68600b91ff2212d5f7.tar.gz busybox-w32-f59739a66361367c29aa1c68600b91ff2212d5f7.tar.bz2 busybox-w32-f59739a66361367c29aa1c68600b91ff2212d5f7.zip |
checkstack: pull from upstream
merge upstream changes
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
-rwxr-xr-x | scripts/checkstack.pl | 107 |
1 files changed, 75 insertions, 32 deletions
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index b5980a2e3..7833554c8 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl | |||
@@ -1,10 +1,11 @@ | |||
1 | #!/usr/bin/perl | 1 | #!/usr/bin/env perl |
2 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | 3 | ||
3 | # Stolen from Linux kernel :) | 4 | # Stolen from Linux kernel :) |
4 | 5 | ||
5 | # Check the stack usage of functions | 6 | # Check the stack usage of functions |
6 | # | 7 | # |
7 | # Copyright Joern Engel <joern@wh.fh-wedel.de> | 8 | # Copyright Joern Engel <joern@lazybastard.org> |
8 | # Inspired by Linus Torvalds | 9 | # Inspired by Linus Torvalds |
9 | # Original idea maybe from Keith Owens | 10 | # Original idea maybe from Keith Owens |
10 | # s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de> | 11 | # s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de> |
@@ -14,41 +15,57 @@ | |||
14 | # sh64 port by Paul Mundt | 15 | # sh64 port by Paul Mundt |
15 | # Random bits by Matt Mackall <mpm@selenic.com> | 16 | # Random bits by Matt Mackall <mpm@selenic.com> |
16 | # M68k port by Geert Uytterhoeven and Andreas Schwab | 17 | # M68k port by Geert Uytterhoeven and Andreas Schwab |
18 | # blackfin port by Alex Landau | ||
19 | # AArch64, PARISC ports by Kyle McMartin | ||
20 | # sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk> | ||
21 | # ppc64le port by Breno Leitao <leitao@debian.org> | ||
17 | # | 22 | # |
18 | # Usage: | 23 | # Usage: |
19 | # objdump -d vmlinux | checkstack.pl [arch] | 24 | # objdump -d vmlinux | scripts/checkstack.pl [arch] |
20 | # | 25 | # |
21 | # TODO : Port to all architectures (one regex per arch) | 26 | # TODO : Port to all architectures (one regex per arch) |
22 | 27 | ||
28 | use strict; | ||
29 | |||
23 | # check for arch | 30 | # check for arch |
24 | # | 31 | # |
25 | # $re is used for two matches: | 32 | # $re is used for two matches: |
26 | # $& (whole re) matches the complete objdump line with the stack growth | 33 | # $& (whole re) matches the complete objdump line with the stack growth |
27 | # $1 (first bracket) matches the size of the stack growth | 34 | # $1 (first bracket) matches the size of the stack growth |
28 | # | 35 | # |
36 | # $dre is similar, but for dynamic stack reductions: | ||
37 | # $& (whole re) matches the complete objdump line with the stack growth | ||
38 | # $1 (first bracket) matches the dynamic amount of the stack growth | ||
39 | # | ||
29 | # use anything else and feel the pain ;) | 40 | # use anything else and feel the pain ;) |
30 | my (@stack, $re, $x, $xs); | 41 | my (@stack, $re, $dre, $x, $xs, $funcre); |
31 | { | 42 | { |
32 | my $arch = shift; | 43 | my $arch = shift; |
33 | if ($arch eq "") { | 44 | if ($arch eq "") { |
34 | $arch = `uname -m`; | 45 | $arch = `uname -m`; |
35 | 1 while chomp $arch; | 46 | chomp($arch); |
36 | } | 47 | } |
37 | 48 | ||
38 | $x = "[0-9a-f]"; # hex character | 49 | $x = "[0-9a-f]"; # hex character |
39 | $xs = "[0-9a-f ]"; # hex character or space | 50 | $xs = "[0-9a-f ]"; # hex character or space |
40 | if ($arch eq 'arm') { | 51 | $funcre = qr/^$x* <(.*)>:$/; |
52 | if ($arch eq 'aarch64') { | ||
53 | #ffffffc0006325cc: a9bb7bfd stp x29, x30, [sp, #-80]! | ||
54 | #a110: d11643ff sub sp, sp, #0x590 | ||
55 | $re = qr/^.*stp.*sp, \#-([0-9]{1,8})\]\!/o; | ||
56 | $dre = qr/^.*sub.*sp, sp, #(0x$x{1,8})/o; | ||
57 | } elsif ($arch eq 'arm') { | ||
41 | #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64 | 58 | #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64 |
42 | $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o; | 59 | $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o; |
60 | } elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) { | ||
61 | #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp | ||
62 | # or | ||
63 | # 2f60: 48 81 ec e8 05 00 00 sub $0x5e8,%rsp | ||
64 | $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%(e|r)sp$/o; | ||
65 | $dre = qr/^.*[as][du][db] (%.*),\%(e|r)sp$/o; | ||
43 | } elsif ($arch eq 'blackfin') { | 66 | } elsif ($arch eq 'blackfin') { |
44 | # 52: 00 e8 03 00 LINK 0xc; | 67 | # 52: 00 e8 03 00 LINK 0xc; |
45 | $re = qr/.*LINK (0x$x{1,5});$/o; | 68 | $re = qr/.*LINK (0x$x{1,5});$/o; |
46 | } elsif ($arch =~ /^i[3456]86$/) { | ||
47 | #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp | ||
48 | $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%esp$/o; | ||
49 | } elsif ($arch eq 'x86_64') { | ||
50 | # 2f60: 48 81 ec e8 05 00 00 sub $0x5e8,%rsp | ||
51 | $re = qr/^.*[as][du][db] \$(0x$x{1,8}),\%rsp$/o; | ||
52 | } elsif ($arch eq 'ia64') { | 69 | } elsif ($arch eq 'ia64') { |
53 | #e0000000044011fc: 01 0f fc 8c adds r12=-384,r12 | 70 | #e0000000044011fc: 01 0f fc 8c adds r12=-384,r12 |
54 | $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o; | 71 | $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o; |
@@ -62,42 +79,43 @@ my (@stack, $re, $x, $xs); | |||
62 | } elsif ($arch eq 'mips') { | 79 | } elsif ($arch eq 'mips') { |
63 | #88003254: 27bdffe0 addiu sp,sp,-32 | 80 | #88003254: 27bdffe0 addiu sp,sp,-32 |
64 | $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o; | 81 | $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o; |
65 | } elsif ($arch eq 'ppc') { | 82 | } elsif ($arch eq 'nios2') { |
66 | #c00029f4: 94 21 ff 30 stwu r1,-208(r1) | 83 | #25a8: defffb04 addi sp,sp,-20 |
67 | $re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o; | 84 | $re = qr/.*addi.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o; |
68 | } elsif ($arch eq 'ppc64') { | 85 | } elsif ($arch eq 'openrisc') { |
69 | #XXX | 86 | # c000043c: 9c 21 fe f0 l.addi r1,r1,-272 |
70 | $re = qr/.*stdu.*r1,-($x{1,8})\(r1\)/o; | 87 | $re = qr/.*l\.addi.*r1,r1,-(([0-9]{2}|[3-9])[0-9]{2})/o; |
71 | } elsif ($arch eq 'powerpc') { | 88 | } elsif ($arch eq 'parisc' || $arch eq 'parisc64') { |
89 | $re = qr/.*ldo ($x{1,8})\(sp\),sp/o; | ||
90 | } elsif ($arch eq 'powerpc' || $arch =~ /^ppc(64)?(le)?$/ ) { | ||
91 | # powerpc : 94 21 ff 30 stwu r1,-208(r1) | ||
92 | # ppc64(le) : 81 ff 21 f8 stdu r1,-128(r1) | ||
72 | $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o; | 93 | $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o; |
73 | } elsif ($arch =~ /^s390x?$/) { | 94 | } elsif ($arch =~ /^s390x?$/) { |
74 | # 11160: a7 fb ff 60 aghi %r15,-160 | 95 | # 11160: a7 fb ff 60 aghi %r15,-160 |
75 | $re = qr/.*ag?hi.*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})/o; | 96 | # or |
97 | # 100092: e3 f0 ff c8 ff 71 lay %r15,-56(%r15) | ||
98 | $re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2}) | ||
99 | (?:\(\%r15\))?$/ox; | ||
76 | } elsif ($arch =~ /^sh64$/) { | 100 | } elsif ($arch =~ /^sh64$/) { |
77 | #XXX: we only check for the immediate case presently, | 101 | #XXX: we only check for the immediate case presently, |
78 | # though we will want to check for the movi/sub | 102 | # though we will want to check for the movi/sub |
79 | # pair for larger users. -- PFM. | 103 | # pair for larger users. -- PFM. |
80 | #a00048e0: d4fc40f0 addi.l r15,-240,r15 | 104 | #a00048e0: d4fc40f0 addi.l r15,-240,r15 |
81 | $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o; | 105 | $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o; |
106 | } elsif ($arch eq 'sparc' || $arch eq 'sparc64') { | ||
107 | # f0019d10: 9d e3 bf 90 save %sp, -112, %sp | ||
108 | $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o; | ||
82 | } else { | 109 | } else { |
83 | print("wrong or unknown architecture\n"); | 110 | print("wrong or unknown architecture \"$arch\"\n"); |
84 | exit | 111 | exit |
85 | } | 112 | } |
86 | } | 113 | } |
87 | 114 | ||
88 | sub bysize($) { | ||
89 | my ($asize, $bsize); | ||
90 | ($asize = $a) =~ s/.*: *(.*)$/$1/; | ||
91 | ($bsize = $b) =~ s/.*: *(.*)$/$1/; | ||
92 | $bsize <=> $asize | ||
93 | } | ||
94 | |||
95 | # | 115 | # |
96 | # main() | 116 | # main() |
97 | # | 117 | # |
98 | my $funcre = qr/^$x* <(.*)>:$/; | 118 | my ($func, $file, $lastslash); |
99 | my $func; | ||
100 | my $file, $lastslash; | ||
101 | 119 | ||
102 | while (my $line = <STDIN>) { | 120 | while (my $line = <STDIN>) { |
103 | if ($line =~ m/$funcre/) { | 121 | if ($line =~ m/$funcre/) { |
@@ -137,6 +155,31 @@ while (my $line = <STDIN>) { | |||
137 | next if ($size < 100); | 155 | next if ($size < 100); |
138 | push @stack, "$intro$size\n"; | 156 | push @stack, "$intro$size\n"; |
139 | } | 157 | } |
158 | elsif (defined $dre && $line =~ m/$dre/) { | ||
159 | my $size = "Dynamic ($1)"; | ||
160 | |||
161 | next if $line !~ m/^($xs*)/; | ||
162 | my $addr = $1; | ||
163 | $addr =~ s/ /0/g; | ||
164 | $addr = "0x$addr"; | ||
165 | |||
166 | #bbox: was: my $intro = "$addr $func [$file]:"; | ||
167 | my $intro = "$func [$file]:"; | ||
168 | my $padlen = 56 - length($intro); | ||
169 | while ($padlen > 0) { | ||
170 | $intro .= ' '; | ||
171 | $padlen -= 8; | ||
172 | } | ||
173 | push @stack, "$intro$size\n"; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | sub bysize($) { | ||
178 | my ($asize, $bsize); | ||
179 | ($asize = $a) =~ s/.*: *(.*)$/$1/; | ||
180 | ($bsize = $b) =~ s/.*: *(.*)$/$1/; | ||
181 | $bsize <=> $asize | ||
140 | } | 182 | } |
141 | 183 | ||
142 | print sort bysize @stack; | 184 | # Sort output by size (last field) |
185 | print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack; | ||