[ELF] Convert ELF.h to Expected<T>.

This has two advantages:
1) We slowly move away from ErrorOr to the new handling interface,
in the hope of having an uniform error handling in LLVM, eventually.
2) We're starting to have *meaningful* error messages for invalid
object ELF files, rather than a generic "parse error". At some point
we should include also the offset to improve the quality of the
diagnostic.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@287081 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Davide Italiano 2016-11-16 05:10:28 +00:00
parent 68e337a67b
commit 63830bcae9
8 changed files with 316 additions and 271 deletions

View File

@ -33,6 +33,10 @@ getElfArchType(StringRef Object) {
(uint8_t)Object[ELF::EI_DATA]); (uint8_t)Object[ELF::EI_DATA]);
} }
static inline Error createError(StringRef Err) {
return make_error<StringError>(Err, object_error::parse_failed);
}
template <class ELFT> template <class ELFT>
class ELFFile { class ELFFile {
public: public:
@ -75,17 +79,17 @@ public:
} }
template <typename T> template <typename T>
ErrorOr<const T *> getEntry(uint32_t Section, uint32_t Entry) const; Expected<const T *> getEntry(uint32_t Section, uint32_t Entry) const;
template <typename T> template <typename T>
ErrorOr<const T *> getEntry(const Elf_Shdr *Section, uint32_t Entry) const; Expected<const T *> getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const; Expected<StringRef> getStringTable(const Elf_Shdr *Section) const;
ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const; Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section, Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
Elf_Shdr_Range Sections) const; Elf_Shdr_Range Sections) const;
ErrorOr<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const; Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
ErrorOr<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section, Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
Elf_Shdr_Range Sections) const; Elf_Shdr_Range Sections) const;
void VerifyStrTab(const Elf_Shdr *sh) const; void VerifyStrTab(const Elf_Shdr *sh) const;
@ -95,7 +99,7 @@ public:
SmallVectorImpl<char> &Result) const; SmallVectorImpl<char> &Result) const;
/// \brief Get the symbol for a given relocation. /// \brief Get the symbol for a given relocation.
ErrorOr<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel, Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
const Elf_Shdr *SymTab) const; const Elf_Shdr *SymTab) const;
ELFFile(StringRef Object); ELFFile(StringRef Object);
@ -110,50 +114,51 @@ public:
getHeader()->getDataEncoding() == ELF::ELFDATA2LSB; getHeader()->getDataEncoding() == ELF::ELFDATA2LSB;
} }
ErrorOr<Elf_Shdr_Range> sections() const; Expected<Elf_Shdr_Range> sections() const;
ErrorOr<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const { Expected<Elf_Sym_Range> symbols(const Elf_Shdr *Sec) const {
if (!Sec) if (!Sec)
return makeArrayRef<Elf_Sym>(nullptr, nullptr); return makeArrayRef<Elf_Sym>(nullptr, nullptr);
return getSectionContentsAsArray<Elf_Sym>(Sec); return getSectionContentsAsArray<Elf_Sym>(Sec);
} }
ErrorOr<Elf_Rela_Range> relas(const Elf_Shdr *Sec) const { Expected<Elf_Rela_Range> relas(const Elf_Shdr *Sec) const {
return getSectionContentsAsArray<Elf_Rela>(Sec); return getSectionContentsAsArray<Elf_Rela>(Sec);
} }
ErrorOr<Elf_Rel_Range> rels(const Elf_Shdr *Sec) const { Expected<Elf_Rel_Range> rels(const Elf_Shdr *Sec) const {
return getSectionContentsAsArray<Elf_Rel>(Sec); return getSectionContentsAsArray<Elf_Rel>(Sec);
} }
/// \brief Iterate over program header table. /// \brief Iterate over program header table.
ErrorOr<Elf_Phdr_Range> program_headers() const { Expected<Elf_Phdr_Range> program_headers() const {
if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr)) if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
return object_error::parse_failed; return createError("invalid e_phentsize");
auto *Begin = auto *Begin =
reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff); reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
return makeArrayRef(Begin, Begin + getHeader()->e_phnum); return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
} }
ErrorOr<StringRef> getSectionStringTable(Elf_Shdr_Range Sections) const; Expected<StringRef> getSectionStringTable(Elf_Shdr_Range Sections) const;
ErrorOr<uint32_t> getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, Expected<uint32_t> getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
ArrayRef<Elf_Word> ShndxTable) const; ArrayRef<Elf_Word> ShndxTable) const;
ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym, Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
const Elf_Shdr *SymTab, const Elf_Shdr *SymTab,
ArrayRef<Elf_Word> ShndxTable) const; ArrayRef<Elf_Word> ShndxTable) const;
ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym, Elf_Sym_Range Symtab, Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
Elf_Sym_Range Symtab,
ArrayRef<Elf_Word> ShndxTable) const; ArrayRef<Elf_Word> ShndxTable) const;
ErrorOr<const Elf_Shdr *> getSection(uint32_t Index) const; Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
ErrorOr<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec, Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
uint32_t Index) const; uint32_t Index) const;
ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const; Expected<StringRef> getSectionName(const Elf_Shdr *Section) const;
ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section, Expected<StringRef> getSectionName(const Elf_Shdr *Section,
StringRef DotShstrtab) const; StringRef DotShstrtab) const;
template <typename T> template <typename T>
ErrorOr<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const; Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const;
ErrorOr<ArrayRef<uint8_t> > getSectionContents(const Elf_Shdr *Sec) const; Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
}; };
typedef ELFFile<ELFType<support::little, false>> ELF32LEFile; typedef ELFFile<ELFType<support::little, false>> ELF32LEFile;
@ -162,36 +167,37 @@ typedef ELFFile<ELFType<support::big, false>> ELF32BEFile;
typedef ELFFile<ELFType<support::big, true>> ELF64BEFile; typedef ELFFile<ELFType<support::big, true>> ELF64BEFile;
template <class ELFT> template <class ELFT>
inline ErrorOr<const typename ELFT::Shdr *> inline Expected<const typename ELFT::Shdr *>
getSection(typename ELFT::ShdrRange Sections, uint32_t Index) { getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
if (Index >= Sections.size()) if (Index >= Sections.size())
return object_error::invalid_section_index; return createError("invalid section index");
return &Sections[Index]; return &Sections[Index];
} }
template <class ELFT> template <class ELFT>
inline ErrorOr<uint32_t> inline Expected<uint32_t>
getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym, getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym,
const typename ELFT::Sym *FirstSym, const typename ELFT::Sym *FirstSym,
ArrayRef<typename ELFT::Word> ShndxTable) { ArrayRef<typename ELFT::Word> ShndxTable) {
assert(Sym->st_shndx == ELF::SHN_XINDEX); assert(Sym->st_shndx == ELF::SHN_XINDEX);
unsigned Index = Sym - FirstSym; unsigned Index = Sym - FirstSym;
if (Index >= ShndxTable.size()) if (Index >= ShndxTable.size())
return object_error::parse_failed; return createError("index past the end of the symbol table");
// The size of the table was checked in getSHNDXTable. // The size of the table was checked in getSHNDXTable.
return ShndxTable[Index]; return ShndxTable[Index];
} }
template <class ELFT> template <class ELFT>
ErrorOr<uint32_t> Expected<uint32_t>
ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
ArrayRef<Elf_Word> ShndxTable) const { ArrayRef<Elf_Word> ShndxTable) const {
uint32_t Index = Sym->st_shndx; uint32_t Index = Sym->st_shndx;
if (Index == ELF::SHN_XINDEX) { if (Index == ELF::SHN_XINDEX) {
auto ErrorOrIndex = object::getExtendedSymbolTableIndex<ELFT>( auto ErrorOrIndex = object::getExtendedSymbolTableIndex<ELFT>(
Sym, Syms.begin(), ShndxTable); Sym, Syms.begin(), ShndxTable);
if (std::error_code EC = ErrorOrIndex.getError()) if (!ErrorOrIndex)
return EC; return ErrorOrIndex.takeError();
return *ErrorOrIndex; return *ErrorOrIndex;
} }
if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE) if (Index == ELF::SHN_UNDEF || Index >= ELF::SHN_LORESERVE)
@ -200,70 +206,70 @@ ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
} }
template <class ELFT> template <class ELFT>
ErrorOr<const typename ELFT::Shdr *> Expected<const typename ELFT::Shdr *>
ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab, ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
ArrayRef<Elf_Word> ShndxTable) const { ArrayRef<Elf_Word> ShndxTable) const {
auto SymsOrErr = symbols(SymTab); auto SymsOrErr = symbols(SymTab);
if (std::error_code EC = SymsOrErr.getError()) if (!SymsOrErr)
return EC; return SymsOrErr.takeError();
return getSection(Sym, *SymsOrErr, ShndxTable); return getSection(Sym, *SymsOrErr, ShndxTable);
} }
template <class ELFT> template <class ELFT>
ErrorOr<const typename ELFT::Shdr *> Expected<const typename ELFT::Shdr *>
ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols, ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
ArrayRef<Elf_Word> ShndxTable) const { ArrayRef<Elf_Word> ShndxTable) const {
ErrorOr<uint32_t> IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable); auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
if (std::error_code EC = IndexOrErr.getError()) if (!IndexOrErr)
return EC; return IndexOrErr.takeError();
uint32_t Index = *IndexOrErr; uint32_t Index = *IndexOrErr;
if (Index == 0) if (Index == 0)
return nullptr; return nullptr;
auto SectionsOrErr = sections(); auto SectionsOrErr = sections();
if (std::error_code EC = SectionsOrErr.getError()) if (!SectionsOrErr)
return EC; return SectionsOrErr.takeError();
return object::getSection<ELFT>(*SectionsOrErr, Index); return object::getSection<ELFT>(*SectionsOrErr, Index);
} }
template <class ELFT> template <class ELFT>
inline ErrorOr<const typename ELFT::Sym *> inline Expected<const typename ELFT::Sym *>
getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) { getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
if (Index >= Symbols.size()) if (Index >= Symbols.size())
return object_error::invalid_symbol_index; return createError("invalid symbol index");
return &Symbols[Index]; return &Symbols[Index];
} }
template <class ELFT> template <class ELFT>
ErrorOr<const typename ELFT::Sym *> Expected<const typename ELFT::Sym *>
ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const { ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
auto SymtabOrErr = symbols(Sec); auto SymtabOrErr = symbols(Sec);
if (std::error_code EC = SymtabOrErr.getError()) if (!SymtabOrErr)
return EC; return SymtabOrErr.takeError();
return object::getSymbol<ELFT>(*SymtabOrErr, Index); return object::getSymbol<ELFT>(*SymtabOrErr, Index);
} }
template <class ELFT> template <class ELFT>
template <typename T> template <typename T>
ErrorOr<ArrayRef<T>> Expected<ArrayRef<T>>
ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const { ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const {
if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1) if (Sec->sh_entsize != sizeof(T) && sizeof(T) != 1)
return object_error::parse_failed; return createError("invalid sh_entsize");
uintX_t Offset = Sec->sh_offset; uintX_t Offset = Sec->sh_offset;
uintX_t Size = Sec->sh_size; uintX_t Size = Sec->sh_size;
if (Size % sizeof(T)) if (Size % sizeof(T))
return object_error::parse_failed; return createError("size is not a multiple of sh_entsize");
if ((std::numeric_limits<uintX_t>::max() - Offset < Size) || if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
Offset + Size > Buf.size()) Offset + Size > Buf.size())
return object_error::parse_failed; return createError("invalid section offset");
const T *Start = reinterpret_cast<const T *>(base() + Offset); const T *Start = reinterpret_cast<const T *>(base() + Offset);
return makeArrayRef(Start, Size / sizeof(T)); return makeArrayRef(Start, Size / sizeof(T));
} }
template <class ELFT> template <class ELFT>
ErrorOr<ArrayRef<uint8_t>> Expected<ArrayRef<uint8_t>>
ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const { ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
return getSectionContentsAsArray<uint8_t>(Sec); return getSectionContentsAsArray<uint8_t>(Sec);
} }
@ -305,7 +311,7 @@ void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
} }
template <class ELFT> template <class ELFT>
ErrorOr<const typename ELFT::Sym *> Expected<const typename ELFT::Sym *>
ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel, ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
const Elf_Shdr *SymTab) const { const Elf_Shdr *SymTab) const {
uint32_t Index = Rel->getSymbol(isMips64EL()); uint32_t Index = Rel->getSymbol(isMips64EL());
@ -315,7 +321,7 @@ ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> Expected<StringRef>
ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const { ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
uint32_t Index = getHeader()->e_shstrndx; uint32_t Index = getHeader()->e_shstrndx;
if (Index == ELF::SHN_XINDEX) if (Index == ELF::SHN_XINDEX)
@ -324,7 +330,7 @@ ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
if (!Index) // no section string table. if (!Index) // no section string table.
return ""; return "";
if (Index >= Sections.size()) if (Index >= Sections.size())
return object_error::parse_failed; return createError("invalid section index");
return getStringTable(&Sections[Index]); return getStringTable(&Sections[Index]);
} }
@ -339,24 +345,23 @@ static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
} }
template <class ELFT> template <class ELFT>
ErrorOr<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const { Expected<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
const uintX_t SectionTableOffset = getHeader()->e_shoff; const uintX_t SectionTableOffset = getHeader()->e_shoff;
if (SectionTableOffset == 0) if (SectionTableOffset == 0)
return ArrayRef<Elf_Shdr>(); return ArrayRef<Elf_Shdr>();
// Invalid section header entry size (e_shentsize) in ELF header
if (getHeader()->e_shentsize != sizeof(Elf_Shdr)) if (getHeader()->e_shentsize != sizeof(Elf_Shdr))
return object_error::parse_failed; return createError(
"invalid section header entry size (e_shentsize) in ELF header");
const uint64_t FileSize = Buf.size(); const uint64_t FileSize = Buf.size();
// Section header table goes past end of file!
if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize)
return object_error::parse_failed; return createError("section header table goes past the end of the file");
// Invalid address alignment of section headers // Invalid address alignment of section headers
if (SectionTableOffset & (alignof(Elf_Shdr) - 1)) if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
return object_error::parse_failed; return createError("invalid alignment of section headers");
const Elf_Shdr *First = const Elf_Shdr *First =
reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
@ -365,140 +370,138 @@ ErrorOr<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
if (NumSections == 0) if (NumSections == 0)
NumSections = First->sh_size; NumSections = First->sh_size;
// Section table goes past end of file!
if (NumSections > UINT64_MAX / sizeof(Elf_Shdr)) if (NumSections > UINT64_MAX / sizeof(Elf_Shdr))
return object_error::parse_failed; return createError("section table goes past the end of file");
const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr); const uint64_t SectionTableSize = NumSections * sizeof(Elf_Shdr);
// Section table goes past end of file! // Section table goes past end of file!
if (SectionTableOffset + SectionTableSize > FileSize) if (SectionTableOffset + SectionTableSize > FileSize)
return object_error::parse_failed; return createError("section table goes past the end of file");
return makeArrayRef(First, NumSections); return makeArrayRef(First, NumSections);
} }
template <class ELFT> template <class ELFT>
template <typename T> template <typename T>
ErrorOr<const T *> ELFFile<ELFT>::getEntry(uint32_t Section, Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
uint32_t Entry) const { uint32_t Entry) const {
ErrorOr<const Elf_Shdr *> Sec = getSection(Section); auto SecOrErr = getSection(Section);
if (std::error_code EC = Sec.getError()) if (!SecOrErr)
return EC; return SecOrErr.takeError();
return getEntry<T>(*Sec, Entry); return getEntry<T>(*SecOrErr, Entry);
} }
template <class ELFT> template <class ELFT>
template <typename T> template <typename T>
ErrorOr<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section, Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
uint32_t Entry) const { uint32_t Entry) const {
if (sizeof(T) != Section->sh_entsize) if (sizeof(T) != Section->sh_entsize)
return object_error::parse_failed; return createError("invalid sh_entsize");
size_t Pos = Section->sh_offset + Entry * sizeof(T); size_t Pos = Section->sh_offset + Entry * sizeof(T);
if (Pos + sizeof(T) > Buf.size()) if (Pos + sizeof(T) > Buf.size())
return object_error::parse_failed; return createError("invalid section offset");
return reinterpret_cast<const T *>(base() + Pos); return reinterpret_cast<const T *>(base() + Pos);
} }
template <class ELFT> template <class ELFT>
ErrorOr<const typename ELFT::Shdr *> Expected<const typename ELFT::Shdr *>
ELFFile<ELFT>::getSection(uint32_t Index) const { ELFFile<ELFT>::getSection(uint32_t Index) const {
auto TableOrErr = sections(); auto TableOrErr = sections();
if (std::error_code EC = TableOrErr.getError()) if (!TableOrErr)
return EC; return TableOrErr.takeError();
return object::getSection<ELFT>(*TableOrErr, Index); return object::getSection<ELFT>(*TableOrErr, Index);
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> Expected<StringRef>
ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const { ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
if (Section->sh_type != ELF::SHT_STRTAB) if (Section->sh_type != ELF::SHT_STRTAB)
return object_error::parse_failed; return createError("invalid sh_type for string table, expected SHT_STRTAB");
auto V = getSectionContentsAsArray<char>(Section); auto V = getSectionContentsAsArray<char>(Section);
if (std::error_code EC = V.getError()) if (!V)
return EC; return V.takeError();
ArrayRef<char> Data = *V; ArrayRef<char> Data = *V;
if (Data.empty()) if (Data.empty())
return object_error::parse_failed; return createError("empty string table");
if (Data.back() != '\0') if (Data.back() != '\0')
return object_error::string_table_non_null_end; return createError("string table non-null terminated");
return StringRef(Data.begin(), Data.size()); return StringRef(Data.begin(), Data.size());
} }
template <class ELFT> template <class ELFT>
ErrorOr<ArrayRef<typename ELFT::Word>> Expected<ArrayRef<typename ELFT::Word>>
ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const { ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
auto SectionsOrErr = sections(); auto SectionsOrErr = sections();
if (std::error_code EC = SectionsOrErr.getError()) if (!SectionsOrErr)
return EC; return SectionsOrErr.takeError();
return getSHNDXTable(Section, *SectionsOrErr); return getSHNDXTable(Section, *SectionsOrErr);
} }
template <class ELFT> template <class ELFT>
ErrorOr<ArrayRef<typename ELFT::Word>> Expected<ArrayRef<typename ELFT::Word>>
ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section, ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
Elf_Shdr_Range Sections) const { Elf_Shdr_Range Sections) const {
assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX); assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section); auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
if (std::error_code EC = VOrErr.getError()) if (!VOrErr)
return EC; return VOrErr.takeError();
ArrayRef<Elf_Word> V = *VOrErr; ArrayRef<Elf_Word> V = *VOrErr;
ErrorOr<const Elf_Shdr *> SymTableOrErr = auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
object::getSection<ELFT>(Sections, Section.sh_link); if (!SymTableOrErr)
if (std::error_code EC = SymTableOrErr.getError()) return SymTableOrErr.takeError();
return EC;
const Elf_Shdr &SymTable = **SymTableOrErr; const Elf_Shdr &SymTable = **SymTableOrErr;
if (SymTable.sh_type != ELF::SHT_SYMTAB && if (SymTable.sh_type != ELF::SHT_SYMTAB &&
SymTable.sh_type != ELF::SHT_DYNSYM) SymTable.sh_type != ELF::SHT_DYNSYM)
return object_error::parse_failed; return createError("invalid sh_type");
if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym))) if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
return object_error::parse_failed; return createError("invalid section contents size");
return V; return V;
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> Expected<StringRef>
ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const { ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
auto SectionsOrErr = sections(); auto SectionsOrErr = sections();
if (std::error_code EC = SectionsOrErr.getError()) if (!SectionsOrErr)
return EC; return SectionsOrErr.takeError();
return getStringTableForSymtab(Sec, *SectionsOrErr); return getStringTableForSymtab(Sec, *SectionsOrErr);
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> Expected<StringRef>
ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec, ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
Elf_Shdr_Range Sections) const { Elf_Shdr_Range Sections) const {
if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM) if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
return object_error::parse_failed; return createError(
ErrorOr<const Elf_Shdr *> SectionOrErr = "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
object::getSection<ELFT>(Sections, Sec.sh_link); auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
if (std::error_code EC = SectionOrErr.getError()) if (!SectionOrErr)
return EC; return SectionOrErr.takeError();
return getStringTable(*SectionOrErr); return getStringTable(*SectionOrErr);
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> Expected<StringRef>
ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const { ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
auto SectionsOrErr = sections(); auto SectionsOrErr = sections();
if (std::error_code EC = SectionsOrErr.getError()) if (!SectionsOrErr)
return EC; return SectionsOrErr.takeError();
ErrorOr<StringRef> Table = getSectionStringTable(*SectionsOrErr); auto Table = getSectionStringTable(*SectionsOrErr);
if (std::error_code EC = Table.getError()) if (!Table)
return EC; return Table.takeError();
return getSectionName(Section, *Table); return getSectionName(Section, *Table);
} }
template <class ELFT> template <class ELFT>
ErrorOr<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section, Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section,
StringRef DotShstrtab) const { StringRef DotShstrtab) const {
uint32_t Offset = Section->sh_name; uint32_t Offset = Section->sh_name;
if (Offset == 0) if (Offset == 0)
return StringRef(); return StringRef();
if (Offset >= DotShstrtab.size()) if (Offset >= DotShstrtab.size())
return object_error::parse_failed; return createError("invalid string offset");
return StringRef(DotShstrtab.data() + Offset); return StringRef(DotShstrtab.data() + Offset);
} }

