#!/usr/bin/perl # check_stack --- check for too deep stack depths; it most likely only # only works for the linux kernel.... use 5.006; use strict; use warnings; use Getopt::Std; use lib "blib/lib"; use Disassemble::X86; use vars qw ( $opt_d ); getopts ("d") and $#ARGV == 1 or die <; close OBJ; $/ = $slash_save; # init the disassembler my $dis = Disassemble::X86->new ( start => 0xc0100000 - 0x1000, # text addr - file offset pos => 0, size => 32, text => $file, ); # you may change these as you see fit # max_check is the maximum number of instructions to scan for the 'sub esp,...' # before giving up my $max_check = 10; # stack_limit is the size that we'll consider worthy of reporting my $stack_limit = 512; # end of changables # max_stack is the maximum stack size we saw my $max_stack = 0; # open System.map. It contains the address, type, and names of each function # (among other things) open MAP, "<$ARGV[1]" or die "$0: can't read $ARGV[1]: $!\n"; while () { my ($addr, $type, $name) = split (' ', $_); next if $name =~ /^\./; # we don't want names like '.yadda' if ($type =~ /^[Tt]$/) { # we only want text symbols print "looking at $name ($addr)\n" if $opt_d; $dis->pos (hex ($addr)); for (my $i = 0; $i < $max_check && !$dis->at_end; $i++) { my $op = $dis->disasm (); printf "%04x %s\n", $dis->op_start (), $op if $opt_d; next if (!defined $op); if ($op =~ /sub esp,(0x[[:xdigit:]]+)/) { my $stack = hex ($1); $max_stack = $stack if $stack > $max_stack; printf "check $name (stack %d)\n", $stack if $stack >= $stack_limit; last; } } } } close MAP; print "max single stack used is $max_stack\n"; exit 0; # end check_stack