This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Calltree problem

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);
}
Function1 gets called from Function2 via pointer. Both functions declare a local variable (a and b).

The linker LX51 produces this calltree:
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
I think that's not correct, because Function1 is not called by main() !

As a result of this calltree the linker locates the variables a and b to the same address!

      00000008H   SYMBOL    DATA     INT       a
      00000008H   SYMBOL    DATA     INT       b

As workaround I manipulated the calltree via linker options. Any other ideas ??

Bernhard

Parents
  • Look at this simple code:

    That code uses function pointers. On an 8051, that makes it decidedly unsimple.

    Please see the app notes and the Manual about how to tell the calltree analyser in the linker about your usage of function pointers. In particular, you'll have to add OVERLAY directives to your linker command line.

Reply
  • Look at this simple code:

    That code uses function pointers. On an 8051, that makes it decidedly unsimple.

    Please see the app notes and the Manual about how to tell the calltree analyser in the linker about your usage of function pointers. In particular, you'll have to add OVERLAY directives to your linker command line.

Children
  • 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.