User forums > Using Code::Blocks

strange "undefined reference" only with 32-bit ASM symbols

<< < (2/2)

bootstrap:
Thanks for the ideas and link.

The way this is handled is VERY BAD.  It is clear to me that the assembler, not the compiler should prefix underscores or not based upon a switch, unless the compiler generates the object file directly, bypassing any assembler.  Then every symbol would be generated correctly for the target ABI (which is OS dependent).  Since the assembler appears not to have any such ability to prefix symbols, there is a serious and inherent problem for anyone writing assembly language code to build and run on both linux and windoze.

One thing to remember is this.  The functions within OS libraries (*.so on linux and *.dll on windoze) either have or do not have leading underscores.  When an application is built, that is a fixed fact that cannot be changed.  Therefore, some potential solutions are problematic.  For example, it doesn't help much to add or strip underscore prefixes from the symbols in your own application functions, because then, when functions are called, some need to have underscores prepended, and others don't - a seriously bad situation.

So it is a fixed fact of life that build tools need to generate prefixes on win32 --- but not win64 or linux32 or linux64.  The problem at hand is... the mingw tools only generate underscore prefixes for win32 C files, but not win32 assembly-language files.  Again, I claim this is a serious mistake in the design of the 32-bit assembler, for the same reason it would be a serious mistake for the C/C++ compilers to not generate underscore prefixes when generating win32 object files.

I eventually created a FUNC(x) macro in my .s file, which I had to rename as a .S file to enable preprocessor support within the assembly-language file.  This function prefixes __USER_LABEL_PREFIX__ to the symbol inside the macro parentheses.  __USER_LABEL_PREFIX__ is "_" on windoze and "" on linux.

However, I think the solution Radek proposes is cleaner.  Unfortunately, I don't think this will let me rename my assembly-language file back to .s again though, because I probably need to keep the preprocessor enabled on both my 32-bit and 64-bit assembly-language files to overcome yet another stupid decision on the windoze side --- their stupid decision on what registers need to be preserved across function calls, especially SIMD registers --- where this becomes revoltingly gross when you realize they only require the lower 128-bits of the preserved 256-bit ymm registers be preserved.  Sheesh, what a kludge!  Typical macroshaft design.  Linux is so clean and efficient in comparison.

So the Radek solution works for me.  I'm not 100% clear whether problems might occur on a system where multiple symbols like "malloc", "_malloc" and "__malloc" exist (at different addresses in the code).  I'm also not entirely clear what happens with assembly language code that must call functions outside itself in a portable way.

I guess one other solution isn't too horribly bad, though it does render the code forever not capable of compilation with macroshaft tools --- which will very soon be quite fine with me!  And that is appending an "asm" suffix on function declarations in the .h files for assembly-language files.  I haven't tried this yet, but it appears changing:

int funcname();
... to ...
int funcname() asm ("funcname");

might do the trick --- by telling the compiler to NOT prepend the underline in code that calls those functions.

Navigation

[0] Message Index

[*] Previous page

Go to full version