For reference, please take a look at this older question of mine:https://community.arm.com/developer/tools-software/tools/f/keil-forum/41992/spurious-link-from-isr-to-pr-mainPreviously, function pointers that were placed in a global table made the linker think ?CO?MAIN is calling all of those referenced functions. Telling the linker to OVERLAY(?CO?MAIN ~ ThoseReferencedFunctions) (and adding OVERLAY(TheFunctionUsingThatTable ! ThoseReferencedFunctions), of course) fixed the problem.
OVERLAY(?CO?MAIN ~ ThoseReferencedFunctions)
OVERLAY(TheFunctionUsingThatTable ! ThoseReferencedFunctions)
The linker warnings back then looked very similar to the ones I am getting now:
*** WARNING L15: MULTIPLE CALL TO FUNCTION NAME: FOO/MAIN CALLER1: INTERRUPTVECTORS_INT0/MAIN CALLER2: INTERRUPTVECTORS_UART/MAIN*** WARNING L15: MULTIPLE CALL TO FUNCTION NAME: FOO/MAIN CALLER1: INTERRUPTVECTORS_UART/MAIN CALLER2: ?C_C51STARTUP
*** WARNING L15: MULTIPLE CALL TO FUNCTION
NAME: FOO/MAIN
CALLER1: INTERRUPTVECTORS_INT0/MAIN
CALLER2: INTERRUPTVECTORS_UART/MAIN
CALLER1: INTERRUPTVECTORS_UART/MAIN
CALLER2: ?C_C51STARTUP
These warnigs show up when, in `void Foo()`, i simply only declare a local variable. Like unsigned char i; or bit b;. (That is, the function is empty except for the declaration.) If I add some more code that accesses a few global variables (but does not call any other functions), an L13 appears too:
unsigned char i;
bit b;
*** WARNING L13: RECURSIVE CALL TO FUNCTION CALLED: MAIN CALLER: HARDWARETEST_GP_TESTRS485_QUEUEFIRSTIDLETEST/MAIN
*** WARNING L13: RECURSIVE CALL TO FUNCTION
CALLED: MAIN
CALLER: HARDWARETEST_GP_TESTRS485_QUEUEFIRSTIDLETEST/MAIN
But all of these warnings only show up when the code optimization level is set to 9: Common Block Subroutines. On the lower levels, the warnings don't show up. Now... the errors last time were also insane, so nothing can shock me anymore, but goodamnit the error messages are just so useless for finding the actual cause.
9: Common Block Subroutines
Curiously, the MAP file says
MAIN ----- ----- ----- ----- +--> ?CO?MAIN +--> ?PR?FOO... +--> ?PR?_BAR?MAIN
MAIN ----- ----- ----- -----
+--> ?CO?MAIN
+--> ?PR?FOO...
+--> ?PR?_BAR?MAIN
(Please note that Foo and Bar are short placeholders. The real function names are longer, which is why "FOO..." has an ellipsis at the end.)I don't know why BAR has an underscore and FOO doesn't. I also don't know why these show up here in the first place. I never take function pointers to either. They are also not called directly from void main().
void main()
Any suggestions on what is going on and how to fix it are welcome!
I don't think this explains all of the symptoms I'm seeing. I made sure to add appropriate overlay-directives in regards to function pointers. Remove the link between the "function that takes the pointer" to "the function pointed to" and add a link between "the function that performs the indirect call" to "the function pointed to". Simply declaring a local variable does not add anything to the constant segment. Or at least it should not. f it does, it's non-deterministic when it does and when it doesn't. Anyways, "?CO?EXAMPLE1 ~ FUNC2 deletes the implied call reference between func2 and the code constant segment in the example." seems like a very bad workaround. Either link isn't actually needed when using a string literal like that, in which case the compiler shouldn't add that link in the first place, or the link is needed, in which case removing it will likely break things.
Also, at some point this worked:
void Blubb(); void Bla() { Blubb(); } void Blubb() { unsigned char c; }
While this didn't:
void Blubb(); void Blubb() { unsigned char c; } void Bla() { Blubb(); }
Which is just insane.