From f04f184d9c4d7c079d67488f714f02e3fa16bd93 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 17 Feb 2016 16:21:49 +0000 Subject: [PATCH] Add a unwrapOrError utility and use it to simplify ELFDumper.cpp. Utility extracted from r260488. llvm-svn: 261103 --- llvm/tools/llvm-readobj/ELFDumper.cpp | 190 ++++++++++++--------------------- llvm/tools/llvm-readobj/llvm-readobj.h | 6 ++ 2 files changed, 77 insertions(+), 119 deletions(-) diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 407f971..86b6ab6 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -146,14 +146,10 @@ private: Elf_Rela_Range dyn_relas() const; StringRef getDynamicString(uint64_t Offset) const; const Elf_Dyn *dynamic_table_begin() const { - ErrorOr Ret = Obj->dynamic_table_begin(DynamicProgHeader); - error(Ret.getError()); - return *Ret; + return unwrapOrError(Obj->dynamic_table_begin(DynamicProgHeader)); } const Elf_Dyn *dynamic_table_end() const { - ErrorOr Ret = Obj->dynamic_table_end(DynamicProgHeader); - error(Ret.getError()); - return *Ret; + return unwrapOrError(Obj->dynamic_table_end(DynamicProgHeader)); } StringRef getSymbolVersion(StringRef StrTab, const Elf_Sym *symb, bool &IsDefault); @@ -203,9 +199,7 @@ private: public: Elf_Dyn_Range dynamic_table() const { - ErrorOr Ret = Obj->dynamic_table(DynamicProgHeader); - error(Ret.getError()); - return *Ret; + return unwrapOrError(Obj->dynamic_table(DynamicProgHeader)); } Elf_Sym_Range dynamic_symbols() const { @@ -254,14 +248,6 @@ private: StreamWriter &W; }; -template T errorOrDefault(ErrorOr Val, T Default = T()) { - if (!Val) { - error(Val.getError()); - return Default; - } - - return *Val; -} } // namespace namespace llvm { @@ -387,7 +373,7 @@ static void printVersionSymbolSection(ELFDumper *Dumper, DictScope SS(W, "Version symbols"); if (!Sec) return; - StringRef Name = errorOrDefault(Obj->getSectionName(Sec)); + StringRef Name = unwrapOrError(Obj->getSectionName(Sec)); W.printNumber("Section Name", Name, Sec->sh_name); W.printHex("Address", Sec->sh_addr); W.printHex("Offset", Sec->sh_offset); @@ -416,7 +402,7 @@ static void printVersionDefinitionSection(ELFDumper *Dumper, DictScope SD(W, "Version definition"); if (!Sec) return; - StringRef Name = errorOrDefault(Obj->getSectionName(Sec)); + StringRef Name = unwrapOrError(Obj->getSectionName(Sec)); W.printNumber("Section Name", Name, Sec->sh_name); W.printHex("Address", Sec->sh_addr); W.printHex("Offset", Sec->sh_offset); @@ -433,9 +419,8 @@ static void printVersionDefinitionSection(ELFDumper *Dumper, (const uint8_t *)Obj->base() + Sec->sh_offset; const uint8_t *SecEndAddress = SecStartAddress + Sec->sh_size; const uint8_t *P = SecStartAddress; - ErrorOr StrTabOrErr = - Obj->getSection(Sec->sh_link); - error(StrTabOrErr.getError()); + const typename ELFO::Elf_Shdr *StrTab = + unwrapOrError(Obj->getSection(Sec->sh_link)); ListScope Entries(W, "Entries"); for (unsigned i = 0; i < verdef_entries; ++i) { @@ -449,9 +434,9 @@ static void printVersionDefinitionSection(ELFDumper *Dumper, W.printNumber("Flags", VD->vd_flags); W.printNumber("Index", VD->vd_ndx); W.printNumber("Cnt", VD->vd_cnt); - W.printString("Name", StringRef((const char *)(Obj->base() + - (*StrTabOrErr)->sh_offset + - VD->getAux()->vda_name))); + W.printString("Name", + StringRef((const char *)(Obj->base() + StrTab->sh_offset + + VD->getAux()->vda_name))); P += VD->vd_next; } } @@ -517,7 +502,7 @@ template std::string ELFDumper::getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic) { - StringRef SymbolName = errorOrDefault(Symbol->getName(StrTable)); + StringRef SymbolName = unwrapOrError(Symbol->getName(StrTable)); if (!IsDynamic) return SymbolName; @@ -553,9 +538,9 @@ getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, if (SectionIndex == SHN_XINDEX) SectionIndex = Obj.getExtendedSymbolTableIndex(Symbol, FirstSym, ShndxTable); - ErrorOr Sec = Obj.getSection(SectionIndex); - error(Sec.getError()); - SectionName = errorOrDefault(Obj.getSectionName(*Sec)); + const typename ELFO::Elf_Shdr *Sec = + unwrapOrError(Obj.getSection(SectionIndex)); + SectionName = unwrapOrError(Obj.getSectionName(Sec)); } } @@ -572,7 +557,7 @@ template static const typename ELFO::Elf_Shdr *findSectionByName(const ELFO &Obj, StringRef Name) { for (const auto &Shdr : Obj.sections()) { - if (Name == errorOrDefault(Obj.getSectionName(&Shdr))) + if (Name == unwrapOrError(Obj.getSectionName(&Shdr))) return &Shdr; } return nullptr; @@ -1027,9 +1012,7 @@ ELFDumper::ELFDumper(const ELFFile *Obj, StreamWriter &Writer) DynSymRegion = createDRIFrom(&Sec); break; case ELF::SHT_SYMTAB_SHNDX: { - ErrorOr> TableOrErr = Obj->getSHNDXTable(Sec); - error(TableOrErr.getError()); - ShndxTable = *TableOrErr; + ShndxTable = unwrapOrError(Obj->getSHNDXTable(Sec)); break; } case ELF::SHT_GNU_versym: @@ -1164,7 +1147,7 @@ void ELFDumper::printSections() { for (const Elf_Shdr &Sec : Obj->sections()) { ++SectionIndex; - StringRef Name = errorOrDefault(Obj->getSectionName(&Sec)); + StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); DictScope SectionD(W, "Section"); W.printNumber("Index", SectionIndex); @@ -1213,22 +1196,18 @@ void ELFDumper::printSections() { if (opts::SectionSymbols) { ListScope D(W, "Symbols"); const Elf_Shdr *Symtab = DotSymtabSec; - ErrorOr StrTableOrErr = Obj->getStringTableForSymtab(*Symtab); - error(StrTableOrErr.getError()); - StringRef StrTable = *StrTableOrErr; + StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab)); for (const Elf_Sym &Sym : Obj->symbols(Symtab)) { - ErrorOr SymSec = - Obj->getSection(&Sym, Symtab, ShndxTable); - if (!SymSec) - continue; - if (*SymSec == &Sec) + const Elf_Shdr *SymSec = + unwrapOrError(Obj->getSection(&Sym, Symtab, ShndxTable)); + if (SymSec == &Sec) printSymbol(&Sym, Obj->symbol_begin(Symtab), StrTable, false); } } if (opts::SectionData && Sec.sh_type != ELF::SHT_NOBITS) { - ArrayRef Data = errorOrDefault(Obj->getSectionContents(&Sec)); + ArrayRef Data = unwrapOrError(Obj->getSectionContents(&Sec)); W.printBinaryBlock("SectionData", StringRef((const char *)Data.data(), Data.size())); } @@ -1246,7 +1225,7 @@ void ELFDumper::printRelocations() { if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA) continue; - StringRef Name = errorOrDefault(Obj->getSectionName(&Sec)); + StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; W.indent(); @@ -1291,9 +1270,7 @@ template void ELFDumper::printDynamicRelocations() { template void ELFDumper::printRelocations(const Elf_Shdr *Sec) { - ErrorOr SymTabOrErr = Obj->getSection(Sec->sh_link); - error(SymTabOrErr.getError()); - const Elf_Shdr *SymTab = *SymTabOrErr; + const Elf_Shdr *SymTab = unwrapOrError(Obj->getSection(Sec->sh_link)); switch (Sec->sh_type) { case ELF::SHT_REL: @@ -1319,15 +1296,12 @@ void ELFDumper::printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab) { StringRef TargetName; const Elf_Sym *Sym = Obj->getRelocationSymbol(&Rel, SymTab); if (Sym && Sym->getType() == ELF::STT_SECTION) { - ErrorOr Sec = Obj->getSection(Sym, SymTab, ShndxTable); - error(Sec.getError()); - ErrorOr SecName = Obj->getSectionName(*Sec); - if (SecName) - TargetName = SecName.get(); + const Elf_Shdr *Sec = + unwrapOrError(Obj->getSection(Sym, SymTab, ShndxTable)); + TargetName = unwrapOrError(Obj->getSectionName(Sec)); } else if (Sym) { - ErrorOr StrTableOrErr = Obj->getStringTableForSymtab(*SymTab); - error(StrTableOrErr.getError()); - TargetName = errorOrDefault(Sym->getName(*StrTableOrErr)); + StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTab)); + TargetName = unwrapOrError(Sym->getName(StrTable)); } if (opts::ExpandRelocs) { @@ -1352,7 +1326,7 @@ void ELFDumper::printDynamicRelocation(Elf_Rela Rel) { StringRef SymbolName; uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL()); const Elf_Sym *Sym = dynamic_symbols().begin() + SymIndex; - SymbolName = errorOrDefault(Sym->getName(DynamicStringTable)); + SymbolName = unwrapOrError(Sym->getName(DynamicStringTable)); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); W.printHex("Offset", Rel.r_offset); @@ -1378,10 +1352,7 @@ void ELFDumper::printSymbolsHelper(bool IsDynamic) { } else { if (!DotSymtabSec) return; - ErrorOr StrTableOrErr = - Obj->getStringTableForSymtab(*DotSymtabSec); - error(StrTableOrErr.getError()); - StrTable = *StrTableOrErr; + StrTable = unwrapOrError(Obj->getStringTableForSymtab(*DotSymtabSec)); Syms = Obj->symbols(DotSymtabSec); } for (const Elf_Sym &Sym : Syms) @@ -1808,21 +1779,18 @@ template <> void ELFDumper>::printAttributes() { if (Sec.sh_type != ELF::SHT_ARM_ATTRIBUTES) continue; - ErrorOr> Contents = Obj->getSectionContents(&Sec); - if (!Contents) - continue; - - if ((*Contents)[0] != ARMBuildAttrs::Format_Version) { - errs() << "unrecognised FormatVersion: 0x" << utohexstr((*Contents)[0]) + ArrayRef Contents = unwrapOrError(Obj->getSectionContents(&Sec)); + if (Contents[0] != ARMBuildAttrs::Format_Version) { + errs() << "unrecognised FormatVersion: 0x" << utohexstr(Contents[0]) << '\n'; continue; } - W.printHex("FormatVersion", (*Contents)[0]); - if (Contents->size() == 1) + W.printHex("FormatVersion", Contents[0]); + if (Contents.size() == 1) continue; - ARMAttributeParser(W).Parse(*Contents); + ARMAttributeParser(W).Parse(Contents); } } } @@ -1932,13 +1900,13 @@ template void MipsGOTParser::parseGOT() { report_fatal_error("There is no not empty GOT section at 0x" + Twine::utohexstr(*DtPltGot)); - ErrorOr> GOT = Obj->getSectionContents(GOTShdr); + ArrayRef GOT = unwrapOrError(Obj->getSectionContents(GOTShdr)); - if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(*GOT)) + if (*DtLocalGotNum + GlobalGotNum > getGOTTotal(GOT)) report_fatal_error("Number of GOT entries exceeds the size of GOT section"); - const GOTEntry *GotBegin = makeGOTIter(*GOT, 0); - const GOTEntry *GotLocalEnd = makeGOTIter(*GOT, *DtLocalGotNum); + const GOTEntry *GotBegin = makeGOTIter(GOT, 0); + const GOTEntry *GotLocalEnd = makeGOTIter(GOT, *DtLocalGotNum); const GOTEntry *It = GotBegin; DictScope GS(W, "Primary GOT"); @@ -1970,7 +1938,7 @@ template void MipsGOTParser::parseGOT() { ListScope GS(W, "Global entries"); const GOTEntry *GotGlobalEnd = - makeGOTIter(*GOT, *DtLocalGotNum + GlobalGotNum); + makeGOTIter(GOT, *DtLocalGotNum + GlobalGotNum); const Elf_Sym *GotDynSym = DynSymBegin + *DtGotSym; for (; It != GotGlobalEnd; ++It) { DictScope D(W, "Entry"); @@ -1979,7 +1947,7 @@ template void MipsGOTParser::parseGOT() { } } - std::size_t SpecGotNum = getGOTTotal(*GOT) - *DtLocalGotNum - GlobalGotNum; + std::size_t SpecGotNum = getGOTTotal(GOT) - *DtLocalGotNum - GlobalGotNum; W.printNumber("Number of TLS and multi-GOT entries", uint64_t(SpecGotNum)); } @@ -1997,21 +1965,18 @@ template void MipsGOTParser::parsePLT() { if (!PLTShdr) report_fatal_error("There is no not empty PLTGOT section at 0x " + Twine::utohexstr(*DtMipsPltGot)); - ErrorOr> PLT = Obj->getSectionContents(PLTShdr); + ArrayRef PLT = unwrapOrError(Obj->getSectionContents(PLTShdr)); const Elf_Shdr *PLTRelShdr = findNotEmptySectionByAddress(Obj, *DtJmpRel); if (!PLTRelShdr) report_fatal_error("There is no not empty RELPLT section at 0x" + Twine::utohexstr(*DtJmpRel)); - ErrorOr SymTableOrErr = - Obj->getSection(PLTRelShdr->sh_link); - error(SymTableOrErr.getError()); - const Elf_Shdr *SymTable = *SymTableOrErr; - ErrorOr StrTable = Obj->getStringTableForSymtab(*SymTable); - error(StrTable.getError()); - - const GOTEntry *PLTBegin = makeGOTIter(*PLT, 0); - const GOTEntry *PLTEnd = makeGOTIter(*PLT, getGOTTotal(*PLT)); + const Elf_Shdr *SymTable = + unwrapOrError(Obj->getSection(PLTRelShdr->sh_link)); + StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*SymTable)); + + const GOTEntry *PLTBegin = makeGOTIter(PLT, 0); + const GOTEntry *PLTEnd = makeGOTIter(PLT, getGOTTotal(PLT)); const GOTEntry *It = PLTBegin; DictScope GS(W, "PLT GOT"); @@ -2030,7 +1995,7 @@ template void MipsGOTParser::parsePLT() { *RE = Obj->rel_end(PLTRelShdr); RI != RE && It != PLTEnd; ++RI, ++It) { const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable); - printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, *StrTable, Sym); + printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym); } break; case ELF::SHT_RELA: @@ -2038,7 +2003,7 @@ template void MipsGOTParser::parsePLT() { *RE = Obj->rela_end(PLTRelShdr); RI != RE && It != PLTEnd; ++RI, ++It) { const Elf_Sym *Sym = Obj->getRelocationSymbol(&*RI, SymTable); - printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, *StrTable, Sym); + printPLTEntry(PLTShdr->sh_addr, PLTBegin, It, StrTable, Sym); } break; } @@ -2208,17 +2173,13 @@ template void ELFDumper::printMipsABIFlags() { W.startLine() << "There is no .MIPS.abiflags section in the file.\n"; return; } - ErrorOr> Sec = Obj->getSectionContents(Shdr); - if (!Sec) { - W.startLine() << "The .MIPS.abiflags section is empty.\n"; - return; - } - if (Sec->size() != sizeof(Elf_Mips_ABIFlags)) { + ArrayRef Sec = unwrapOrError(Obj->getSectionContents(Shdr)); + if (Sec.size() != sizeof(Elf_Mips_ABIFlags)) { W.startLine() << "The .MIPS.abiflags section has a wrong size.\n"; return; } - auto *Flags = reinterpret_cast *>(Sec->data()); + auto *Flags = reinterpret_cast *>(Sec.data()); raw_ostream &OS = W.getOStream(); DictScope GS(W, "MIPS ABI Flags"); @@ -2246,17 +2207,13 @@ template void ELFDumper::printMipsReginfo() { W.startLine() << "There is no .reginfo section in the file.\n"; return; } - ErrorOr> Sec = Obj->getSectionContents(Shdr); - if (!Sec) { - W.startLine() << "The .reginfo section is empty.\n"; - return; - } - if (Sec->size() != sizeof(Elf_Mips_RegInfo)) { + ArrayRef Sec = unwrapOrError(Obj->getSectionContents(Shdr)); + if (Sec.size() != sizeof(Elf_Mips_RegInfo)) { W.startLine() << "The .reginfo section has a wrong size.\n"; return; } - auto *Reginfo = reinterpret_cast *>(Sec->data()); + auto *Reginfo = reinterpret_cast *>(Sec.data()); DictScope GS(W, "MIPS RegInfo"); W.printHex("GP", Reginfo->ri_gp_value); @@ -2270,8 +2227,8 @@ template void ELFDumper::printMipsReginfo() { template void ELFDumper::printStackMap() const { const Elf_Shdr *StackMapSection = nullptr; for (const auto &Sec : Obj->sections()) { - ErrorOr Name = Obj->getSectionName(&Sec); - if (*Name == ".llvm_stackmaps") { + StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); + if (Name == ".llvm_stackmaps") { StackMapSection = &Sec; break; } @@ -2281,12 +2238,11 @@ template void ELFDumper::printStackMap() const { return; StringRef StackMapContents; - ErrorOr> StackMapContentsArray = - Obj->getSectionContents(StackMapSection); + ArrayRef StackMapContentsArray = + unwrapOrError(Obj->getSectionContents(StackMapSection)); - prettyPrintStackMap( - llvm::outs(), - StackMapV1Parser(*StackMapContentsArray)); + prettyPrintStackMap(llvm::outs(), StackMapV1Parser( + StackMapContentsArray)); } template void ELFDumper::printGroupSections() { @@ -2296,17 +2252,13 @@ template void ELFDumper::printGroupSections() { for (const Elf_Shdr &Sec : Obj->sections()) { if (Sec.sh_type == ELF::SHT_GROUP) { HasGroups = true; - ErrorOr Symtab = - errorOrDefault(Obj->getSection(Sec.sh_link)); - ErrorOr StrTableOrErr = Obj->getStringTableForSymtab(**Symtab); - error(StrTableOrErr.getError()); - StringRef StrTable = *StrTableOrErr; - const Elf_Sym *Sym = - Obj->template getEntry(*Symtab, Sec.sh_info); - auto Data = errorOrDefault( + const Elf_Shdr *Symtab = unwrapOrError(Obj->getSection(Sec.sh_link)); + StringRef StrTable = unwrapOrError(Obj->getStringTableForSymtab(*Symtab)); + const Elf_Sym *Sym = Obj->template getEntry(Symtab, Sec.sh_info); + auto Data = unwrapOrError( Obj->template getSectionContentsAsArray(&Sec)); DictScope D(W, "Group"); - StringRef Name = errorOrDefault(Obj->getSectionName(&Sec)); + StringRef Name = unwrapOrError(Obj->getSectionName(&Sec)); W.printNumber("Name", Name, Sec.sh_name); W.printNumber("Index", SectionIndex); W.printHex("Type", getGroupType(Data[0]), Data[0]); @@ -2315,8 +2267,8 @@ template void ELFDumper::printGroupSections() { ListScope L(W, "Section(s) in group"); size_t Member = 1; while (Member < Data.size()) { - auto Sec = errorOrDefault(Obj->getSection(Data[Member])); - const StringRef Name = errorOrDefault(Obj->getSectionName(Sec)); + auto Sec = unwrapOrError(Obj->getSection(Data[Member])); + const StringRef Name = unwrapOrError(Obj->getSectionName(Sec)); W.startLine() << Name << " (" << Data[Member++] << ")\n"; } } diff --git a/llvm/tools/llvm-readobj/llvm-readobj.h b/llvm/tools/llvm-readobj/llvm-readobj.h index 39af478..3eb21e4 100644 --- a/llvm/tools/llvm-readobj/llvm-readobj.h +++ b/llvm/tools/llvm-readobj/llvm-readobj.h @@ -12,6 +12,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorOr.h" #include namespace llvm { @@ -22,6 +23,11 @@ namespace llvm { // Various helper functions. LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg); void error(std::error_code ec); + template T unwrapOrError(ErrorOr EO) { + if (EO) + return *EO; + reportError(EO.getError().message()); + } bool relocAddressLess(object::RelocationRef A, object::RelocationRef B); } // namespace llvm -- 2.7.4