@@ -482,16 +482,45 @@ static uint64_t computeHeadersSize(object::Archive::Kind Kind,
482
482
}
483
483
484
484
static Expected<std::unique_ptr<SymbolicFile>>
485
- getSymbolicFile (MemoryBufferRef Buf, LLVMContext &Context) {
485
+ getSymbolicFile (MemoryBufferRef Buf, LLVMContext &Context,
486
+ object::Archive::Kind Kind, function_ref<void (Error)> Warn) {
486
487
const file_magic Type = identify_magic (Buf.getBuffer ());
487
488
// Don't attempt to read non-symbolic file types.
488
489
if (!object::SymbolicFile::isSymbolicFile (Type, &Context))
489
490
return nullptr ;
490
491
if (Type == file_magic::bitcode) {
491
492
auto ObjOrErr = object::SymbolicFile::createSymbolicFile (
492
493
Buf, file_magic::bitcode, &Context);
493
- if (!ObjOrErr)
494
- return ObjOrErr.takeError ();
494
+ // An error reading a bitcode file most likely indicates that the file
495
+ // was created by a compiler from the future. Normally we don't try to
496
+ // implement forwards compatibility for bitcode files, but when creating an
497
+ // archive we can implement best-effort forwards compatibility by treating
498
+ // the file as a blob and not creating symbol index entries for it. lld and
499
+ // mold ignore the archive symbol index, so provided that you use one of
500
+ // these linkers, LTO will work as long as lld or the gold plugin is newer
501
+ // than the compiler. We only ignore errors if the archive format is one
502
+ // that is supported by a linker that is known to ignore the index,
503
+ // otherwise there's no chance of this working so we may as well error out.
504
+ // We print a warning on read failure so that users of linkers that rely on
505
+ // the symbol index can diagnose the issue.
506
+ //
507
+ // This is the same behavior as GNU ar when the linker plugin returns an
508
+ // error when reading the input file. If the bitcode file is actually
509
+ // malformed, it will be diagnosed at link time.
510
+ if (!ObjOrErr) {
511
+ switch (Kind) {
512
+ case object::Archive::K_BSD:
513
+ case object::Archive::K_GNU:
514
+ case object::Archive::K_GNU64:
515
+ Warn (ObjOrErr.takeError ());
516
+ return nullptr ;
517
+ case object::Archive::K_AIXBIG:
518
+ case object::Archive::K_COFF:
519
+ case object::Archive::K_DARWIN:
520
+ case object::Archive::K_DARWIN64:
521
+ return ObjOrErr.takeError ();
522
+ }
523
+ }
495
524
return std::move (*ObjOrErr);
496
525
} else {
497
526
auto ObjOrErr = object::SymbolicFile::createSymbolicFile (Buf);
@@ -751,7 +780,7 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
751
780
object::Archive::Kind Kind, bool Thin, bool Deterministic,
752
781
SymtabWritingMode NeedSymbols, SymMap *SymMap,
753
782
LLVMContext &Context, ArrayRef<NewArchiveMember> NewMembers,
754
- std::optional<bool > IsEC) {
783
+ std::optional<bool > IsEC, function_ref< void (Error)> Warn ) {
755
784
static char PaddingData[8 ] = {' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' , ' \n ' };
756
785
uint64_t MemHeadPadSize = 0 ;
757
786
uint64_t Pos =
@@ -819,8 +848,10 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
819
848
820
849
if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive (Kind)) {
821
850
for (const NewArchiveMember &M : NewMembers) {
822
- Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr =
823
- getSymbolicFile (M.Buf ->getMemBufferRef (), Context);
851
+ Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr = getSymbolicFile (
852
+ M.Buf ->getMemBufferRef (), Context, Kind, [&](Error Err) {
853
+ Warn (createFileError (M.MemberName , std::move (Err)));
854
+ });
824
855
if (!SymFileOrErr)
825
856
return createFileError (M.MemberName , SymFileOrErr.takeError ());
826
857
SymFiles.push_back (std::move (*SymFileOrErr));
@@ -1001,7 +1032,8 @@ Error writeArchiveToStream(raw_ostream &Out,
1001
1032
ArrayRef<NewArchiveMember> NewMembers,
1002
1033
SymtabWritingMode WriteSymtab,
1003
1034
object::Archive::Kind Kind, bool Deterministic,
1004
- bool Thin, std::optional<bool > IsEC) {
1035
+ bool Thin, std::optional<bool > IsEC,
1036
+ function_ref<void (Error)> Warn) {
1005
1037
assert ((!Thin || !isBSDLike (Kind)) && " Only the gnu format has a thin mode" );
1006
1038
1007
1039
SmallString<0 > SymNamesBuf;
@@ -1023,7 +1055,7 @@ Error writeArchiveToStream(raw_ostream &Out,
1023
1055
1024
1056
Expected<std::vector<MemberData>> DataOrErr = computeMemberData (
1025
1057
StringTable, SymNames, Kind, Thin, Deterministic, WriteSymtab,
1026
- isCOFFArchive (Kind) ? &SymMap : nullptr , Context, NewMembers, IsEC);
1058
+ isCOFFArchive (Kind) ? &SymMap : nullptr , Context, NewMembers, IsEC, Warn );
1027
1059
if (Error E = DataOrErr.takeError ())
1028
1060
return E;
1029
1061
std::vector<MemberData> &Data = *DataOrErr;
@@ -1266,19 +1298,23 @@ Error writeArchiveToStream(raw_ostream &Out,
1266
1298
return Error::success ();
1267
1299
}
1268
1300
1301
+ void warnToStderr (Error Err) {
1302
+ llvm::logAllUnhandledErrors (std::move (Err), llvm::errs (), " warning: " );
1303
+ }
1304
+
1269
1305
Error writeArchive (StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
1270
1306
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
1271
1307
bool Deterministic, bool Thin,
1272
1308
std::unique_ptr<MemoryBuffer> OldArchiveBuf,
1273
- std::optional<bool > IsEC) {
1309
+ std::optional<bool > IsEC, function_ref< void (Error)> Warn ) {
1274
1310
Expected<sys::fs::TempFile> Temp =
1275
1311
sys::fs::TempFile::create (ArcName + " .temp-archive-%%%%%%%.a" );
1276
1312
if (!Temp)
1277
1313
return Temp.takeError ();
1278
1314
raw_fd_ostream Out (Temp->FD , false );
1279
1315
1280
1316
if (Error E = writeArchiveToStream (Out, NewMembers, WriteSymtab, Kind,
1281
- Deterministic, Thin, IsEC)) {
1317
+ Deterministic, Thin, IsEC, Warn )) {
1282
1318
if (Error DiscardError = Temp->discard ())
1283
1319
return joinErrors (std::move (E), std::move (DiscardError));
1284
1320
return E;
@@ -1302,12 +1338,14 @@ Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
1302
1338
Expected<std::unique_ptr<MemoryBuffer>>
1303
1339
writeArchiveToBuffer (ArrayRef<NewArchiveMember> NewMembers,
1304
1340
SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
1305
- bool Deterministic, bool Thin) {
1341
+ bool Deterministic, bool Thin,
1342
+ function_ref<void (Error)> Warn) {
1306
1343
SmallVector<char , 0 > ArchiveBufferVector;
1307
1344
raw_svector_ostream ArchiveStream (ArchiveBufferVector);
1308
1345
1309
- if (Error E = writeArchiveToStream (ArchiveStream, NewMembers, WriteSymtab,
1310
- Kind, Deterministic, Thin, std::nullopt))
1346
+ if (Error E =
1347
+ writeArchiveToStream (ArchiveStream, NewMembers, WriteSymtab, Kind,
1348
+ Deterministic, Thin, std::nullopt, Warn))
1311
1349
return std::move (E);
1312
1350
1313
1351
return std::make_unique<SmallVectorMemoryBuffer>(
0 commit comments