2016-05-21 11 views
2

Ich schreibe einen einfachen LLVM-Plugin-Pass, der opt erfordert, um xxx.so Datei zu laden und einen ModulePass auszuführen. Die seltsame Sache ist, dass, wenn ich deb Paket opt (z. B. von apt-get, nennen wir es opt-3.7) verwenden, funktioniert das Plugin gut (der Nachteil ist, dass es ein Release Build ist); aber wenn ich den opt ich mich bauen (vereinfachen nennen es opt), ist es häufig beklagt:undefined symbol für selbstgebaute llvm opt?

Error opening 'xxx.so': xxx.so: undefined symbol: _ZNK4llvm12FunctionPass17createPrinterPassERNS_11raw_ostreamERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 

mit c++filt Ich weiß, dass opt nicht llvm::FunctionPass::createPrinterPass(llvm::raw_ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const finden.

Es ist ein großes merkwürdiges, da ich keine FunctionPass im Durchlauf verwendete; aber lass uns das ignorieren und weitermachen.

Ich habe dann das Ergebnis von ldd opt

linux-vdso.so.1 => (0x00007ffd5c1ce000) 
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f16a90d3000) 
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f16a8ea9000) 
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f16a8c8c000) 
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f16a8a72000) 
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f16a86ef000) 
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f16a83e6000) 
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f16a81d0000) 
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f16a7e06000) 
/lib64/ld-linux-x86-64.so.2 (0x00005645f6210000) 

und ldd opt-3.7

linux-vdso.so.1 => (0x00007ffc51bc0000) 
libLLVM-3.7.so.1 => /usr/lib/x86_64-linux-gnu/libLLVM-3.7.so.1 (0x00007fec3f725000) 
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fec3f3a2000) 
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fec3efb1000) 
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fec3ed97000) 
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fec3eb79000) 
libffi.so.6 => /usr/lib/x86_64-linux-gnu/libffi.so.6 (0x00007fec3e971000) 
libedit.so.2 => /usr/lib/x86_64-linux-gnu/libedit.so.2 (0x00007fec3e739000) 
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fec3e50f000) 
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fec3e30b000) 
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fec3e002000) 
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fec3ddeb000) 
/lib64/ld-linux-x86-64.so.2 (0x000055bad2080000) 
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fec3dbd6000) 

Der Unterschied, denke ich, ist die so libLLVM-3.7.so.1 Datei.

Also, wo bin ich nicht falsch gelaufen?

BTW, meine Llvm wurde ohne und w/-DLLVM_BUILD_LLVM_DYLIB=1 gebaut, beide hat das undefinierte Symbol Problem.

Antwort

2

Wir hatten genau den gleichen Fehler bei der Verwendung von LLVM-Plugin mit CLANG 3.9. Wir haben dann die Lösung hier gefunden: https://github.com/klee/klee/issues/336

Die Erklärung ist, dass ABI für libstdC++ für LLVM und Ihr Plugin anders ist. Um dieses Problem zu lösen, müssen Sie Ihr Plugin mit dem folgenden Flag "-D_GLIBCXX_USE_CXX11_ABI = 0" neu kompilieren.

Überprüfen Sie dieses Makefile für LLVM-Plugin als Beispiel: https://github.com/SamAinsworth/reproduce-cgo2017-paper/blob/master/package/plugin-llvm-sw-prefetch-pass/Makefile