Need more intelligent conditionalization of libgcc rts symbols for x32
In rts/RtsSymbols.c we have
// 64-bit support functions in libgcc.a
#if defined(__GNUC__) && SIZEOF_VOID_P <= 4 && !defined(_ABIN32)
#define RTS_LIBGCC_SYMBOLS \
SymI_NeedsProto(__divdi3) \
SymI_NeedsProto(__udivdi3) \
...
The purpose is to provide these symbols to .o files that use these symbols, expecting to be linked against libgcc. These symbols are for things like 64-bit integer division that aren't available as machine instructions on some platforms.
But the #if is wrong on x32, which, despite having sizeof(void *) == 4, naturally has a full complement of 64-bit arithmetic instructions, since its registers are 64 bits wide. So libgcc does not provide these symbols, and as a result we eventually encounter missing symbol errors when linking the rts.
Some possible solutions include
- Figure out if there is a CPP variable set for x32 and don't include these symbols if that variable is set. I'm not sure whether
__ILP32__is such a variable (after all x86 is also an architecture on which int, long and pointers are 32-bits). - Use autoconf to detect the presence of these symbols in libgcc. (Probably just pick one, like
__divdi3, and hope they are all present or all missing.) - Use weak symbols somehow to add these symbols to the RTS's internal symbol table if and only if the RTS was linked against a libgcc that provides these symbols.
My Android ghci also needs lots more of these, including __modsi3, __umodsi3, __ctzdi2, a bunch of __aeabi_* and __sync_*, and __sF (no idea what that is). So I'm inclined towards the last option.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Runtime System (Linker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |