forked from OSchip/llvm-project
[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. llvm-svn: 287081
This commit is contained in:
parent
86dd66e96c
commit
6cf09265f9
|
@ -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,19 +79,19 @@ 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;
|
||||||
|
|
||||||
|
Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
|
||||||
|
Expected<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
|
||||||
Elf_Shdr_Range Sections) const;
|
Elf_Shdr_Range Sections) const;
|
||||||
|
|
||||||
ErrorOr<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section) const;
|
|
||||||
ErrorOr<ArrayRef<Elf_Word>> getSHNDXTable(const Elf_Shdr &Section,
|
|
||||||
Elf_Shdr_Range Sections) const;
|
|
||||||
|
|
||||||
void VerifyStrTab(const Elf_Shdr *sh) const;
|
void VerifyStrTab(const Elf_Shdr *sh) const;
|
||||||
|
|
||||||
StringRef getRelocationTypeName(uint32_t Type) const;
|
StringRef getRelocationTypeName(uint32_t Type) const;
|
||||||
|
@ -95,8 +99,8 @@ 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,
|
||||||
ArrayRef<Elf_Word> ShndxTable) const;
|
Elf_Sym_Range Symtab,
|
||||||
ErrorOr<const Elf_Shdr *> getSection(uint32_t Index) const;
|
ArrayRef<Elf_Word> ShndxTable) 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 | \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue