~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/checkstack.pl

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/checkstack.pl (Version linux-6.12-rc7) and /scripts/checkstack.pl (Version linux-5.9.16)


  1 #!/usr/bin/env perl                                 1 #!/usr/bin/env perl
  2 # SPDX-License-Identifier: GPL-2.0                  2 # SPDX-License-Identifier: GPL-2.0
  3                                                     3 
  4 #       Check the stack usage of functions          4 #       Check the stack usage of functions
  5 #                                                   5 #
  6 #       Copyright Joern Engel <joern@lazybastar      6 #       Copyright Joern Engel <joern@lazybastard.org>
  7 #       Inspired by Linus Torvalds                  7 #       Inspired by Linus Torvalds
  8 #       Original idea maybe from Keith Owens        8 #       Original idea maybe from Keith Owens
  9 #       s390 port and big speedup by Arnd Berg<      9 #       s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de>
 10 #       Mips port by Juan Quintela <quintela@ma     10 #       Mips port by Juan Quintela <quintela@mandrakesoft.com>
                                                   >>  11 #       IA64 port via Andreas Dilger
 11 #       Arm port by Holger Schurig                 12 #       Arm port by Holger Schurig
                                                   >>  13 #       sh64 port by Paul Mundt
 12 #       Random bits by Matt Mackall <mpm@seleni     14 #       Random bits by Matt Mackall <mpm@selenic.com>
 13 #       M68k port by Geert Uytterhoeven and An     15 #       M68k port by Geert Uytterhoeven and Andreas Schwab
 14 #       AArch64, PARISC ports by Kyle McMartin     16 #       AArch64, PARISC ports by Kyle McMartin
 15 #       sparc port by Martin Habets <errandir_n     17 #       sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>
 16 #       ppc64le port by Breno Leitao <leitao@de     18 #       ppc64le port by Breno Leitao <leitao@debian.org>
 17 #       riscv port by Wadim Mueller <wafgo01@gm << 
 18 #       loongarch port by Youling Tang <tangyou << 
 19 #                                                  19 #
 20 #       Usage:                                     20 #       Usage:
 21 #       objdump -d vmlinux | scripts/checkstac !!  21 #       objdump -d vmlinux | scripts/checkstack.pl [arch]
 22 #                                                  22 #
 23 #       TODO :  Port to all architectures (one     23 #       TODO :  Port to all architectures (one regex per arch)
 24                                                    24 
 25 use strict;                                        25 use strict;
 26                                                    26 
 27 # check for arch                                   27 # check for arch
 28 #                                                  28 #
 29 # $re is used for two matches:                     29 # $re is used for two matches:
 30 # $& (whole re) matches the complete objdump l     30 # $& (whole re) matches the complete objdump line with the stack growth
 31 # $1 (first bracket) matches the size of the s     31 # $1 (first bracket) matches the size of the stack growth
 32 #                                                  32 #
 33 # $dre is similar, but for dynamic stack redut     33 # $dre is similar, but for dynamic stack redutions:
 34 # $& (whole re) matches the complete objdump l     34 # $& (whole re) matches the complete objdump line with the stack growth
 35 # $1 (first bracket) matches the dynamic amoun     35 # $1 (first bracket) matches the dynamic amount of the stack growth
 36 #                                                  36 #
 37 # $sub: subroutine for special handling to che     37 # $sub: subroutine for special handling to check stack usage.
 38 #                                                  38 #
 39 # use anything else and feel the pain ;)           39 # use anything else and feel the pain ;)
 40 my (@stack, $re, $dre, $sub, $x, $xs, $funcre,     40 my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack);
 41 {                                                  41 {
 42         my $arch = shift;                          42         my $arch = shift;
 43         if ($arch eq "") {                         43         if ($arch eq "") {
 44                 $arch = `uname -m`;                44                 $arch = `uname -m`;
 45                 chomp($arch);                      45                 chomp($arch);
 46         }                                          46         }
 47                                                    47 
 48         $min_stack = shift;                        48         $min_stack = shift;
 49         if ($min_stack eq "" || $min_stack !~      49         if ($min_stack eq "" || $min_stack !~ /^\d+$/) {
 50                 $min_stack = 512;              !!  50                 $min_stack = 100;
 51         }                                          51         }
 52                                                    52 
 53         $x      = "[0-9a-f]";   # hex characte     53         $x      = "[0-9a-f]";   # hex character
 54         $xs     = "[0-9a-f ]";  # hex characte     54         $xs     = "[0-9a-f ]";  # hex character or space
 55         $funcre = qr/^$x* <(.*)>:$/;               55         $funcre = qr/^$x* <(.*)>:$/;
 56         if ($arch =~ '^(aarch|arm)64$') {          56         if ($arch =~ '^(aarch|arm)64$') {
 57                 #ffffffc0006325cc:       a9bb7     57                 #ffffffc0006325cc:       a9bb7bfd        stp     x29, x30, [sp, #-80]!
 58                 #a110:       d11643ff        s     58                 #a110:       d11643ff        sub     sp, sp, #0x590
 59                 $re = qr/^.*stp.*sp, ?\#-([0-9 !!  59                 $re = qr/^.*stp.*sp, \#-([0-9]{1,8})\]\!/o;
 60                 $dre = qr/^.*sub.*sp, sp, #(0x     60                 $dre = qr/^.*sub.*sp, sp, #(0x$x{1,8})/o;
 61         } elsif ($arch eq 'arm') {                 61         } elsif ($arch eq 'arm') {
 62                 #c0008ffc:      e24dd064           62                 #c0008ffc:      e24dd064        sub     sp, sp, #100    ; 0x64
 63                 $re = qr/.*sub.*sp, sp, #([0-9     63                 $re = qr/.*sub.*sp, sp, #([0-9]{1,4})/o;
 64                 $sub = \&arm_push_handling;        64                 $sub = \&arm_push_handling;
 65         } elsif ($arch =~ /^x86(_64)?$/ || $ar     65         } elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) {
 66                 #c0105234:       81 ec ac 05 0     66                 #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
 67                 # or                               67                 # or
 68                 #    2f60:    48 81 ec e8 05 0     68                 #    2f60:    48 81 ec e8 05 00 00       sub    $0x5e8,%rsp
 69                 $re = qr/^.*[as][du][db]    \$     69                 $re = qr/^.*[as][du][db]    \$(0x$x{1,8}),\%(e|r)sp$/o;
 70                 $dre = qr/^.*[as][du][db]    (     70                 $dre = qr/^.*[as][du][db]    (%.*),\%(e|r)sp$/o;
                                                   >>  71         } elsif ($arch eq 'ia64') {
                                                   >>  72                 #e0000000044011fc:       01 0f fc 8c     adds r12=-384,r12
                                                   >>  73                 $re = qr/.*adds.*r12=-(([0-9]{2}|[3-9])[0-9]{2}),r12/o;
 71         } elsif ($arch eq 'm68k') {                74         } elsif ($arch eq 'm68k') {
 72                 #    2b6c:       4e56 fb70         75                 #    2b6c:       4e56 fb70       linkw %fp,#-1168
 73                 #  1df770:       defc ffe4         76                 #  1df770:       defc ffe4       addaw #-28,%sp
 74                 $re = qr/.*(?:linkw %fp,|addaw     77                 $re = qr/.*(?:linkw %fp,|addaw )#-([0-9]{1,4})(?:,%sp)?$/o;
 75         } elsif ($arch eq 'mips64') {              78         } elsif ($arch eq 'mips64') {
 76                 #8800402c:       67bdfff0          79                 #8800402c:       67bdfff0        daddiu  sp,sp,-16
 77                 $re = qr/.*daddiu.*sp,sp,-([0- !!  80                 $re = qr/.*daddiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
 78         } elsif ($arch eq 'mips') {                81         } elsif ($arch eq 'mips') {
 79                 #88003254:       27bdffe0          82                 #88003254:       27bdffe0        addiu   sp,sp,-32
 80                 $re = qr/.*addiu.*sp,sp,-([0-9 !!  83                 $re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
 81         } elsif ($arch eq 'nios2') {               84         } elsif ($arch eq 'nios2') {
 82                 #25a8:  defffb04        addi       85                 #25a8:  defffb04        addi    sp,sp,-20
 83                 $re = qr/.*addi.*sp,sp,-([0-9] !!  86                 $re = qr/.*addi.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
 84         } elsif ($arch eq 'openrisc') {            87         } elsif ($arch eq 'openrisc') {
 85                 # c000043c:       9c 21 fe f0      88                 # c000043c:       9c 21 fe f0     l.addi r1,r1,-272
 86                 $re = qr/.*l\.addi.*r1,r1,-([0 !!  89                 $re = qr/.*l\.addi.*r1,r1,-(([0-9]{2}|[3-9])[0-9]{2})/o;
 87         } elsif ($arch eq 'parisc' || $arch eq     90         } elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
 88                 $re = qr/.*ldo ($x{1,8})\(sp\)     91                 $re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
 89         } elsif ($arch eq 'powerpc' || $arch =     92         } elsif ($arch eq 'powerpc' || $arch =~ /^ppc(64)?(le)?$/ ) {
 90                 # powerpc    : 94 21 ff 30         93                 # powerpc    : 94 21 ff 30     stwu    r1,-208(r1)
 91                 # ppc64(le)  : 81 ff 21 f8         94                 # ppc64(le)  : 81 ff 21 f8     stdu    r1,-128(r1)
 92                 $re = qr/.*st[dw]u.*r1,-($x{1,     95                 $re = qr/.*st[dw]u.*r1,-($x{1,8})\(r1\)/o;
 93         } elsif ($arch =~ /^s390x?$/) {            96         } elsif ($arch =~ /^s390x?$/) {
 94                 #   11160:       a7 fb ff 60       97                 #   11160:       a7 fb ff 60             aghi   %r15,-160
 95                 # or                               98                 # or
 96                 #  100092:       e3 f0 ff c8 f     99                 #  100092:       e3 f0 ff c8 ff 71       lay     %r15,-56(%r15)
 97                 $re = qr/.*(?:lay|ag?hi).*\%r1 !! 100                 $re = qr/.*(?:lay|ag?hi).*\%r15,-(([0-9]{2}|[3-9])[0-9]{2})
                                                   >> 101                       (?:\(\%r15\))?$/ox;
                                                   >> 102         } elsif ($arch =~ /^sh64$/) {
                                                   >> 103                 #XXX: we only check for the immediate case presently,
                                                   >> 104                 #     though we will want to check for the movi/sub
                                                   >> 105                 #     pair for larger users. -- PFM.
                                                   >> 106                 #a00048e0:       d4fc40f0        addi.l  r15,-240,r15
                                                   >> 107                 $re = qr/.*addi\.l.*r15,-(([0-9]{2}|[3-9])[0-9]{2}),r15/o;
 98         } elsif ($arch eq 'sparc' || $arch eq     108         } elsif ($arch eq 'sparc' || $arch eq 'sparc64') {
 99                 # f0019d10:       9d e3 bf 90     109                 # f0019d10:       9d e3 bf 90     save  %sp, -112, %sp
100                 $re = qr/.*save.*%sp, -([0-9]{ !! 110                 $re = qr/.*save.*%sp, -(([0-9]{2}|[3-9])[0-9]{2}), %sp/o;
101         } elsif ($arch =~ /^riscv(64)?$/) {    << 
102                 #ffffffff8036e868:      c20101 << 
103                 $re = qr/.*addi.*sp,sp,-([0-9] << 
104         } elsif ($arch =~ /^loongarch(32|64)?$ << 
105                 #9000000000224708:      02ff40 << 
106                 $re = qr/.*addi\..*sp, .*sp, - << 
107         } else {                                  111         } else {
108                 print("wrong or unknown archit    112                 print("wrong or unknown architecture \"$arch\"\n");
109                 exit                              113                 exit
110         }                                         114         }
111 }                                                 115 }
112                                                   116 
113 #                                                 117 #
114 # To count stack usage of push {*, fp, ip, lr,    118 # To count stack usage of push {*, fp, ip, lr, pc} instruction in ARM,
115 # if FRAME POINTER is enabled.                    119 # if FRAME POINTER is enabled.
116 # e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7    120 # e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
117 #                                                 121 #
118 sub arm_push_handling {                           122 sub arm_push_handling {
119         my $regex = qr/.*push.*fp, ip, lr, pc}    123         my $regex = qr/.*push.*fp, ip, lr, pc}/o;
120         my $size = 0;                             124         my $size = 0;
121         my $line_arg = shift;                     125         my $line_arg = shift;
122                                                   126 
123         if ($line_arg =~ m/$regex/) {             127         if ($line_arg =~ m/$regex/) {
124                 $size = $line_arg =~ tr/,//;      128                 $size = $line_arg =~ tr/,//;
125                 $size = ($size + 1) * 4;          129                 $size = ($size + 1) * 4;
126         }                                         130         }
127                                                   131 
128         return $size;                             132         return $size;
129 }                                                 133 }
130                                                   134 
131 #                                                 135 #
132 # main()                                          136 # main()
133 #                                                 137 #
134 my ($func, $file, $lastslash, $total_size, $ad    138 my ($func, $file, $lastslash, $total_size, $addr, $intro);
135                                                   139 
136 $total_size = 0;                                  140 $total_size = 0;
137                                                   141 
138 while (my $line = <STDIN>) {                      142 while (my $line = <STDIN>) {
139         if ($line =~ m/$funcre/) {                143         if ($line =~ m/$funcre/) {
140                 $func = $1;                       144                 $func = $1;
141                 next if $line !~ m/^($x*)/;    !! 145                 next if $line !~ m/^($xs*)/;
142                 if ($total_size > $min_stack)     146                 if ($total_size > $min_stack) {
143                         push @stack, "$intro$t    147                         push @stack, "$intro$total_size\n";
144                 }                                 148                 }
145                 $addr = "0x$1";                !! 149 
                                                   >> 150                 $addr = $1;
                                                   >> 151                 $addr =~ s/ /0/g;
                                                   >> 152                 $addr = "0x$addr";
                                                   >> 153 
146                 $intro = "$addr $func [$file]:    154                 $intro = "$addr $func [$file]:";
147                 my $padlen = 56 - length($intr    155                 my $padlen = 56 - length($intro);
148                 while ($padlen > 0) {             156                 while ($padlen > 0) {
149                         $intro .= '     ';        157                         $intro .= '     ';
150                         $padlen -= 8;             158                         $padlen -= 8;
151                 }                                 159                 }
152                                                   160 
153                 $total_size = 0;                  161                 $total_size = 0;
154         }                                         162         }
155         elsif ($line =~ m/(.*):\s*file format/    163         elsif ($line =~ m/(.*):\s*file format/) {
156                 $file = $1;                       164                 $file = $1;
157                 $file =~ s/\.ko//;                165                 $file =~ s/\.ko//;
158                 $lastslash = rindex($file, "/"    166                 $lastslash = rindex($file, "/");
159                 if ($lastslash != -1) {           167                 if ($lastslash != -1) {
160                         $file = substr($file,     168                         $file = substr($file, $lastslash + 1);
161                 }                                 169                 }
162         }                                         170         }
163         elsif ($line =~ m/$re/) {                 171         elsif ($line =~ m/$re/) {
164                 my $size = $1;                    172                 my $size = $1;
165                 $size = hex($size) if ($size =    173                 $size = hex($size) if ($size =~ /^0x/);
166                                                   174 
167                 if ($size > 0xf0000000) {         175                 if ($size > 0xf0000000) {
168                         $size = - $size;          176                         $size = - $size;
169                         $size += 0x80000000;      177                         $size += 0x80000000;
170                         $size += 0x80000000;      178                         $size += 0x80000000;
171                 }                                 179                 }
172                 next if ($size > 0x10000000);     180                 next if ($size > 0x10000000);
173                                                   181 
174                 $total_size += $size;             182                 $total_size += $size;
175         }                                         183         }
176         elsif (defined $dre && $line =~ m/$dre    184         elsif (defined $dre && $line =~ m/$dre/) {
177                 my $size = $1;                    185                 my $size = $1;
178                                                   186 
179                 $size = hex($size) if ($size =    187                 $size = hex($size) if ($size =~ /^0x/);
180                 $total_size += $size;             188                 $total_size += $size;
181         }                                         189         }
182         elsif (defined $sub) {                    190         elsif (defined $sub) {
183                 my $size = &$sub($line);          191                 my $size = &$sub($line);
184                                                   192 
185                 $total_size += $size;             193                 $total_size += $size;
186         }                                         194         }
187 }                                                 195 }
188 if ($total_size > $min_stack) {                   196 if ($total_size > $min_stack) {
189         push @stack, "$intro$total_size\n";       197         push @stack, "$intro$total_size\n";
190 }                                                 198 }
191                                                   199 
192 # Sort output by size (last field) and functio !! 200 # Sort output by size (last field)
193 sub sort_lines {                               !! 201 print sort { ($b =~ /:\t*(\d+)$/)[0] <=> ($a =~ /:\t*(\d+)$/)[0] } @stack;
194         my ($a, $b) = @_;                      << 
195                                                << 
196         my $num_a = $1 if $a =~ /:\t*(\d+)$/;  << 
197         my $num_b = $1 if $b =~ /:\t*(\d+)$/;  << 
198         my $func_a = $1 if $a =~ / (.*):/;     << 
199         my $func_b = $1 if $b =~ / (.*):/;     << 
200                                                << 
201         if ($num_a != $num_b) {                << 
202                 return $num_b <=> $num_a;      << 
203         } else {                               << 
204                 return $func_a cmp $func_b;    << 
205         }                                      << 
206 }                                              << 
207                                                << 
208 print sort { sort_lines($a, $b) } @stack;      << 
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php