Skip to content

Commit 9c5001e

Browse files
committed
[JITLink] Add convenience methods to LinkGraph to find symbols by name.
Adds new convenience methods findDefinedSymbolByName, findExternalSymbolByName and findAbsoluteSymbolByName to the LinkGraph class. These should be used to find symbols of the given types by name. COFFLinkGraphBuilder and MachOPlatform are updated to take advantage of the new methods.
1 parent 21ade5a commit 9c5001e

File tree

4 files changed

+96
-48
lines changed

4 files changed

+96
-48
lines changed

Diff for: llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h

+25
Original file line numberDiff line numberDiff line change
@@ -1387,10 +1387,26 @@ class LinkGraph {
13871387
GetExternalSymbolMapEntryValue()));
13881388
}
13891389

1390+
/// Returns the external symbol with the given name if one exists, otherwise
1391+
/// returns nullptr.
1392+
Symbol *findExternalSymbolByName(const orc::SymbolStringPtrBase &Name) {
1393+
for (auto *Sym : external_symbols())
1394+
if (Sym->getName() == Name)
1395+
return Sym;
1396+
return nullptr;
1397+
}
1398+
13901399
iterator_range<absolute_symbol_iterator> absolute_symbols() {
13911400
return make_range(AbsoluteSymbols.begin(), AbsoluteSymbols.end());
13921401
}
13931402

