There is a strange behaviour of the linker concerning the calltree! Look at this simple code:
void Function1() { int a; } void Function2(void (code *fptr)(void)) { int b; fptr(); } main() { Function2(Function1); }
FUNCTION/MODULE BIT_GROUP DATA_GROUP --> CALLED FUNCTION/MODULE START STOP START STOP ==================================================== ?C_C51STARTUP ----- ----- ----- ----- +--> ?PR?MAIN?MAIN MAIN/MAIN ----- ----- ----- ----- +--> ?PR?FUNCTION1?MAIN +--> ?PR?_FUNCTION2?MAIN FUNCTION1/MAIN ----- ----- 0008H 0009H _FUNCTION2/MAIN ----- ----- 0008H 0009H
00000008H SYMBOL DATA INT a 00000008H SYMBOL DATA INT b
Function1() is actually NOT called by main() You and I know that. But the linker doesn't. The linker has to do call graph analysis based on what it can see. And what it sees is that main() uses Function1() in some way. It doesn't know how it uses it, so it has to assume that main() contains a call to Function2(), since that's by far the most probable case. Anyway, omitting the arc "main() calls Function1()" from the call graph is only one half of the job: the more important one is to add an arc "Function2() calls Function1()" --- this is quite entirely impossible for the call tree analysis to find out on its own. The OVERLAY directive is the way to manually overrule that faulty analysis performed by the linker, for both these issues. You either have to use it, or avoid using function pointers.