Error with Gold Linker during LTO

We’ve found an error during the use of LTO that appears to happen only during the use of the gold linker.

We essentially have a file which is compiled without LTO:

f1() {

h1();

}

And a second file that is compiled/linked with LTO:

f2() {

f1();

h1();

}

This second file has the function h1() inlined during LTO.

The resulting executable fails because the symbol for h1 is weak in the first .o and doesn’t exist in the second .o.

All the actual code is below for reproducing the error.

Is this an error in the linker itself or in how LLVM deals with the symbols?

Daniel

cat > weakCpp.h << !

class C {

public:

int simple_method() {return 1;}

int caller_method() ;

};

!

cat > weakImpl.cpp << !

#include “weakCpp.h”

int C::caller_method() {

return simple_method();

}

!

cat > weakMain.cpp << !

#include “weakCpp.h”

int call_methods_main() {

C instance;

return instance.simple_method() + instance.caller_method();

}

int main() {

return call_methods_main();

}

!

clang++ -O0 weakImpl.cpp -o weakImpl.o -c

clang++ -O1 -o weakMainO1.exe -flto -mcpu=cortex-a15 -mllvm -debug-only=inline -static weakMain.cpp weakImpl.o -v -Wl,-plugin-opt=-debug-only=inline -Wl,-fuse-ld=gold -Wl,-plugin-opt=also-emit-llvm -Wl,-plugin-opt=obj-path=. >& O1.log

Daniel

clang++ -O1 -o weakMainO1.exe -flto -mcpu=cortex-a15 -mllvm
-debug-only=inline -static weakMain.cpp weakImpl.o -v
-Wl,-plugin-opt=-debug-only=inline -Wl,-fuse-ld=gold
-Wl,-plugin-opt=also-emit-llvm -Wl,-plugin-opt=obj-path=. >& O1.log

Those command line options don't exist on trunk.

The following works for me:

$ clang++ -O0 weakImpl.cpp -o weakImpl.o -c
$ clang++ -O1 -o weakMainO1.exe -flto -static weakMain.cpp weakImpl.o

Do you also see the issue with x86_64?

Cheers,
Rafael

So you see the issue as well in ARM? When doing a

objdump -D weakMainO1.exe | grep -A 10 "<_ZN1C13caller_methodEv>:"

I see:

00008b88 <_ZN1C13caller_methodEv>:
    8b88: e92d4800 push {fp, lr}
    8b8c: e1a0b00d mov fp, sp
    8b90: e24dd008 sub sp, sp, #8
    8b94: e58d0004 str r0, [sp, #4]
    8b98: e59d0004 ldr r0, [sp, #4]
    8b9c: ebffdd17 bl 0 <__preinit_array_end>
    8ba0: e1a0d00b mov sp, fp
    8ba4: e8bd4800 pop {fp, lr}
    8ba8: e12fff1e bx lr

where the bl 0 causes a seg fault.

I'll check x86_64, but currently don't have that setup, so it'll take me a little bit of time to check.

Sorry, I had understood that the linker was crashing, not the generated program.

I can reproduce the issue now.

Glad to hear you can reproduce it.

What I don't know is if this is a linker issue or an LLVM issue.

Hi Rafael,

Just pointing out, that this test fails with x86_64 with trunk.

http://llvm.org/bugs/show_bug.cgi?id=19888

Thanks

Shankar Easwaran

LLVM. I reported the underlying issue in llvm.org/pr19901.

Cheers,
Rafael

Thanks Rafael.

symbols. It sounds like the linker sees an object that refers to h1
but does not see any objects that define h1. There is nothing the
linker can do in such a case.

Ian

From your description, it's an error in how LLVM generates the
symbols. It sounds like the linker sees an object that refers to h1
but does not see any objects that define h1. There is nothing the
linker can do in such a case.

That is exactly right. It is 19901 – The plugin can drop a symbol gold has asked for.

Cheers,
Rafael