Skip to content

[Object][Archive][NFC] Create all symbolic files objects before calculating offsets. #85229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 23 additions & 35 deletions llvm/lib/Object/ArchiveWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,23 +795,31 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
Entry.second = Entry.second > 1 ? 1 : 0;
}

std::vector<std::unique_ptr<SymbolicFile>> SymFiles;

if (NeedSymbols != SymtabWritingMode::NoSymtab || isAIXBigArchive(Kind)) {
for (const NewArchiveMember &M : NewMembers) {
Expected<std::unique_ptr<SymbolicFile>> 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<SymbolicFile> CurSymFile;
std::unique_ptr<SymbolicFile> 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
Expand All @@ -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<std::unique_ptr<SymbolicFile>> 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<SymbolicFile> 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.
Expand All @@ -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;
}
Expand All @@ -902,7 +890,7 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
std::vector<unsigned> Symbols;
if (NeedSymbols != SymtabWritingMode::NoSymtab) {
Expected<std::vector<unsigned>> 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);
Expand Down