diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index aa57e55de70c8..97d0e4f75be8e 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -795,23 +795,31 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, Entry.second = Entry.second > 1 ? 1 : 0; } + std::vector> SymFiles; + + if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) { + for (const NewArchiveMember &M : NewMembers) { + Expected> SymFileOrErr = + getSymbolicFile(M.Buf->getMemBufferRef(), Context); + if (!SymFileOrErr) + return createFileError(M.MemberName, SymFileOrErr.takeError()); + SymFiles.push_back(std::move(*SymFileOrErr)); + } + } + // The big archive format needs to know the offset of the previous member // header. uint64_t PrevOffset = 0; uint64_t NextMemHeadPadSize = 0; - std::unique_ptr CurSymFile; - std::unique_ptr NextSymFile; - uint16_t Index = 0; - for (auto M = NewMembers.begin(); M < NewMembers.end(); ++M) { + for (uint32_t Index = 0; Index < NewMembers.size(); ++Index) { + const NewArchiveMember *M = &NewMembers[Index]; std::string Header; raw_string_ostream Out(Header); MemoryBufferRef Buf = M->Buf->getMemBufferRef(); StringRef Data = Thin ? "" : Buf.getBuffer(); - Index++; - // ld64 expects the members to be 8-byte aligned for 64-bit content and at // least 4-byte aligned for 32-bit content. Opt for the larger encoding // uniformly. This matches the behaviour with cctools and ensures that ld64 @@ -837,29 +845,9 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, std::move(StringMsg), object::object_error::parse_failed); } - if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) { - auto SetNextSymFile = [&NextSymFile, - &Context](MemoryBufferRef Buf, - StringRef MemberName) -> Error { - Expected> SymFileOrErr = - getSymbolicFile(Buf, Context); - if (!SymFileOrErr) - return createFileError(MemberName, SymFileOrErr.takeError()); - NextSymFile = std::move(*SymFileOrErr); - return Error::success(); - }; - - if (M == NewMembers.begin()) - if (Error Err = SetNextSymFile(Buf, M->MemberName)) - return std::move(Err); - - CurSymFile = std::move(NextSymFile); - - if ((M + 1) != NewMembers.end()) - if (Error Err = SetNextSymFile((M + 1)->Buf->getMemBufferRef(), - (M + 1)->MemberName)) - return std::move(Err); - } + std::unique_ptr CurSymFile; + if (!SymFiles.empty()) + CurSymFile = std::move(SymFiles[Index]); // In the big archive file format, we need to calculate and include the next // member offset and previous member offset in the file member header. @@ -880,13 +868,13 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, // If there is another member file after this, we need to calculate the // padding before the header. - if ((M + 1) != NewMembers.end()) { - uint64_t OffsetToNextMemData = NextOffset + - sizeof(object::BigArMemHdrType) + - alignTo((M + 1)->MemberName.size(), 2); + if (Index + 1 != SymFiles.size()) { + uint64_t OffsetToNextMemData = + NextOffset + sizeof(object::BigArMemHdrType) + + alignTo(NewMembers[Index + 1].MemberName.size(), 2); NextMemHeadPadSize = alignToPowerOf2(OffsetToNextMemData, - getMemberAlignment(NextSymFile.get())) - + getMemberAlignment(SymFiles[Index + 1].get())) - OffsetToNextMemData; NextOffset += NextMemHeadPadSize; } @@ -902,7 +890,7 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, std::vector Symbols; if (NeedSymbols != SymtabWritingMode::NoSymtab) { Expected> SymbolsOrErr = - getSymbols(CurSymFile.get(), Index, SymNames, SymMap); + getSymbols(CurSymFile.get(), Index + 1, SymNames, SymMap); if (!SymbolsOrErr) return createFileError(M->MemberName, SymbolsOrErr.takeError()); Symbols = std::move(*SymbolsOrErr);