Gold plugin and LLVM tools documentation

Hi,

I've been following the instructions on how to use the LLVM Gold
plugin at http://llvm.org/docs/GoldPlugin.html while building an
multiple versions of WebKit. The documentation hasn't been updated
since 2010 and hasn't really matched my experiences, so I'd like to
ask if I'm doing these steps incorrectly. What I'm trying to do is
force all compilation steps to bitcode so I can use the LTO plugin.

I'm working with both LLVM/Clang 2.9 and 3.0 with binutils 2.22.
According to the documentation, I replaced the system ar, nm, and ld
with the versions from binutils 2.22, and placed LLVMgold.so in
/usr/bin/bfd-plugins. The host system is Ubuntu 11.10. CFLAGS and
CXXflags are all set to include "-emit-llvm".

First, I create libjscore.a with ar, where I've changed the command
line to load the plugin:
ar cqs --plugin
/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
libjscore.a <list of object files>

Then I link jsc against libjscore.a:
/home/tmjackso/multicompiler/llvm-3.0/release/bin/clang++
-Wl,-plugin,/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
-Wl,-rpath,/home/tmjackso/builds/qt/qt-4.8.1/lib
-Wl,-rpath,/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
-o ./jsc obj/release/jsc.o -L./release
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -ljscore -lQtCore
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lpthread
/usr/bin/ld: error: jscore: malformed archive header name at 8

When I change the link command to not use "-ljscore" but the path to
libjscore.a, it works:
/home/tmjackso/multicompiler/llvm-3.0/release/bin/clang++
-Wl,-plugin,/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
-Wl,-rpath,/home/tmjackso/builds/qt/qt-4.8.1/lib
-Wl,-rpath,/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
-o ./jsc obj/release/jsc.o libjscore.a -L./release
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lQtCore
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lpthread

Does anyone know what I'm doing wrong in the first case? The build is
managed by qmake, and I'm working on coaxing it into generating the
second line.

Also, because the documentation is dated in 2010, is it current? I'll
have some time in about two weeks to take a look at it if it's not.
For example, using clang -O4 has never worked for me. That's why I
pass -Wl to load the linker plugin.

Thanks,

Todd Jackson

First, I create libjscore.a with ar, where I've changed the command
line to load the plugin:
ar cqs --plugin
/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
libjscore.a <list of object files>

Note that you shouldn't need to pass --plugin to ar, it searches bfd-plugins.

Then I link jsc against libjscore.a:
/home/tmjackso/multicompiler/llvm-3.0/release/bin/clang++
-Wl,-plugin,/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
-Wl,-rpath,/home/tmjackso/builds/qt/qt-4.8.1/lib
-Wl,-rpath,/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
-o ./jsc obj/release/jsc.o -L./release
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -ljscore -lQtCore
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lpthread
/usr/bin/ld: error: jscore: malformed archive header name at 8

When I change the link command to not use "-ljscore" but the path to
libjscore.a, it works:
/home/tmjackso/multicompiler/llvm-3.0/release/bin/clang++
-Wl,-plugin,/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
-Wl,-rpath,/home/tmjackso/builds/qt/qt-4.8.1/lib
-Wl,-rpath,/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
-o ./jsc obj/release/jsc.o libjscore.a -L./release
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lQtCore
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lpthread

Does anyone know what I'm doing wrong in the first case? The build is
managed by qmake, and I'm working on coaxing it into generating the
second line.

What does ld -v shows? Can you run nm on libjscore.a?

Also, because the documentation is dated in 2010, is it current? I'll
have some time in about two weeks to take a look at it if it's not.
For example, using clang -O4 has never worked for me. That's why I
pass -Wl to load the linker plugin.

Not a lot has changed. You should be able to pass -flto when linking
to causes clang to pass the plugin to the linker automatically btw.

Thanks,

Todd Jackson

Cheers,
Rafael

First, I create libjscore.a with ar, where I've changed the command
line to load the plugin:
ar cqs --plugin
/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
libjscore.a <list of object files>

Note that you shouldn't need to pass --plugin to ar, it searches bfd-plugins.

Ok. I'll keep that in mind, but I'll leave it in for now.

