![]() |
Forum Index : Microcontroller and PC projects : CMM2: V5.05.04b3a: CSUBs - not for the faint hearted!!!!
![]() ![]() |
|||||
Author | Message | ||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
|
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
I agree, but I'm holding off having a proper look until I get to the bottom of why my original example worked for @epsilon, but not for me. Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Thanks @epsilon, That is peculiar as I believe I am using the same settings. I'll have to take another look tomorrow - it would certainly pour cold-water on my GOT theory. I assume you used "merge" strategy to create the CSB and there was no funny-business in how you are calling the CSUB ... perhaps you could attach your calling code too so that I can repeat what you did exactly. Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
It's because in my case the compiler optimized away the fptr assignment and replaced it with a direct call to foo. If I push it a little harder by making fptr volatile, I see the same problem. The program hangs after printing 'c': a * b c <--- hangs here. void main(long long int *c, MMFLOAT *b){ putConsole('a'); putConsole('\r'); putConsole('\n'); foo(); putConsole('b'); putConsole('\r'); putConsole('\n'); void (* volatile fptr)(void); putConsole('c'); putConsole('\r'); putConsole('\n'); fptr = (void (* volatile)(void)) &foo; // <--- hangs here, how is that even possible? fptr(); putConsole('d'); putConsole('\r'); putConsole('\n'); } Epsilon CMM2 projects |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Ha, yes, because you put the actual call through the pointer into the code so as to suppress the compiler warning - glad I didn't do that or it would have frustrated the hell out of me when it worked for a small example but didn't work for the larger (Forth) example. Back to my theory regarding the GOT then, which I still think holds water. @GerryL's "trick" works by bypassing the GOT, basically you would have to call every function in advance to get the function address and use those to build your own "GOT". Best wishes, Tom Edited 2021-03-11 21:07 by thwill MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
Interestingly, just declaring foo() static also seems to work: static void foo(void) { putConsole('*'); putConsole('\r'); putConsole('\n'); } For a static call, the compiler generates position independent code rather than going through a GOT: 80000ba: 4b0b ldr r3, [pc, #44] ; (80000e8 <main+0x84>) 80000bc: 447b add r3, pc <-- foo converted here from relative to absolute 80000be: 60fb str r3, [r7, #12] 80000c0: 68fb ldr r3, [r7, #12] 80000c2: 4798 blx r3 80000c4: 4b07 ldr r3, [pc, #28] ; (80000e4 <main+0x80>) 80000c6: 681b ldr r3, [r3, #0] 80000c8: 2064 movs r0, #100 ; 0x64 80000ca: 4798 blx r3 80000cc: 4b05 ldr r3, [pc, #20] ; (80000e4 <main+0x80>) 80000ce: 681b ldr r3, [r3, #0] 80000d0: 200d movs r0, #13 80000d2: 4798 blx r3 80000d4: 4b03 ldr r3, [pc, #12] ; (80000e4 <main+0x80>) 80000d6: 681b ldr r3, [r3, #0] 80000d8: 200a movs r0, #10 80000da: 4798 blx r3 80000dc: bf00 nop 80000de: 3710 adds r7, #16 80000e0: 46bd mov sp, r7 80000e2: bd80 pop {r7, pc} 80000e4: 080002a4 .word 0x080002a4 80000e8: ffffff81 .word 0xffffff81 <-- offset to 'foo' Epsilon CMM2 projects |
||||
GerryL Newbie ![]() Joined: 24/01/2019 Location: AustraliaPosts: 36 |
Just a FYI in case you also see this when building CMM2 CSUBS, Whilst writing a large CSUB for the CMM2 I noticed a minor issue with armcfgenV143.bas, which I assume is due to the fact that 16 bit and 32 bit instructions can be generated by the compiler. As armcfgenV143 reads the '.text' section of the ELF file in 32 bit chunks its possible, in the case where a function does not finish on a 32 bit boundary due to an uneven number of 16 bit instructions, that the start of the next function is missed in armcfgenV143. In the case of a MERGE all the code is there so it runs OK but you wont see in the generated CSUB text the commented name of the function directly after this missed 32 bit boundary function and the missing function code gets appended to this previous function that didn't finish on the 32 bit boundary. All not an issue as its all relative branches. In the case of a JOIN where you have multiple functions in the source a missing function could be a problem, but a quick fix would be to go to the function directly before the missing function (i.e. the one with the uneven 16 bit instructions) and add asm("nop"); to even up the 16 bit instructions or you could just ensure your source only has a single function. In my experience its not often you end up with an uneven number of 16 bit instructions and if using MERGE of no consequence to it running. Gerry |
||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
Isn't JOIN the option you're supposed to use when you have just one function? What exactly happens if you run armcfgen with join on a file with multiple functions? Which function gets called when you invoked the CSUB? Epsilon CMM2 projects |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4251 |
Isn't JOIN the option you're supposed to use when you have just one function? What exactly happens if you run armcfgen with join on a file with multiple functions? Which function gets called when you invoked the CSUB? Unless my short-term memory is malfunctioning: MERGE combines everything into a single CSUB with main() as its entry point. JOIN keeps the functions separate ... and is strangely named. Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
epsilon![]() Senior Member ![]() Joined: 30/07/2020 Location: BelgiumPosts: 255 |
OK. Got it. If a C file has multiple functions, join will generate multiple CSUBs, one for each function, and in that case you might get bitten by the bug that Gerry found. Good find, Gerry! I'm glad I didn't have to debug my way through that one. Epsilon CMM2 projects |
||||
![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |