diff --git a/lld/test/ELF/invalid/data-encoding.test b/lld/test/ELF/invalid/data-encoding.test --- a/lld/test/ELF/invalid/data-encoding.test +++ b/lld/test/ELF/invalid/data-encoding.test @@ -4,7 +4,7 @@ # Check we report this. # RUN: yaml2obj %s -o %t.o -# RUN: llvm-ar rcs %t.a %t.o +# RUN: llvm-ar rcS %t.a %t.o # RUN: not ld.lld --whole-archive %t.a -o /dev/null 2>&1 | FileCheck %s # CHECK: {{.*}}.a({{.*}}.o): corrupted ELF file: invalid data encoding diff --git a/lld/test/ELF/invalid/invalid-file-class.test b/lld/test/ELF/invalid/invalid-file-class.test --- a/lld/test/ELF/invalid/invalid-file-class.test +++ b/lld/test/ELF/invalid/invalid-file-class.test @@ -11,7 +11,7 @@ ## EV_CURRENT(1), ELFOSABI_LINUX(3), , ET_REL(1), EM_NONE(0) # RUN: echo -e -n "\x7f\x45\x4c\x46\x00\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00" > %t/invalid.o -# RUN: llvm-ar --format=gnu cr %t/invalid-class.a %t/invalid.o +# RUN: llvm-ar --format=gnu crS %t/invalid-class.a %t/invalid.o # RUN: not ld.lld -whole-archive %t/invalid-class.a -o /dev/null 2>&1 | FileCheck %s # CHECK: invalid-class.a(invalid.o): corrupted ELF file: invalid file class diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -362,17 +362,20 @@ if (identify_magic(Buf.getBuffer()) == 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()); + if (Error Err = + handleErrors(ObjOrErr.takeError(), [](const ECError &E) -> Error { + std::error_code EC = E.convertToErrorCode(); + if (EC != object::object_error::invalid_file_type) + return errorCodeToError(EC); + return Error::success(); + })) + return std::move(Err); return Ret; } Obj = std::move(*ObjOrErr); @@ -393,7 +396,7 @@ static Expected> computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames, object::Archive::Kind Kind, bool Thin, bool Deterministic, - ArrayRef NewMembers) { + bool NeedSymbols, ArrayRef 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 +497,17 @@ ModTime, Size); Out.flush(); - Expected> Symbols = - getSymbols(Buf, SymNames, HasObject); - if (auto E = Symbols.takeError()) - return std::move(E); + std::vector Symbols; + if (NeedSymbols) { + Expected> 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 +571,9 @@ SmallString<0> StringTableBuf; raw_svector_ostream StringTable(StringTableBuf); - Expected> DataOrErr = computeMemberData( - StringTable, SymNames, Kind, Thin, Deterministic, NewMembers); + Expected> DataOrErr = + computeMemberData(StringTable, SymNames, Kind, Thin, Deterministic, + WriteSymtab, NewMembers); if (Error E = DataOrErr.takeError()) return E; std::vector &Data = *DataOrErr; diff --git a/llvm/test/Object/archive-malformed-object.test b/llvm/test/Object/archive-malformed-object.test new file mode 100644 --- /dev/null +++ b/llvm/test/Object/archive-malformed-object.test @@ -0,0 +1,38 @@ +## Show that the archive library emits error messages when adding malformed +## objects. + +# RUN: rm -rf %t.dir +# RUN: split-file %s %t.dir +# RUN: cd %t.dir + +## Malformed bitcode object. +# RUN: llvm-as input.ll -o input.bc +# RUN: %python -c "with open('input.bc', 'a') as f: f.truncate(10)" +# RUN: not llvm-ar rc bad.a input.bc 2>&1 | FileCheck %s --check-prefix=ERR1 + +# ERR1: error: bad.a: Invalid bitcode signature + +## Non-bitcode malformed file. +# RUN: yaml2obj input.yaml -o input.o +# RUN: not llvm-ar rc bad.a input.o 2>&1 | FileCheck %s --check-prefix=ERR2 + +# ERR2: error: bad.a: section header table goes past the end of the file: e_shoff = 0x9999 + +## Don't emit an error if the symbol table is not required. +# RUN: llvm-ar rcS good.a input.o input.bc +# RUN: llvm-ar t good.a | FileCheck %s --check-prefix=CONTENTS + +# CONTENTS: input.o +# CONTENTS-NEXT: input.bc + +#--- input.ll +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux" + +#--- input.yaml +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + EShOff: 0x9999 diff --git a/llvm/test/Object/archive-unknown-filetype.test b/llvm/test/Object/archive-unknown-filetype.test new file mode 100644 --- /dev/null +++ b/llvm/test/Object/archive-unknown-filetype.test @@ -0,0 +1,11 @@ +## Show that the archive library ignores does not emit an error or add any +## symbols to the archive symbol table, when it encounters an unknown file type, +## but still adds it to the archive. + +# RUN: touch %t +# RUN: rm -f %t.a +# RUN: llvm-ar rc %t.a %t +# RUN: llvm-ar t %t.a | FileCheck %s --check-prefix=CONTENTS -DFILE=%basename_t +# RUN: llvm-nm --print-armap %t.a | FileCheck %s --allow-empty --implicit-check-not={{.}} + +# CONTENTS: [[FILE]]