.. | .. |
---|
34 | 34 | # $& (whole re) matches the complete objdump line with the stack growth |
---|
35 | 35 | # $1 (first bracket) matches the dynamic amount of the stack growth |
---|
36 | 36 | # |
---|
| 37 | +# $sub: subroutine for special handling to check stack usage. |
---|
| 38 | +# |
---|
37 | 39 | # use anything else and feel the pain ;) |
---|
38 | | -my (@stack, $re, $dre, $x, $xs, $funcre); |
---|
| 40 | +my (@stack, $re, $dre, $sub, $x, $xs, $funcre, $min_stack); |
---|
39 | 41 | { |
---|
40 | 42 | my $arch = shift; |
---|
41 | 43 | if ($arch eq "") { |
---|
.. | .. |
---|
43 | 45 | chomp($arch); |
---|
44 | 46 | } |
---|
45 | 47 | |
---|
| 48 | + $min_stack = shift; |
---|
| 49 | + if ($min_stack eq "" || $min_stack !~ /^\d+$/) { |
---|
| 50 | + $min_stack = 100; |
---|
| 51 | + } |
---|
| 52 | + |
---|
46 | 53 | $x = "[0-9a-f]"; # hex character |
---|
47 | 54 | $xs = "[0-9a-f ]"; # hex character or space |
---|
48 | 55 | $funcre = qr/^$x* <(.*)>:$/; |
---|
49 | 56 | if ($arch =~ '^(aarch|arm)64$') { |
---|
50 | 57 | #ffffffc0006325cc: a9bb7bfd stp x29, x30, [sp, #-80]! |
---|
| 58 | + #a110: d11643ff sub sp, sp, #0x590 |
---|
51 | 59 | $re = qr/^.*stp.*sp, \#-([0-9]{1,8})\]\!/o; |
---|
| 60 | + $dre = qr/^.*sub.*sp, sp, #(0x$x{1,8})/o; |
---|
52 | 61 | } elsif ($arch eq 'arm') { |
---|
53 | 62 | #c0008ffc: e24dd064 sub sp, sp, #100 ; 0x64 |
---|
54 | | - $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o; |
---|
| 63 | + $re = qr/.*sub.*sp, sp, #([0-9]{1,4})/o; |
---|
| 64 | + $sub = \&arm_push_handling; |
---|
55 | 65 | } elsif ($arch =~ /^x86(_64)?$/ || $arch =~ /^i[3456]86$/) { |
---|
56 | 66 | #c0105234: 81 ec ac 05 00 00 sub $0x5ac,%esp |
---|
57 | 67 | # or |
---|
.. | .. |
---|
105 | 115 | } |
---|
106 | 116 | |
---|
107 | 117 | # |
---|
| 118 | +# To count stack usage of push {*, fp, ip, lr, pc} instruction in ARM, |
---|
| 119 | +# if FRAME POINTER is enabled. |
---|
| 120 | +# e.g. c01f0d48: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc} |
---|
| 121 | +# |
---|
| 122 | +sub arm_push_handling { |
---|
| 123 | + my $regex = qr/.*push.*fp, ip, lr, pc}/o; |
---|
| 124 | + my $size = 0; |
---|
| 125 | + my $line_arg = shift; |
---|
| 126 | + |
---|
| 127 | + if ($line_arg =~ m/$regex/) { |
---|
| 128 | + $size = $line_arg =~ tr/,//; |
---|
| 129 | + $size = ($size + 1) * 4; |
---|
| 130 | + } |
---|
| 131 | + |
---|
| 132 | + return $size; |
---|
| 133 | +} |
---|
| 134 | + |
---|
| 135 | +# |
---|
108 | 136 | # main() |
---|
109 | 137 | # |
---|
110 | | -my ($func, $file, $lastslash); |
---|
| 138 | +my ($func, $file, $lastslash, $total_size, $addr, $intro); |
---|
| 139 | + |
---|
| 140 | +$total_size = 0; |
---|
111 | 141 | |
---|
112 | 142 | while (my $line = <STDIN>) { |
---|
113 | 143 | if ($line =~ m/$funcre/) { |
---|
114 | 144 | $func = $1; |
---|
| 145 | + next if $line !~ m/^($xs*)/; |
---|
| 146 | + if ($total_size > $min_stack) { |
---|
| 147 | + push @stack, "$intro$total_size\n"; |
---|
| 148 | + } |
---|
| 149 | + |
---|
| 150 | + $addr = $1; |
---|
| 151 | + $addr =~ s/ /0/g; |
---|
| 152 | + $addr = "0x$addr"; |
---|
| 153 | + |
---|
| 154 | + $intro = "$addr $func [$file]:"; |
---|
| 155 | + my $padlen = 56 - length($intro); |
---|
| 156 | + while ($padlen > 0) { |
---|
| 157 | + $intro .= ' '; |
---|
| 158 | + $padlen -= 8; |
---|
| 159 | + } |
---|
| 160 | + |
---|
| 161 | + $total_size = 0; |
---|
115 | 162 | } |
---|
116 | 163 | elsif ($line =~ m/(.*):\s*file format/) { |
---|
117 | 164 | $file = $1; |
---|
.. | .. |
---|
132 | 179 | } |
---|
133 | 180 | next if ($size > 0x10000000); |
---|
134 | 181 | |
---|
135 | | - next if $line !~ m/^($xs*)/; |
---|
136 | | - my $addr = $1; |
---|
137 | | - $addr =~ s/ /0/g; |
---|
138 | | - $addr = "0x$addr"; |
---|
139 | | - |
---|
140 | | - my $intro = "$addr $func [$file]:"; |
---|
141 | | - my $padlen = 56 - length($intro); |
---|
142 | | - while ($padlen > 0) { |
---|
143 | | - $intro .= ' '; |
---|
144 | | - $padlen -= 8; |
---|
145 | | - } |
---|
146 | | - next if ($size < 100); |
---|
147 | | - push @stack, "$intro$size\n"; |
---|
| 182 | + $total_size += $size; |
---|
148 | 183 | } |
---|
149 | 184 | elsif (defined $dre && $line =~ m/$dre/) { |
---|
150 | | - my $size = "Dynamic ($1)"; |
---|
| 185 | + my $size = $1; |
---|
151 | 186 | |
---|
152 | | - next if $line !~ m/^($xs*)/; |
---|
153 | | - my $addr = $1; |
---|
154 | | - $addr =~ s/ /0/g; |
---|
155 | | - $addr = "0x$addr"; |
---|
156 | | - |
---|
157 | | - my $intro = "$addr $func [$file]:"; |
---|
158 | | - my $padlen = 56 - length($intro); |
---|
159 | | - while ($padlen > 0) { |
---|
160 | | - $intro .= ' '; |
---|
161 | | - $padlen -= 8; |
---|
162 | | - } |
---|
163 | | - push @stack, "$intro$size\n"; |
---|
| 187 | + $size = hex($size) if ($size =~ /^0x/); |
---|
| 188 | + $total_size += $size; |
---|
164 | 189 | } |
---|
| 190 | + elsif (defined $sub) { |
---|
| 191 | + my $size = &$sub($line); |
---|
| 192 | + |
---|
| 193 | + $total_size += $size; |
---|
| 194 | + } |
---|
| 195 | +} |
---|
| 196 | +if ($total_size > $min_stack) { |
---|
| 197 | + push @stack, "$intro$total_size\n"; |
---|
165 | 198 | } |
---|
166 | 199 | |
---|
167 | 200 | # Sort output by size (last field) |
---|