Perl: What Does Checkstack.Pl in Linux Source Do

Perl: what does checkstack.pl in linux source do?

It creates a listing of the size of the stack frame used by every function in the kernel (i.e. the total amount of local scratch space used by each function for local variables and whatnot).

The way it does this is by going through the disassembly of the kernel and looking for 2 things: function names and instructions which adjust the stack. It looks for function names by looking for lines that match $funcre (qr/^$x* <(.*)>:$/), and it looks for stack adjustment instructions that match $re or $dre; the latter two depend highly on what architecture the kernel was compiled for, which is what the first big block if if/else statements is checking for. $re searches for functions which adjust the stack by a fixed amount (the vast majority of functions), and $dre searches for functions which adjust the stack by a variable amount (rare).

objdump is part of binutils; objdump -d is the command to disassemble an object file. The usage of this script is to disassemble the kernel (objdump -d vmlinux) and pipe the output into the script. The output of the script is a listing of all of the functions in the kernel, sorted by the largest stack frame size. I assume the purpose of the script is for the kernel maintainers to be able to avoid stack overflows by painfully making sure that the stack frames of everything is as small as possible, and this script allows them to verify this.

Understanding Regular Expression converting to Linux from Perl script

This expression

$file_directory =~ s/[^\\\/]+$//;

will match with all the characters after the last forward or backward slash, and replace it with nothing. Usually this will end up with the directory name. (Note that there are safer ways to do this, which are also cross-platform. For instance Path::Class.)

  • [^] is a negated character class, and will match anything not in the group.
  • + gives one or more matches
  • $ matches end of string

If I wish to convert it into Linux should the changes be like this ?

Since the line already checks for both slashes, the code in question should work for Linux as is.

Checking stack usage at compile time

Linux kernel code runs on a 4K stack on x86. Hence they care. What they use to check that, is a perl script they wrote, which you may find as scripts/checkstack.pl in a recent kernel tarball (2.6.25 has got it). It runs on the output of objdump, usage documentation is in the initial comment.

I think I already used it for user-space binaries ages ago, and if you know a bit of perl programming, it's easy to fix that if it is broken.

Anyway, what it basically does is to look automatically at GCC's output. And the fact that kernel hackers wrote such a tool means that there is no static way to do it with GCC (or maybe that it was added very recently, but I doubt so).

Btw, with objdump from the mingw project and ActivePerl, or with Cygwin, you should be able to do that also on Windows and also on binaries obtained with other compilers.

How to get maximum frame size of each function compiled by gcc?

You can try -fstack-usage.

  • https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html

There is also -Wstack-usage=<stack_limit> (eg. -Wstack-usage=4096) which will give you a warning as you compile your code.

Possible stack size of embedded device

All sorts of guesses can be made :) Most (all?) embedded development environments provide mechanisms for allocating device memories (read-only, stack, heap, etc.) This is commonly done through linker directive files or C #pragmas placed in a setup source file. Without more information on your development environment, no accurate guess can be made.

In function f(), variable p will exist on the stack. When the function exits, that location on the stack will likely be used for something else.

As for function f2(), you can expect that 100 bytes from the stack will be assigned to t while this function is executing. The size of p will not be considered.

Note that the stack can be used for other information, so you cannot reliably estimate stack usage without considering other factors. For example, do you expect recursion? The stack can be used to store function call/return information - thereby reducing the amount of space you have for local (stack) variables.

Lastly, I've worked with devices operating with less than 1KB of stack, so assumptions should be made carefully.



Related Topics



Leave a reply



Submit