aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/ArchiveWriter.cpp
diff options
context:
space:
mode:
authorJames Henderson <james.henderson@sony.com>2020-09-25 10:21:39 +0100
committerJames Henderson <james.henderson@sony.com>2020-10-01 14:03:34 +0100
commita20168d0307860047ad7c8a2074f98fc25b057c2 (patch)
treeeee9b302c3a52f8c6a9c3c6c8d439f8beebd18b0 /llvm/lib/Object/ArchiveWriter.cpp
parent5101e7e8dd01719f9161e01e2f053c9797c247a8 (diff)
downloadllvm-a20168d0307860047ad7c8a2074f98fc25b057c2.zip
llvm-a20168d0307860047ad7c8a2074f98fc25b057c2.tar.gz
llvm-a20168d0307860047ad7c8a2074f98fc25b057c2.tar.bz2
[Archive] Don't throw away errors for malformed archive members
When adding an archive member with a problem, e.g. a new bitcode with an old archiver, containing an unsupported attribute, or an ELF file with a malformed symbol table, the archiver would throw away the error and simply add the member to the archive without any symbol entries. This meant that the resultant archive could be silently unusable when not using --whole-archive, and result in unexpected undefined symbols. This change fixes this issue by addressing two FIXMEs and only throwing away not-an-object errors. However, this meant that some LLD tests which didn't need symbol tables and were using invalid members deliberately to test the linker's malformed input handling no longer worked, so this patch also stops the archiver from looking for symbols in an object if it doesn't require a symbol table, and updates the tests accordingly. Differential Revision: https://reviews.llvm.org/D88288 Reviewed by: grimar, rupprecht, MaskRay
Diffstat (limited to 'llvm/lib/Object/ArchiveWriter.cpp')
-rw-r--r--llvm/lib/Object/ArchiveWriter.cpp42
1 files changed, 23 insertions, 19 deletions
diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp
index ca8ffa7..08f1b85 100644
--- a/llvm/lib/Object/ArchiveWriter.cpp
+++ b/llvm/lib/Object/ArchiveWriter.cpp
@@ -359,22 +359,21 @@ getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject) {
// reference to it, thus SymbolicFile should be destroyed first.
LLVMContext Context;
std::unique_ptr<object::SymbolicFile> Obj;
- if (identify_magic(Buf.getBuffer()) == file_magic::bitcode) {
+
+ const file_magic Type = identify_magic(Buf.getBuffer());
+ // Treat unsupported file types as having no symbols.
+ if (!object::SymbolicFile::isSymbolicFile(Type, &Context))
+ return Ret;
+ if (Type == file_magic::bitcode) {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
Buf, file_magic::bitcode, &Context);
- if (!ObjOrErr) {
- // FIXME: check only for "not an object file" errors.
- consumeError(ObjOrErr.takeError());
- return Ret;
- }
+ if (!ObjOrErr)
+ return ObjOrErr.takeError();
Obj = std::move(*ObjOrErr);
} else {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(Buf);
- if (!ObjOrErr) {
- // FIXME: check only for "not an object file" errors.
- consumeError(ObjOrErr.takeError());
- return Ret;
- }
+ if (!ObjOrErr)
+ return ObjOrErr.takeError();
Obj = std::move(*ObjOrErr);
}
@@ -393,7 +392,7 @@ getSymbols(MemoryBufferRef Buf, raw_ostream &SymNames, bool &HasObject) {
static Expected<std::vector<MemberData>>
computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
object::Archive::Kind Kind, bool Thin, bool Deterministic,
- ArrayRef<NewArchiveMember> NewMembers) {
+ bool NeedSymbols, ArrayRef<NewArchiveMember> NewMembers) {
static char PaddingData[8] = {'\n', '\n', '\n', '\n', '\n', '\n', '\n', '\n'};
// This ignores the symbol table, but we only need the value mod 8 and the
@@ -494,13 +493,17 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
ModTime, Size);
Out.flush();
- Expected<std::vector<unsigned>> Symbols =
- getSymbols(Buf, SymNames, HasObject);
- if (auto E = Symbols.takeError())
- return std::move(E);
+ std::vector<unsigned> Symbols;
+ if (NeedSymbols) {
+ Expected<std::vector<unsigned>> SymbolsOrErr =
+ getSymbols(Buf, SymNames, HasObject);
+ if (auto E = SymbolsOrErr.takeError())
+ return std::move(E);
+ Symbols = std::move(*SymbolsOrErr);
+ }
Pos += Header.size() + Data.size() + Padding.size();
- Ret.push_back({std::move(*Symbols), std::move(Header), Data, Padding});
+ Ret.push_back({std::move(Symbols), std::move(Header), Data, Padding});
}
// If there are no symbols, emit an empty symbol table, to satisfy Solaris
// tools, older versions of which expect a symbol table in a non-empty
@@ -564,8 +567,9 @@ static Error writeArchiveToStream(raw_ostream &Out,
SmallString<0> StringTableBuf;
raw_svector_ostream StringTable(StringTableBuf);
- Expected<std::vector<MemberData>> DataOrErr = computeMemberData(
- StringTable, SymNames, Kind, Thin, Deterministic, NewMembers);
+ Expected<std::vector<MemberData>> DataOrErr =
+ computeMemberData(StringTable, SymNames, Kind, Thin, Deterministic,
+ WriteSymtab, NewMembers);
if (Error E = DataOrErr.takeError())
return E;
std::vector<MemberData> &Data = *DataOrErr;