Hi
I ran into a odd problem yesterday when I add a code file to control the GPIO for a Cortex M3. All of the routines that were being called from the main code (4 of them) were called out by the linker to be undefined symbols. ??? The .c file compiled with no errors.
I did some experiments to see what the issue might be. I thought maybe the calling signature was wrong and it could not match it up so I cut and pasted just the subroutine definition of one of the subroutines and put it into the top of the only file that called that particular one and just made it a do nothing loop and the linker did resolve the subroutines name/symbol!!
So it is has nothing to do with how the subroutines are called or defined. I did another experiment to see if it had anything to do with the physical number of files being linked. I combined the new GPIO.c file with a existing file and removed the GPIO.c from the link list. I relinked and all of the subroutines names/symbols were resolved BUT a another assembly language name showed up as unresolved. Gees. Its definitely there in a totally different .s file so I don't know why started it will not resolve all of the sudden.
I tried combining more and more files to reduce the number of physical files but nothing seemed to help make this new unresolved system that did not show up before, go away.
So now I don't know what to do. The only thing that makes sense (cause and effect) is a limit on the number of files that the linker can accept. Maybe beyond that there is a internal limit on the number of routines or something that is causing this .s routine to be declared undefined.
Has anyone ever had a problem like this before?
Thanks
Great thought! I totally forgot about name mangling. And yes when I changed all of the vendor supplied driver .c files to be compiled as c++ the functions in GPIO.c are now resolved.
But it seems that I am having (probably) this same issue with the assembly routines in the hw_reg_access.s file. The GPIO.c is calling assembly routines (exported) to write to registers. Those are still not being resolved. It has to be the same issue with name mangling.
Since this is a .s and not .c, what can be done to get the assembly name when called from c++ not to be mangled?
I obviously cannot compile the assembly routine as a c++ in this case
OK it looks like the convention is the same when declaring assembly routines per the AAPCS specification. To use extern "C"
I did that with one of the offending assembly routines:
extern "C" uint32_t HW_get_32bit_reg ( addr_t reg_addr );
and the compiler gave me a error #40 expected an identifier
The syntax looks correct so I don't quite know what it is expecting
I found my mistake this morning. I must have accidentally deleted the definition of that routine when adding the extern "c" . Once I replaced it everything linked just fine.
Thank you for your help in finding out what was wrong with what I was doing with the linker.
I really appreciate it and I hope this thread helps someone else in the future. :-)
Steve
Make sure you are exporting the function name
... Foo PROC EXPORT Foo IMPORT Bar PUSH {LR} LDR R0, =Bar BLX R0 POP {PC} ENDP ; Foo ...
Thanks. Yes I did see that in the code (from microsemi manufacturer).
Everything links fine now (yea) so I move on to the real work.