10a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin//===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===// 20a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin// 30a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin// The LLVM Compiler Infrastructure 40a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin// 50a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin// This file is distributed under the University of Illinois Open Source 60a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin// License. See LICENSE.TXT for details. 70a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin// 80a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin//===----------------------------------------------------------------------===// 90a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 105a88dda4be791426ab4d20a6a6c9c65d66614a27Chandler Carruth#include "llvm/ExecutionEngine/Interpreter.h" 1137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/ExecutionEngine/RTDyldMemoryManager.h" 124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/ADT/STLExtras.h" 130b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 140b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 150b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 1737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/DynamicLibrary.h" 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/ManagedStatic.h" 190a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin#include "gtest/gtest.h" 200a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 210a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskinusing namespace llvm; 220a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 230a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskinnamespace { 240a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 250a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskinclass ExecutionEngineTest : public testing::Test { 2637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesprivate: 2737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 2837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 290a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskinprotected: 3037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ExecutionEngineTest() { 31de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar auto Owner = make_unique<Module>("<main>", Context); 3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines M = Owner.get(); 3337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create()); 340a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin } 350a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 360c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar void SetUp() override { 37c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ASSERT_TRUE(Engine.get() != nullptr) << "EngineBuilder returned error: '" 3835af1d7e2c32cf9743d39577d143110e92e1c8bbDylan Noblesmith << Error << "'"; 390a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin } 400a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 41db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) { 420a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin return new GlobalVariable(*M, T, false, // Not constant. 43c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines GlobalValue::ExternalLinkage, nullptr, Name); 440a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin } 450a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 4635af1d7e2c32cf9743d39577d143110e92e1c8bbDylan Noblesmith std::string Error; 47de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar LLVMContext Context; 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines Module *M; // Owned by ExecutionEngine. 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::unique_ptr<ExecutionEngine> Engine; 500a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin}; 510a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 520a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey YasskinTEST_F(ExecutionEngineTest, ForwardGlobalMapping) { 53de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1"); 540a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin int32_t Mem1 = 3; 550a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->addGlobalMapping(G1, &Mem1); 560a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1)); 570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable("Global1")); 580a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin int32_t Mem2 = 4; 590a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->updateGlobalMapping(G1, &Mem2); 600a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1)); 61c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Engine->updateGlobalMapping(G1, nullptr); 62c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G1)); 630a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->updateGlobalMapping(G1, &Mem2); 640a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1)); 650a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 66de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *G2 = NewExtGlobal(Type::getInt32Ty(Context), "Global1"); 67c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G2)) 680a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin << "The NULL return shouldn't depend on having called" 690a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin << " updateGlobalMapping(..., NULL)"; 700a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin // Check that update...() can be called before add...(). 710a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->updateGlobalMapping(G2, &Mem1); 720a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G2)); 730a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1)) 740a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin << "A second mapping shouldn't affect the first."; 750a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin} 760a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 770a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey YasskinTEST_F(ExecutionEngineTest, ReverseGlobalMapping) { 78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1"); 790a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 800a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin int32_t Mem1 = 3; 810a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->addGlobalMapping(G1, &Mem1); 820a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1)); 830a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin int32_t Mem2 = 4; 840a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->updateGlobalMapping(G1, &Mem2); 85c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1)); 860a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2)); 870a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *G2 = NewExtGlobal(Type::getInt32Ty(Context), "Global2"); 890a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->updateGlobalMapping(G2, &Mem1); 900a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1)); 910a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2)); 92c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Engine->updateGlobalMapping(G1, nullptr); 930a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1)) 940a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin << "Removing one mapping doesn't affect a different one."; 95c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem2)); 960a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin Engine->updateGlobalMapping(G2, &Mem2); 97c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1)); 980a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2)) 990a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin << "Once a mapping is removed, we can point another GV at the" 1000a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin << " now-free address."; 1010a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin} 1020a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin 103c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey YasskinTEST_F(ExecutionEngineTest, ClearModuleMappings) { 104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1"); 105c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin 106c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin int32_t Mem1 = 3; 107c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin Engine->addGlobalMapping(G1, &Mem1); 108c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1)); 109c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin 110c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin Engine->clearGlobalMappingsFromModule(M); 111c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin 112c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1)); 113c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin 114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *G2 = NewExtGlobal(Type::getInt32Ty(Context), "Global2"); 115c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin // After clearing the module mappings, we can assign a new GV to the 116c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin // same address. 117c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin Engine->addGlobalMapping(G2, &Mem1); 118c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1)); 119c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin} 120c89d27a440370455336202b2a8f25eb9c73e67bcJeffrey Yasskin 1214c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey YasskinTEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) { 122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1"); 1234c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin int32_t Mem1 = 3; 1244c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin Engine->addGlobalMapping(G1, &Mem1); 1254c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin // Make sure the reverse mapping is enabled. 1264c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1)); 1274c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin // When the GV goes away, the ExecutionEngine should remove any 1284c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin // mappings that refer to it. 1294c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin G1->eraseFromParent(); 130c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1)); 1314c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin} 1324c5b23b24f230607fa18a162519875a91a5e89e0Jeffrey Yasskin 13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesTEST_F(ExecutionEngineTest, LookupWithMangledAndDemangledSymbol) { 13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int x; 13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines int _x; 13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::sys::DynamicLibrary::AddSymbol("x", &x); 13737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines llvm::sys::DynamicLibrary::AddSymbol("_x", &_x); 13837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 139de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // RTDyldMemoryManager::getSymbolAddressInProcess expects a mangled symbol, 140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // but DynamicLibrary is a wrapper for dlsym, which expects the unmangled C 141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // symbol name. This test verifies that getSymbolAddressInProcess strips the 142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // leading '_' on Darwin, but not on other platforms. 143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#ifdef __APPLE__ 14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(reinterpret_cast<uint64_t>(&x), 14537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RTDyldMemoryManager::getSymbolAddressInProcess("_x")); 146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#else 14737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines EXPECT_EQ(reinterpret_cast<uint64_t>(&_x), 14837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines RTDyldMemoryManager::getSymbolAddressInProcess("_x")); 149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#endif 15037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 15137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1520a962314fb5b3e9654ad9ab50b7d1b684f154270Jeffrey Yasskin} 153