llvm-dwp: Use llvm::Error to improve diagnostic quality/error handling in llvm-dwp

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269339 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2016-05-12 19:59:54 +00:00
parent edf855dc9d
commit 13dad4bbfc
11 changed files with 55 additions and 20 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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'

View File

@ -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

View File

@ -10,4 +10,5 @@ set(LLVM_LINK_COMPONENTS
add_llvm_tool(llvm-dwp
llvm-dwp.cpp
DWPError.cpp
)

View File

@ -0,0 +1,3 @@
#include "DWPError.h"
using namespace llvm;
char DWPError::ID;

17
tools/llvm-dwp/DWPError.h Normal file
View File

@ -0,0 +1,17 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include <string>
namespace llvm {
class DWPError : public ErrorInfo<DWPError> {
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;
};
}

View File

@ -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 <iostream>
#include <memory>
#include <system_error>
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<uint32_t> &Strings,
uint32_t &StringOffset, MCSection *StrSection,
MCSection *StrOffsetSection, StringRef CurStrSection,
@ -67,7 +68,7 @@ writeStringsAndOffsets(MCStreamer &Out, StringMap<uint32_t> &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<uint32_t, uint32_t> OffsetRemapping;
@ -99,7 +100,7 @@ writeStringsAndOffsets(MCStreamer &Out, StringMap<uint32_t> &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<uint64_t, UnitIndexEntry> &PrevE,
}
errs() << '\n';
}
static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
static Error write(MCStreamer &Out, ArrayRef<std::string> 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<std::string> 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<std::string> 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<DWPError>("zlib not available");
if (!consumeCompressedDebugSectionHeader(Contents, OriginalSize))
return make_error<DWPError>(
("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<std::string> Inputs) {
DataExtractor CUIndexData(CurCUIndexSection,
ErrOrObj->getBinary()->isLittleEndian(), 0);
if (!CUIndex.parse(CUIndexData))
return make_error_code(std::errc::invalid_argument);
return make_error<DWPError>("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<std::string> Inputs) {
CurStrSection);
if (!P.second) {
printDuplicateError(*P.first, ID, Input);
return make_error_code(std::errc::invalid_argument);
return make_error<DWPError>("Duplicate DWO ID");
}
auto &NewEntry = P.first->second;
NewEntry.Name = ID.Name;
@ -518,13 +522,11 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> 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<DWPError>("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<std::string> 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<DWPError>("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<std::string> 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();
}