Skip to content

Commit c7fc95b

Browse files
authored
[Object][Archive][NFC] Create all symbolic files objects before calculating offsets. (#85229)
This is refactoring preparing to move UseECMap computation to the archive writer. We currently require writeArchive caller to pass that. This is not practical for llvm-ar, which currently interprets at most one passed object. For a reliable UseECMap, we need to interpret all symbolic objects: we may have, for example, a list of x86_64 files followed by aarch64 file, which indicates that we should use EC map for x86_64 objects. This commit interprets symbolic files in a separated pass, which will be a convenient place to implement UseECMap computation in the follow up. It also makes accessing the next member for AIX big archive offset computation a bit easier.
1 parent 5334afc commit c7fc95b

File tree

1 file changed

+23
-35
lines changed

1 file changed

+23
-35
lines changed

llvm/lib/Object/ArchiveWriter.cpp

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -795,23 +795,31 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
795795
Entry.second = Entry.second > 1 ? 1 : 0;
796796
}
797797

798+
std::vector<std::unique_ptr<SymbolicFile>> SymFiles;
799+
800+
if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) {
801+
for (const NewArchiveMember &M : NewMembers) {
802+
Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr =
803+
getSymbolicFile(M.Buf->getMemBufferRef(), Context);
804+
if (!SymFileOrErr)
805+
return createFileError(M.MemberName, SymFileOrErr.takeError());
806+
SymFiles.push_back(std::move(*SymFileOrErr));
807+
}
808+
}
809+
798810
// The big archive format needs to know the offset of the previous member
799811
// header.
800812
uint64_t PrevOffset = 0;
801813
uint64_t NextMemHeadPadSize = 0;
802-
std::unique_ptr<SymbolicFile> CurSymFile;
803-
std::unique_ptr<SymbolicFile> NextSymFile;
804-
uint16_t Index = 0;
805814

806-
for (auto M = NewMembers.begin(); M < NewMembers.end(); ++M) {
815+
for (uint32_t Index = 0; Index < NewMembers.size(); ++Index) {
816+
const NewArchiveMember *M = &NewMembers[Index];
807817
std::string Header;
808818
raw_string_ostream Out(Header);
809819

810820
MemoryBufferRef Buf = M->Buf->getMemBufferRef();
811821
StringRef Data = Thin ? "" : Buf.getBuffer();
812822

813-
Index++;
814-
815823
// ld64 expects the members to be 8-byte aligned for 64-bit content and at
816824
// least 4-byte aligned for 32-bit content. Opt for the larger encoding
817825
// uniformly. This matches the behaviour with cctools and ensures that ld64
@@ -837,29 +845,9 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
837845
std::move(StringMsg), object::object_error::parse_failed);
838846
}
839847

840-
if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) {
841-
auto SetNextSymFile = [&NextSymFile,
842-
&Context](MemoryBufferRef Buf,
843-
StringRef MemberName) -> Error {
844-
Expected<std::unique_ptr<SymbolicFile>> SymFileOrErr =
845-
getSymbolicFile(Buf, Context);
846-
if (!SymFileOrErr)
847-
return createFileError(MemberName, SymFileOrErr.takeError());
848-
NextSymFile = std::move(*SymFileOrErr);
849-
return Error::success();
850-
};
851-
852-
if (M == NewMembers.begin())
853-
if (Error Err = SetNextSymFile(Buf, M->MemberName))
854-
return std::move(Err);
855-
856-
CurSymFile = std::move(NextSymFile);
857-
858-
if ((M + 1) != NewMembers.end())
859-
if (Error Err = SetNextSymFile((M + 1)->Buf->getMemBufferRef(),
860-
(M + 1)->MemberName))
861-
return std::move(Err);
862-
}
848+
std::unique_ptr<SymbolicFile> CurSymFile;
849+
if (!SymFiles.empty())
850+
CurSymFile = std::move(SymFiles[Index]);
863851

864852
// In the big archive file format, we need to calculate and include the next
865853
// member offset and previous member offset in the file member header.
@@ -880,13 +868,13 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
880868

881869
// If there is another member file after this, we need to calculate the
882870
// padding before the header.
883-
if ((M + 1) != NewMembers.end()) {
884-
uint64_t OffsetToNextMemData = NextOffset +
885-
sizeof(object::BigArMemHdrType) +
886-
alignTo((M + 1)->MemberName.size(), 2);
871+
if (Index + 1 != SymFiles.size()) {
872+
uint64_t OffsetToNextMemData =
873+
NextOffset + sizeof(object::BigArMemHdrType) +
874+
alignTo(NewMembers[Index + 1].MemberName.size(), 2);
887875
NextMemHeadPadSize =
888876
alignToPowerOf2(OffsetToNextMemData,
889-
getMemberAlignment(NextSymFile.get())) -
877+
getMemberAlignment(SymFiles[Index + 1].get())) -
890878
OffsetToNextMemData;
891879
NextOffset += NextMemHeadPadSize;
892880
}
@@ -902,7 +890,7 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
902890
std::vector<unsigned> Symbols;
903891
if (NeedSymbols != SymtabWritingMode::NoSymtab) {
904892
Expected<std::vector<unsigned>> SymbolsOrErr =
905-
getSymbols(CurSymFile.get(), Index, SymNames, SymMap);
893+
getSymbols(CurSymFile.get(), Index + 1, SymNames, SymMap);
906894
if (!SymbolsOrErr)
907895
return createFileError(M->MemberName, SymbolsOrErr.takeError());
908896
Symbols = std::move(*SymbolsOrErr);

0 commit comments

Comments
 (0)