Skip to content

Commit d8b6935

Browse files
committed
[Object][Archive][NFC] Create all symbolic files objects before calculating offsets.
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. I think it also makes accessing the next member for AIX big archive offset computation a bit easier.
1 parent 4528c44 commit d8b6935

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)