diff --git a/bolt/CMakeLists.txt b/bolt/CMakeLists.txt --- a/bolt/CMakeLists.txt +++ b/bolt/CMakeLists.txt @@ -73,6 +73,8 @@ endif() endif() +find_program(GNU_LD_EXECUTABLE NAMES ${LLVM_DEFAULT_TARGET_TRIPLE}-ld.bfd ld.bfd DOC "GNU ld") + # If we can't find a revision, set it to "". if (NOT BOLT_REVISION) set(BOLT_REVISION "") diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -1885,6 +1885,14 @@ // Check for PLT entry registered with symbol name if (!SymbolAddress && IsAArch64) { BinaryData *BD = BC->getBinaryDataByName(SymbolName + "@PLT"); + size_t End; + if ((!BD) && ((End = SymbolName.find("@")) != std::string::npos)) { + // The symbol might contain its versioning in name e.g. + // memcpy@@GLIBC_2.17 + SymbolName = SymbolName.substr(0, End); + BD = BC->getBinaryDataByName(SymbolName + "@PLT"); + } + SymbolAddress = BD ? BD->getAddress() : 0; } } diff --git a/bolt/test/lit.cfg.py b/bolt/test/lit.cfg.py --- a/bolt/test/lit.cfg.py +++ b/bolt/test/lit.cfg.py @@ -53,6 +53,9 @@ if config.bolt_enable_runtime: config.available_features.add("bolt-runtime") +if config.gnu_ld: + config.available_features.add("gnu_ld") + llvm_config.use_default_substitutions() llvm_config.config.environment['CLANG'] = config.bolt_clang diff --git a/bolt/test/lit.site.cfg.py.in b/bolt/test/lit.site.cfg.py.in --- a/bolt/test/lit.site.cfg.py.in +++ b/bolt/test/lit.site.cfg.py.in @@ -21,6 +21,7 @@ config.python_executable = "@PYTHON_EXECUTABLE@" config.bolt_clang = "@BOLT_CLANG_EXE@" config.bolt_lld = "@BOLT_LLD_EXE@" +config.gnu_ld = "@GNU_LD_EXECUTABLE@" import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/bolt/test/runtime/AArch64/plt.c b/bolt/test/runtime/Inputs/plt.c rename from bolt/test/runtime/AArch64/plt.c rename to bolt/test/runtime/Inputs/plt.c --- a/bolt/test/runtime/AArch64/plt.c +++ b/bolt/test/runtime/Inputs/plt.c @@ -1,10 +1,3 @@ -// This test checks that the pointers to PLT are properly updated. - -// RUN: %clang %cflags %s -fuse-ld=lld \ -// RUN: -o %t.exe -Wl,-q -// RUN: llvm-bolt %t.exe -o %t.bolt.exe -use-old-text=0 -lite=0 -// RUN: %t.bolt.exe - #include void *(*memcpy_p)(void *dest, const void *src, size_t n); diff --git a/bolt/test/runtime/AArch64/iplt.c b/bolt/test/runtime/iplt.c rename from bolt/test/runtime/AArch64/iplt.c rename to bolt/test/runtime/iplt.c diff --git a/bolt/test/runtime/plt_gnu_ld.test b/bolt/test/runtime/plt_gnu_ld.test new file mode 100644 --- /dev/null +++ b/bolt/test/runtime/plt_gnu_ld.test @@ -0,0 +1,10 @@ +// This test checks that the pointers to PLT are properly updated. +// The test is using bfd linker, since it may add versioning string +// to the symbol name e.g. memcpy@@GLIBC_2.17 + +// REQUIRES: gnu_ld + +// RUN: %clang %cflags %p/Inputs/plt.c -fuse-ld=bfd \ +// RUN: -o %t.bfd.exe -Wl,-q +// RUN: llvm-bolt %t.bfd.exe -o %t.bfd.bolt.exe -use-old-text=0 -lite=0 +// RUN: %t.bfd.bolt.exe diff --git a/bolt/test/runtime/plt_lld.test b/bolt/test/runtime/plt_lld.test new file mode 100644 --- /dev/null +++ b/bolt/test/runtime/plt_lld.test @@ -0,0 +1,8 @@ +// This test checks that the pointers to PLT are properly updated. +// The test is using lld linker. + +// Test with lld linker: +// RUN: %clang %cflags %p/Inputs/plt.c -fuse-ld=lld \ +// RUN: -o %t.lld.exe -Wl,-q +// RUN: llvm-bolt %t.lld.exe -o %t.lld.bolt.exe -use-old-text=0 -lite=0 +// RUN: %t.lld.bolt.exe