1403+
Symbol *findAbsoluteSymbolByName(const orc::SymbolStringPtrBase &Name) {
1404+
for (auto *Sym : absolute_symbols())
1405+
if (Sym->getName() == Name)
1406+
return Sym;
1407+
return nullptr;
1408+
}
1409+
13941410
iterator_range<defined_symbol_iterator> defined_symbols() {
13951411
auto Secs = sections();
13961412
return make_range(defined_symbol_iterator(Secs.begin(), Secs.end()),
@@ -1403,6 +1419,15 @@ class LinkGraph {
14031419
const_defined_symbol_iterator(Secs.end(), Secs.end()));
14041420
}
14051421

1422+
/// Returns the defined symbol with the given name if one exists, otherwise
1423+
/// returns nullptr.
1424+
Symbol *findDefinedSymbolByName(const orc::SymbolStringPtrBase &Name) {
1425+
for (auto *Sym : defined_symbols())
1426+
if (Sym->hasName() && Sym->getName() == Name)
1427+
return Sym;
1428+
return nullptr;
1429+
}
1430+
14061431
/// Make the given symbol external (must not already be external).
14071432
///
14081433
/// Symbol size, linkage and callability will be left unchanged. Symbol scope

Diff for: llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp

+9-25
Original file line numberDiff line numberDiff line change
@@ -635,32 +635,16 @@ Symbol *GetImageBaseSymbol::operator()(LinkGraph &G) {
635635
return *ImageBase;
636636

637637
auto IBN = G.intern(ImageBaseName);
638+
ImageBase = G.findExternalSymbolByName(IBN);
639+
if (*ImageBase)
640+
return *ImageBase;
641+
ImageBase = G.findAbsoluteSymbolByName(IBN);
642+
if (*ImageBase)
643+
return *ImageBase;
644+
ImageBase = G.findDefinedSymbolByName(IBN);
645+
if (*ImageBase)
646+
return *ImageBase;
638647

639-
// Check external symbols for image base.
640-
for (auto *Sym : G.external_symbols()) {
641-
if (Sym->getName() == IBN) {
642-
ImageBase = Sym;
643-
return Sym;
644-
}
645-
}
646-
647-
// Check absolute symbols (unexpected, but legal).
648-
for (auto *Sym : G.absolute_symbols()) {
649-
if (Sym->getName() == IBN) {
650-
ImageBase = Sym;
651-
return Sym;
652-
}
653-
}
654-
655-
// Finally, check defined symbols.
656-
for (auto *Sym : G.defined_symbols()) {
657-
if (Sym->hasName() && Sym->getName() == IBN) {
658-
ImageBase = Sym;
659-
return Sym;
660-
}
661-
}
662-
663-
ImageBase = nullptr;
664648
return nullptr;
665649
}
666650

Diff for: llvm/lib/ExecutionEngine/Orc/MachOPlatform.cpp

+17-23
Original file line numberDiff line numberDiff line change
@@ -1492,26 +1492,19 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
14921492
memcpy(SD.Sec.sectname, "__objc_imageinfo", 16);
14931493
strcpy(SD.Sec.segname, "__DATA");
14941494
SD.Sec.size = 8;
1495-
SD.AddFixups = [&](size_t RecordOffset) {
1495+
jitlink::Symbol *ObjCImageInfoSym = nullptr;
1496+
SD.AddFixups = [&, ObjCImageInfoSym](size_t RecordOffset) mutable {
14961497
auto PointerEdge = getPointerEdgeKind(G);
14971498

14981499
// Look for an existing __objc_imageinfo symbol.
1499-
jitlink::Symbol *ObjCImageInfoSym = nullptr;
1500-
for (auto *Sym : G.external_symbols())
1501-
if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
1502-
ObjCImageInfoSym = Sym;
1503-
break;
1504-
}
1505-
if (!ObjCImageInfoSym)
1506-
for (auto *Sym : G.absolute_symbols())
1507-
if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
1508-
ObjCImageInfoSym = Sym;
1509-
break;
1510-
}
1511-
if (!ObjCImageInfoSym)
1512-
for (auto *Sym : G.defined_symbols())
1513-
if (Sym->hasName() && *Sym->getName() == ObjCImageInfoSymbolName) {
1514-
ObjCImageInfoSym = Sym;
1500+
if (!ObjCImageInfoSym) {
1501+
auto Name = G.intern(ObjCImageInfoSymbolName);
1502+
ObjCImageInfoSym = G.findExternalSymbolByName(Name);
1503+
if (!ObjCImageInfoSym)
1504+
ObjCImageInfoSym = G.findAbsoluteSymbolByName(Name);
1505+
if (!ObjCImageInfoSym) {
1506+
ObjCImageInfoSym = G.findDefinedSymbolByName(Name);
1507+
if (ObjCImageInfoSym) {
15151508
std::optional<uint32_t> Flags;
15161509
{
15171510
std::lock_guard<std::mutex> Lock(PluginMutex);
@@ -1525,16 +1518,17 @@ Error MachOPlatform::MachOPlatformPlugin::populateObjCRuntimeObject(
15251518
if (Flags) {
15261519
// We own the definition of __objc_image_info; write the final
15271520
// merged flags value.
1528-
auto Content = Sym->getBlock().getMutableContent(G);
1529-
assert(Content.size() == 8 &&
1521+
auto Content = ObjCImageInfoSym->getBlock().getMutableContent(G);
1522+
assert(
1523+
Content.size() == 8 &&
15301524
"__objc_image_info size should have been verified already");
15311525
support::endian::write32(&Content[4], *Flags, G.getEndianness());
15321526
}
1533-
break;
15341527
}
1535-
if (!ObjCImageInfoSym)
1536-
ObjCImageInfoSym =
1537-
&G.addExternalSymbol(ObjCImageInfoSymbolName, 8, false);
1528+
}
1529+
if (!ObjCImageInfoSym)
1530+
ObjCImageInfoSym = &G.addExternalSymbol(std::move(Name), 8, false);
1531+
}
15381532

15391533
SecBlock.addEdge(PointerEdge,
15401534
RecordOffset + ((char *)&SD.Sec.addr - (char *)&SD.Sec),

Diff for: llvm/unittests/ExecutionEngine/JITLink/LinkGraphTests.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,51 @@ TEST(LinkGraphTest, ContentAccessAndUpdate) {
217217
[](char C) { return C == 0; }));
218218
}
219219

220+
TEST(LinkGraphTest, FindSymbolsByName) {
221+
// Check that we can make defined and absolute symbols external.
222+
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),
223+
Triple("x86_64-apple-darwin"), SubtargetFeatures(),
224+
getGenericEdgeKindName);
225+
auto &Sec =
226+
G.createSection("__data", orc::MemProt::Read | orc::MemProt::Write);
227+
228+
auto &B1 =
229+
G.createContentBlock(Sec, BlockContent, orc::ExecutorAddr(0x1000), 8, 0);
230+
231+
// Add an anonymous symbol to make sure that these don't disrupt by-name
232+
// lookup of defined symbols.
233+
G.addAnonymousSymbol(B1, 0, 0, false, false);
234+
235+
// Add named defined, external and absolute symbols.
236+
auto Foo = G.intern("foo");
237+
auto &FooSym = G.addDefinedSymbol(B1, 0, Foo, 4, Linkage::Strong,
238+
Scope::Default, false, false);
239+
240+
auto Bar = G.intern("bar");
241+
auto &BarSym = G.addExternalSymbol(Bar, 0, false);
242+
243+
auto Baz = G.intern("baz");
244+
auto &BazSym = G.addAbsoluteSymbol(Baz, orc::ExecutorAddr(0x1234), 0,
245+
Linkage::Strong, Scope::Default, true);
246+
247+
EXPECT_EQ(G.findDefinedSymbolByName(Foo), &FooSym);
248+
EXPECT_EQ(G.findExternalSymbolByName(Foo), nullptr);
249+
EXPECT_EQ(G.findAbsoluteSymbolByName(Foo), nullptr);
250+
251+
EXPECT_EQ(G.findDefinedSymbolByName(Bar), nullptr);
252+
EXPECT_EQ(G.findExternalSymbolByName(Bar), &BarSym);
253+
EXPECT_EQ(G.findAbsoluteSymbolByName(Bar), nullptr);
254+
255+
EXPECT_EQ(G.findDefinedSymbolByName(Baz), nullptr);
256+
EXPECT_EQ(G.findExternalSymbolByName(Baz), nullptr);
257+
EXPECT_EQ(G.findAbsoluteSymbolByName(Baz), &BazSym);
258+
259+
auto Qux = G.intern("qux");
260+
EXPECT_EQ(G.findDefinedSymbolByName(Qux), nullptr);
261+
EXPECT_EQ(G.findExternalSymbolByName(Qux), nullptr);
262+
EXPECT_EQ(G.findAbsoluteSymbolByName(Qux), nullptr);
263+
}
264+
220265
TEST(LinkGraphTest, MakeExternal) {
221266
// Check that we can make defined and absolute symbols external.
222267
LinkGraph G("foo", std::make_shared<orc::SymbolStringPool>(),

0 commit comments

Comments
 (0)