Then I link jsc against libjscore.a:
/home/tmjackso/multicompiler/llvm-3.0/release/bin/clang++
-Wl,-plugin,/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
-Wl,-rpath,/home/tmjackso/builds/qt/qt-4.8.1/lib
-Wl,-rpath,/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
-o ./jsc obj/release/jsc.o -L./release
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -ljscore -lQtCore
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lpthread
/usr/bin/ld: error: jscore: malformed archive header name at 8

When I change the link command to not use "-ljscore" but the path to
libjscore.a, it works:
/home/tmjackso/multicompiler/llvm-3.0/release/bin/clang++
-Wl,-plugin,/home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
-Wl,-rpath,/home/tmjackso/builds/qt/qt-4.8.1/lib
-Wl,-rpath,/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
-o ./jsc obj/release/jsc.o libjscore.a -L./release
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lQtCore
-L/home/tmjackso/builds/qt/qt-4.8.1/lib -lpthread

Does anyone know what I'm doing wrong in the first case? The build is
managed by qmake, and I'm working on coaxing it into generating the
second line.

What does ld -v shows? Can you run nm on libjscore.a?

$ ld -v
GNU gold (GNU Binutils 2.22) 1.11

Without passing --plugin to nm:
$ nm WebKitBuild/Release/JavaScriptCore/release/libjscore.a
nm: YarrInterpreter.o: File format not recognized
nm: YarrPattern.o: File format not recognized
nm: YarrSyntaxChecker.o: File format not recognized
nm: Assertions.o: File format not recognized
nm: ByteArray.o: File format not recognized
nm: CryptographicallyRandomNumber.o: File format not recognized
...
(...etc)

With passing --plugin to nm:
$ nm --plugin /home/tmjackso/multicompiler/llvm-3.0/release/lib/LLVMgold.so
WebKitBuild/Release/JavaScriptCore/release/libjscore.a | head -n 5

YarrInterpreter.o:
         U WTFReportBacktrace
00000000 W _ZN3JSC4Yarr11Interpreter16matchDisjunctionEPNS0_15ByteDisjunctionEPNS1_18DisjunctionContextEb
00000000 W _ZN3JSC4Yarr11Interpreter16matchParenthesesERNS0_8ByteTermEPNS1_18DisjunctionContextE
00000000 W _ZN3JSC4Yarr11Interpreter17matchAssertionEOLERNS0_8ByteTermE
...

Not a lot has changed. You should be able to pass -flto when linking
to causes clang to pass the plugin to the linker automatically btw.

This is what I get when I use just -flto -v:
$ /home/tmjackso/multicompiler/llvm-3.0/release/bin/clang++ -flto -v
-Wl,-rpath,/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
-o ./jsc obj/release/jsc.o -L./release -L/usr/lib/x86_64-linux-gnu
-ljscore -lQtCore -lpthread
clang version 3.0
(ssh://tmjackso@ssllab.org/gitroot/multicompiler/clang.git
8c04ba90b6edfc97cedd7eae248c91775687805b)
Target: x86_64-unknown-linux-gnu
Thread model: posix
"/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m
elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o ./jsc
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crti.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/crtbegin.o -L./release
-L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.6
-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu
-L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu
-L/usr/lib/gcc/x86_64-linux-gnu/4.6/../../.. -L/lib/x86_64-linux-gnu
-L/lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib -rpath
/home/tmjackso/builds/webkit/WebKit-r94287/WebKitBuild/Release/lib
obj/release/jsc.o -ljscore -lQtCore -lpthread -lstdc++ -lm -lgcc_s
-lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.6/crtend.o
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crtn.o
/usr/bin/ld: error: obj/release/jsc.o:1:3: invalid character
/usr/bin/ld: error: obj/release/jsc.o:1:3: syntax error, unexpected $end
/usr/bin/ld: error: obj/release/jsc.o: not an object or archive
/usr/bin/ld: error: jscore: no archive symbol table (run ranlib)
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o(.text+0x20):
error: undefined reference to 'main'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

When I use -flto -v -Wl,-plugin, it links successfully.

Thanks,

Todd