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() - it is just a parameter for Function2(). And therefore I would expect, that the linker excludes Function1() from the calltree and reserve a seperate piece of memory for it. It seeems, for the linker a call to a function and a function-pointer as parameter is the same (!?). Bernhard
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.