diff --git a/llvm/test/tools/llvm-dwp/Inputs/compressfail/a.dwo b/llvm/test/tools/llvm-dwp/Inputs/compressfail/a.dwo new file mode 100644 index 000000000000..0201f07d8daf Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/compressfail/a.dwo differ diff --git a/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.dwo b/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.dwo new file mode 100644 index 000000000000..63459442e08d Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.dwo differ diff --git a/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.o b/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.o new file mode 100644 index 000000000000..f12bb0985792 Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/compressfail/compress.o differ diff --git a/llvm/test/tools/llvm-dwp/Inputs/invalid_cu_index/x.dwp b/llvm/test/tools/llvm-dwp/Inputs/invalid_cu_index/x.dwp new file mode 100644 index 000000000000..1a1e94936bc8 Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/invalid_cu_index/x.dwp differ diff --git a/llvm/test/tools/llvm-dwp/Inputs/missing_tu_index/x.dwp b/llvm/test/tools/llvm-dwp/Inputs/missing_tu_index/x.dwp new file mode 100644 index 000000000000..f5d09f0f5e77 Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/missing_tu_index/x.dwp differ diff --git a/llvm/test/tools/llvm-dwp/X86/compressfail.test b/llvm/test/tools/llvm-dwp/X86/compressfail.test new file mode 100644 index 000000000000..d9f50cb434ff --- /dev/null +++ b/llvm/test/tools/llvm-dwp/X86/compressfail.test @@ -0,0 +1,5 @@ +RUN: not llvm-dwp %p/../Inputs/compressfail/a.dwo -o %t 2>&1 | FileCheck %s + +REQUIRES: zlib + +CHECK: error: failure while decompressing compressed section: 'zdebug_info.dwo' diff --git a/llvm/test/tools/llvm-dwp/X86/nocompress.test b/llvm/test/tools/llvm-dwp/X86/nocompress.test new file mode 100644 index 000000000000..1de9444dd3eb --- /dev/null +++ b/llvm/test/tools/llvm-dwp/X86/nocompress.test @@ -0,0 +1,5 @@ +RUN: not llvm-dwp %p/../Inputs/compress/a.dwo -o %t 2>&1 | FileCheck %s + +REQUIRES: nozlib + +CHECK: error: zlib not available diff --git a/llvm/tools/llvm-dwp/CMakeLists.txt b/llvm/tools/llvm-dwp/CMakeLists.txt index b29c00d49c3d..740ab5ca9040 100644 --- a/llvm/tools/llvm-dwp/CMakeLists.txt +++ b/llvm/tools/llvm-dwp/CMakeLists.txt @@ -10,4 +10,5 @@ set(LLVM_LINK_COMPONENTS add_llvm_tool(llvm-dwp llvm-dwp.cpp + DWPError.cpp ) diff --git a/llvm/tools/llvm-dwp/DWPError.cpp b/llvm/tools/llvm-dwp/DWPError.cpp new file mode 100644 index 000000000000..21d53ed6d198 --- /dev/null +++ b/llvm/tools/llvm-dwp/DWPError.cpp @@ -0,0 +1,3 @@ +#include "DWPError.h" +using namespace llvm; +char DWPError::ID; diff --git a/llvm/tools/llvm-dwp/DWPError.h b/llvm/tools/llvm-dwp/DWPError.h new file mode 100644 index 000000000000..e0dd4edc8a87 --- /dev/null +++ b/llvm/tools/llvm-dwp/DWPError.h @@ -0,0 +1,17 @@ +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" +#include +namespace llvm { +class DWPError : public ErrorInfo { +public: + DWPError(std::string Info) : Info(std::move(Info)) {} + void log(raw_ostream &OS) const override { OS << Info; } + std::error_code convertToErrorCode() const override { + llvm_unreachable("Not implemented"); + } + static char ID; + +private: + std::string Info; +}; +} diff --git a/llvm/tools/llvm-dwp/llvm-dwp.cpp b/llvm/tools/llvm-dwp/llvm-dwp.cpp index 78545677df37..f25c87c241a8 100644 --- a/llvm/tools/llvm-dwp/llvm-dwp.cpp +++ b/llvm/tools/llvm-dwp/llvm-dwp.cpp @@ -35,10 +35,11 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Error.h" #include "llvm/Target/TargetMachine.h" +#include "DWPError.h" #include #include -#include using namespace llvm; using namespace llvm::object; @@ -59,7 +60,7 @@ static int error(const Twine &Error, const Twine &Context) { return 1; } -static std::error_code +static Error writeStringsAndOffsets(MCStreamer &Out, StringMap &Strings, uint32_t &StringOffset, MCSection *StrSection, MCSection *StrOffsetSection, StringRef CurStrSection, @@ -67,7 +68,7 @@ writeStringsAndOffsets(MCStreamer &Out, StringMap &Strings, // Could possibly produce an error or warning if one of these was non-null but // the other was null. if (CurStrSection.empty() || CurStrOffsetSection.empty()) - return std::error_code(); + return Error(); DenseMap OffsetRemapping; @@ -99,7 +100,7 @@ writeStringsAndOffsets(MCStreamer &Out, StringMap &Strings, Out.EmitIntValue(NewOffset, 4); } - return std::error_code(); + return Error(); } static uint32_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) { @@ -364,7 +365,7 @@ void printDuplicateError(const std::pair &PrevE, } errs() << '\n'; } -static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { +static Error write(MCStreamer &Out, ArrayRef Inputs) { const auto &MCOFI = *Out.getContext().getObjectFileInfo(); MCSection *const StrSection = MCOFI.getDwarfStrDWOSection(); MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection(); @@ -393,7 +394,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { for (const auto &Input : Inputs) { auto ErrOrObj = object::ObjectFile::createObjectFile(Input); if (!ErrOrObj) - return errorToErrorCode(ErrOrObj.takeError()); + return ErrOrObj.takeError(); UnitIndexEntry CurEntry = {}; @@ -415,19 +416,22 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { StringRef Name; if (std::error_code Err = Section.getName(Name)) - return Err; + return errorCodeToError(Err); Name = Name.substr(Name.find_first_not_of("._")); StringRef Contents; if (auto Err = Section.getContents(Contents)) - return Err; + return errorCodeToError(Err); if (Name.startswith("zdebug_")) { uint64_t OriginalSize; - if (!zlib::isAvailable() || - !consumeCompressedDebugSectionHeader(Contents, OriginalSize)) - return make_error_code(std::errc::invalid_argument); + if (!zlib::isAvailable()) + return make_error("zlib not available"); + if (!consumeCompressedDebugSectionHeader(Contents, OriginalSize)) + return make_error( + ("failure while decompressing compressed section: '" + Name + + "\'").str()); UncompressedSections.resize(UncompressedSections.size() + 1); if (zlib::uncompress(Contents, UncompressedSections.back(), OriginalSize) != zlib::StatusOK) { @@ -487,7 +491,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { DataExtractor CUIndexData(CurCUIndexSection, ErrOrObj->getBinary()->isLittleEndian(), 0); if (!CUIndex.parse(CUIndexData)) - return make_error_code(std::errc::invalid_argument); + return make_error("Failed to parse cu_index"); for (const DWARFUnitIndex::Entry &E : CUIndex.getRows()) { auto *I = E.getOffsets(); @@ -502,7 +506,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { CurStrSection); if (!P.second) { printDuplicateError(*P.first, ID, Input); - return make_error_code(std::errc::invalid_argument); + return make_error("Duplicate DWO ID"); } auto &NewEntry = P.first->second; NewEntry.Name = ID.Name; @@ -518,13 +522,11 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { if (!CurTypesSection.empty()) { assert(CurTypesSection.size() == 1); - if (CurTUIndexSection.empty()) - return make_error_code(std::errc::invalid_argument); DWARFUnitIndex TUIndex(DW_SECT_TYPES); DataExtractor TUIndexData(CurTUIndexSection, ErrOrObj->getBinary()->isLittleEndian(), 0); if (!TUIndex.parse(TUIndexData)) - return make_error_code(std::errc::invalid_argument); + return make_error("Failed to parse tu_index"); addAllTypesFromDWP(Out, TypeIndexEntries, TUIndex, TypesSection, CurTypesSection.front(), CurEntry, ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]); @@ -535,7 +537,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { auto P = IndexEntries.insert(std::make_pair(ID.Signature, CurEntry)); if (!P.second) { printDuplicateError(*P.first, ID, ""); - return make_error_code(std::errc::invalid_argument); + return make_error("Duplicate DWO ID"); } P.first->second.Name = ID.Name; P.first->second.DWOName = ID.DWOName; @@ -563,7 +565,7 @@ static std::error_code write(MCStreamer &Out, ArrayRef Inputs) { writeIndex(Out, MCOFI.getDwarfCUIndexSection(), ContributionOffsets, IndexEntries); - return std::error_code(); + return Error(); } int main(int argc, char **argv) { @@ -631,8 +633,10 @@ int main(int argc, char **argv) { if (!MS) return error("no object streamer for target " + TripleName, Context); - if (auto Err = write(*MS, InputFiles)) - return error(Err.message(), "Writing DWP file"); + if (auto Err = write(*MS, InputFiles)) { + logAllUnhandledErrors(std::move(Err), errs(), "error: "); + return 1; + } MS->Finish(); }