@@ -331,8 +331,12 @@ operator<<(raw_ostream &OS, const Session::FileInfo &FI) {
331331 OS << " Section \" " << SIKV.first () << " \" : " << SIKV.second << " \n " ;
332332 for (auto &GOTKV : FI.GOTEntryInfos )
333333 OS << " GOT \" " << GOTKV.first () << " \" : " << GOTKV.second << " \n " ;
334- for (auto &StubKV : FI.StubInfos )
335- OS << " Stub \" " << StubKV.first () << " \" : " << StubKV.second << " \n " ;
334+ for (auto &StubKVs : FI.StubInfos ) {
335+ OS << " Stubs \" " << StubKVs.first () << " \" :" ;
336+ for (auto MemRegion : StubKVs.second )
337+ OS << " " << MemRegion;
338+ OS << " \n " ;
339+ }
336340 return OS;
337341}
338342
@@ -1207,9 +1211,35 @@ Error Session::FileInfo::registerStubEntry(
12071211 auto TS = GetSymbolTarget (G, Sym.getBlock ());
12081212 if (!TS)
12091213 return TS.takeError ();
1210- StubInfos[TS->getName ()] = {Sym.getSymbolContent (),
1211- Sym.getAddress ().getValue (),
1212- Sym.getTargetFlags ()};
1214+
1215+ SmallVector<MemoryRegionInfo> &Entry = StubInfos[TS->getName ()];
1216+ Entry.insert (Entry.begin (),
1217+ {Sym.getSymbolContent (), Sym.getAddress ().getValue (),
1218+ Sym.getTargetFlags ()});
1219+ return Error::success ();
1220+ }
1221+
1222+ Error Session::FileInfo::registerMultiStubEntry (
1223+ LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
1224+ if (Sym.isSymbolZeroFill ())
1225+ return make_error<StringError>(" Unexpected zero-fill symbol in section " +
1226+ Sym.getBlock ().getSection ().getName (),
1227+ inconvertibleErrorCode ());
1228+
1229+ auto Target = GetSymbolTarget (G, Sym.getBlock ());
1230+ if (!Target)
1231+ return Target.takeError ();
1232+
1233+ SmallVector<MemoryRegionInfo> &Entry = StubInfos[Target->getName ()];
1234+ Entry.emplace_back (Sym.getSymbolContent (), Sym.getAddress ().getValue (),
1235+ Sym.getTargetFlags ());
1236+
1237+ // Let's keep stubs ordered by ascending address.
1238+ std::sort (Entry.begin (), Entry.end (),
1239+ [](const MemoryRegionInfo &L, const MemoryRegionInfo &R) {
1240+ return L.getTargetAddress () < R.getTargetAddress ();
1241+ });
1242+
12131243 return Error::success ();
12141244}
12151245
@@ -1235,8 +1265,14 @@ Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
12351265 return SecInfoItr->second ;
12361266}
12371267
1268+ static StringRef detectStubKind (const Session::MemoryRegionInfo &Stub) {
1269+ // Implement acutal stub kind detection
1270+ return " " ;
1271+ }
1272+
12381273Expected<Session::MemoryRegionInfo &>
1239- Session::findStubInfo (StringRef FileName, StringRef TargetName) {
1274+ Session::findStubInfo (StringRef FileName, StringRef TargetName,
1275+ StringRef KindNameFilter) {
12401276 auto FI = findFileInfo (FileName);
12411277 if (!FI)
12421278 return FI.takeError ();
@@ -1246,7 +1282,38 @@ Session::findStubInfo(StringRef FileName, StringRef TargetName) {
12461282 " \" registered for file \" " + FileName +
12471283 " \" " ,
12481284 inconvertibleErrorCode ());
1249- return StubInfoItr->second ;
1285+ auto &StubsForTarget = StubInfoItr->second ;
1286+ assert (!StubsForTarget.empty () && " At least 1 stub in each entry" );
1287+ if (KindNameFilter.empty () && StubsForTarget.size () == 1 )
1288+ return StubsForTarget[0 ]; // Regular single-stub match
1289+
1290+ std::string KindsStr;
1291+ SmallVector<MemoryRegionInfo *, 1 > Matches;
1292+ Regex KindNameMatcher (KindNameFilter.empty () ? " .*" : KindNameFilter);
1293+ for (MemoryRegionInfo &Stub : StubsForTarget) {
1294+ StringRef Kind = detectStubKind (Stub);
1295+ if (KindNameMatcher.match (Kind))
1296+ Matches.push_back (&Stub);
1297+ KindsStr += " \" " + (Kind.empty () ? " <unknown>" : Kind.str ()) + " \" , " ;
1298+ }
1299+ if (Matches.empty ())
1300+ return make_error<StringError>(
1301+ " \" " + TargetName + " \" has " + Twine (StubsForTarget.size ()) +
1302+ " stubs in file \" " + FileName +
1303+ " \" , but none of them matches the stub-kind filter \" " +
1304+ KindNameFilter + " \" (all encountered kinds are " +
1305+ StringRef (KindsStr.data (), KindsStr.size () - 2 ) + " )." ,
1306+ inconvertibleErrorCode ());
1307+ if (Matches.size () > 1 )
1308+ return make_error<StringError>(
1309+ " \" " + TargetName + " \" has " + Twine (Matches.size ()) +
1310+ " candidate stubs in file \" " + FileName +
1311+ " \" . Please refine stub-kind filter \" " + KindNameFilter +
1312+ " \" for disambiguation (encountered kinds are " +
1313+ StringRef (KindsStr.data (), KindsStr.size () - 2 ) + " )." ,
1314+ inconvertibleErrorCode ());
1315+
1316+ return *Matches[0 ];
12501317}
12511318
12521319Expected<Session::MemoryRegionInfo &>
@@ -2015,8 +2082,9 @@ static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
20152082 return S.findSectionInfo (FileName, SectionName);
20162083 };
20172084
2018- auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName) {
2019- return S.findStubInfo (FileName, SectionName);
2085+ auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName,
2086+ StringRef KindNameFilter) {
2087+ return S.findStubInfo (FileName, SectionName, KindNameFilter);
20202088 };
20212089
20222090 auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {
0 commit comments