@@ -331,8 +331,12 @@ operator<<(raw_ostream &OS, const Session::FileInfo &FI) {
331
331
OS << " Section \" " << SIKV.first () << " \" : " << SIKV.second << " \n " ;
332
332
for (auto &GOTKV : FI.GOTEntryInfos )
333
333
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
+ }
336
340
return OS;
337
341
}
338
342
@@ -1207,9 +1211,35 @@ Error Session::FileInfo::registerStubEntry(
1207
1211
auto TS = GetSymbolTarget (G, Sym.getBlock ());
1208
1212
if (!TS)
1209
1213
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
+
1213
1243
return Error::success ();
1214
1244
}
1215
1245
@@ -1235,8 +1265,14 @@ Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
1235
1265
return SecInfoItr->second ;
1236
1266
}
1237
1267
1268
+ static StringRef detectStubKind (const Session::MemoryRegionInfo &Stub) {
1269
+ // Implement acutal stub kind detection
1270
+ return " " ;
1271
+ }
1272
+
1238
1273
Expected<Session::MemoryRegionInfo &>
1239
- Session::findStubInfo (StringRef FileName, StringRef TargetName) {
1274
+ Session::findStubInfo (StringRef FileName, StringRef TargetName,
1275
+ StringRef KindNameFilter) {
1240
1276
auto FI = findFileInfo (FileName);
1241
1277
if (!FI)
1242
1278
return FI.takeError ();
@@ -1246,7 +1282,38 @@ Session::findStubInfo(StringRef FileName, StringRef TargetName) {
1246
1282
" \" registered for file \" " + FileName +
1247
1283
" \" " ,
1248
1284
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 ];
1250
1317
}
1251
1318
1252
1319
Expected<Session::MemoryRegionInfo &>
@@ -2015,8 +2082,9 @@ static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
2015
2082
return S.findSectionInfo (FileName, SectionName);
2016
2083
};
2017
2084
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);
2020
2088
};
2021
2089
2022
2090
auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {
0 commit comments