blob: 2b6b5a7670d4b75765650c11cc134216f2f3a01c [file] [log] [blame]
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +00001//===- ObjectTransformLayerTest.cpp - Unit tests for ObjectTransformLayer -===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +00006//
7//===----------------------------------------------------------------------===//
8
Chandler Carruth9a67b072017-06-06 11:06:56 +00009#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
Benjamin Kramer3bdcc8c2015-06-25 13:47:36 +000010#include "llvm/ADT/STLExtras.h"
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000011#include "llvm/ADT/SmallVector.h"
Joseph Tremoulet23d02f62016-01-23 18:36:01 +000012#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
Lang Hames1cd3dd02018-02-14 22:13:02 +000013#include "llvm/ExecutionEngine/Orc/NullResolver.h"
Lang Hames67de5d22017-02-20 05:45:14 +000014#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
Lang Hames5b518162017-07-04 04:42:30 +000015#include "llvm/ExecutionEngine/SectionMemoryManager.h"
Lang Hames5721ee42018-03-15 00:30:14 +000016#include "llvm/IR/Module.h"
Joseph Tremoulet23d02f62016-01-23 18:36:01 +000017#include "llvm/Object/ObjectFile.h"
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000018#include "gtest/gtest.h"
19
20using namespace llvm::orc;
21
22namespace {
23
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000024// stand-in for object::ObjectFile
25typedef int MockObjectFile;
26
27// stand-in for llvm::MemoryBuffer set
Lang Hames26620222017-06-22 21:06:54 +000028typedef int MockMemoryBuffer;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000029
30// Mock transform that operates on unique pointers to object files, and
31// allocates new object files rather than mutating the given ones.
32struct AllocatingTransform {
Lang Hames26620222017-06-22 21:06:54 +000033 std::shared_ptr<MockObjectFile>
34 operator()(std::shared_ptr<MockObjectFile> Obj) const {
35 return std::make_shared<MockObjectFile>(*Obj + 1);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000036 }
37};
38
39// Mock base layer for verifying behavior of transform layer.
40// Each method "T foo(args)" is accompanied by two auxiliary methods:
41// - "void expectFoo(args)", to be called before calling foo on the transform
42// layer; saves values of args, which mock layer foo then verifies against.
43// - "void verifyFoo(T)", to be called after foo, which verifies that the
44// transform layer called the base layer and forwarded any return value.
45class MockBaseLayer {
46public:
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000047 MockBaseLayer() : MockSymbol(nullptr) { resetExpectations(); }
48
Lang Hames0976cee2018-02-09 02:30:40 +000049 template <typename ObjPtrT> llvm::Error addObject(VModuleKey K, ObjPtrT Obj) {
Lang Hames4b546c92018-02-06 21:25:11 +000050 EXPECT_EQ(MockKey, K) << "Key should pass through";
Lang Hames26620222017-06-22 21:06:54 +000051 EXPECT_EQ(MockObject + 1, *Obj) << "Transform should be applied";
52 LastCalled = "addObject";
Lang Hames0976cee2018-02-09 02:30:40 +000053 return llvm::Error::success();
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000054 }
Lang Hames5b518162017-07-04 04:42:30 +000055
Lang Hames4b546c92018-02-06 21:25:11 +000056 template <typename ObjPtrT> void expectAddObject(VModuleKey K, ObjPtrT Obj) {
57 MockKey = K;
Lang Hames26620222017-06-22 21:06:54 +000058 MockObject = *Obj;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000059 }
Lang Hames5b518162017-07-04 04:42:30 +000060
Lang Hames0976cee2018-02-09 02:30:40 +000061 void verifyAddObject() {
Lang Hames26620222017-06-22 21:06:54 +000062 EXPECT_EQ("addObject", LastCalled);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000063 resetExpectations();
64 }
65
Lang Hames0976cee2018-02-09 02:30:40 +000066 llvm::Error removeObject(VModuleKey K) {
67 EXPECT_EQ(MockKey, K);
Lang Hames26620222017-06-22 21:06:54 +000068 LastCalled = "removeObject";
Lang Hames4ce98662017-07-07 02:59:13 +000069 return llvm::Error::success();
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000070 }
Lang Hames4ce98662017-07-07 02:59:13 +000071
Lang Hames0976cee2018-02-09 02:30:40 +000072 void expectRemoveObject(VModuleKey K) { MockKey = K; }
Lang Hames26620222017-06-22 21:06:54 +000073 void verifyRemoveObject() {
74 EXPECT_EQ("removeObject", LastCalled);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000075 resetExpectations();
76 }
77
Lang Hamesad4a9112016-08-01 20:49:11 +000078 llvm::JITSymbol findSymbol(const std::string &Name,
79 bool ExportedSymbolsOnly) {
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000080 EXPECT_EQ(MockName, Name) << "Name should pass through";
81 EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
82 LastCalled = "findSymbol";
Lang Hamesad4a9112016-08-01 20:49:11 +000083 MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
Lang Hames4ce98662017-07-07 02:59:13 +000084 return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000085 }
86 void expectFindSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
87 MockName = Name;
88 MockBool = ExportedSymbolsOnly;
89 }
Lang Hamesad4a9112016-08-01 20:49:11 +000090 void verifyFindSymbol(llvm::JITSymbol Returned) {
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000091 EXPECT_EQ("findSymbol", LastCalled);
Lang Hames4ce98662017-07-07 02:59:13 +000092 EXPECT_EQ(cantFail(MockSymbol.getAddress()),
93 cantFail(Returned.getAddress()))
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +000094 << "Return should pass through";
95 resetExpectations();
96 }
97
Lang Hames0976cee2018-02-09 02:30:40 +000098 llvm::JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
Lang Hamesad4a9112016-08-01 20:49:11 +000099 bool ExportedSymbolsOnly) {
Lang Hames0976cee2018-02-09 02:30:40 +0000100 EXPECT_EQ(MockKey, K) << "VModuleKey should pass through";
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000101 EXPECT_EQ(MockName, Name) << "Name should pass through";
102 EXPECT_EQ(MockBool, ExportedSymbolsOnly) << "Flag should pass through";
103 LastCalled = "findSymbolIn";
Lang Hamesad4a9112016-08-01 20:49:11 +0000104 MockSymbol = llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
Lang Hames4ce98662017-07-07 02:59:13 +0000105 return llvm::JITSymbol(122, llvm::JITSymbolFlags::None);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000106 }
Lang Hames0976cee2018-02-09 02:30:40 +0000107 void expectFindSymbolIn(VModuleKey K, const std::string &Name,
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000108 bool ExportedSymbolsOnly) {
Lang Hames0976cee2018-02-09 02:30:40 +0000109 MockKey = K;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000110 MockName = Name;
111 MockBool = ExportedSymbolsOnly;
112 }
Lang Hamesad4a9112016-08-01 20:49:11 +0000113 void verifyFindSymbolIn(llvm::JITSymbol Returned) {
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000114 EXPECT_EQ("findSymbolIn", LastCalled);
Lang Hames4ce98662017-07-07 02:59:13 +0000115 EXPECT_EQ(cantFail(MockSymbol.getAddress()),
116 cantFail(Returned.getAddress()))
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000117 << "Return should pass through";
118 resetExpectations();
119 }
120
Lang Hames0976cee2018-02-09 02:30:40 +0000121 llvm::Error emitAndFinalize(VModuleKey K) {
122 EXPECT_EQ(MockKey, K) << "VModuleKey should pass through";
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000123 LastCalled = "emitAndFinalize";
Lang Hames4ce98662017-07-07 02:59:13 +0000124 return llvm::Error::success();
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000125 }
Lang Hames4ce98662017-07-07 02:59:13 +0000126
Lang Hames0976cee2018-02-09 02:30:40 +0000127 void expectEmitAndFinalize(VModuleKey K) { MockKey = K; }
Lang Hames4ce98662017-07-07 02:59:13 +0000128
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000129 void verifyEmitAndFinalize() {
130 EXPECT_EQ("emitAndFinalize", LastCalled);
131 resetExpectations();
132 }
133
Lang Hames0976cee2018-02-09 02:30:40 +0000134 void mapSectionAddress(VModuleKey K, const void *LocalAddress,
Lang Hamesad4a9112016-08-01 20:49:11 +0000135 llvm::JITTargetAddress TargetAddr) {
Lang Hames0976cee2018-02-09 02:30:40 +0000136 EXPECT_EQ(MockKey, K);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000137 EXPECT_EQ(MockLocalAddress, LocalAddress);
138 EXPECT_EQ(MockTargetAddress, TargetAddr);
139 LastCalled = "mapSectionAddress";
140 }
Lang Hames0976cee2018-02-09 02:30:40 +0000141 void expectMapSectionAddress(VModuleKey K, const void *LocalAddress,
Lang Hamesad4a9112016-08-01 20:49:11 +0000142 llvm::JITTargetAddress TargetAddr) {
Lang Hames0976cee2018-02-09 02:30:40 +0000143 MockKey = K;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000144 MockLocalAddress = LocalAddress;
145 MockTargetAddress = TargetAddr;
146 }
147 void verifyMapSectionAddress() {
148 EXPECT_EQ("mapSectionAddress", LastCalled);
149 resetExpectations();
150 }
151
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000152private:
153 // Backing fields for remembering parameter/return values
154 std::string LastCalled;
Lang Hames4b546c92018-02-06 21:25:11 +0000155 VModuleKey MockKey;
Lang Hames26620222017-06-22 21:06:54 +0000156 MockObjectFile MockObject;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000157 std::string MockName;
158 bool MockBool;
Lang Hamesad4a9112016-08-01 20:49:11 +0000159 llvm::JITSymbol MockSymbol;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000160 const void *MockLocalAddress;
Lang Hamesad4a9112016-08-01 20:49:11 +0000161 llvm::JITTargetAddress MockTargetAddress;
Lang Hames26620222017-06-22 21:06:54 +0000162 MockMemoryBuffer MockBuffer;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000163
164 // Clear remembered parameters between calls
165 void resetExpectations() {
166 LastCalled = "nothing";
Lang Hames4b546c92018-02-06 21:25:11 +0000167 MockKey = 0;
Lang Hames26620222017-06-22 21:06:54 +0000168 MockObject = 0;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000169 MockName = "bogus";
Lang Hamesad4a9112016-08-01 20:49:11 +0000170 MockSymbol = llvm::JITSymbol(nullptr);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000171 MockLocalAddress = nullptr;
172 MockTargetAddress = 0;
Lang Hames26620222017-06-22 21:06:54 +0000173 MockBuffer = 0;
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000174 }
175};
176
Lang Hames079df9a2018-10-15 22:56:10 +0000177// Test each operation on LegacyObjectTransformLayer.
178TEST(LegacyObjectTransformLayerTest, Main) {
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000179 MockBaseLayer M;
180
Lang Hames3fdfc042018-04-02 20:57:56 +0000181 ExecutionSession ES(std::make_shared<SymbolStringPool>());
Lang Hames4b546c92018-02-06 21:25:11 +0000182
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000183 // Create one object transform layer using a transform (as a functor)
184 // that allocates new objects, and deals in unique pointers.
Lang Hames079df9a2018-10-15 22:56:10 +0000185 LegacyObjectTransformLayer<MockBaseLayer, AllocatingTransform> T1(M);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000186
187 // Create a second object transform layer using a transform (as a lambda)
188 // that mutates objects in place, and deals in naked pointers
Lang Hames079df9a2018-10-15 22:56:10 +0000189 LegacyObjectTransformLayer<MockBaseLayer,
Lang Hames26620222017-06-22 21:06:54 +0000190 std::function<std::shared_ptr<MockObjectFile>(
191 std::shared_ptr<MockObjectFile>)>>
192 T2(M, [](std::shared_ptr<MockObjectFile> Obj) {
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000193 ++(*Obj);
194 return Obj;
195 });
196
Lang Hames26620222017-06-22 21:06:54 +0000197 // Test addObject with T1 (allocating)
Lang Hames4b546c92018-02-06 21:25:11 +0000198 auto K1 = ES.allocateVModule();
Lang Hames26620222017-06-22 21:06:54 +0000199 auto Obj1 = std::make_shared<MockObjectFile>(211);
Lang Hames4b546c92018-02-06 21:25:11 +0000200 M.expectAddObject(K1, Obj1);
Lang Hames0976cee2018-02-09 02:30:40 +0000201 cantFail(T1.addObject(K1, std::move(Obj1)));
202 M.verifyAddObject();
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000203
Lang Hames26620222017-06-22 21:06:54 +0000204 // Test addObjectSet with T2 (mutating)
Lang Hames4b546c92018-02-06 21:25:11 +0000205 auto K2 = ES.allocateVModule();
Lang Hames26620222017-06-22 21:06:54 +0000206 auto Obj2 = std::make_shared<MockObjectFile>(222);
Lang Hames4b546c92018-02-06 21:25:11 +0000207 M.expectAddObject(K2, Obj2);
Lang Hames0976cee2018-02-09 02:30:40 +0000208 cantFail(T2.addObject(K2, Obj2));
209 M.verifyAddObject();
Lang Hames26620222017-06-22 21:06:54 +0000210 EXPECT_EQ(223, *Obj2) << "Expected mutation";
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000211
212 // Test removeObjectSet
Lang Hames0976cee2018-02-09 02:30:40 +0000213 M.expectRemoveObject(K2);
214 cantFail(T1.removeObject(K2));
Lang Hames26620222017-06-22 21:06:54 +0000215 M.verifyRemoveObject();
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000216
217 // Test findSymbol
218 std::string Name = "foo";
219 bool ExportedOnly = true;
220 M.expectFindSymbol(Name, ExportedOnly);
Lang Hames4ce98662017-07-07 02:59:13 +0000221 llvm::JITSymbol Sym1 = T2.findSymbol(Name, ExportedOnly);
222 M.verifyFindSymbol(std::move(Sym1));
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000223
224 // Test findSymbolIn
225 Name = "bar";
226 ExportedOnly = false;
Lang Hames0976cee2018-02-09 02:30:40 +0000227 M.expectFindSymbolIn(K1, Name, ExportedOnly);
228 llvm::JITSymbol Sym2 = T1.findSymbolIn(K1, Name, ExportedOnly);
Lang Hames4ce98662017-07-07 02:59:13 +0000229 M.verifyFindSymbolIn(std::move(Sym2));
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000230
231 // Test emitAndFinalize
Lang Hames0976cee2018-02-09 02:30:40 +0000232 M.expectEmitAndFinalize(K1);
233 cantFail(T2.emitAndFinalize(K1));
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000234 M.verifyEmitAndFinalize();
235
236 // Test mapSectionAddress
237 char Buffer[24];
Lang Hamesad4a9112016-08-01 20:49:11 +0000238 llvm::JITTargetAddress MockAddress = 255;
Lang Hames0976cee2018-02-09 02:30:40 +0000239 M.expectMapSectionAddress(K1, Buffer, MockAddress);
240 T1.mapSectionAddress(K1, Buffer, MockAddress);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000241 M.verifyMapSectionAddress();
242
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000243 // Verify transform getter (non-const)
Lang Hames26620222017-06-22 21:06:54 +0000244 auto Mutatee = std::make_shared<MockObjectFile>(277);
245 auto Out = T2.getTransform()(Mutatee);
246 EXPECT_EQ(*Mutatee, *Out) << "Expected in-place transform";
247 EXPECT_EQ(278, *Mutatee) << "Expected incrementing transform";
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000248
249 // Verify transform getter (const)
Lang Hames26620222017-06-22 21:06:54 +0000250 auto OwnedObj = std::make_shared<MockObjectFile>(288);
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000251 const auto &T1C = T1;
252 OwnedObj = T1C.getTransform()(std::move(OwnedObj));
253 EXPECT_EQ(289, *OwnedObj) << "Expected incrementing transform";
Joseph Tremoulet23d02f62016-01-23 18:36:01 +0000254
255 volatile bool RunStaticChecks = false;
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000256 if (!RunStaticChecks)
257 return;
Joseph Tremoulet23d02f62016-01-23 18:36:01 +0000258
Lang Hames079df9a2018-10-15 22:56:10 +0000259 // Make sure that LegacyObjectTransformLayer implements the object layer concept
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000260 // correctly by sandwitching one between an ObjectLinkingLayer and an
Lang Hames079df9a2018-10-15 22:56:10 +0000261 // LegacyIRCompileLayer, verifying that it compiles if we have a call to the
Lang Hames26620222017-06-22 21:06:54 +0000262 // IRComileLayer's addModule that should call the transform layer's
263 // addObject, and also calling the other public transform layer methods
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000264 // directly to make sure the methods they intend to forward to exist on
265 // the ObjectLinkingLayer.
Joseph Tremoulet23d02f62016-01-23 18:36:01 +0000266
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000267 // We'll need a concrete MemoryManager class.
268 class NullManager : public llvm::RuntimeDyld::MemoryManager {
269 public:
270 uint8_t *allocateCodeSection(uintptr_t, unsigned, unsigned,
271 llvm::StringRef) override {
272 return nullptr;
273 }
274 uint8_t *allocateDataSection(uintptr_t, unsigned, unsigned, llvm::StringRef,
275 bool) override {
276 return nullptr;
277 }
278 void registerEHFrames(uint8_t *, uint64_t, size_t) override {}
Lang Hamesc936ac72017-05-09 21:32:18 +0000279 void deregisterEHFrames() override {}
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000280 bool finalizeMemory(std::string *) override { return false; }
281 };
Joseph Tremoulet23d02f62016-01-23 18:36:01 +0000282
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000283 // Construct the jit layers.
Lang Hames079df9a2018-10-15 22:56:10 +0000284 LegacyRTDyldObjectLinkingLayer BaseLayer(ES, [](VModuleKey) {
285 return LegacyRTDyldObjectLinkingLayer::Resources{
Lang Hames1cd3dd02018-02-14 22:13:02 +0000286 std::make_shared<llvm::SectionMemoryManager>(),
287 std::make_shared<NullResolver>()};
288 });
Lang Hames5b518162017-07-04 04:42:30 +0000289
Lang Hames589eece2018-02-21 21:55:49 +0000290 auto IdentityTransform = [](std::unique_ptr<llvm::MemoryBuffer> Obj) {
291 return Obj;
292 };
Lang Hames079df9a2018-10-15 22:56:10 +0000293 LegacyObjectTransformLayer<decltype(BaseLayer), decltype(IdentityTransform)>
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000294 TransformLayer(BaseLayer, IdentityTransform);
295 auto NullCompiler = [](llvm::Module &) {
Lang Hames589eece2018-02-21 21:55:49 +0000296 return std::unique_ptr<llvm::MemoryBuffer>(nullptr);
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000297 };
Lang Hames079df9a2018-10-15 22:56:10 +0000298 LegacyIRCompileLayer<decltype(TransformLayer), decltype(NullCompiler)>
Lang Hames26620222017-06-22 21:06:54 +0000299 CompileLayer(TransformLayer, NullCompiler);
Joseph Tremoulet23d02f62016-01-23 18:36:01 +0000300
Lang Hames079df9a2018-10-15 22:56:10 +0000301 // Make sure that the calls from LegacyIRCompileLayer to LegacyObjectTransformLayer
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000302 // compile.
Lang Hames4b546c92018-02-06 21:25:11 +0000303 cantFail(CompileLayer.addModule(ES.allocateVModule(),
Lang Hames5721ee42018-03-15 00:30:14 +0000304 std::unique_ptr<llvm::Module>()));
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000305
Lang Hames079df9a2018-10-15 22:56:10 +0000306 // Make sure that the calls from LegacyObjectTransformLayer to ObjectLinkingLayer
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000307 // compile.
Lang Hames0976cee2018-02-09 02:30:40 +0000308 VModuleKey DummyKey = ES.allocateVModule();
309 cantFail(TransformLayer.emitAndFinalize(DummyKey));
310 TransformLayer.findSymbolIn(DummyKey, Name, false);
Joseph Tremoulete1014a32016-02-03 17:11:24 +0000311 TransformLayer.findSymbol(Name, true);
Lang Hames0976cee2018-02-09 02:30:40 +0000312 TransformLayer.mapSectionAddress(DummyKey, nullptr, 0);
313 cantFail(TransformLayer.removeObject(DummyKey));
Joseph Tremoulet7ff086c2015-06-25 13:35:22 +0000314}
315}