自建llvm opt的未定义符号?
undefined symbol for self-built llvm opt?
我写了一个简单的 llvm plugin pass,需要 opt 加载 xxx.so
文件和 运行 ModulePass。奇怪的是,当我使用 deb
包 opt
(例如,来自 apt-get
,我们称它为 opt-3.7
)时,插件工作正常(缺点是它是发布 版本);然而,当我使用 opt 构建自己时(简称为 opt
),它经常抱怨:
Error opening 'xxx.so': xxx.so: undefined symbol: _ZNK4llvm12FunctionPass17createPrinterPassERNS_11raw_ostreamERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
使用 c++filt
我知道 opt
找不到 llvm::FunctionPass::createPrinterPass(llvm::raw_ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const
.
这很奇怪,因为我在通行证中没有使用任何 FunctionPass
;但让我们忽略它并继续。
然后我检查了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)
和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)
区别,我猜是so文件libLLVM-3.7.so.1
.
那我哪里没弄错?
顺便说一句,我的 llvm 是 w/o 和 -DLLVM_BUILD_LLVM_DYLIB=1
构建的,两者都有未定义的符号问题。
在 CLANG 3.9 中使用 LLVM 插件时,我们遇到了完全相同的错误。然后我们在这里找到了解决方案:https://github.com/klee/klee/issues/336
解释是用于 LLVM 的 libstdc++ 的 ABI 与您的插件不同。要解决此问题,您需要使用以下标志“-D_GLIBCXX_USE_CXX11_ABI=0”重新编译您的插件。
检查 LLVM 插件的 Makefile 作为示例:https://github.com/SamAinsworth/reproduce-cgo2017-paper/blob/master/package/plugin-llvm-sw-prefetch-pass/Makefile
我写了一个简单的 llvm plugin pass,需要 opt 加载 xxx.so
文件和 运行 ModulePass。奇怪的是,当我使用 deb
包 opt
(例如,来自 apt-get
,我们称它为 opt-3.7
)时,插件工作正常(缺点是它是发布 版本);然而,当我使用 opt 构建自己时(简称为 opt
),它经常抱怨:
Error opening 'xxx.so': xxx.so: undefined symbol: _ZNK4llvm12FunctionPass17createPrinterPassERNS_11raw_ostreamERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
使用 c++filt
我知道 opt
找不到 llvm::FunctionPass::createPrinterPass(llvm::raw_ostream&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const
.
这很奇怪,因为我在通行证中没有使用任何 FunctionPass
;但让我们忽略它并继续。
然后我检查了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)
和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)
区别,我猜是so文件libLLVM-3.7.so.1
.
那我哪里没弄错?
顺便说一句,我的 llvm 是 w/o 和 -DLLVM_BUILD_LLVM_DYLIB=1
构建的,两者都有未定义的符号问题。
在 CLANG 3.9 中使用 LLVM 插件时,我们遇到了完全相同的错误。然后我们在这里找到了解决方案:https://github.com/klee/klee/issues/336
解释是用于 LLVM 的 libstdc++ 的 ABI 与您的插件不同。要解决此问题,您需要使用以下标志“-D_GLIBCXX_USE_CXX11_ABI=0”重新编译您的插件。
检查 LLVM 插件的 Makefile 作为示例:https://github.com/SamAinsworth/reproduce-cgo2017-paper/blob/master/package/plugin-llvm-sw-prefetch-pass/Makefile