View File

@ -255,7 +255,10 @@ protected:
/// \brief Get the relocation section that contains \a Rel. /// \brief Get the relocation section that contains \a Rel.
const Elf_Shdr *getRelSection(DataRefImpl Rel) const { const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
return *EF.getSection(Rel.d.a); auto RelSecOrErr = EF.getSection(Rel.d.a);
if (!RelSecOrErr)
report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
return *RelSecOrErr;
} }
DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const { DataRefImpl toDRI(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
@ -268,7 +271,13 @@ protected:
assert(SymTable->sh_type == ELF::SHT_SYMTAB || assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
SymTable->sh_type == ELF::SHT_DYNSYM); SymTable->sh_type == ELF::SHT_DYNSYM);
uintptr_t SHT = reinterpret_cast<uintptr_t>((*EF.sections()).begin()); auto SectionsOrErr = EF.sections();
if (!SectionsOrErr) {
DRI.d.a = 0;
DRI.d.b = 0;
return DRI;
}
uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
unsigned SymTableIndex = unsigned SymTableIndex =
(reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr); (reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
@ -318,8 +327,8 @@ public:
const Elf_Sym *getSymbol(DataRefImpl Sym) const { const Elf_Sym *getSymbol(DataRefImpl Sym) const {
auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b); auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
if (std::error_code EC = Ret.getError()) if (!Ret)
report_fatal_error(EC.message()); report_fatal_error(errorToErrorCode(Ret.takeError()).message());
return *Ret; return *Ret;
} }
@ -373,10 +382,18 @@ void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
template <class ELFT> template <class ELFT>
Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const { Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
const Elf_Sym *ESym = getSymbol(Sym); const Elf_Sym *ESym = getSymbol(Sym);
const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a); auto SymTabOrErr = EF.getSection(Sym.d.a);
const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link); if (!SymTabOrErr)
StringRef SymTable = *EF.getStringTable(StringTableSec); return SymTabOrErr.takeError();
return ESym->getName(SymTable); const Elf_Shdr *SymTableSec = *SymTabOrErr;
auto StrTabOrErr = EF.getSection(SymTableSec->sh_link);
if (!StrTabOrErr)
return StrTabOrErr.takeError();
const Elf_Shdr *StringTableSec = *StrTabOrErr;
auto SymStrTabOrErr = EF.getStringTable(StringTableSec);
if (!SymStrTabOrErr)
return SymStrTabOrErr.takeError();
return ESym->getName(*SymStrTabOrErr);
} }
template <class ELFT> template <class ELFT>
@ -423,13 +440,15 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
} }
const Elf_Ehdr *Header = EF.getHeader(); const Elf_Ehdr *Header = EF.getHeader();
const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a); auto SymTabOrErr = EF.getSection(Symb.d.a);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
const Elf_Shdr *SymTab = *SymTabOrErr;
if (Header->e_type == ELF::ET_REL) { if (Header->e_type == ELF::ET_REL) {
ErrorOr<const Elf_Shdr *> SectionOrErr = auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable);
EF.getSection(ESym, SymTab, ShndxTable); if (!SectionOrErr)
if (std::error_code EC = SectionOrErr.getError()) return SectionOrErr.takeError();
return errorCodeToError(EC);
const Elf_Shdr *Section = *SectionOrErr; const Elf_Shdr *Section = *SectionOrErr;
if (Section) if (Section)
Result += Section->sh_addr; Result += Section->sh_addr;
@ -509,9 +528,14 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
if (ESym->st_shndx == ELF::SHN_ABS) if (ESym->st_shndx == ELF::SHN_ABS)
Result |= SymbolRef::SF_Absolute; Result |= SymbolRef::SF_Absolute;
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
ESym == (*EF.symbols(DotSymtabSec)).begin() || Result |= SymbolRef::SF_FormatSpecific;
ESym == (*EF.symbols(DotDynSymSec)).begin())
auto DotSymtabSecSyms = EF.symbols(DotSymtabSec);
if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin())
Result |= SymbolRef::SF_FormatSpecific;
auto DotDynSymSecSyms = EF.symbols(DotDynSymSec);
if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin())
Result |= SymbolRef::SF_FormatSpecific; Result |= SymbolRef::SF_FormatSpecific;
if (EF.getHeader()->e_machine == ELF::EM_ARM) { if (EF.getHeader()->e_machine == ELF::EM_ARM) {
@ -547,9 +571,9 @@ template <class ELFT>
Expected<section_iterator> Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym, ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
const Elf_Shdr *SymTab) const { const Elf_Shdr *SymTab) const {
ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable); auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
if (std::error_code EC = ESecOrErr.getError()) if (!ESecOrErr)
return errorCodeToError(EC); return ESecOrErr.takeError();
const Elf_Shdr *ESec = *ESecOrErr; const Elf_Shdr *ESec = *ESecOrErr;
if (!ESec) if (!ESec)
@ -564,7 +588,10 @@ template <class ELFT>
Expected<section_iterator> Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const { ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
const Elf_Sym *Sym = getSymbol(Symb); const Elf_Sym *Sym = getSymbol(Symb);
const Elf_Shdr *SymTab = *EF.getSection(Symb.d.a); auto SymTabOrErr = EF.getSection(Symb.d.a);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
const Elf_Shdr *SymTab = *SymTabOrErr;
return getSymbolSection(Sym, SymTab); return getSymbolSection(Sym, SymTab);
} }
@ -577,9 +604,9 @@ void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
template <class ELFT> template <class ELFT>
std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
StringRef &Result) const { StringRef &Result) const {
ErrorOr<StringRef> Name = EF.getSectionName(&*getSection(Sec)); auto Name = EF.getSectionName(&*getSection(Sec));
if (!Name) if (!Name)
return Name.getError(); return errorToErrorCode(Name.takeError());
Result = *Name; Result = *Name;
return std::error_code(); return std::error_code();
} }
@ -641,7 +668,10 @@ template <class ELFT>
relocation_iterator relocation_iterator
ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const { ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
DataRefImpl RelData; DataRefImpl RelData;
uintptr_t SHT = reinterpret_cast<uintptr_t>((*EF.sections()).begin()); auto SectionsOrErr = EF.sections();
if (!SectionsOrErr)
return relocation_iterator(RelocationRef());
uintptr_t SHT = reinterpret_cast<uintptr_t>((*SectionsOrErr).begin());
RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize; RelData.d.a = (Sec.p - SHT) / EF.getHeader()->e_shentsize;
RelData.d.b = 0; RelData.d.b = 0;
return relocation_iterator(RelocationRef(RelData, this)); return relocation_iterator(RelocationRef(RelData, this));
@ -658,9 +688,9 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
const Elf_Shdr *RelSec = getRelSection(RelData); const Elf_Shdr *RelSec = getRelSection(RelData);
// Error check sh_link here so that getRelocationSymbol can just use it. // Error check sh_link here so that getRelocationSymbol can just use it.
ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link); auto SymSecOrErr = EF.getSection(RelSec->sh_link);
if (std::error_code EC = SymSecOrErr.getError()) if (!SymSecOrErr)
report_fatal_error(EC.message()); report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
RelData.d.b += S->sh_size / S->sh_entsize; RelData.d.b += S->sh_size / S->sh_entsize;
return relocation_iterator(RelocationRef(RelData, this)); return relocation_iterator(RelocationRef(RelData, this));
@ -677,9 +707,9 @@ ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
return section_end(); return section_end();
ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info); auto R = EF.getSection(EShdr->sh_info);
if (std::error_code EC = R.getError()) if (!R)
report_fatal_error(EC.message()); report_fatal_error(errorToErrorCode(R.takeError()).message());
return section_iterator(SectionRef(toDRI(*R), this)); return section_iterator(SectionRef(toDRI(*R), this));
} }
@ -753,8 +783,8 @@ const typename ELFObjectFile<ELFT>::Elf_Rel *
ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const { ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
assert(getRelSection(Rel)->sh_type == ELF::SHT_REL); assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b); auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
if (std::error_code EC = Ret.getError()) if (!Ret)
report_fatal_error(EC.message()); report_fatal_error(errorToErrorCode(Ret.takeError()).message());
return *Ret; return *Ret;
} }
@ -763,8 +793,8 @@ const typename ELFObjectFile<ELFT>::Elf_Rela *
ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const { ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA); assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b); auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
if (std::error_code EC = Ret.getError()) if (!Ret)
report_fatal_error(EC.message()); report_fatal_error(errorToErrorCode(Ret.takeError()).message());
return *Ret; return *Ret;
} }
@ -775,8 +805,10 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
Object), Object),
EF(Data.getBuffer()) { EF(Data.getBuffer()) {
auto SectionsOrErr = EF.sections(); auto SectionsOrErr = EF.sections();
if ((EC = SectionsOrErr.getError())) if (!SectionsOrErr) {
EC = errorToErrorCode(SectionsOrErr.takeError());
return; return;
}
for (const Elf_Shdr &Sec : *SectionsOrErr) { for (const Elf_Shdr &Sec : *SectionsOrErr) {
switch (Sec.sh_type) { switch (Sec.sh_type) {
case ELF::SHT_DYNSYM: { case ELF::SHT_DYNSYM: {
@ -798,9 +830,11 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
break; break;
} }
case ELF::SHT_SYMTAB_SHNDX: { case ELF::SHT_SYMTAB_SHNDX: {
ErrorOr<ArrayRef<Elf_Word>> TableOrErr = EF.getSHNDXTable(Sec); auto TableOrErr = EF.getSHNDXTable(Sec);
if ((EC = TableOrErr.getError())) if (!TableOrErr) {
EC = errorToErrorCode(TableOrErr.takeError());
return; return;
}
ShndxTable = *TableOrErr; ShndxTable = *TableOrErr;
break; break;
} }
@ -838,12 +872,18 @@ elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
template <class ELFT> template <class ELFT>
section_iterator ELFObjectFile<ELFT>::section_begin() const { section_iterator ELFObjectFile<ELFT>::section_begin() const {
return section_iterator(SectionRef(toDRI((*EF.sections()).begin()), this)); auto SectionsOrErr = EF.sections();
if (!SectionsOrErr)
return section_iterator(SectionRef());
return section_iterator(SectionRef(toDRI((*SectionsOrErr).begin()), this));
} }
template <class ELFT> template <class ELFT>
section_iterator ELFObjectFile<ELFT>::section_end() const { section_iterator ELFObjectFile<ELFT>::section_end() const {
return section_iterator(SectionRef(toDRI((*EF.sections()).end()), this)); auto SectionsOrErr = EF.sections();
if (!SectionsOrErr)
return section_iterator(SectionRef());
return section_iterator(SectionRef(toDRI((*SectionsOrErr).end()), this));
} }
template <class ELFT> template <class ELFT>

View File

@ -2,21 +2,21 @@
RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -sections \ RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -sections \
RUN: 2>&1 | FileCheck --check-prefix=SECNAME %s RUN: 2>&1 | FileCheck --check-prefix=SECNAME %s
SECNAME: Error reading file: Invalid data was encountered while parsing the file. SECNAME: invalid string offset
// Section data offset past end of file. // Section data offset past end of file.
RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -sections -section-data \ RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -sections -section-data \
RUN: 2>&1 | FileCheck --check-prefix=SECDATA %s RUN: 2>&1 | FileCheck --check-prefix=SECDATA %s
SECDATA: Error reading file: Invalid data was encountered while parsing the file. SECDATA: invalid section offset
// Symbol name offset overflows string table. // Symbol name offset overflows string table.
RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -symbols \ RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -symbols \
RUN: 2>&1 | FileCheck --check-prefix=SYMNAME %s RUN: 2>&1 | FileCheck --check-prefix=SYMNAME %s
SYMNAME: Error reading file: Invalid data was encountered while parsing the file. SYMNAME: invalid string offset
// Version index in .gnu.version overflows the version map. // Version index in .gnu.version overflows the version map.
@ -36,7 +36,7 @@ RUN: not llvm-readobj -program-headers \
RUN: %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \ RUN: %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \
RUN: FileCheck --check-prefix=PHENTSIZE %s RUN: FileCheck --check-prefix=PHENTSIZE %s
PHENTSIZE: Invalid data was encountered while parsing the file. PHENTSIZE: invalid e_phentsize
RUN: not llvm-readobj -dynamic-table \ RUN: not llvm-readobj -dynamic-table \
RUN: %p/Inputs/corrupt-invalid-virtual-addr.elf.x86-64 2>&1 | \ RUN: %p/Inputs/corrupt-invalid-virtual-addr.elf.x86-64 2>&1 | \

View File

@ -5,7 +5,7 @@ RUN: not llvm-objdump -s %p/Inputs/invalid-strtab-zero-size.elf 2>&1 | FileCheck
CHECK: Invalid data was encountered while parsing the file CHECK: Invalid data was encountered while parsing the file
RUN: not llvm-objdump -s %p/Inputs/invalid-strtab-non-null.elf 2>&1 | FileCheck --check-prefix=NON-NULL %s RUN: not llvm-objdump -s %p/Inputs/invalid-strtab-non-null.elf 2>&1 | FileCheck --check-prefix=NON-NULL %s
NON-NULL: String table must end with a null terminator NON-NULL: Invalid data was encountered while parsing the file
Test the sh_entsize are invalid Test the sh_entsize are invalid
RUN: llvm-readobj -s %p/Inputs/invalid-sh_entsize.elf | FileCheck --check-prefix=SECTION %s RUN: llvm-readobj -s %p/Inputs/invalid-sh_entsize.elf | FileCheck --check-prefix=SECTION %s
@ -36,37 +36,37 @@ SECTION-NEXT: AddressAlignment:
SECTION-NEXT: EntrySize: 32 SECTION-NEXT: EntrySize: 32
RUN: not llvm-readobj -t %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-SYM-SIZE %s RUN: not llvm-readobj -t %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-SYM-SIZE %s
INVALID-SYM-SIZE: Invalid data was encountered while parsing the file INVALID-SYM-SIZE: invalid sh_entsize
RUN: not llvm-readobj --dyn-symbols %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-DYNSYM-SIZE %s RUN: not llvm-readobj --dyn-symbols %p/Inputs/invalid-sh_entsize.elf 2>&1 | FileCheck --check-prefix=INVALID-DYNSYM-SIZE %s
INVALID-DYNSYM-SIZE: Invalid entity size INVALID-DYNSYM-SIZE: Invalid entity size
RUN: not llvm-readobj -t %p/Inputs/invalid-section-index.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-INDEX %s RUN: not llvm-readobj -t %p/Inputs/invalid-section-index.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-INDEX %s
INVALID-SECTION-INDEX: Invalid section index INVALID-SECTION-INDEX: invalid section index
RUN: not llvm-readobj -s %p/Inputs/invalid-section-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-SIZE %s RUN: not llvm-readobj -s %p/Inputs/invalid-section-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-SIZE %s
INVALID-SECTION-SIZE: Invalid data was encountered while parsing the file INVALID-SECTION-SIZE: Invalid data was encountered while parsing the file
RUN: not llvm-readobj -t %p/Inputs/invalid-symbol-table-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SYMTAB-SIZE %s RUN: not llvm-readobj -t %p/Inputs/invalid-symbol-table-size.elf 2>&1 | FileCheck --check-prefix=INVALID-SYMTAB-SIZE %s
INVALID-SYMTAB-SIZE: Invalid data was encountered while parsing the file INVALID-SYMTAB-SIZE: size is not a multiple of sh_entsize
RUN: not llvm-readobj -t %p/Inputs/invalid-xindex-size.elf 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s RUN: not llvm-readobj -t %p/Inputs/invalid-xindex-size.elf 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s
INVALID-XINDEX-SIZE: Invalid data was encountered while parsing the file. INVALID-XINDEX-SIZE: Invalid data was encountered while parsing the file.
RUN: not llvm-readobj -t %p/Inputs/invalid-e_shnum.elf 2>&1 | FileCheck --check-prefix=INVALID-SH-NUM %s RUN: not llvm-readobj -t %p/Inputs/invalid-e_shnum.elf 2>&1 | FileCheck --check-prefix=INVALID-SH-NUM %s
INVALID-SH-NUM: Invalid data was encountered while parsing the file. INVALID-SH-NUM: invalid e_phentsize
RUN: not llvm-readobj -t %p/Inputs/invalid-ext-symtab-index.elf-x86-64 2>&1 | \ RUN: not llvm-readobj -t %p/Inputs/invalid-ext-symtab-index.elf-x86-64 2>&1 | \
RUN: FileCheck --check-prefix=INVALID-EXT-SYMTAB-INDEX %s RUN: FileCheck --check-prefix=INVALID-EXT-SYMTAB-INDEX %s
INVALID-EXT-SYMTAB-INDEX: Invalid data was encountered while parsing the file. INVALID-EXT-SYMTAB-INDEX: index past the end of the symbol table
RUN: not llvm-readobj -r %p/Inputs/invalid-relocation-sec-sh_offset.elf-i386 2>&1 | \ RUN: not llvm-readobj -r %p/Inputs/invalid-relocation-sec-sh_offset.elf-i386 2>&1 | \
RUN: FileCheck --check-prefix=INVALID-RELOC-SH-OFFSET %s RUN: FileCheck --check-prefix=INVALID-RELOC-SH-OFFSET %s
RUN: not llvm-readobj -r %p/Inputs/invalid-relocation-sec-sh_offset.elf-x86-64 2>&1 | \ RUN: not llvm-readobj -r %p/Inputs/invalid-relocation-sec-sh_offset.elf-x86-64 2>&1 | \
RUN: FileCheck --check-prefix=INVALID-RELOC-SH-OFFSET %s RUN: FileCheck --check-prefix=INVALID-RELOC-SH-OFFSET %s
INVALID-RELOC-SH-OFFSET: Invalid data was encountered while parsing the file INVALID-RELOC-SH-OFFSET: invalid section offset
RUN: not llvm-readobj -t %p/Inputs/invalid-sections-address-alignment.x86-64 2>&1 | \ RUN: not llvm-readobj -t %p/Inputs/invalid-sections-address-alignment.x86-64 2>&1 | \
RUN: FileCheck --check-prefix=INVALID-SEC-ADDRESS-ALIGNMENT %s RUN: FileCheck --check-prefix=INVALID-SEC-ADDRESS-ALIGNMENT %s
@ -74,10 +74,10 @@ INVALID-SEC-ADDRESS-ALIGNMENT: Invalid data was encountered while parsing the fi
RUN: not llvm-readobj -t %p/Inputs/invalid-section-size2.elf 2>&1 | \ RUN: not llvm-readobj -t %p/Inputs/invalid-section-size2.elf 2>&1 | \
RUN: FileCheck --check-prefix=INVALID-SECTION-SIZE2 %s RUN: FileCheck --check-prefix=INVALID-SECTION-SIZE2 %s
INVALID-SECTION-SIZE2: Invalid data was encountered while parsing the file. INVALID-SECTION-SIZE2: invalid section offset
RUN: not llvm-readobj -t %p/Inputs/invalid-sections-num.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-NUM %s RUN: not llvm-readobj -t %p/Inputs/invalid-sections-num.elf 2>&1 | FileCheck --check-prefix=INVALID-SECTION-NUM %s
INVALID-SECTION-NUM: Invalid data was encountered while parsing the file. INVALID-SECTION-NUM: Invalid data was encountered while parsing the file.
RUN: not llvm-readobj -r %p/Inputs/invalid-rel-sym.elf 2>&1 | FileCheck --check-prefix=INVALID-REL-SYM %s RUN: not llvm-readobj -r %p/Inputs/invalid-rel-sym.elf 2>&1 | FileCheck --check-prefix=INVALID-REL-SYM %s
INVALID-REL-SYM: Invalid data was encountered while parsing the file. INVALID-REL-SYM: invalid section offset

View File

@ -25,8 +25,9 @@ template <class ELFT> void printProgramHeaders(const ELFFile<ELFT> *o) {
typedef ELFFile<ELFT> ELFO; typedef ELFFile<ELFT> ELFO;
outs() << "Program Header:\n"; outs() << "Program Header:\n";
auto ProgramHeaderOrError = o->program_headers(); auto ProgramHeaderOrError = o->program_headers();
if (std::error_code EC = ProgramHeaderOrError.getError()) if (!ProgramHeaderOrError)
report_fatal_error(EC.message()); report_fatal_error(
errorToErrorCode(ProgramHeaderOrError.takeError()).message());
for (const typename ELFO::Elf_Phdr &Phdr : *ProgramHeaderOrError) { for (const typename ELFO::Elf_Phdr &Phdr : *ProgramHeaderOrError) {
switch (Phdr.p_type) { switch (Phdr.p_type) {
case ELF::PT_LOAD: case ELF::PT_LOAD:

View File

@ -608,22 +608,22 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
const ELFFile<ELFT> &EF = *Obj->getELFFile(); const ELFFile<ELFT> &EF = *Obj->getELFFile();
ErrorOr<const Elf_Shdr *> SecOrErr = EF.getSection(Rel.d.a); auto SecOrErr = EF.getSection(Rel.d.a);
if (std::error_code EC = SecOrErr.getError()) if (!SecOrErr)
return EC; return errorToErrorCode(SecOrErr.takeError());
const Elf_Shdr *Sec = *SecOrErr; const Elf_Shdr *Sec = *SecOrErr;
ErrorOr<const Elf_Shdr *> SymTabOrErr = EF.getSection(Sec->sh_link); auto SymTabOrErr = EF.getSection(Sec->sh_link);
if (std::error_code EC = SymTabOrErr.getError()) if (!SymTabOrErr)
return EC; return errorToErrorCode(SymTabOrErr.takeError());
const Elf_Shdr *SymTab = *SymTabOrErr; const Elf_Shdr *SymTab = *SymTabOrErr;
assert(SymTab->sh_type == ELF::SHT_SYMTAB || assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
SymTab->sh_type == ELF::SHT_DYNSYM); SymTab->sh_type == ELF::SHT_DYNSYM);
ErrorOr<const Elf_Shdr *> StrTabSec = EF.getSection(SymTab->sh_link); auto StrTabSec = EF.getSection(SymTab->sh_link);
if (std::error_code EC = StrTabSec.getError()) if (!StrTabSec)
return EC; return errorToErrorCode(StrTabSec.takeError());
ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(*StrTabSec); auto StrTabOrErr = EF.getStringTable(*StrTabSec);
if (std::error_code EC = StrTabOrErr.getError()) if (!StrTabOrErr)
return EC; return errorToErrorCode(StrTabOrErr.takeError());
StringRef StrTab = *StrTabOrErr; StringRef StrTab = *StrTabOrErr;
uint8_t type = RelRef.getType(); uint8_t type = RelRef.getType();
StringRef res; StringRef res;
@ -649,9 +649,9 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
if (!SymSI) if (!SymSI)
return errorToErrorCode(SymSI.takeError()); return errorToErrorCode(SymSI.takeError());
const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl()); const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
ErrorOr<StringRef> SecName = EF.getSectionName(SymSec); auto SecName = EF.getSectionName(SymSec);
if (std::error_code EC = SecName.getError()) if (!SecName)
return EC; return errorToErrorCode(SecName.takeError());
Target = *SecName; Target = *SecName;
} else { } else {
Expected<StringRef> SymName = symb->getName(StrTab); Expected<StringRef> SymName = symb->getName(StrTab);

View File

@ -349,8 +349,9 @@ template <typename ET>
ErrorOr<StringRef> ErrorOr<StringRef>
PrinterContext<ET>::FunctionAtAddress(unsigned Section, PrinterContext<ET>::FunctionAtAddress(unsigned Section,
uint64_t Address) const { uint64_t Address) const {
ErrorOr<StringRef> StrTableOrErr = ELF->getStringTableForSymtab(*Symtab); auto StrTableOrErr = ELF->getStringTableForSymtab(*Symtab);
error(StrTableOrErr.getError()); if (!StrTableOrErr)
error(StrTableOrErr.takeError());
StringRef StrTable = *StrTableOrErr; StringRef StrTable = *StrTableOrErr;
for (const Elf_Sym &Sym : unwrapOrError(ELF->symbols(Symtab))) for (const Elf_Sym &Sym : unwrapOrError(ELF->symbols(Symtab)))
@ -383,8 +384,9 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex) if (Sec.sh_type != ELF::SHT_REL || Sec.sh_info != IndexSectionIndex)
continue; continue;
ErrorOr<const Elf_Shdr *> SymTabOrErr = ELF->getSection(Sec.sh_link); auto SymTabOrErr = ELF->getSection(Sec.sh_link);
error(SymTabOrErr.getError()); if (!SymTabOrErr)
error(SymTabOrErr.takeError());
const Elf_Shdr *SymTab = *SymTabOrErr; const Elf_Shdr *SymTab = *SymTabOrErr;
for (const Elf_Rel &R : unwrapOrError(ELF->rels(&Sec))) { for (const Elf_Rel &R : unwrapOrError(ELF->rels(&Sec))) {
@ -399,10 +401,9 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
const Elf_Sym *Symbol = const Elf_Sym *Symbol =
unwrapOrError(ELF->getRelocationSymbol(&RelA, SymTab)); unwrapOrError(ELF->getRelocationSymbol(&RelA, SymTab));
ErrorOr<const Elf_Shdr *> Ret = auto Ret = ELF->getSection(Symbol, SymTab, ShndxTable);
ELF->getSection(Symbol, SymTab, ShndxTable); if (!Ret)
if (std::error_code EC = Ret.getError()) report_fatal_error(errorToErrorCode(Ret.takeError()).message());
report_fatal_error(EC.message());
return *Ret; return *Ret;
} }
} }
@ -413,7 +414,7 @@ template <typename ET>
void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr *IT, void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr *IT,
const Elf_Shdr *EHT, const Elf_Shdr *EHT,
uint64_t TableEntryOffset) const { uint64_t TableEntryOffset) const {
ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(EHT); Expected<ArrayRef<uint8_t>> Contents = ELF->getSectionContents(EHT);
if (!Contents) if (!Contents)
return; return;
@ -480,7 +481,7 @@ void PrinterContext<ET>::PrintOpcodes(const uint8_t *Entry,
template <typename ET> template <typename ET>
void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex, void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex,
const Elf_Shdr *IT) const { const Elf_Shdr *IT) const {
ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(IT); Expected<ArrayRef<uint8_t>> Contents = ELF->getSectionContents(IT);
if (!Contents) if (!Contents)
return; return;
@ -533,7 +534,7 @@ void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex,
const Elf_Shdr *EHT = const Elf_Shdr *EHT =
FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4); FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4);
if (ErrorOr<StringRef> Name = ELF->getSectionName(EHT)) if (auto Name = ELF->getSectionName(EHT))
SW.printString("ExceptionHandlingTable", *Name); SW.printString("ExceptionHandlingTable", *Name);
uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr); uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr);
@ -554,7 +555,7 @@ void PrinterContext<ET>::PrintUnwindInformation() const {
DictScope UIT(SW, "UnwindIndexTable"); DictScope UIT(SW, "UnwindIndexTable");
SW.printNumber("SectionIndex", SectionIndex); SW.printNumber("SectionIndex", SectionIndex);
if (ErrorOr<StringRef> SectionName = ELF->getSectionName(&Sec)) if (auto SectionName = ELF->getSectionName(&Sec))
SW.printString("SectionName", *SectionName); SW.printString("SectionName", *SectionName);
SW.printHex("SectionOffset", Sec.sh_offset); SW.printHex("SectionOffset", Sec.sh_offset);

View File

@ -75,8 +75,8 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
// Dump sections // Dump sections
auto SectionsOrErr = Obj.sections(); auto SectionsOrErr = Obj.sections();
if (std::error_code EC = SectionsOrErr.getError()) if (!SectionsOrErr)
return EC; return errorToErrorCode(SectionsOrErr.takeError());
for (const Elf_Shdr &Sec : *SectionsOrErr) { for (const Elf_Shdr &Sec : *SectionsOrErr) {
switch (Sec.sh_type) { switch (Sec.sh_type) {
case ELF::SHT_NULL: case ELF::SHT_NULL:
@ -88,9 +88,9 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
Symtab = &Sec; Symtab = &Sec;
break; break;
case ELF::SHT_SYMTAB_SHNDX: { case ELF::SHT_SYMTAB_SHNDX: {
ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj.getSHNDXTable(Sec); auto TableOrErr = Obj.getSHNDXTable(Sec);
if (std::error_code EC = TableOrErr.getError()) if (!TableOrErr)
return EC; return errorToErrorCode(TableOrErr.takeError());
ShndxTable = *TableOrErr; ShndxTable = *TableOrErr;
break; break;
} }
@ -139,15 +139,15 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
} }
// Dump symbols // Dump symbols
ErrorOr<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*Symtab); auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
if (std::error_code EC = StrTableOrErr.getError()) if (!StrTableOrErr)
return EC; return errorToErrorCode(StrTableOrErr.takeError());
StringRef StrTable = *StrTableOrErr; StringRef StrTable = *StrTableOrErr;
bool IsFirstSym = true; bool IsFirstSym = true;
auto SymtabOrErr = Obj.symbols(Symtab); auto SymtabOrErr = Obj.symbols(Symtab);
if (std::error_code EC = SymtabOrErr.getError()) if (!SymtabOrErr)
return EC; return errorToErrorCode(SymtabOrErr.takeError());
for (const Elf_Sym &Sym : *SymtabOrErr) { for (const Elf_Sym &Sym : *SymtabOrErr) {
if (IsFirstSym) { if (IsFirstSym) {
IsFirstSym = false; IsFirstSym = false;
@ -192,16 +192,16 @@ ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
return errorToErrorCode(SymbolNameOrErr.takeError()); return errorToErrorCode(SymbolNameOrErr.takeError());
S.Name = SymbolNameOrErr.get(); S.Name = SymbolNameOrErr.get();
ErrorOr<const Elf_Shdr *> ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable); auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
if (std::error_code EC = ShdrOrErr.getError()) if (!ShdrOrErr)
return EC; return errorToErrorCode(ShdrOrErr.takeError());
const Elf_Shdr *Shdr = *ShdrOrErr; const Elf_Shdr *Shdr = *ShdrOrErr;
if (!Shdr) if (!Shdr)
return obj2yaml_error::success; return obj2yaml_error::success;
ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr); auto NameOrErr = Obj.getSectionName(Shdr);
if (std::error_code EC = NameOrErr.getError()) if (!NameOrErr)
return EC; return errorToErrorCode(NameOrErr.takeError());
S.Section = NameOrErr.get(); S.Section = NameOrErr.get();
return obj2yaml_error::success; return obj2yaml_error::success;
@ -217,15 +217,15 @@ std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
R.Addend = 0; R.Addend = 0;
auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab); auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
if (std::error_code EC = SymOrErr.getError()) if (!SymOrErr)
return EC; return errorToErrorCode(SymOrErr.takeError());
const Elf_Sym *Sym = *SymOrErr; const Elf_Sym *Sym = *SymOrErr;
ErrorOr<const Elf_Shdr *> StrTabSec = Obj.getSection(SymTab->sh_link); auto StrTabSec = Obj.getSection(SymTab->sh_link);
if (std::error_code EC = StrTabSec.getError()) if (!StrTabSec)
return EC; return errorToErrorCode(StrTabSec.takeError());
ErrorOr<StringRef> StrTabOrErr = Obj.getStringTable(*StrTabSec); auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
if (std::error_code EC = StrTabOrErr.getError()) if (!StrTabOrErr)
return EC; return errorToErrorCode(StrTabOrErr.takeError());
StringRef StrTab = *StrTabOrErr; StringRef StrTab = *StrTabOrErr;
Expected<StringRef> NameOrErr = Sym->getName(StrTab); Expected<StringRef> NameOrErr = Sym->getName(StrTab);
@ -244,18 +244,18 @@ std::error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
S.Address = Shdr->sh_addr; S.Address = Shdr->sh_addr;
S.AddressAlign = Shdr->sh_addralign; S.AddressAlign = Shdr->sh_addralign;
ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr); auto NameOrErr = Obj.getSectionName(Shdr);
if (std::error_code EC = NameOrErr.getError()) if (!NameOrErr)
return EC; return errorToErrorCode(NameOrErr.takeError());
S.Name = NameOrErr.get(); S.Name = NameOrErr.get();
if (Shdr->sh_link != ELF::SHN_UNDEF) { if (Shdr->sh_link != ELF::SHN_UNDEF) {
ErrorOr<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link); auto LinkSection = Obj.getSection(Shdr->sh_link);
if (std::error_code EC = LinkSection.getError()) if (LinkSection.takeError())
return EC; return errorToErrorCode(LinkSection.takeError());
NameOrErr = Obj.getSectionName(*LinkSection); NameOrErr = Obj.getSectionName(*LinkSection);
if (std::error_code EC = NameOrErr.getError()) if (!NameOrErr)
return EC; return errorToErrorCode(NameOrErr.takeError());
S.Link = NameOrErr.get(); S.Link = NameOrErr.get();
} }
@ -269,13 +269,13 @@ ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr,
if (std::error_code EC = dumpCommonSection(Shdr, S)) if (std::error_code EC = dumpCommonSection(Shdr, S))
return EC; return EC;
ErrorOr<const Elf_Shdr *> InfoSection = Obj.getSection(Shdr->sh_info); auto InfoSection = Obj.getSection(Shdr->sh_info);
if (std::error_code EC = InfoSection.getError()) if (!InfoSection)
return EC; return errorToErrorCode(InfoSection.takeError());
ErrorOr<StringRef> NameOrErr = Obj.getSectionName(*InfoSection); auto NameOrErr = Obj.getSectionName(*InfoSection);
if (std::error_code EC = NameOrErr.getError()) if (!NameOrErr)
return EC; return errorToErrorCode(NameOrErr.takeError());
S.Info = NameOrErr.get(); S.Info = NameOrErr.get();
return obj2yaml_error::success; return obj2yaml_error::success;
@ -290,14 +290,14 @@ ELFDumper<ELFT>::dumpRelSection(const Elf_Shdr *Shdr) {
if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
return EC; return EC;
ErrorOr<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Shdr->sh_link); auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
if (std::error_code EC = SymTabOrErr.getError()) if (!SymTabOrErr)
return EC; return errorToErrorCode(SymTabOrErr.takeError());
const Elf_Shdr *SymTab = *SymTabOrErr; const Elf_Shdr *SymTab = *SymTabOrErr;
auto Rels = Obj.rels(Shdr); auto Rels = Obj.rels(Shdr);
if (std::error_code EC = Rels.getError()) if (!Rels)
return EC; return errorToErrorCode(Rels.takeError());
for (const Elf_Rel &Rel : *Rels) { for (const Elf_Rel &Rel : *Rels) {
ELFYAML::Relocation R; ELFYAML::Relocation R;
if (std::error_code EC = dumpRelocation(&Rel, SymTab, R)) if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
@ -317,14 +317,14 @@ ELFDumper<ELFT>::dumpRelaSection(const Elf_Shdr *Shdr) {
if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S)) if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
return EC; return EC;
ErrorOr<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Shdr->sh_link); auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
if (std::error_code EC = SymTabOrErr.getError()) if (!SymTabOrErr)
return EC; return errorToErrorCode(SymTabOrErr.takeError());
const Elf_Shdr *SymTab = *SymTabOrErr; const Elf_Shdr *SymTab = *SymTabOrErr;
auto Rels = Obj.relas(Shdr); auto Rels = Obj.relas(Shdr);
if (std::error_code EC = Rels.getError()) if (!Rels)
return EC; return errorToErrorCode(Rels.takeError());
for (const Elf_Rela &Rel : *Rels) { for (const Elf_Rela &Rel : *Rels) {
ELFYAML::Relocation R; ELFYAML::Relocation R;
if (std::error_code EC = dumpRelocation(&Rel, SymTab, R)) if (std::error_code EC = dumpRelocation(&Rel, SymTab, R))
@ -344,9 +344,9 @@ ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
if (std::error_code EC = dumpCommonSection(Shdr, *S)) if (std::error_code EC = dumpCommonSection(Shdr, *S))
return EC; return EC;
ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); auto ContentOrErr = Obj.getSectionContents(Shdr);
if (std::error_code EC = ContentOrErr.getError()) if (!ContentOrErr)
return EC; return errorToErrorCode(ContentOrErr.takeError());
S->Content = yaml::BinaryRef(ContentOrErr.get()); S->Content = yaml::BinaryRef(ContentOrErr.get());
S->Size = S->Content.binary_size(); S->Size = S->Content.binary_size();
@ -372,21 +372,21 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
if (std::error_code EC = dumpCommonSection(Shdr, *S)) if (std::error_code EC = dumpCommonSection(Shdr, *S))
return EC; return EC;
// Get sh_info which is the signature. // Get sh_info which is the signature.
ErrorOr<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Shdr->sh_link); auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
if (std::error_code EC = SymtabOrErr.getError()) if (!SymtabOrErr)
return EC; return errorToErrorCode(SymtabOrErr.takeError());
const Elf_Shdr *Symtab = *SymtabOrErr; const Elf_Shdr *Symtab = *SymtabOrErr;
ErrorOr<const Elf_Sym *> SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info); auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
if (std::error_code EC = SymOrErr.getError()) if (!SymOrErr)
return EC; return errorToErrorCode(SymOrErr.takeError());
const Elf_Sym *symbol = *SymOrErr; const Elf_Sym *symbol = *SymOrErr;
ErrorOr<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*Symtab); auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
if (std::error_code EC = StrTabOrErr.getError()) if (!StrTabOrErr)
return EC; return errorToErrorCode(StrTabOrErr.takeError());
StringRef StrTab = *StrTabOrErr; StringRef StrTab = *StrTabOrErr;
auto sectionContents = Obj.getSectionContents(Shdr); auto sectionContents = Obj.getSectionContents(Shdr);
if (std::error_code ec = sectionContents.getError()) if (!sectionContents)
return ec; return errorToErrorCode(sectionContents.takeError());
Expected<StringRef> symbolName = symbol->getName(StrTab); Expected<StringRef> symbolName = symbol->getName(StrTab);
if (!symbolName) if (!symbolName)
return errorToErrorCode(symbolName.takeError()); return errorToErrorCode(symbolName.takeError());
@ -399,12 +399,12 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT>::dumpGroup(const Elf_Shdr *Shdr) {
if (groupMembers[i] == llvm::ELF::GRP_COMDAT) { if (groupMembers[i] == llvm::ELF::GRP_COMDAT) {
s.sectionNameOrType = "GRP_COMDAT"; s.sectionNameOrType = "GRP_COMDAT";
} else { } else {
ErrorOr<const Elf_Shdr *> sHdr = Obj.getSection(groupMembers[i]); auto sHdr = Obj.getSection(groupMembers[i]);
if (std::error_code EC = sHdr.getError()) if (!sHdr)
return EC; return errorToErrorCode(sHdr.takeError());
ErrorOr<StringRef> sectionName = Obj.getSectionName(*sHdr); auto sectionName = Obj.getSectionName(*sHdr);
if (std::error_code ec = sectionName.getError()) if (!sectionName)
return ec; return errorToErrorCode(sectionName.takeError());
s.sectionNameOrType = *sectionName; s.sectionNameOrType = *sectionName;
} }
S->Members.push_back(s); S->Members.push_back(s);
@ -421,9 +421,9 @@ ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
if (std::error_code EC = dumpCommonSection(Shdr, *S)) if (std::error_code EC = dumpCommonSection(Shdr, *S))
return EC; return EC;
ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr); auto ContentOrErr = Obj.getSectionContents(Shdr);
if (std::error_code EC = ContentOrErr.getError()) if (!ContentOrErr)
return EC; return errorToErrorCode(ContentOrErr.takeError());
auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>( auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
ContentOrErr.get().data()); ContentOrErr.get().data());