[windows) how to use weak references with llvm 3.4 and windows?

Hello,

I’m generating C code (and the resulting obj files) using llvm 3.4 for both unix and windows.
And I use the dreaded weak references, that, for windows, are not too widely supported.

When I link my application on linux, I have no issue.
But when I’m doing the same on windows using mingw I got a duplicate symbol error :

…\robovm-0.0.8\lib\robovm-rt.jar\dalvik\system\BlockGuard$BlockGuardPolicyException.class.o:(.text$dalvik_system_BlockGuard$24BlockGuardPolicyException_getPolicy__I_lookup[_dalvik_system_BlockGuard$24BlockGuardPolicyException_getPolicy__I_lookup]+0x0): multiple definition of dalvik_system_BlockGuard$24BlockGuardPolicyException_getPolicy__I_lookup' ..\Temp\robovm3774596063679264132.tmp\linker.o:(.text+0x340): first defined here ..\robovm-0.0.8\lib\robovm-rt.jar\dalvik\system\BlockGuard$BlockGuardPolicyException.class.o:(.text$dalvik_system_BlockGuard$24BlockGuardPolicyException_getPolicyViolation__I_lookup[_dalvik_system_BlockGuard$24BlockGuardPolicyException_getPolicyViolation__I_lookup]+0x0): multiple definition of dalvik_system_BlockGuard$24BlockGuardPolicyException_getPolicyViolation__I_lookup’
…\Temp\robovm3774596063679264132.tmp\linker.o:(.text+0x350): first defined here
…\robovm-0.0.8\lib\robovm-rt.jar\dalvik\system\BlockGuard$BlockGuardPolicyException.class.o:(.text$dalvik_system_BlockGuard$24BlockGuardPolicyException_getMessage__Ljava_lang_String$3B_lookup[_dalvik_system_BlockGuard$24BlockGuardPolicyException_getMessage__Ljava_lang_String$3B_lookup]+0x0): multiple definition of `dalvik_system_BlockGuard$24BlockGuardPolicyException_getMessage__Ljava_lang_String$3B_lookup’

Because those symbols are declared as weak.

What is the status about the support of weak symbols on windows?
Are they supposed to work? Are they supposed to never work ?

Do you know any way to fix this (or work around it). I use weak symbols everywhere in my code generation, so I would prefer a fix that doesn’t involve to rewrite my code.

I’m considering rewriting the obj files using objcopy.
Has this any chance to work ?
Here are the o.

Cheers,
Carl.

COFF doesn’t support the same kind of concept of ‘weak’ that ELF does. This is the issue that users brought up with mingw: https://sourceware.org/bugzilla/show_bug.cgi?id=9687

Instead, COFF supports weak externals, which you can use like:

$ cat t.c
int foo() attribute((weak));
int main() {
if (foo)
return foo();
return 13;
}

$ cat t2.c
int foo() {
return 42;
}

$ clang t.c t2.c -o t && ./t ; echo $?
42

So, we got the definition of foo from t2.c. If t2.c hadn’t been linked, foo would be null.

Thanks for your clear answer. Do you know what modifier should I use to declare such weak symbols in my llvm intermediate code?

So that it can be compiled to the .o file with the weak attribute ?

You’d have to use extern_weak linkage. Clang compiles the foo declaration to:

$ clang -cc1 -emit-llvm -o - t.c | grep declare.*@foo
declare extern_weak i32 @foo(…) #1

So instead of using linkagetypes.weak I should use externalweaklinkage ?

Yep, llvm::GlobalValue::ExternalWeakLinkage.

Thanks.
You’ve been very helpful.