xref: /aosp_15_r20/external/llvm/unittests/ExecutionEngine/ExecutionEngineTest.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Interpreter.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DerivedTypes.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/GlobalVariable.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/LLVMContext.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DynamicLibrary.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ManagedStatic.h"
19*9880d681SAndroid Build Coastguard Worker #include "gtest/gtest.h"
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker namespace {
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker class ExecutionEngineTest : public testing::Test {
26*9880d681SAndroid Build Coastguard Worker private:
27*9880d681SAndroid Build Coastguard Worker   llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker protected:
ExecutionEngineTest()30*9880d681SAndroid Build Coastguard Worker   ExecutionEngineTest() {
31*9880d681SAndroid Build Coastguard Worker     auto Owner = make_unique<Module>("<main>", Context);
32*9880d681SAndroid Build Coastguard Worker     M = Owner.get();
33*9880d681SAndroid Build Coastguard Worker     Engine.reset(EngineBuilder(std::move(Owner)).setErrorStr(&Error).create());
34*9880d681SAndroid Build Coastguard Worker   }
35*9880d681SAndroid Build Coastguard Worker 
SetUp()36*9880d681SAndroid Build Coastguard Worker   void SetUp() override {
37*9880d681SAndroid Build Coastguard Worker     ASSERT_TRUE(Engine.get() != nullptr) << "EngineBuilder returned error: '"
38*9880d681SAndroid Build Coastguard Worker       << Error << "'";
39*9880d681SAndroid Build Coastguard Worker   }
40*9880d681SAndroid Build Coastguard Worker 
NewExtGlobal(Type * T,const Twine & Name)41*9880d681SAndroid Build Coastguard Worker   GlobalVariable *NewExtGlobal(Type *T, const Twine &Name) {
42*9880d681SAndroid Build Coastguard Worker     return new GlobalVariable(*M, T, false,  // Not constant.
43*9880d681SAndroid Build Coastguard Worker                               GlobalValue::ExternalLinkage, nullptr, Name);
44*9880d681SAndroid Build Coastguard Worker   }
45*9880d681SAndroid Build Coastguard Worker 
46*9880d681SAndroid Build Coastguard Worker   std::string Error;
47*9880d681SAndroid Build Coastguard Worker   LLVMContext Context;
48*9880d681SAndroid Build Coastguard Worker   Module *M;  // Owned by ExecutionEngine.
49*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<ExecutionEngine> Engine;
50*9880d681SAndroid Build Coastguard Worker };
51*9880d681SAndroid Build Coastguard Worker 
TEST_F(ExecutionEngineTest,ForwardGlobalMapping)52*9880d681SAndroid Build Coastguard Worker TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
53*9880d681SAndroid Build Coastguard Worker   GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1");
54*9880d681SAndroid Build Coastguard Worker   int32_t Mem1 = 3;
55*9880d681SAndroid Build Coastguard Worker   Engine->addGlobalMapping(G1, &Mem1);
56*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1));
57*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable("Global1"));
58*9880d681SAndroid Build Coastguard Worker   int32_t Mem2 = 4;
59*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G1, &Mem2);
60*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
61*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G1, nullptr);
62*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G1));
63*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G1, &Mem2);
64*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
65*9880d681SAndroid Build Coastguard Worker 
66*9880d681SAndroid Build Coastguard Worker   GlobalVariable *G2 = NewExtGlobal(Type::getInt32Ty(Context), "Global1");
67*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, Engine->getPointerToGlobalIfAvailable(G2))
68*9880d681SAndroid Build Coastguard Worker     << "The NULL return shouldn't depend on having called"
69*9880d681SAndroid Build Coastguard Worker     << " updateGlobalMapping(..., NULL)";
70*9880d681SAndroid Build Coastguard Worker   // Check that update...() can be called before add...().
71*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G2, &Mem1);
72*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G2));
73*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1))
74*9880d681SAndroid Build Coastguard Worker     << "A second mapping shouldn't affect the first.";
75*9880d681SAndroid Build Coastguard Worker }
76*9880d681SAndroid Build Coastguard Worker 
TEST_F(ExecutionEngineTest,ReverseGlobalMapping)77*9880d681SAndroid Build Coastguard Worker TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
78*9880d681SAndroid Build Coastguard Worker   GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1");
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   int32_t Mem1 = 3;
81*9880d681SAndroid Build Coastguard Worker   Engine->addGlobalMapping(G1, &Mem1);
82*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
83*9880d681SAndroid Build Coastguard Worker   int32_t Mem2 = 4;
84*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G1, &Mem2);
85*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
86*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   GlobalVariable *G2 = NewExtGlobal(Type::getInt32Ty(Context), "Global2");
89*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G2, &Mem1);
90*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
91*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
92*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G1, nullptr);
93*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1))
94*9880d681SAndroid Build Coastguard Worker     << "Removing one mapping doesn't affect a different one.";
95*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem2));
96*9880d681SAndroid Build Coastguard Worker   Engine->updateGlobalMapping(G2, &Mem2);
97*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
98*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2))
99*9880d681SAndroid Build Coastguard Worker     << "Once a mapping is removed, we can point another GV at the"
100*9880d681SAndroid Build Coastguard Worker     << " now-free address.";
101*9880d681SAndroid Build Coastguard Worker }
102*9880d681SAndroid Build Coastguard Worker 
TEST_F(ExecutionEngineTest,ClearModuleMappings)103*9880d681SAndroid Build Coastguard Worker TEST_F(ExecutionEngineTest, ClearModuleMappings) {
104*9880d681SAndroid Build Coastguard Worker   GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1");
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker   int32_t Mem1 = 3;
107*9880d681SAndroid Build Coastguard Worker   Engine->addGlobalMapping(G1, &Mem1);
108*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker   Engine->clearGlobalMappingsFromModule(M);
111*9880d681SAndroid Build Coastguard Worker 
112*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   GlobalVariable *G2 = NewExtGlobal(Type::getInt32Ty(Context), "Global2");
115*9880d681SAndroid Build Coastguard Worker   // After clearing the module mappings, we can assign a new GV to the
116*9880d681SAndroid Build Coastguard Worker   // same address.
117*9880d681SAndroid Build Coastguard Worker   Engine->addGlobalMapping(G2, &Mem1);
118*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker 
TEST_F(ExecutionEngineTest,DestructionRemovesGlobalMapping)121*9880d681SAndroid Build Coastguard Worker TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
122*9880d681SAndroid Build Coastguard Worker   GlobalVariable *G1 = NewExtGlobal(Type::getInt32Ty(Context), "Global1");
123*9880d681SAndroid Build Coastguard Worker   int32_t Mem1 = 3;
124*9880d681SAndroid Build Coastguard Worker   Engine->addGlobalMapping(G1, &Mem1);
125*9880d681SAndroid Build Coastguard Worker   // Make sure the reverse mapping is enabled.
126*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
127*9880d681SAndroid Build Coastguard Worker   // When the GV goes away, the ExecutionEngine should remove any
128*9880d681SAndroid Build Coastguard Worker   // mappings that refer to it.
129*9880d681SAndroid Build Coastguard Worker   G1->eraseFromParent();
130*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, Engine->getGlobalValueAtAddress(&Mem1));
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker 
TEST_F(ExecutionEngineTest,LookupWithMangledAndDemangledSymbol)133*9880d681SAndroid Build Coastguard Worker TEST_F(ExecutionEngineTest, LookupWithMangledAndDemangledSymbol) {
134*9880d681SAndroid Build Coastguard Worker   int x;
135*9880d681SAndroid Build Coastguard Worker   int _x;
136*9880d681SAndroid Build Coastguard Worker   llvm::sys::DynamicLibrary::AddSymbol("x", &x);
137*9880d681SAndroid Build Coastguard Worker   llvm::sys::DynamicLibrary::AddSymbol("_x", &_x);
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   // RTDyldMemoryManager::getSymbolAddressInProcess expects a mangled symbol,
140*9880d681SAndroid Build Coastguard Worker   // but DynamicLibrary is a wrapper for dlsym, which expects the unmangled C
141*9880d681SAndroid Build Coastguard Worker   // symbol name. This test verifies that getSymbolAddressInProcess strips the
142*9880d681SAndroid Build Coastguard Worker   // leading '_' on Darwin, but not on other platforms.
143*9880d681SAndroid Build Coastguard Worker #ifdef __APPLE__
144*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(reinterpret_cast<uint64_t>(&x),
145*9880d681SAndroid Build Coastguard Worker             RTDyldMemoryManager::getSymbolAddressInProcess("_x"));
146*9880d681SAndroid Build Coastguard Worker #else
147*9880d681SAndroid Build Coastguard Worker   EXPECT_EQ(reinterpret_cast<uint64_t>(&_x),
148*9880d681SAndroid Build Coastguard Worker             RTDyldMemoryManager::getSymbolAddressInProcess("_x"));
149*9880d681SAndroid Build Coastguard Worker #endif
150*9880d681SAndroid Build Coastguard Worker }
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker }
153