[ExecutionEngine] Add weak symbol support to RuntimeDyld

Support weak symbols by first looking up if there is an externally visible symbol we can find,
and only if that fails using the one in the object file we're loading.

Reviewed By: lhames
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D6950

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227228 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Keno Fischer
2015-01-27 20:02:31 +00:00
parent 99b52293c7
commit 811b152d85
7 changed files with 93 additions and 2 deletions

View File

@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Support/DynamicLibrary.h"
#include "MCJITTestBase.h"
#include "gtest/gtest.h"
@ -199,4 +200,45 @@ TEST_F(MCJITTest, multiple_decl_lookups) {
EXPECT_EQ(A, B) << "Repeat calls to getPointerToFunction fail.";
}
// Test weak symbol linking when the weak symbol is present in a shared
// library
TEST_F(MCJITTest, weak_symbol_present) {
SKIP_UNSUPPORTED_PLATFORM;
int FakeWeakSymbol;
llvm::sys::DynamicLibrary::AddSymbol("FakeWeakSymbol", &FakeWeakSymbol);
createJITFromAssembly(
"$FakeWeakSymbol = comdat any\n"
"@FakeWeakSymbol = linkonce_odr global i32 42, comdat, align 4\n"
"define i32 @weak_test(i32* %arg) {\n"
" %r = icmp eq i32* %arg, @FakeWeakSymbol\n"
" %ret = zext i1 %r to i32\n"
" ret i32 %ret\n"
" }");
uint64_t Addr = TheJIT->getFunctionAddress("weak_test");;
EXPECT_TRUE(Addr != 0);
int32_t(*FuncPtr)(int32_t *) = (int32_t(*)(int32_t *))Addr;
EXPECT_EQ(FuncPtr(&FakeWeakSymbol),1);
EXPECT_TRUE(TheJIT->getGlobalValueAddress("FakeWeakSymbol") == 0);
}
// Test weak symbol linking when the weak symbol is not present in a
// shared library
TEST_F(MCJITTest, weak_symbol_absent) {
SKIP_UNSUPPORTED_PLATFORM;
SMDiagnostic Error;
createJITFromAssembly(
" $FakeWeakSymbol2 = comdat any\n"
" @FakeWeakSymbol2 = linkonce_odr global i32 42, comdat, align 4\n"
" define i32* @get_weak() {\n"
" ret i32* @FakeWeakSymbol2\n"
" }\n");
void*(*FuncPtr)() =
(void*(*)(void))TheJIT->getFunctionAddress("get_weak");
EXPECT_EQ(FuncPtr(),(void*)TheJIT->getGlobalValueAddress("FakeWeakSymbol2"));
}
}