Your question assumes that, given the executable, you can always find the names of static (local) functions that have been compiled into it using nm or another tool. That way, you can see when two or more of these names are the same and raise the question of how to find which source files they were compiled.
However, this assumption is incorrect. In the case of gcc, if the files are compiled with -O0 optimization, then local characters will be emitted in the file's character table object. -O0 is the default value, so it applies to your case:
gcc -o test test.c other.c
But if the files are compiled at any higher level of optimization β as they will certainly be for release builds β then local characters will not be removed from the character table object. Therefore, the linker never sees them. Thus, you cannot restore them from the executable using nm or anything else.
Compile your files with:
gcc -O1 -o test test.c other.c
then nm test , and you will notice that:
00000000004004ed t foo 0000000000400500 t foo
disappeared along with all other static function names.
In this case, if you say that you cannot control how the executable is executed, then you cannot guarantee that this is possible even for your question.
If you can control how the executable is created to ensure that the files are compiled with -O0 , then there are several ways you can link static function names to source files. Two equally simple:
readelf -s test
and
objdump -t test
each of which will display the name of the source file at the beginning of each fragment with the characters that come from it.
(And if you need to say, the gdb approach proposed by @Amol does not allow us to avoid the limitation that the executable should have compiled with the -O0 optimization)