xref: /llvm-project/llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp (revision 29e63328a79af9501bf8d6b7e5a07303427ded73)
1 //===------ LinkGraphTests.cpp - Unit tests for core JITLink classes ------===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "JITLinkTestUtils.h"
10 
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
13 #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
14 #include "llvm/Support/Memory.h"
15 
16 #include "llvm/Testing/Support/Error.h"
17 #include "gtest/gtest.h"
18 
19 using namespace llvm;
20 using namespace llvm::jitlink;
21 
22 TEST(LinkGraphTest, Construction) {
23   // Check that LinkGraph construction works as expected.
24   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
25               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
26               getGenericEdgeKindName);
27   EXPECT_EQ(G.getName(), "foo");
28   EXPECT_EQ(G.getTargetTriple().str(), "x86_64-apple-darwin");
29   EXPECT_EQ(G.getPointerSize(), 8U);
30   EXPECT_EQ(G.getEndianness(), llvm::endianness::little);
31   EXPECT_TRUE(G.external_symbols().empty());
32   EXPECT_TRUE(G.absolute_symbols().empty());
33   EXPECT_TRUE(G.defined_symbols().empty());
34   EXPECT_TRUE(G.blocks().empty());
35 }
36 
37 TEST(LinkGraphTest, AddressAccess) {
38   // Check that we can get addresses for blocks, symbols, and edges.
39   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
40               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
41               getGenericEdgeKindName);
42 
43   auto &Sec1 =
44       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
45   orc::ExecutorAddr B1Addr(0x1000);
46   auto &B1 = G.createContentBlock(Sec1, BlockContent, B1Addr, 8, 0);
47   auto &S1 = G.addDefinedSymbol(B1, 4, "S1", 4, Linkage::Strong, Scope::Default,
48                                 false, false);
49   B1.addEdge(Edge::FirstRelocation, 8, S1, 0);
50   auto &E1 = *B1.edges().begin();
51 
52   EXPECT_EQ(B1.getAddress(), B1Addr) << "Incorrect block address";
53   EXPECT_EQ(S1.getAddress(), B1Addr + 4) << "Incorrect symbol address";
54   EXPECT_EQ(B1.getFixupAddress(E1), B1Addr + 8) << "Incorrect fixup address";
55 }
56 
57 TEST(LinkGraphTest, SectionEmpty) {
58   // Check that Section::empty behaves as expected.
59   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
60               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
61               getGenericEdgeKindName);
62   auto &Sec1 =
63       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
64   auto &B =
65       G.createContentBlock(Sec1, BlockContent, orc::ExecutorAddr(0x1000), 8, 0);
66   G.addDefinedSymbol(B, 0, "S", 4, Linkage::Strong, Scope::Default, false,
67                      false);
68 
69   auto &Sec2 =
70       G.createSection("__data.2", orc::MemProt::Read | orc::MemProt::Write);
71 
72   EXPECT_FALSE(Sec1.empty());
73   EXPECT_TRUE(Sec2.empty());
74 }
75 
76 TEST(LinkGraphTest, BlockAndSymbolIteration) {
77   // Check that we can iterate over blocks within Sections and across sections.
78   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
79               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
80               getGenericEdgeKindName);
81   auto &Sec1 =
82       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
83   orc::ExecutorAddr B1Addr(0x1000);
84   auto &B1 = G.createContentBlock(Sec1, BlockContent, B1Addr, 8, 0);
85   orc::ExecutorAddr B2Addr(0x2000);
86   auto &B2 = G.createContentBlock(Sec1, BlockContent, B2Addr, 8, 0);
87   auto &S1 = G.addDefinedSymbol(B1, 0, "S1", 4, Linkage::Strong, Scope::Default,
88                                 false, false);
89   auto &S2 = G.addDefinedSymbol(B2, 4, "S2", 4, Linkage::Strong, Scope::Default,
90                                 false, false);
91 
92   auto &Sec2 =
93       G.createSection("__data.2", orc::MemProt::Read | orc::MemProt::Write);
94   orc::ExecutorAddr B3Addr(0x3000);
95   auto &B3 = G.createContentBlock(Sec2, BlockContent, B3Addr, 8, 0);
96   orc::ExecutorAddr B4Addr(0x4000);
97   auto &B4 = G.createContentBlock(Sec2, BlockContent, B4Addr, 8, 0);
98   auto &S3 = G.addDefinedSymbol(B3, 0, "S3", 4, Linkage::Strong, Scope::Default,
99                                 false, false);
100   auto &S4 = G.addDefinedSymbol(B4, 4, "S4", 4, Linkage::Strong, Scope::Default,
101                                 false, false);
102 
103   // Check that iteration of blocks within a section behaves as expected.
104   EXPECT_EQ(std::distance(Sec1.blocks().begin(), Sec1.blocks().end()), 2);
105   EXPECT_TRUE(llvm::count(Sec1.blocks(), &B1));
106   EXPECT_TRUE(llvm::count(Sec1.blocks(), &B2));
107 
108   // Check that iteration of symbols within a section behaves as expected.
109   EXPECT_EQ(std::distance(Sec1.symbols().begin(), Sec1.symbols().end()), 2);
110   EXPECT_TRUE(llvm::count(Sec1.symbols(), &S1));
111   EXPECT_TRUE(llvm::count(Sec1.symbols(), &S2));
112 
113   // Check that iteration of blocks across sections behaves as expected.
114   EXPECT_EQ(std::distance(G.blocks().begin(), G.blocks().end()), 4);
115   EXPECT_TRUE(llvm::count(G.blocks(), &B1));
116   EXPECT_TRUE(llvm::count(G.blocks(), &B2));
117   EXPECT_TRUE(llvm::count(G.blocks(), &B3));
118   EXPECT_TRUE(llvm::count(G.blocks(), &B4));
119 
120   // Check that iteration of defined symbols across sections behaves as
121   // expected.
122   EXPECT_EQ(
123       std::distance(G.defined_symbols().begin(), G.defined_symbols().end()), 4);
124   EXPECT_TRUE(llvm::count(G.defined_symbols(), &S1));
125   EXPECT_TRUE(llvm::count(G.defined_symbols(), &S2));
126   EXPECT_TRUE(llvm::count(G.defined_symbols(), &S3));
127   EXPECT_TRUE(llvm::count(G.defined_symbols(), &S4));
128 }
129 
130 TEST(LinkGraphTest, EdgeIteration) {
131   // Check that we can iterate over blocks within Sections and across sections.
132   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
133               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
134               getGenericEdgeKindName);
135   auto &Sec1 =
136       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
137   auto &B =
138       G.createContentBlock(Sec1, BlockContent, orc::ExecutorAddr(0x1000), 8, 0);
139   auto &S = G.addExternalSymbol("S1", 0, false);
140 
141   constexpr size_t NumEdges = 6;
142   Edge::OffsetT Offsets[NumEdges] = {0, 1, 2, 2, 3, 7};
143 
144   for (auto O : Offsets)
145     B.addEdge(Edge::KeepAlive, O, S, 0);
146 
147   EXPECT_EQ(llvm::range_size(B.edges()), NumEdges);
148   EXPECT_EQ(llvm::range_size(B.edges_at(0)), 1U);
149   EXPECT_EQ(llvm::range_size(B.edges_at(2)), 2U);
150   EXPECT_EQ(llvm::range_size(B.edges_at(4)), 0U);
151 
152   {
153     // Check that offsets and iteration order are as expected.
154     size_t Idx = 0;
155     for (auto &E : B.edges())
156       EXPECT_EQ(E.getOffset(), Offsets[Idx++]);
157   }
158 }
159 
160 TEST(LinkGraphTest, ContentAccessAndUpdate) {
161   // Check that we can make a defined symbol external.
162   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
163               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
164               getGenericEdgeKindName);
165   auto &Sec =
166       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
167 
168   // Create an initial block.
169   orc::ExecutorAddr BAddr(0x1000);
170   auto &B = G.createContentBlock(Sec, BlockContent, BAddr, 8, 0);
171 
172   EXPECT_FALSE(B.isContentMutable()) << "Content unexpectedly mutable";
173   EXPECT_EQ(B.getContent().data(), BlockContent.data())
174       << "Unexpected block content data pointer";
175   EXPECT_EQ(B.getContent().size(), BlockContent.size())
176       << "Unexpected block content size";
177 
178   // Expect that attempting to get already-mutable content fails if the
179   // content is not yet mutable (debug builds only).
180 #ifndef NDEBUG
181   EXPECT_DEATH({ (void)B.getAlreadyMutableContent(); },
182                "Content is not mutable")
183       << "Unexpected mutable access allowed to immutable data";
184 #endif
185 
186   // Check that mutable content is copied on request as expected.
187   auto MutableContent = B.getMutableContent(G);
188   EXPECT_TRUE(B.isContentMutable()) << "Content unexpectedly immutable";
189   EXPECT_NE(MutableContent.data(), BlockContent.data())
190       << "Unexpected mutable content data pointer";
191   EXPECT_EQ(MutableContent.size(), BlockContent.size())
192       << "Unexpected mutable content size";
193   EXPECT_TRUE(std::equal(MutableContent.begin(), MutableContent.end(),
194                          BlockContent.begin()))
195       << "Unexpected mutable content value";
196 
197   // Check that already-mutable content behaves as expected, with no
198   // further copies.
199   auto MutableContent2 = B.getMutableContent(G);
200   EXPECT_TRUE(B.isContentMutable()) << "Content unexpectedly immutable";
201   EXPECT_EQ(MutableContent2.data(), MutableContent.data())
202       << "Unexpected mutable content 2 data pointer";
203   EXPECT_EQ(MutableContent2.size(), MutableContent.size())
204       << "Unexpected mutable content 2 size";
205 
206   // Check that getAlreadyMutableContent behaves as expected, with no
207   // further copies.
208   auto MutableContent3 = B.getMutableContent(G);
209   EXPECT_TRUE(B.isContentMutable()) << "Content unexpectedly immutable";
210   EXPECT_EQ(MutableContent3.data(), MutableContent.data())
211       << "Unexpected mutable content 2 data pointer";
212   EXPECT_EQ(MutableContent3.size(), MutableContent.size())
213       << "Unexpected mutable content 2 size";
214 
215   // Check that we can obtain a writer and reader over the content.
216   // Check that we can get a BinaryStreamReader for B.
217   auto Writer = G.getBlockContentWriter(B);
218   EXPECT_THAT_ERROR(Writer.writeInteger((uint32_t)0xcafef00d), Succeeded());
219 
220   auto Reader = G.getBlockContentReader(B);
221   uint32_t Initial32Bits = 0;
222   EXPECT_THAT_ERROR(Reader.readInteger(Initial32Bits), Succeeded());
223   EXPECT_EQ(Initial32Bits, (uint32_t)0xcafef00d);
224 
225   // Set content back to immutable and check that everything behaves as
226   // expected again.
227   B.setContent(BlockContent);
228   EXPECT_FALSE(B.isContentMutable()) << "Content unexpectedly mutable";
229   EXPECT_EQ(B.getContent().data(), BlockContent.data())
230       << "Unexpected block content data pointer";
231   EXPECT_EQ(B.getContent().size(), BlockContent.size())
232       << "Unexpected block content size";
233 
234   // Create an initially mutable block.
235   auto &B2 = G.createMutableContentBlock(Sec, MutableContent,
236                                          orc::ExecutorAddr(0x10000), 8, 0);
237 
238   EXPECT_TRUE(B2.isContentMutable()) << "Expected B2 content to be mutable";
239   EXPECT_EQ(B2.getSize(), MutableContent.size());
240 
241   // Create a mutable content block with initial zero-fill.
242   auto &B3 =
243       G.createMutableContentBlock(Sec, 16, orc::ExecutorAddr(0x2000), 8, 0);
244   EXPECT_TRUE(B3.isContentMutable()) << "Expected B2 content to be mutable";
245   EXPECT_EQ(B3.getSize(), 16U);
246   EXPECT_TRUE(llvm::all_of(B3.getAlreadyMutableContent(),
247                            [](char C) { return C == 0; }));
248 }
249 
250 TEST(LinkGraphTest, FindSymbolsByName) {
251   // Check that we can make defined and absolute symbols external.
252   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
253               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
254               getGenericEdgeKindName);
255   auto &Sec =
256       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
257 
258   auto &B1 =
259       G.createContentBlock(Sec, BlockContent, orc::ExecutorAddr(0x1000), 8, 0);
260 
261   // Add an anonymous symbol to make sure that these don't disrupt by-name
262   // lookup of defined symbols.
263   G.addAnonymousSymbol(B1, 0, 0, false, false);
264 
265   // Add named defined, external and absolute symbols.
266   auto Foo = G.intern("foo");
267   auto &FooSym = G.addDefinedSymbol(B1, 0, Foo, 4, Linkage::Strong,
268                                     Scope::Default, false, false);
269 
270   auto Bar = G.intern("bar");
271   auto &BarSym = G.addExternalSymbol(Bar, 0, false);
272 
273   auto Baz = G.intern("baz");
274   auto &BazSym = G.addAbsoluteSymbol(Baz, orc::ExecutorAddr(0x1234), 0,
275                                      Linkage::Strong, Scope::Default, true);
276 
277   EXPECT_EQ(G.findDefinedSymbolByName(Foo), &FooSym);
278   EXPECT_EQ(G.findExternalSymbolByName(Foo), nullptr);
279   EXPECT_EQ(G.findAbsoluteSymbolByName(Foo), nullptr);
280 
281   EXPECT_EQ(G.findDefinedSymbolByName(Bar), nullptr);
282   EXPECT_EQ(G.findExternalSymbolByName(Bar), &BarSym);
283   EXPECT_EQ(G.findAbsoluteSymbolByName(Bar), nullptr);
284 
285   EXPECT_EQ(G.findDefinedSymbolByName(Baz), nullptr);
286   EXPECT_EQ(G.findExternalSymbolByName(Baz), nullptr);
287   EXPECT_EQ(G.findAbsoluteSymbolByName(Baz), &BazSym);
288 
289   auto Qux = G.intern("qux");
290   EXPECT_EQ(G.findDefinedSymbolByName(Qux), nullptr);
291   EXPECT_EQ(G.findExternalSymbolByName(Qux), nullptr);
292   EXPECT_EQ(G.findAbsoluteSymbolByName(Qux), nullptr);
293 }
294 
295 TEST(LinkGraphTest, MakeExternal) {
296   // Check that we can make defined and absolute symbols external.
297   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
298               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
299               getGenericEdgeKindName);
300   auto &Sec =
301       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
302 
303   // Create an initial block.
304   auto &B1 =
305       G.createContentBlock(Sec, BlockContent, orc::ExecutorAddr(0x1000), 8, 0);
306 
307   // Add a symbol to the block.
308   auto &S1 = G.addDefinedSymbol(B1, 0, "S1", 4, Linkage::Strong, Scope::Default,
309                                 false, false);
310 
311   EXPECT_TRUE(S1.isDefined()) << "Symbol should be defined";
312   EXPECT_FALSE(S1.isExternal()) << "Symbol should not be external";
313   EXPECT_FALSE(S1.isAbsolute()) << "Symbol should not be absolute";
314   EXPECT_TRUE(&S1.getBlock()) << "Symbol should have a non-null block";
315   EXPECT_EQ(S1.getAddress(), orc::ExecutorAddr(0x1000))
316       << "Unexpected symbol address";
317 
318   EXPECT_EQ(
319       std::distance(G.defined_symbols().begin(), G.defined_symbols().end()), 1U)
320       << "Unexpected number of defined symbols";
321   EXPECT_EQ(
322       std::distance(G.external_symbols().begin(), G.external_symbols().end()),
323       0U)
324       << "Unexpected number of external symbols";
325 
326   // Add an absolute symbol.
327   auto &S2 = G.addAbsoluteSymbol("S2", orc::ExecutorAddr(0x2000), 0,
328                                  Linkage::Strong, Scope::Default, true);
329 
330   EXPECT_TRUE(S2.isAbsolute()) << "Symbol should be absolute";
331   EXPECT_EQ(
332       std::distance(G.absolute_symbols().begin(), G.absolute_symbols().end()),
333       1U)
334       << "Unexpected number of symbols";
335 
336   // Make S1 and S2 external, confirm that the its flags are updated and that it
337   // is moved from the defined/absolute symbols lists to the externals list.
338   G.makeExternal(S1);
339   G.makeExternal(S2);
340 
341   EXPECT_FALSE(S1.isDefined()) << "Symbol should not be defined";
342   EXPECT_TRUE(S1.isExternal()) << "Symbol should be external";
343   EXPECT_FALSE(S1.isAbsolute()) << "Symbol should not be absolute";
344   EXPECT_FALSE(S2.isDefined()) << "Symbol should not be defined";
345   EXPECT_TRUE(S2.isExternal()) << "Symbol should be external";
346   EXPECT_FALSE(S2.isAbsolute()) << "Symbol should not be absolute";
347 
348   EXPECT_EQ(S1.getAddress(), orc::ExecutorAddr())
349       << "Unexpected symbol address";
350   EXPECT_EQ(S2.getAddress(), orc::ExecutorAddr())
351       << "Unexpected symbol address";
352 
353   EXPECT_EQ(
354       std::distance(G.defined_symbols().begin(), G.defined_symbols().end()), 0U)
355       << "Unexpected number of defined symbols";
356   EXPECT_EQ(
357       std::distance(G.external_symbols().begin(), G.external_symbols().end()),
358       2U)
359       << "Unexpected number of external symbols";
360   EXPECT_EQ(
361       std::distance(G.absolute_symbols().begin(), G.absolute_symbols().end()),
362       0U)
363       << "Unexpected number of external symbols";
364 }
365 
366 TEST(LinkGraphTest, MakeAbsolute) {
367   // Check that we can make defined and external symbols absolute.
368   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
369               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
370               getGenericEdgeKindName);
371   auto &Sec =
372       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
373 
374   // Create an initial block.
375   auto &B1 =
376       G.createContentBlock(Sec, BlockContent, orc::ExecutorAddr(0x1000), 8, 0);
377 
378   // Add a symbol to the block.
379   auto &S1 = G.addDefinedSymbol(B1, 0, "S1", 4, Linkage::Strong, Scope::Default,
380                                 false, false);
381 
382   EXPECT_TRUE(S1.isDefined()) << "Symbol should be defined";
383   EXPECT_FALSE(S1.isExternal()) << "Symbol should not be external";
384   EXPECT_FALSE(S1.isAbsolute()) << "Symbol should not be absolute";
385   EXPECT_TRUE(&S1.getBlock()) << "Symbol should have a non-null block";
386   EXPECT_EQ(S1.getAddress(), orc::ExecutorAddr(0x1000))
387       << "Unexpected symbol address";
388 
389   EXPECT_EQ(
390       std::distance(G.defined_symbols().begin(), G.defined_symbols().end()), 1U)
391       << "Unexpected number of defined symbols";
392   EXPECT_EQ(
393       std::distance(G.external_symbols().begin(), G.external_symbols().end()),
394       0U)
395       << "Unexpected number of external symbols";
396 
397   // Add an external symbol.
398   auto &S2 = G.addExternalSymbol("S2", 0, true);
399 
400   EXPECT_TRUE(S2.isExternal()) << "Symbol should be external";
401   EXPECT_EQ(
402       std::distance(G.external_symbols().begin(), G.external_symbols().end()),
403       1U)
404       << "Unexpected number of symbols";
405 
406   // Make S1 and S2 absolute, confirm that the its flags are updated and that it
407   // is moved from the defined/external symbols lists to the absolutes list.
408   orc::ExecutorAddr S1AbsAddr(0xA000);
409   orc::ExecutorAddr S2AbsAddr(0xB000);
410   G.makeAbsolute(S1, S1AbsAddr);
411   G.makeAbsolute(S2, S2AbsAddr);
412 
413   EXPECT_FALSE(S1.isDefined()) << "Symbol should not be defined";
414   EXPECT_FALSE(S1.isExternal()) << "Symbol should not be external";
415   EXPECT_TRUE(S1.isAbsolute()) << "Symbol should be absolute";
416   EXPECT_FALSE(S2.isDefined()) << "Symbol should not be defined";
417   EXPECT_FALSE(S2.isExternal()) << "Symbol should not be absolute";
418   EXPECT_TRUE(S2.isAbsolute()) << "Symbol should be absolute";
419 
420   EXPECT_EQ(S1.getAddress(), S1AbsAddr) << "Unexpected symbol address";
421   EXPECT_EQ(S2.getAddress(), S2AbsAddr) << "Unexpected symbol address";
422 
423   EXPECT_EQ(
424       std::distance(G.defined_symbols().begin(), G.defined_symbols().end()), 0U)
425       << "Unexpected number of defined symbols";
426   EXPECT_EQ(
427       std::distance(G.external_symbols().begin(), G.external_symbols().end()),
428       0U)
429       << "Unexpected number of external symbols";
430   EXPECT_EQ(
431       std::distance(G.absolute_symbols().begin(), G.absolute_symbols().end()),
432       2U)
433       << "Unexpected number of external symbols";
434 }
435 
436 TEST(LinkGraphTest, MakeDefined) {
437   // Check that we can make an external symbol defined.
438   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
439               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
440               getGenericEdgeKindName);
441   auto &Sec =
442       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
443 
444   // Create an initial block.
445   orc::ExecutorAddr B1Addr(0x1000);
446   auto &B1 = G.createContentBlock(Sec, BlockContent, B1Addr, 8, 0);
447 
448   // Add an external symbol.
449   auto &S1 = G.addExternalSymbol("S1", 4, true);
450 
451   EXPECT_FALSE(S1.isDefined()) << "Symbol should not be defined";
452   EXPECT_TRUE(S1.isExternal()) << "Symbol should be external";
453   EXPECT_FALSE(S1.isAbsolute()) << "Symbol should not be absolute";
454   EXPECT_EQ(S1.getAddress(), orc::ExecutorAddr())
455       << "Unexpected symbol address";
456 
457   EXPECT_EQ(
458       std::distance(G.defined_symbols().begin(), G.defined_symbols().end()), 0U)
459       << "Unexpected number of defined symbols";
460   EXPECT_EQ(
461       std::distance(G.external_symbols().begin(), G.external_symbols().end()),
462       1U)
463       << "Unexpected number of external symbols";
464 
465   // Make S1 defined, confirm that its flags are updated and that it is
466   // moved from the defined symbols to the externals list.
467   G.makeDefined(S1, B1, 0, 4, Linkage::Strong, Scope::Default, false);
468 
469   EXPECT_TRUE(S1.isDefined()) << "Symbol should be defined";
470   EXPECT_FALSE(S1.isExternal()) << "Symbol should not be external";
471   EXPECT_FALSE(S1.isAbsolute()) << "Symbol should not be absolute";
472   EXPECT_TRUE(&S1.getBlock()) << "Symbol should have a non-null block";
473   EXPECT_EQ(S1.getAddress(), orc::ExecutorAddr(0x1000U))
474       << "Unexpected symbol address";
475 
476   EXPECT_EQ(
477       std::distance(G.defined_symbols().begin(), G.defined_symbols().end()), 1U)
478       << "Unexpected number of defined symbols";
479   EXPECT_EQ(
480       std::distance(G.external_symbols().begin(), G.external_symbols().end()),
481       0U)
482       << "Unexpected number of external symbols";
483 }
484 
485 TEST(LinkGraphTest, TransferDefinedSymbol) {
486   // Check that we can transfer a defined symbol from one block to another.
487   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
488               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
489               getGenericEdgeKindName);
490   auto &Sec =
491       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
492 
493   // Create initial blocks.
494   orc::ExecutorAddr B1Addr(0x1000);
495   auto &B1 = G.createContentBlock(Sec, BlockContent, B1Addr, 8, 0);
496   orc::ExecutorAddr B2Addr(0x2000);
497   auto &B2 = G.createContentBlock(Sec, BlockContent, B2Addr, 8, 0);
498   orc::ExecutorAddr B3Addr(0x3000);
499   auto &B3 = G.createContentBlock(Sec, BlockContent.slice(0, 32), B3Addr, 8, 0);
500 
501   // Add a symbol.
502   auto &S1 = G.addDefinedSymbol(B1, 0, "S1", B1.getSize(), Linkage::Strong,
503                                 Scope::Default, false, false);
504 
505   // Transfer with zero offset, explicit size.
506   G.transferDefinedSymbol(S1, B2, 0, 64);
507 
508   EXPECT_EQ(&S1.getBlock(), &B2) << "Block was not updated";
509   EXPECT_EQ(S1.getOffset(), 0U) << "Unexpected offset";
510   EXPECT_EQ(S1.getSize(), 64U) << "Size was not updated";
511 
512   // Transfer with non-zero offset, implicit truncation.
513   G.transferDefinedSymbol(S1, B3, 16, std::nullopt);
514 
515   EXPECT_EQ(&S1.getBlock(), &B3) << "Block was not updated";
516   EXPECT_EQ(S1.getOffset(), 16U) << "Offset was not updated";
517   EXPECT_EQ(S1.getSize(), 16U) << "Size was not updated";
518 }
519 
520 TEST(LinkGraphTest, TransferDefinedSymbolAcrossSections) {
521   // Check that we can transfer a defined symbol from an existing block in one
522   // section to another.
523   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
524               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
525               getGenericEdgeKindName);
526   auto &Sec1 =
527       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
528   auto &Sec2 =
529       G.createSection("__data.2", orc::MemProt::Read | orc::MemProt::Write);
530 
531   // Create blocks in each section.
532   orc::ExecutorAddr B1Addr(0x1000);
533   auto &B1 = G.createContentBlock(Sec1, BlockContent, B1Addr, 8, 0);
534   orc::ExecutorAddr B2Addr(0x2000);
535   auto &B2 = G.createContentBlock(Sec2, BlockContent, B2Addr, 8, 0);
536 
537   // Add a symbol to section 1.
538   auto &S1 = G.addDefinedSymbol(B1, 0, "S1", B1.getSize(), Linkage::Strong,
539                                 Scope::Default, false, false);
540 
541   // Transfer with zero offset, explicit size to section 2.
542   G.transferDefinedSymbol(S1, B2, 0, 64);
543 
544   EXPECT_EQ(&S1.getBlock(), &B2) << "Block was not updated";
545   EXPECT_EQ(S1.getOffset(), 0U) << "Unexpected offset";
546   EXPECT_EQ(S1.getSize(), 64U) << "Size was not updated";
547 
548   EXPECT_EQ(Sec1.symbols_size(), 0u) << "Symbol was not removed from Sec1";
549   EXPECT_EQ(Sec2.symbols_size(), 1u) << "Symbol was not added to Sec2";
550   if (Sec2.symbols_size() == 1) {
551     EXPECT_EQ(*Sec2.symbols().begin(), &S1) << "Unexpected symbol";
552   }
553 }
554 
555 TEST(LinkGraphTest, TransferBlock) {
556   // Check that we can transfer a block (and all associated symbols) from one
557   // section to another.
558   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
559               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
560               getGenericEdgeKindName);
561   auto &Sec1 =
562       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
563   auto &Sec2 =
564       G.createSection("__data.2", orc::MemProt::Read | orc::MemProt::Write);
565 
566   // Create an initial block.
567   orc::ExecutorAddr B1Addr(0x1000);
568   auto &B1 = G.createContentBlock(Sec1, BlockContent, B1Addr, 8, 0);
569   orc::ExecutorAddr B2Addr(0x2000);
570   auto &B2 = G.createContentBlock(Sec1, BlockContent, B2Addr, 8, 0);
571 
572   // Add some symbols on B1...
573   G.addDefinedSymbol(B1, 0, "S1", B1.getSize(), Linkage::Strong, Scope::Default,
574                      false, false);
575   G.addDefinedSymbol(B1, 1, "S2", B1.getSize() - 1, Linkage::Strong,
576                      Scope::Default, false, false);
577 
578   // ... and on B2.
579   G.addDefinedSymbol(B2, 0, "S3", B2.getSize(), Linkage::Strong, Scope::Default,
580                      false, false);
581   G.addDefinedSymbol(B2, 1, "S4", B2.getSize() - 1, Linkage::Strong,
582                      Scope::Default, false, false);
583 
584   EXPECT_EQ(Sec1.blocks_size(), 2U) << "Expected two blocks in Sec1 initially";
585   EXPECT_EQ(Sec1.symbols_size(), 4U)
586       << "Expected four symbols in Sec1 initially";
587   EXPECT_EQ(Sec2.blocks_size(), 0U) << "Expected zero blocks in Sec2 initially";
588   EXPECT_EQ(Sec2.symbols_size(), 0U)
589       << "Expected zero symbols in Sec2 initially";
590 
591   // Transfer with zero offset, explicit size.
592   G.transferBlock(B1, Sec2);
593 
594   EXPECT_EQ(Sec1.blocks_size(), 1U)
595       << "Expected one blocks in Sec1 after transfer";
596   EXPECT_EQ(Sec1.symbols_size(), 2U)
597       << "Expected two symbols in Sec1 after transfer";
598   EXPECT_EQ(Sec2.blocks_size(), 1U)
599       << "Expected one blocks in Sec2 after transfer";
600   EXPECT_EQ(Sec2.symbols_size(), 2U)
601       << "Expected two symbols in Sec2 after transfer";
602 }
603 
604 TEST(LinkGraphTest, MergeSections) {
605   // Check that we can transfer a block (and all associated symbols) from one
606   // section to another.
607   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
608               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
609               getGenericEdgeKindName);
610   auto &Sec1 =
611       G.createSection("__data.1", orc::MemProt::Read | orc::MemProt::Write);
612   auto &Sec2 =
613       G.createSection("__data.2", orc::MemProt::Read | orc::MemProt::Write);
614   auto &Sec3 =
615       G.createSection("__data.3", orc::MemProt::Read | orc::MemProt::Write);
616 
617   // Create an initial block.
618   orc::ExecutorAddr B1Addr(0x1000);
619   auto &B1 = G.createContentBlock(Sec1, BlockContent, B1Addr, 8, 0);
620   orc::ExecutorAddr B2Addr(0x2000);
621   auto &B2 = G.createContentBlock(Sec2, BlockContent, B2Addr, 8, 0);
622   orc::ExecutorAddr B3Addr(0x3000);
623   auto &B3 = G.createContentBlock(Sec3, BlockContent, B3Addr, 8, 0);
624 
625   // Add a symbols for each block.
626   G.addDefinedSymbol(B1, 0, "S1", B1.getSize(), Linkage::Strong, Scope::Default,
627                      false, false);
628   G.addDefinedSymbol(B2, 0, "S2", B2.getSize(), Linkage::Strong, Scope::Default,
629                      false, false);
630   G.addDefinedSymbol(B3, 0, "S3", B2.getSize(), Linkage::Strong, Scope::Default,
631                      false, false);
632 
633   EXPECT_EQ(&B1.getSection(), &Sec1);
634   EXPECT_EQ(&B2.getSection(), &Sec2);
635   EXPECT_EQ(G.sections_size(), 3U) << "Expected three sections initially";
636   EXPECT_EQ(Sec1.blocks_size(), 1U) << "Expected one block in Sec1 initially";
637   EXPECT_EQ(Sec1.symbols_size(), 1U) << "Expected one symbol in Sec1 initially";
638   EXPECT_EQ(Sec2.blocks_size(), 1U) << "Expected one block in Sec2 initially";
639   EXPECT_EQ(Sec2.symbols_size(), 1U) << "Expected one symbol in Sec2 initially";
640   EXPECT_EQ(Sec3.blocks_size(), 1U) << "Expected one block in Sec3 initially";
641   EXPECT_EQ(Sec3.symbols_size(), 1U) << "Expected one symbol in Sec3 initially";
642 
643   // Check that self-merge is a no-op.
644   G.mergeSections(Sec1, Sec1);
645 
646   EXPECT_EQ(&B1.getSection(), &Sec1)
647       << "Expected B1.getSection() to remain unchanged";
648   EXPECT_EQ(G.sections_size(), 3U)
649       << "Expected three sections after first merge";
650   EXPECT_EQ(Sec1.blocks_size(), 1U)
651       << "Expected one block in Sec1 after first merge";
652   EXPECT_EQ(Sec1.symbols_size(), 1U)
653       << "Expected one symbol in Sec1 after first merge";
654   EXPECT_EQ(Sec2.blocks_size(), 1U)
655       << "Expected one block in Sec2 after first merge";
656   EXPECT_EQ(Sec2.symbols_size(), 1U)
657       << "Expected one symbol in Sec2 after first merge";
658   EXPECT_EQ(Sec3.blocks_size(), 1U)
659       << "Expected one block in Sec3 after first merge";
660   EXPECT_EQ(Sec3.symbols_size(), 1U)
661       << "Expected one symbol in Sec3 after first merge";
662 
663   // Merge Sec2 into Sec1, removing Sec2.
664   G.mergeSections(Sec1, Sec2);
665 
666   EXPECT_EQ(&B2.getSection(), &Sec1)
667       << "Expected B2.getSection() to have been changed to &Sec1";
668   EXPECT_EQ(G.sections_size(), 2U)
669       << "Expected two sections after section merge";
670   EXPECT_EQ(Sec1.blocks_size(), 2U)
671       << "Expected two blocks in Sec1 after section merge";
672   EXPECT_EQ(Sec1.symbols_size(), 2U)
673       << "Expected two symbols in Sec1 after section merge";
674   EXPECT_EQ(Sec3.blocks_size(), 1U)
675       << "Expected one block in Sec3 after section merge";
676   EXPECT_EQ(Sec3.symbols_size(), 1U)
677       << "Expected one symbol in Sec3 after section merge";
678 
679   G.mergeSections(Sec1, Sec3, true);
680 
681   EXPECT_EQ(G.sections_size(), 2U) << "Expected two sections after third merge";
682   EXPECT_EQ(Sec1.blocks_size(), 3U)
683       << "Expected three blocks in Sec1 after third merge";
684   EXPECT_EQ(Sec1.symbols_size(), 3U)
685       << "Expected three symbols in Sec1 after third merge";
686   EXPECT_EQ(Sec3.blocks_size(), 0U)
687       << "Expected one block in Sec3 after third merge";
688   EXPECT_EQ(Sec3.symbols_size(), 0U)
689       << "Expected one symbol in Sec3 after third merge";
690 }
691 
692 TEST(LinkGraphTest, SplitBlock) {
693   // Check that the LinkGraph::splitBlock test works as expected.
694   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
695               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
696               getGenericEdgeKindName);
697   auto &Sec =
698       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
699 
700   // Create the block to split.
701   orc::ExecutorAddr B1Addr(0x1000);
702   auto &B1 = G.createContentBlock(Sec, BlockContent, B1Addr, 8, 0);
703 
704   // Add some symbols to the block.
705   auto &S1 = G.addDefinedSymbol(B1, 0, "S1", 4, Linkage::Strong, Scope::Default,
706                                 false, false);
707   auto &S2 = G.addDefinedSymbol(B1, 4, "S2", 4, Linkage::Strong, Scope::Default,
708                                 false, false);
709   auto &S3 = G.addDefinedSymbol(B1, 8, "S3", 4, Linkage::Strong, Scope::Default,
710                                 false, false);
711   auto &S4 = G.addDefinedSymbol(B1, 12, "S4", 4, Linkage::Strong,
712                                 Scope::Default, false, false);
713   // Add some symbols that extend beyond splits, one in the first block and one
714   // in a subsequent block.
715   auto &S5 = G.addDefinedSymbol(B1, 0, "S5", 16, Linkage::Strong,
716                                 Scope::Default, false, false);
717   auto &S6 = G.addDefinedSymbol(B1, 6, "S6", 10, Linkage::Strong,
718                                 Scope::Default, false, false);
719 
720   // Add an extra block, EB, and target symbols, and use these to add edges
721   // from B1 to EB.
722   orc::ExecutorAddr EBAddr(0x2000);
723   auto &EB = G.createContentBlock(Sec, BlockContent, EBAddr, 8, 0);
724   auto &ES1 = G.addDefinedSymbol(EB, 0, "TS1", 4, Linkage::Strong,
725                                  Scope::Default, false, false);
726   auto &ES2 = G.addDefinedSymbol(EB, 4, "TS2", 4, Linkage::Strong,
727                                  Scope::Default, false, false);
728   auto &ES3 = G.addDefinedSymbol(EB, 8, "TS3", 4, Linkage::Strong,
729                                  Scope::Default, false, false);
730   auto &ES4 = G.addDefinedSymbol(EB, 12, "TS4", 4, Linkage::Strong,
731                                  Scope::Default, false, false);
732 
733   // Add edges from B1 to EB.
734   B1.addEdge(Edge::FirstRelocation, 0, ES1, 0);
735   B1.addEdge(Edge::FirstRelocation, 4, ES2, 0);
736   B1.addEdge(Edge::FirstRelocation, 8, ES3, 0);
737   B1.addEdge(Edge::FirstRelocation, 12, ES4, 0);
738 
739   // Split B1.
740   auto Blocks = G.splitBlock(B1, ArrayRef<int>({4, 12}));
741 
742   EXPECT_EQ(Blocks.size(), 3U);
743   EXPECT_EQ(Blocks[0], &B1);
744   auto &B2 = *Blocks[1];
745   auto &B3 = *Blocks[2];
746 
747   // Check that the block addresses and content matches what we would expect.
748   EXPECT_EQ(B1.getAddress(), B1Addr);
749   EXPECT_EQ(B1.getContent(), BlockContent.slice(0, 4));
750   EXPECT_EQ(B1.edges_size(), 1U);
751 
752   EXPECT_EQ(B2.getAddress(), B1Addr + 4);
753   EXPECT_EQ(B2.getContent(), BlockContent.slice(4, 8));
754   EXPECT_EQ(B2.edges_size(), 2U);
755 
756   EXPECT_EQ(B3.getAddress(), B1Addr + 12);
757   EXPECT_EQ(B3.getContent(), BlockContent.slice(12));
758   EXPECT_EQ(B3.edges_size(), 1U);
759 
760   // Check that symbols in B2 were transferred as expected:
761   // We expect S1 and S5 to have been transferred to B1; S2, S3 and S6 to
762   // B2; and S4 to B3. Symbols should have had their offsets slid to account
763   // for the change of containing block.
764   EXPECT_EQ(&S1.getBlock(), &B1);
765   EXPECT_EQ(S1.getOffset(), 0U);
766 
767   EXPECT_EQ(&S2.getBlock(), &B2);
768   EXPECT_EQ(S2.getOffset(), 0U);
769 
770   EXPECT_EQ(&S3.getBlock(), &B2);
771   EXPECT_EQ(S3.getOffset(), 4U);
772 
773   EXPECT_EQ(&S4.getBlock(), &B3);
774   EXPECT_EQ(S4.getOffset(), 0U);
775 
776   EXPECT_EQ(&S5.getBlock(), &B1);
777   EXPECT_EQ(S5.getOffset(), 0U);
778 
779   EXPECT_EQ(&S6.getBlock(), &B2);
780   EXPECT_EQ(S6.getOffset(), 2U);
781 
782   // Size shrinks to fit.
783   EXPECT_EQ(S5.getSize(), 4U);
784   EXPECT_EQ(S6.getSize(), 6U);
785 
786   // Check that edges in have been transferred as expected:
787   EXPECT_EQ(llvm::size(B1.edges()), 1);
788   if (size(B1.edges()) == 2)
789     EXPECT_EQ(B1.edges().begin()->getOffset(), 0U);
790 
791   EXPECT_EQ(llvm::size(B2.edges()), 2);
792   if (size(B2.edges()) == 2) {
793     auto *E1 = &*B2.edges().begin();
794     auto *E2 = &*(B2.edges().begin() + 1);
795     if (E2->getOffset() < E1->getOffset())
796       std::swap(E1, E2);
797     EXPECT_EQ(E1->getOffset(), 0U);
798     EXPECT_EQ(E2->getOffset(), 4U);
799   }
800 
801   EXPECT_EQ(llvm::size(B3.edges()), 1);
802   if (size(B3.edges()) == 2)
803     EXPECT_EQ(B3.edges().begin()->getOffset(), 0U);
804 }
805 
806 TEST(LinkGraphTest, GraphAllocationMethods) {
807   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
808               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
809               getGenericEdgeKindName);
810 
811   // Test allocation of sized, uninitialized buffer.
812   auto Buf1 = G.allocateBuffer(10);
813   EXPECT_EQ(Buf1.size(), 10U);
814 
815   // Test allocation of content-backed buffer.
816   char Buf2Src[] = {1, static_cast<char>(-1), 0, 42};
817   auto Buf2 = G.allocateContent(ArrayRef<char>(Buf2Src));
818   EXPECT_EQ(Buf2, ArrayRef<char>(Buf2Src));
819 
820   // Test c-string allocation from StringRef.
821   StringRef Buf3Src = "hello";
822   auto Buf3 = G.allocateCString(Buf3Src);
823   EXPECT_TRUE(llvm::equal(Buf3.drop_back(1), Buf3Src));
824   EXPECT_EQ(Buf3.back(), '\0');
825 }
826 
827 TEST(LinkGraphTest, IsCStringBlockTest) {
828   // Check that the LinkGraph::splitBlock test works as expected.
829   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
830               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
831               getGenericEdgeKindName);
832   auto &Sec =
833       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
834 
835   char CString[] = "hello, world!";
836   char NotACString[] = {0, 1, 0, 1, 0};
837 
838   auto &CStringBlock =
839       G.createContentBlock(Sec, CString, orc::ExecutorAddr(), 1, 0);
840   auto &NotACStringBlock =
841       G.createContentBlock(Sec, NotACString, orc::ExecutorAddr(), 1, 0);
842   auto &SizeOneZeroFillBlock =
843       G.createZeroFillBlock(Sec, 1, orc::ExecutorAddr(), 1, 0);
844   auto &LargerZeroFillBlock =
845       G.createZeroFillBlock(Sec, 2, orc::ExecutorAddr(), 1, 0);
846 
847   EXPECT_TRUE(isCStringBlock(CStringBlock));
848   EXPECT_FALSE(isCStringBlock(NotACStringBlock));
849   EXPECT_TRUE(isCStringBlock(SizeOneZeroFillBlock));
850   EXPECT_FALSE(isCStringBlock(LargerZeroFillBlock));
851 }
852 
853 TEST(LinkGraphTest, BasicLayoutHonorsNoAlloc) {
854   LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
855               Triple("x86_64-apple-darwin"), SubtargetFeatures(),
856               getGenericEdgeKindName);
857 
858   // Create a regular section and block.
859   auto &Sec1 =
860       G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
861   G.createContentBlock(Sec1, BlockContent.slice(0, 8), orc::ExecutorAddr(), 8,
862                        0);
863 
864   // Create a NoAlloc section and block.
865   auto &Sec2 =
866       G.createSection("__metadata", orc::MemProt::Read | orc::MemProt::Write);
867   Sec2.setMemLifetime(orc::MemLifetime::NoAlloc);
868   G.createContentBlock(Sec2, BlockContent.slice(0, 8), orc::ExecutorAddr(), 8,
869                        0);
870 
871   BasicLayout BL(G);
872 
873   EXPECT_EQ(std::distance(BL.segments().begin(), BL.segments().end()), 1U);
874   EXPECT_EQ(BL.segments().begin()->first,
875             orc::MemProt::Read | orc::MemProt::Write);
876   auto &SegInfo = BL.segments().begin()->second;
877   EXPECT_EQ(SegInfo.Alignment, 8U);
878   EXPECT_EQ(SegInfo.ContentSize, 8U);
879 }
880