I am trying to process the output of a nm or readelf -s on an executable. However, I am having trouble differentiating static functions from each other in the output.
Here is what I am working with:
test.c
static int foo() {
int x = 6;
}
main() {}
other.c
static int foo() {
int x = 5;
}
I compile these like so:
gcc -o test test.c other.c
And then run a nm command to get all the symbols:
nm test
Among which the following two symbols (for my static functions) appear:
00000000004004ed t foo
0000000000400500 t foo
Is there a method to be able to distinguish which file the specific foo function appeared from? Or will I need to do some magic before compiling to get this to work?
I should add that for my use case, I have access to the final binary and the object files used by it, but I cannot actually build it myself to ensure that it has a symbol table.
Thanks!
Your question assumes that, given an executable, you can always discover the names of the
static
(local) functions that were compiled into it, usingnm
or another tool. Thus you will be able to see when two or more such names are the same and to raise the question of how to discover what source files they were compiled from.However, that assumption is false. In the case of gcc, if files are compiled with optimization
-O0
then local symbols will be emitted in the object file symbol table.-O0
is the default, so it applies in the case of your:But if files are compiled at any higher optimization level - as they certainly will be for a release build - then local symbols are omitted from the object files symbol table. So the linker never even sees them. So you cannot recover them from the executable with
nm
or anything else.Compile your sample files with:
then
nm test
again, and you will observe that the:have vanished, together with all of the other static function names.
In that case, if as you say you cannot control how the executable is built, then you cannot ensure that it is even possible for your question to arise.
If you could control how the executable is built to ensure that files are compiled with
-O0
, then there are several ways in which you can tie the static function names to source files. Two equally simple ones would be:and
each of which will list a source file name at the head of each chunk of symbols that come from it.
(And if it needs saying, the
gdb
approach suggested by by @Amol does not escape the restriction that the executable must have been compiled with optimization-O0
)