Gold Linker and Weak Functions

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

This may be a gold bug. I know that there was a bug in some versions of gold that caused the wrong symbol binding and/or visibility to appear in the output file. This bug also ended up manifesting as gold plugin test failures. Does the problem go away if you use a very recent (git master) version of gold?

Peter

I’m using a relatively recent version of the gold plugin, but haven’t look at a newer linker itself. Eric mentioned that it wasn’t expected to work with regular LTO, so I’m going to stay with ThinLTO for the time being.