It appears as if the gold linker doesn’t resolve weak functions to the strong definition with regular LTO (ThinLTO seems to work).
weak.c:
#define __init attribute ((section(".init.text")))
#define __weak attribute ((weak))
int __init __weak early_irq_init(void)
{
return 0;
}
strong.c:
#define __init attribute ((section(".init.text")))
extern int arch_early_irq_init(void);
int __init early_irq_init(void)
{
return arch_early_irq_init();
}
Compiled like so:
clang -flto -c weak.c
clang -flto -c strong.c
Linked:
ld.gold -plugin llvm-r337625.install/lib/LLVMgold.so -r -o bad.o weak.o strong.o
The resulting object file has a weak reference to “early_irq_init”:
$ nm bad.o
0000000000000000 W early_irq_init
$ objdump -d bad.o
bad.o: file format elf64-x86-64
Disassembly of section .init.text:
0000000000000000 <early_irq_init>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 31 c0 xor %eax,%eax
6: 5d pop %rbp
7: c3 retq
I’ve been combing through the gold linker code, but I haven’t found the correct set of attributes to get it to work. Note that if I change the weak symbol to a symbol reference then everything links correctly.
-bw