mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-25 12:49:50 +00:00
[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:
parent
68e337a67b
commit
63830bcae9
@ -33,6 +33,10 @@ getElfArchType(StringRef Object) {
|
||||
(uint8_t)Object[ELF::EI_DATA]);
|
||||
}
|
||||
|
||||
static inline Error createError(StringRef Err) {
|
||||
return make_error<StringError>(Err, object_error::parse_failed);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
class ELFFile {
|
||||
public:
|
||||
@ -75,19 +79,19 @@ public:
|
||||
}
|
||||
|
||||
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>
|
||||
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;
|
||||
ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
|
||||
ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section,
|
||||
Expected<StringRef> getStringTable(const Elf_Shdr *Section) const;
|
||||
Expected<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
StringRef getRelocationTypeName(uint32_t Type) const;
|
||||
@ -95,8 +99,8 @@ public:
|
||||
SmallVectorImpl<char> &Result) const;
|
||||
|
||||
/// \brief Get the symbol for a given relocation.
|
||||
ErrorOr<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
|
||||
const Elf_Shdr *SymTab) const;
|
||||
Expected<const Elf_Sym *> getRelocationSymbol(const Elf_Rel *Rel,
|
||||
const Elf_Shdr *SymTab) const;
|
||||
|
||||
ELFFile(StringRef Object);
|
||||
|
||||
@ -110,50 +114,51 @@ public:
|
||||
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)
|
||||
return makeArrayRef<Elf_Sym>(nullptr, nullptr);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/// \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))
|
||||
return object_error::parse_failed;
|
||||
return createError("invalid e_phentsize");
|
||||
auto *Begin =
|
||||
reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
|
||||
return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
|
||||
}
|
||||
|
||||
ErrorOr<StringRef> getSectionStringTable(Elf_Shdr_Range Sections) const;
|
||||
ErrorOr<uint32_t> getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
|
||||
ArrayRef<Elf_Word> ShndxTable) const;
|
||||
ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
|
||||
const Elf_Shdr *SymTab,
|
||||
ArrayRef<Elf_Word> ShndxTable) const;
|
||||
ErrorOr<const Elf_Shdr *> getSection(const Elf_Sym *Sym, Elf_Sym_Range Symtab,
|
||||
ArrayRef<Elf_Word> ShndxTable) const;
|
||||
ErrorOr<const Elf_Shdr *> getSection(uint32_t Index) const;
|
||||
Expected<StringRef> getSectionStringTable(Elf_Shdr_Range Sections) const;
|
||||
Expected<uint32_t> getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
|
||||
ArrayRef<Elf_Word> ShndxTable) const;
|
||||
Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
|
||||
const Elf_Shdr *SymTab,
|
||||
ArrayRef<Elf_Word> ShndxTable) const;
|
||||
Expected<const Elf_Shdr *> getSection(const Elf_Sym *Sym,
|
||||
Elf_Sym_Range Symtab,
|
||||
ArrayRef<Elf_Word> ShndxTable) const;
|
||||
Expected<const Elf_Shdr *> getSection(uint32_t Index) const;
|
||||
|
||||
ErrorOr<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
|
||||
uint32_t Index) const;
|
||||
Expected<const Elf_Sym *> getSymbol(const Elf_Shdr *Sec,
|
||||
uint32_t Index) const;
|
||||
|
||||
ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section) const;
|
||||
ErrorOr<StringRef> getSectionName(const Elf_Shdr *Section,
|
||||
StringRef DotShstrtab) const;
|
||||
Expected<StringRef> getSectionName(const Elf_Shdr *Section) const;
|
||||
Expected<StringRef> getSectionName(const Elf_Shdr *Section,
|
||||
StringRef DotShstrtab) const;
|
||||
template <typename T>
|
||||
ErrorOr<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const;
|
||||
ErrorOr<ArrayRef<uint8_t> > getSectionContents(const Elf_Shdr *Sec) const;
|
||||
Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const;
|
||||
Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
template <class ELFT>
|
||||
inline ErrorOr<const typename ELFT::Shdr *>
|
||||
inline Expected<const typename ELFT::Shdr *>
|
||||
getSection(typename ELFT::ShdrRange Sections, uint32_t Index) {
|
||||
if (Index >= Sections.size())
|
||||
return object_error::invalid_section_index;
|
||||
return createError("invalid section index");
|
||||
return &Sections[Index];
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
inline ErrorOr<uint32_t>
|
||||
inline Expected<uint32_t>
|
||||
getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym,
|
||||
const typename ELFT::Sym *FirstSym,
|
||||
ArrayRef<typename ELFT::Word> ShndxTable) {
|
||||
assert(Sym->st_shndx == ELF::SHN_XINDEX);
|
||||
unsigned Index = Sym - FirstSym;
|
||||
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.
|
||||
return ShndxTable[Index];
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<uint32_t>
|
||||
Expected<uint32_t>
|
||||
ELFFile<ELFT>::getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms,
|
||||
ArrayRef<Elf_Word> ShndxTable) const {
|
||||
uint32_t Index = Sym->st_shndx;
|
||||
if (Index == ELF::SHN_XINDEX) {
|
||||
auto ErrorOrIndex = object::getExtendedSymbolTableIndex<ELFT>(
|
||||
Sym, Syms.begin(), ShndxTable);
|
||||
if (std::error_code EC = ErrorOrIndex.getError())
|
||||
return EC;
|
||||
if (!ErrorOrIndex)
|
||||
return ErrorOrIndex.takeError();
|
||||
return *ErrorOrIndex;
|
||||
}
|
||||
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>
|
||||
ErrorOr<const typename ELFT::Shdr *>
|
||||
Expected<const typename ELFT::Shdr *>
|
||||
ELFFile<ELFT>::getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
ArrayRef<Elf_Word> ShndxTable) const {
|
||||
auto SymsOrErr = symbols(SymTab);
|
||||
if (std::error_code EC = SymsOrErr.getError())
|
||||
return EC;
|
||||
if (!SymsOrErr)
|
||||
return SymsOrErr.takeError();
|
||||
return getSection(Sym, *SymsOrErr, ShndxTable);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<const typename ELFT::Shdr *>
|
||||
Expected<const typename ELFT::Shdr *>
|
||||
ELFFile<ELFT>::getSection(const Elf_Sym *Sym, Elf_Sym_Range Symbols,
|
||||
ArrayRef<Elf_Word> ShndxTable) const {
|
||||
ErrorOr<uint32_t> IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
|
||||
if (std::error_code EC = IndexOrErr.getError())
|
||||
return EC;
|
||||
auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
|
||||
if (!IndexOrErr)
|
||||
return IndexOrErr.takeError();
|
||||
uint32_t Index = *IndexOrErr;
|
||||
if (Index == 0)
|
||||
return nullptr;
|
||||
auto SectionsOrErr = sections();
|
||||
if (std::error_code EC = SectionsOrErr.getError())
|
||||
return EC;
|
||||
if (!SectionsOrErr)
|
||||
return SectionsOrErr.takeError();
|
||||
return object::getSection<ELFT>(*SectionsOrErr, Index);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
inline ErrorOr<const typename ELFT::Sym *>
|
||||
inline Expected<const typename ELFT::Sym *>
|
||||
getSymbol(typename ELFT::SymRange Symbols, uint32_t Index) {
|
||||
if (Index >= Symbols.size())
|
||||
return object_error::invalid_symbol_index;
|
||||
return createError("invalid symbol index");
|
||||
return &Symbols[Index];
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<const typename ELFT::Sym *>
|
||||
Expected<const typename ELFT::Sym *>
|
||||
ELFFile<ELFT>::getSymbol(const Elf_Shdr *Sec, uint32_t Index) const {
|
||||
auto SymtabOrErr = symbols(Sec);
|
||||
if (std::error_code EC = SymtabOrErr.getError())
|
||||
return EC;
|
||||
if (!SymtabOrErr)
|
||||
return SymtabOrErr.takeError();
|
||||
return object::getSymbol<ELFT>(*SymtabOrErr, Index);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
template <typename T>
|
||||
ErrorOr<ArrayRef<T>>
|
||||
Expected<ArrayRef<T>>
|
||||
ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const {
|
||||
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 Size = Sec->sh_size;
|
||||
|
||||
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) ||
|
||||
Offset + Size > Buf.size())
|
||||
return object_error::parse_failed;
|
||||
return createError("invalid section offset");
|
||||
|
||||
const T *Start = reinterpret_cast<const T *>(base() + Offset);
|
||||
return makeArrayRef(Start, Size / sizeof(T));
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ArrayRef<uint8_t>>
|
||||
Expected<ArrayRef<uint8_t>>
|
||||
ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
|
||||
return getSectionContentsAsArray<uint8_t>(Sec);
|
||||
}
|
||||
@ -305,7 +311,7 @@ void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type,
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<const typename ELFT::Sym *>
|
||||
Expected<const typename ELFT::Sym *>
|
||||
ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
|
||||
const Elf_Shdr *SymTab) const {
|
||||
uint32_t Index = Rel->getSymbol(isMips64EL());
|
||||
@ -315,7 +321,7 @@ ELFFile<ELFT>::getRelocationSymbol(const Elf_Rel *Rel,
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<StringRef>
|
||||
Expected<StringRef>
|
||||
ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
|
||||
uint32_t Index = getHeader()->e_shstrndx;
|
||||
if (Index == ELF::SHN_XINDEX)
|
||||
@ -324,7 +330,7 @@ ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections) const {
|
||||
if (!Index) // no section string table.
|
||||
return "";
|
||||
if (Index >= Sections.size())
|
||||
return object_error::parse_failed;
|
||||
return createError("invalid section index");
|
||||
return getStringTable(&Sections[Index]);
|
||||
}
|
||||
|
||||
@ -339,24 +345,23 @@ static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl<ELFT> *Phdr) {
|
||||
}
|
||||
|
||||
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;
|
||||
if (SectionTableOffset == 0)
|
||||
return ArrayRef<Elf_Shdr>();
|
||||
|
||||
// Invalid section header entry size (e_shentsize) in ELF header
|
||||
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();
|
||||
|
||||
// Section header table goes past end of file!
|
||||
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
|
||||
if (SectionTableOffset & (alignof(Elf_Shdr) - 1))
|
||||
return object_error::parse_failed;
|
||||
return createError("invalid alignment of section headers");
|
||||
|
||||
const Elf_Shdr *First =
|
||||
reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset);
|
||||
@ -365,140 +370,138 @@ ErrorOr<typename ELFT::ShdrRange> ELFFile<ELFT>::sections() const {
|
||||
if (NumSections == 0)
|
||||
NumSections = First->sh_size;
|
||||
|
||||
// Section table goes past end of file!
|
||||
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);
|
||||
|
||||
// Section table goes past end of file!
|
||||
if (SectionTableOffset + SectionTableSize > FileSize)
|
||||
return object_error::parse_failed;
|
||||
return createError("section table goes past the end of file");
|
||||
|
||||
return makeArrayRef(First, NumSections);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
template <typename T>
|
||||
ErrorOr<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
|
||||
uint32_t Entry) const {
|
||||
ErrorOr<const Elf_Shdr *> Sec = getSection(Section);
|
||||
if (std::error_code EC = Sec.getError())
|
||||
return EC;
|
||||
return getEntry<T>(*Sec, Entry);
|
||||
Expected<const T *> ELFFile<ELFT>::getEntry(uint32_t Section,
|
||||
uint32_t Entry) const {
|
||||
auto SecOrErr = getSection(Section);
|
||||
if (!SecOrErr)
|
||||
return SecOrErr.takeError();
|
||||
return getEntry<T>(*SecOrErr, Entry);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
template <typename T>
|
||||
ErrorOr<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
|
||||
uint32_t Entry) const {
|
||||
Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
|
||||
uint32_t Entry) const {
|
||||
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);
|
||||
if (Pos + sizeof(T) > Buf.size())
|
||||
return object_error::parse_failed;
|
||||
return createError("invalid section offset");
|
||||
return reinterpret_cast<const T *>(base() + Pos);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<const typename ELFT::Shdr *>
|
||||
Expected<const typename ELFT::Shdr *>
|
||||
ELFFile<ELFT>::getSection(uint32_t Index) const {
|
||||
auto TableOrErr = sections();
|
||||
if (std::error_code EC = TableOrErr.getError())
|
||||
return EC;
|
||||
if (!TableOrErr)
|
||||
return TableOrErr.takeError();
|
||||
return object::getSection<ELFT>(*TableOrErr, Index);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<StringRef>
|
||||
Expected<StringRef>
|
||||
ELFFile<ELFT>::getStringTable(const Elf_Shdr *Section) const {
|
||||
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);
|
||||
if (std::error_code EC = V.getError())
|
||||
return EC;
|
||||
if (!V)
|
||||
return V.takeError();
|
||||
ArrayRef<char> Data = *V;
|
||||
if (Data.empty())
|
||||
return object_error::parse_failed;
|
||||
return createError("empty string table");
|
||||
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());
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ArrayRef<typename ELFT::Word>>
|
||||
Expected<ArrayRef<typename ELFT::Word>>
|
||||
ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section) const {
|
||||
auto SectionsOrErr = sections();
|
||||
if (std::error_code EC = SectionsOrErr.getError())
|
||||
return EC;
|
||||
if (!SectionsOrErr)
|
||||
return SectionsOrErr.takeError();
|
||||
return getSHNDXTable(Section, *SectionsOrErr);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<ArrayRef<typename ELFT::Word>>
|
||||
Expected<ArrayRef<typename ELFT::Word>>
|
||||
ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
|
||||
Elf_Shdr_Range Sections) const {
|
||||
assert(Section.sh_type == ELF::SHT_SYMTAB_SHNDX);
|
||||
auto VOrErr = getSectionContentsAsArray<Elf_Word>(&Section);
|
||||
if (std::error_code EC = VOrErr.getError())
|
||||
return EC;
|
||||
if (!VOrErr)
|
||||
return VOrErr.takeError();
|
||||
ArrayRef<Elf_Word> V = *VOrErr;
|
||||
ErrorOr<const Elf_Shdr *> SymTableOrErr =
|
||||
object::getSection<ELFT>(Sections, Section.sh_link);
|
||||
if (std::error_code EC = SymTableOrErr.getError())
|
||||
return EC;
|
||||
auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
|
||||
if (!SymTableOrErr)
|
||||
return SymTableOrErr.takeError();
|
||||
const Elf_Shdr &SymTable = **SymTableOrErr;
|
||||
if (SymTable.sh_type != ELF::SHT_SYMTAB &&
|
||||
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)))
|
||||
return object_error::parse_failed;
|
||||
return createError("invalid section contents size");
|
||||
return V;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<StringRef>
|
||||
Expected<StringRef>
|
||||
ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec) const {
|
||||
auto SectionsOrErr = sections();
|
||||
if (std::error_code EC = SectionsOrErr.getError())
|
||||
return EC;
|
||||
if (!SectionsOrErr)
|
||||
return SectionsOrErr.takeError();
|
||||
return getStringTableForSymtab(Sec, *SectionsOrErr);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<StringRef>
|
||||
Expected<StringRef>
|
||||
ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
|
||||
Elf_Shdr_Range Sections) const {
|
||||
|
||||
if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
|
||||
return object_error::parse_failed;
|
||||
ErrorOr<const Elf_Shdr *> SectionOrErr =
|
||||
object::getSection<ELFT>(Sections, Sec.sh_link);
|
||||
if (std::error_code EC = SectionOrErr.getError())
|
||||
return EC;
|
||||
return createError(
|
||||
"invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
|
||||
auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
|
||||
if (!SectionOrErr)
|
||||
return SectionOrErr.takeError();
|
||||
return getStringTable(*SectionOrErr);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<StringRef>
|
||||
Expected<StringRef>
|
||||
ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section) const {
|
||||
auto SectionsOrErr = sections();
|
||||
if (std::error_code EC = SectionsOrErr.getError())
|
||||
return EC;
|
||||
ErrorOr<StringRef> Table = getSectionStringTable(*SectionsOrErr);
|
||||
if (std::error_code EC = Table.getError())
|
||||
return EC;
|
||||
if (!SectionsOrErr)
|
||||
return SectionsOrErr.takeError();
|
||||
auto Table = getSectionStringTable(*SectionsOrErr);
|
||||
if (!Table)
|
||||
return Table.takeError();
|
||||
return getSectionName(Section, *Table);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section,
|
||||
StringRef DotShstrtab) const {
|
||||
Expected<StringRef> ELFFile<ELFT>::getSectionName(const Elf_Shdr *Section,
|
||||
StringRef DotShstrtab) const {
|
||||
uint32_t Offset = Section->sh_name;
|
||||
if (Offset == 0)
|
||||
return StringRef();
|
||||
if (Offset >= DotShstrtab.size())
|
||||
return object_error::parse_failed;
|
||||
return createError("invalid string offset");
|
||||
return StringRef(DotShstrtab.data() + Offset);
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,10 @@ protected:
|
||||
|
||||
/// \brief Get the relocation section that contains \a Rel.
|
||||
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 {
|
||||
@ -268,7 +271,13 @@ protected:
|
||||
assert(SymTable->sh_type == ELF::SHT_SYMTAB ||
|
||||
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 =
|
||||
(reinterpret_cast<uintptr_t>(SymTable) - SHT) / sizeof(Elf_Shdr);
|
||||
|
||||
@ -318,8 +327,8 @@ public:
|
||||
|
||||
const Elf_Sym *getSymbol(DataRefImpl Sym) const {
|
||||
auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
|
||||
if (std::error_code EC = Ret.getError())
|
||||
report_fatal_error(EC.message());
|
||||
if (!Ret)
|
||||
report_fatal_error(errorToErrorCode(Ret.takeError()).message());
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
@ -373,10 +382,18 @@ void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Sym) const {
|
||||
template <class ELFT>
|
||||
Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
|
||||
const Elf_Sym *ESym = getSymbol(Sym);
|
||||
const Elf_Shdr *SymTableSec = *EF.getSection(Sym.d.a);
|
||||
const Elf_Shdr *StringTableSec = *EF.getSection(SymTableSec->sh_link);
|
||||
StringRef SymTable = *EF.getStringTable(StringTableSec);
|
||||
return ESym->getName(SymTable);
|
||||
auto SymTabOrErr = EF.getSection(Sym.d.a);
|
||||
if (!SymTabOrErr)
|
||||
return SymTabOrErr.takeError();
|
||||
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>
|
||||
@ -423,13 +440,15 @@ ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
|
||||
}
|
||||
|
||||
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) {
|
||||
ErrorOr<const Elf_Shdr *> SectionOrErr =
|
||||
EF.getSection(ESym, SymTab, ShndxTable);
|
||||
if (std::error_code EC = SectionOrErr.getError())
|
||||
return errorCodeToError(EC);
|
||||
auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable);
|
||||
if (!SectionOrErr)
|
||||
return SectionOrErr.takeError();
|
||||
const Elf_Shdr *Section = *SectionOrErr;
|
||||
if (Section)
|
||||
Result += Section->sh_addr;
|
||||
@ -509,9 +528,14 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
|
||||
if (ESym->st_shndx == ELF::SHN_ABS)
|
||||
Result |= SymbolRef::SF_Absolute;
|
||||
|
||||
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION ||
|
||||
ESym == (*EF.symbols(DotSymtabSec)).begin() ||
|
||||
ESym == (*EF.symbols(DotDynSymSec)).begin())
|
||||
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
|
||||
Result |= SymbolRef::SF_FormatSpecific;
|
||||
|
||||
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;
|
||||
|
||||
if (EF.getHeader()->e_machine == ELF::EM_ARM) {
|
||||
@ -547,9 +571,9 @@ template <class ELFT>
|
||||
Expected<section_iterator>
|
||||
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
|
||||
const Elf_Shdr *SymTab) const {
|
||||
ErrorOr<const Elf_Shdr *> ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
|
||||
if (std::error_code EC = ESecOrErr.getError())
|
||||
return errorCodeToError(EC);
|
||||
auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
|
||||
if (!ESecOrErr)
|
||||
return ESecOrErr.takeError();
|
||||
|
||||
const Elf_Shdr *ESec = *ESecOrErr;
|
||||
if (!ESec)
|
||||
@ -564,7 +588,10 @@ template <class ELFT>
|
||||
Expected<section_iterator>
|
||||
ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -577,9 +604,9 @@ void ELFObjectFile<ELFT>::moveSectionNext(DataRefImpl &Sec) const {
|
||||
template <class ELFT>
|
||||
std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
|
||||
StringRef &Result) const {
|
||||
ErrorOr<StringRef> Name = EF.getSectionName(&*getSection(Sec));
|
||||
auto Name = EF.getSectionName(&*getSection(Sec));
|
||||
if (!Name)
|
||||
return Name.getError();
|
||||
return errorToErrorCode(Name.takeError());
|
||||
Result = *Name;
|
||||
return std::error_code();
|
||||
}
|
||||
@ -641,7 +668,10 @@ template <class ELFT>
|
||||
relocation_iterator
|
||||
ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
|
||||
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.b = 0;
|
||||
return relocation_iterator(RelocationRef(RelData, this));
|
||||
@ -658,9 +688,9 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
|
||||
const Elf_Shdr *RelSec = getRelSection(RelData);
|
||||
|
||||
// Error check sh_link here so that getRelocationSymbol can just use it.
|
||||
ErrorOr<const Elf_Shdr *> SymSecOrErr = EF.getSection(RelSec->sh_link);
|
||||
if (std::error_code EC = SymSecOrErr.getError())
|
||||
report_fatal_error(EC.message());
|
||||
auto SymSecOrErr = EF.getSection(RelSec->sh_link);
|
||||
if (!SymSecOrErr)
|
||||
report_fatal_error(errorToErrorCode(SymSecOrErr.takeError()).message());
|
||||
|
||||
RelData.d.b += S->sh_size / S->sh_entsize;
|
||||
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)
|
||||
return section_end();
|
||||
|
||||
ErrorOr<const Elf_Shdr *> R = EF.getSection(EShdr->sh_info);
|
||||
if (std::error_code EC = R.getError())
|
||||
report_fatal_error(EC.message());
|
||||
auto R = EF.getSection(EShdr->sh_info);
|
||||
if (!R)
|
||||
report_fatal_error(errorToErrorCode(R.takeError()).message());
|
||||
return section_iterator(SectionRef(toDRI(*R), this));
|
||||
}
|
||||
|
||||
@ -753,8 +783,8 @@ const typename ELFObjectFile<ELFT>::Elf_Rel *
|
||||
ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
|
||||
assert(getRelSection(Rel)->sh_type == ELF::SHT_REL);
|
||||
auto Ret = EF.template getEntry<Elf_Rel>(Rel.d.a, Rel.d.b);
|
||||
if (std::error_code EC = Ret.getError())
|
||||
report_fatal_error(EC.message());
|
||||
if (!Ret)
|
||||
report_fatal_error(errorToErrorCode(Ret.takeError()).message());
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
@ -763,8 +793,8 @@ const typename ELFObjectFile<ELFT>::Elf_Rela *
|
||||
ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
|
||||
assert(getRelSection(Rela)->sh_type == ELF::SHT_RELA);
|
||||
auto Ret = EF.template getEntry<Elf_Rela>(Rela.d.a, Rela.d.b);
|
||||
if (std::error_code EC = Ret.getError())
|
||||
report_fatal_error(EC.message());
|
||||
if (!Ret)
|
||||
report_fatal_error(errorToErrorCode(Ret.takeError()).message());
|
||||
return *Ret;
|
||||
}
|
||||
|
||||
@ -775,8 +805,10 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
|
||||
Object),
|
||||
EF(Data.getBuffer()) {
|
||||
auto SectionsOrErr = EF.sections();
|
||||
if ((EC = SectionsOrErr.getError()))
|
||||
if (!SectionsOrErr) {
|
||||
EC = errorToErrorCode(SectionsOrErr.takeError());
|
||||
return;
|
||||
}
|
||||
for (const Elf_Shdr &Sec : *SectionsOrErr) {
|
||||
switch (Sec.sh_type) {
|
||||
case ELF::SHT_DYNSYM: {
|
||||
@ -798,9 +830,11 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC)
|
||||
break;
|
||||
}
|
||||
case ELF::SHT_SYMTAB_SHNDX: {
|
||||
ErrorOr<ArrayRef<Elf_Word>> TableOrErr = EF.getSHNDXTable(Sec);
|
||||
if ((EC = TableOrErr.getError()))
|
||||
auto TableOrErr = EF.getSHNDXTable(Sec);
|
||||
if (!TableOrErr) {
|
||||
EC = errorToErrorCode(TableOrErr.takeError());
|
||||
return;
|
||||
}
|
||||
ShndxTable = *TableOrErr;
|
||||
break;
|
||||
}
|
||||
@ -838,12 +872,18 @@ elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
|
||||
|
||||
template <class ELFT>
|
||||
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>
|
||||
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>
|
||||
|
@ -2,21 +2,21 @@
|
||||
RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -sections \
|
||||
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.
|
||||
RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -sections -section-data \
|
||||
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.
|
||||
RUN: not llvm-readobj %p/Inputs/corrupt.elf-x86-64 -symbols \
|
||||
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.
|
||||
@ -36,7 +36,7 @@ RUN: not llvm-readobj -program-headers \
|
||||
RUN: %p/Inputs/corrupt-invalid-phentsize.elf.x86-64 2>&1 | \
|
||||
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: %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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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: 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: 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: 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: 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: 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
|
||||
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
|
||||
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;
|
||||
outs() << "Program Header:\n";
|
||||
auto ProgramHeaderOrError = o->program_headers();
|
||||
if (std::error_code EC = ProgramHeaderOrError.getError())
|
||||
report_fatal_error(EC.message());
|
||||
if (!ProgramHeaderOrError)
|
||||
report_fatal_error(
|
||||
errorToErrorCode(ProgramHeaderOrError.takeError()).message());
|
||||
for (const typename ELFO::Elf_Phdr &Phdr : *ProgramHeaderOrError) {
|
||||
switch (Phdr.p_type) {
|
||||
case ELF::PT_LOAD:
|
||||
|
@ -608,22 +608,22 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
|
||||
|
||||
const ELFFile<ELFT> &EF = *Obj->getELFFile();
|
||||
|
||||
ErrorOr<const Elf_Shdr *> SecOrErr = EF.getSection(Rel.d.a);
|
||||
if (std::error_code EC = SecOrErr.getError())
|
||||
return EC;
|
||||
auto SecOrErr = EF.getSection(Rel.d.a);
|
||||
if (!SecOrErr)
|
||||
return errorToErrorCode(SecOrErr.takeError());
|
||||
const Elf_Shdr *Sec = *SecOrErr;
|
||||
ErrorOr<const Elf_Shdr *> SymTabOrErr = EF.getSection(Sec->sh_link);
|
||||
if (std::error_code EC = SymTabOrErr.getError())
|
||||
return EC;
|
||||
auto SymTabOrErr = EF.getSection(Sec->sh_link);
|
||||
if (!SymTabOrErr)
|
||||
return errorToErrorCode(SymTabOrErr.takeError());
|
||||
const Elf_Shdr *SymTab = *SymTabOrErr;
|
||||
assert(SymTab->sh_type == ELF::SHT_SYMTAB ||
|
||||
SymTab->sh_type == ELF::SHT_DYNSYM);
|
||||
ErrorOr<const Elf_Shdr *> StrTabSec = EF.getSection(SymTab->sh_link);
|
||||
if (std::error_code EC = StrTabSec.getError())
|
||||
return EC;
|
||||
ErrorOr<StringRef> StrTabOrErr = EF.getStringTable(*StrTabSec);
|
||||
if (std::error_code EC = StrTabOrErr.getError())
|
||||
return EC;
|
||||
auto StrTabSec = EF.getSection(SymTab->sh_link);
|
||||
if (!StrTabSec)
|
||||
return errorToErrorCode(StrTabSec.takeError());
|
||||
auto StrTabOrErr = EF.getStringTable(*StrTabSec);
|
||||
if (!StrTabOrErr)
|
||||
return errorToErrorCode(StrTabOrErr.takeError());
|
||||
StringRef StrTab = *StrTabOrErr;
|
||||
uint8_t type = RelRef.getType();
|
||||
StringRef res;
|
||||
@ -649,9 +649,9 @@ static std::error_code getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
|
||||
if (!SymSI)
|
||||
return errorToErrorCode(SymSI.takeError());
|
||||
const Elf_Shdr *SymSec = Obj->getSection((*SymSI)->getRawDataRefImpl());
|
||||
ErrorOr<StringRef> SecName = EF.getSectionName(SymSec);
|
||||
if (std::error_code EC = SecName.getError())
|
||||
return EC;
|
||||
auto SecName = EF.getSectionName(SymSec);
|
||||
if (!SecName)
|
||||
return errorToErrorCode(SecName.takeError());
|
||||
Target = *SecName;
|
||||
} else {
|
||||
Expected<StringRef> SymName = symb->getName(StrTab);
|
||||
|
@ -349,8 +349,9 @@ template <typename ET>
|
||||
ErrorOr<StringRef>
|
||||
PrinterContext<ET>::FunctionAtAddress(unsigned Section,
|
||||
uint64_t Address) const {
|
||||
ErrorOr<StringRef> StrTableOrErr = ELF->getStringTableForSymtab(*Symtab);
|
||||
error(StrTableOrErr.getError());
|
||||
auto StrTableOrErr = ELF->getStringTableForSymtab(*Symtab);
|
||||
if (!StrTableOrErr)
|
||||
error(StrTableOrErr.takeError());
|
||||
StringRef StrTable = *StrTableOrErr;
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
ErrorOr<const Elf_Shdr *> SymTabOrErr = ELF->getSection(Sec.sh_link);
|
||||
error(SymTabOrErr.getError());
|
||||
auto SymTabOrErr = ELF->getSection(Sec.sh_link);
|
||||
if (!SymTabOrErr)
|
||||
error(SymTabOrErr.takeError());
|
||||
const Elf_Shdr *SymTab = *SymTabOrErr;
|
||||
|
||||
for (const Elf_Rel &R : unwrapOrError(ELF->rels(&Sec))) {
|
||||
@ -399,10 +401,9 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
|
||||
const Elf_Sym *Symbol =
|
||||
unwrapOrError(ELF->getRelocationSymbol(&RelA, SymTab));
|
||||
|
||||
ErrorOr<const Elf_Shdr *> Ret =
|
||||
ELF->getSection(Symbol, SymTab, ShndxTable);
|
||||
if (std::error_code EC = Ret.getError())
|
||||
report_fatal_error(EC.message());
|
||||
auto Ret = ELF->getSection(Symbol, SymTab, ShndxTable);
|
||||
if (!Ret)
|
||||
report_fatal_error(errorToErrorCode(Ret.takeError()).message());
|
||||
return *Ret;
|
||||
}
|
||||
}
|
||||
@ -413,7 +414,7 @@ template <typename ET>
|
||||
void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr *IT,
|
||||
const Elf_Shdr *EHT,
|
||||
uint64_t TableEntryOffset) const {
|
||||
ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(EHT);
|
||||
Expected<ArrayRef<uint8_t>> Contents = ELF->getSectionContents(EHT);
|
||||
if (!Contents)
|
||||
return;
|
||||
|
||||
@ -480,7 +481,7 @@ void PrinterContext<ET>::PrintOpcodes(const uint8_t *Entry,
|
||||
template <typename ET>
|
||||
void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex,
|
||||
const Elf_Shdr *IT) const {
|
||||
ErrorOr<ArrayRef<uint8_t> > Contents = ELF->getSectionContents(IT);
|
||||
Expected<ArrayRef<uint8_t>> Contents = ELF->getSectionContents(IT);
|
||||
if (!Contents)
|
||||
return;
|
||||
|
||||
@ -533,7 +534,7 @@ void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex,
|
||||
const Elf_Shdr *EHT =
|
||||
FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4);
|
||||
|
||||
if (ErrorOr<StringRef> Name = ELF->getSectionName(EHT))
|
||||
if (auto Name = ELF->getSectionName(EHT))
|
||||
SW.printString("ExceptionHandlingTable", *Name);
|
||||
|
||||
uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr);
|
||||
@ -554,7 +555,7 @@ void PrinterContext<ET>::PrintUnwindInformation() const {
|
||||
DictScope UIT(SW, "UnwindIndexTable");
|
||||
|
||||
SW.printNumber("SectionIndex", SectionIndex);
|
||||
if (ErrorOr<StringRef> SectionName = ELF->getSectionName(&Sec))
|
||||
if (auto SectionName = ELF->getSectionName(&Sec))
|
||||
SW.printString("SectionName", *SectionName);
|
||||
SW.printHex("SectionOffset", Sec.sh_offset);
|
||||
|
||||
|
@ -75,8 +75,8 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
|
||||
// Dump sections
|
||||
auto SectionsOrErr = Obj.sections();
|
||||
if (std::error_code EC = SectionsOrErr.getError())
|
||||
return EC;
|
||||
if (!SectionsOrErr)
|
||||
return errorToErrorCode(SectionsOrErr.takeError());
|
||||
for (const Elf_Shdr &Sec : *SectionsOrErr) {
|
||||
switch (Sec.sh_type) {
|
||||
case ELF::SHT_NULL:
|
||||
@ -88,9 +88,9 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
Symtab = &Sec;
|
||||
break;
|
||||
case ELF::SHT_SYMTAB_SHNDX: {
|
||||
ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj.getSHNDXTable(Sec);
|
||||
if (std::error_code EC = TableOrErr.getError())
|
||||
return EC;
|
||||
auto TableOrErr = Obj.getSHNDXTable(Sec);
|
||||
if (!TableOrErr)
|
||||
return errorToErrorCode(TableOrErr.takeError());
|
||||
ShndxTable = *TableOrErr;
|
||||
break;
|
||||
}
|
||||
@ -139,15 +139,15 @@ ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
||||
}
|
||||
|
||||
// Dump symbols
|
||||
ErrorOr<StringRef> StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
|
||||
if (std::error_code EC = StrTableOrErr.getError())
|
||||
return EC;
|
||||
auto StrTableOrErr = Obj.getStringTableForSymtab(*Symtab);
|
||||
if (!StrTableOrErr)
|
||||
return errorToErrorCode(StrTableOrErr.takeError());
|
||||
StringRef StrTable = *StrTableOrErr;
|
||||
|
||||
bool IsFirstSym = true;
|
||||
auto SymtabOrErr = Obj.symbols(Symtab);
|
||||
if (std::error_code EC = SymtabOrErr.getError())
|
||||
return EC;
|
||||
if (!SymtabOrErr)
|
||||
return errorToErrorCode(SymtabOrErr.takeError());
|
||||
for (const Elf_Sym &Sym : *SymtabOrErr) {
|
||||
if (IsFirstSym) {
|
||||
IsFirstSym = false;
|
||||
@ -192,16 +192,16 @@ ELFDumper<ELFT>::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
return errorToErrorCode(SymbolNameOrErr.takeError());
|
||||
S.Name = SymbolNameOrErr.get();
|
||||
|
||||
ErrorOr<const Elf_Shdr *> ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
|
||||
if (std::error_code EC = ShdrOrErr.getError())
|
||||
return EC;
|
||||
auto ShdrOrErr = Obj.getSection(Sym, SymTab, ShndxTable);
|
||||
if (!ShdrOrErr)
|
||||
return errorToErrorCode(ShdrOrErr.takeError());
|
||||
const Elf_Shdr *Shdr = *ShdrOrErr;
|
||||
if (!Shdr)
|
||||
return obj2yaml_error::success;
|
||||
|
||||
ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr);
|
||||
if (std::error_code EC = NameOrErr.getError())
|
||||
return EC;
|
||||
auto NameOrErr = Obj.getSectionName(Shdr);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
S.Section = NameOrErr.get();
|
||||
|
||||
return obj2yaml_error::success;
|
||||
@ -217,15 +217,15 @@ std::error_code ELFDumper<ELFT>::dumpRelocation(const RelT *Rel,
|
||||
R.Addend = 0;
|
||||
|
||||
auto SymOrErr = Obj.getRelocationSymbol(Rel, SymTab);
|
||||
if (std::error_code EC = SymOrErr.getError())
|
||||
return EC;
|
||||
if (!SymOrErr)
|
||||
return errorToErrorCode(SymOrErr.takeError());
|
||||
const Elf_Sym *Sym = *SymOrErr;
|
||||
ErrorOr<const Elf_Shdr *> StrTabSec = Obj.getSection(SymTab->sh_link);
|
||||
if (std::error_code EC = StrTabSec.getError())
|
||||
return EC;
|
||||
ErrorOr<StringRef> StrTabOrErr = Obj.getStringTable(*StrTabSec);
|
||||
if (std::error_code EC = StrTabOrErr.getError())
|
||||
return EC;
|
||||
auto StrTabSec = Obj.getSection(SymTab->sh_link);
|
||||
if (!StrTabSec)
|
||||
return errorToErrorCode(StrTabSec.takeError());
|
||||
auto StrTabOrErr = Obj.getStringTable(*StrTabSec);
|
||||
if (!StrTabOrErr)
|
||||
return errorToErrorCode(StrTabOrErr.takeError());
|
||||
StringRef StrTab = *StrTabOrErr;
|
||||
|
||||
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.AddressAlign = Shdr->sh_addralign;
|
||||
|
||||
ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr);
|
||||
if (std::error_code EC = NameOrErr.getError())
|
||||
return EC;
|
||||
auto NameOrErr = Obj.getSectionName(Shdr);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
S.Name = NameOrErr.get();
|
||||
|
||||
if (Shdr->sh_link != ELF::SHN_UNDEF) {
|
||||
ErrorOr<const Elf_Shdr *> LinkSection = Obj.getSection(Shdr->sh_link);
|
||||
if (std::error_code EC = LinkSection.getError())
|
||||
return EC;
|
||||
auto LinkSection = Obj.getSection(Shdr->sh_link);
|
||||
if (LinkSection.takeError())
|
||||
return errorToErrorCode(LinkSection.takeError());
|
||||
NameOrErr = Obj.getSectionName(*LinkSection);
|
||||
if (std::error_code EC = NameOrErr.getError())
|
||||
return EC;
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
S.Link = NameOrErr.get();
|
||||
}
|
||||
|
||||
@ -269,13 +269,13 @@ ELFDumper<ELFT>::dumpCommonRelocationSection(const Elf_Shdr *Shdr,
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, S))
|
||||
return EC;
|
||||
|
||||
ErrorOr<const Elf_Shdr *> InfoSection = Obj.getSection(Shdr->sh_info);
|
||||
if (std::error_code EC = InfoSection.getError())
|
||||
return EC;
|
||||
auto InfoSection = Obj.getSection(Shdr->sh_info);
|
||||
if (!InfoSection)
|
||||
return errorToErrorCode(InfoSection.takeError());
|
||||
|
||||
ErrorOr<StringRef> NameOrErr = Obj.getSectionName(*InfoSection);
|
||||
if (std::error_code EC = NameOrErr.getError())
|
||||
return EC;
|
||||
auto NameOrErr = Obj.getSectionName(*InfoSection);
|
||||
if (!NameOrErr)
|
||||
return errorToErrorCode(NameOrErr.takeError());
|
||||
S.Info = NameOrErr.get();
|
||||
|
||||
return obj2yaml_error::success;
|
||||
@ -290,14 +290,14 @@ ELFDumper<ELFT>::dumpRelSection(const Elf_Shdr *Shdr) {
|
||||
if (std::error_code EC = dumpCommonRelocationSection(Shdr, *S))
|
||||
return EC;
|
||||
|
||||
ErrorOr<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (std::error_code EC = SymTabOrErr.getError())
|
||||
return EC;
|
||||
auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (!SymTabOrErr)
|
||||
return errorToErrorCode(SymTabOrErr.takeError());
|
||||
const Elf_Shdr *SymTab = *SymTabOrErr;
|
||||
|
||||
auto Rels = Obj.rels(Shdr);
|
||||
if (std::error_code EC = Rels.getError())
|
||||
return EC;
|
||||
if (!Rels)
|
||||
return errorToErrorCode(Rels.takeError());
|
||||
for (const Elf_Rel &Rel : *Rels) {
|
||||
ELFYAML::Relocation 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))
|
||||
return EC;
|
||||
|
||||
ErrorOr<const Elf_Shdr *> SymTabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (std::error_code EC = SymTabOrErr.getError())
|
||||
return EC;
|
||||
auto SymTabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (!SymTabOrErr)
|
||||
return errorToErrorCode(SymTabOrErr.takeError());
|
||||
const Elf_Shdr *SymTab = *SymTabOrErr;
|
||||
|
||||
auto Rels = Obj.relas(Shdr);
|
||||
if (std::error_code EC = Rels.getError())
|
||||
return EC;
|
||||
if (!Rels)
|
||||
return errorToErrorCode(Rels.takeError());
|
||||
for (const Elf_Rela &Rel : *Rels) {
|
||||
ELFYAML::Relocation 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))
|
||||
return EC;
|
||||
|
||||
ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr);
|
||||
if (std::error_code EC = ContentOrErr.getError())
|
||||
return EC;
|
||||
auto ContentOrErr = Obj.getSectionContents(Shdr);
|
||||
if (!ContentOrErr)
|
||||
return errorToErrorCode(ContentOrErr.takeError());
|
||||
S->Content = yaml::BinaryRef(ContentOrErr.get());
|
||||
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))
|
||||
return EC;
|
||||
// Get sh_info which is the signature.
|
||||
ErrorOr<const Elf_Shdr *> SymtabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (std::error_code EC = SymtabOrErr.getError())
|
||||
return EC;
|
||||
auto SymtabOrErr = Obj.getSection(Shdr->sh_link);
|
||||
if (!SymtabOrErr)
|
||||
return errorToErrorCode(SymtabOrErr.takeError());
|
||||
const Elf_Shdr *Symtab = *SymtabOrErr;
|
||||
ErrorOr<const Elf_Sym *> SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
|
||||
if (std::error_code EC = SymOrErr.getError())
|
||||
return EC;
|
||||
auto SymOrErr = Obj.getSymbol(Symtab, Shdr->sh_info);
|
||||
if (!SymOrErr)
|
||||
return errorToErrorCode(SymOrErr.takeError());
|
||||
const Elf_Sym *symbol = *SymOrErr;
|
||||
ErrorOr<StringRef> StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
|
||||
if (std::error_code EC = StrTabOrErr.getError())
|
||||
return EC;
|
||||
auto StrTabOrErr = Obj.getStringTableForSymtab(*Symtab);
|
||||
if (!StrTabOrErr)
|
||||
return errorToErrorCode(StrTabOrErr.takeError());
|
||||
StringRef StrTab = *StrTabOrErr;
|
||||
auto sectionContents = Obj.getSectionContents(Shdr);
|
||||
if (std::error_code ec = sectionContents.getError())
|
||||
return ec;
|
||||
if (!sectionContents)
|
||||
return errorToErrorCode(sectionContents.takeError());
|
||||
Expected<StringRef> symbolName = symbol->getName(StrTab);
|
||||
if (!symbolName)
|
||||
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) {
|
||||
s.sectionNameOrType = "GRP_COMDAT";
|
||||
} else {
|
||||
ErrorOr<const Elf_Shdr *> sHdr = Obj.getSection(groupMembers[i]);
|
||||
if (std::error_code EC = sHdr.getError())
|
||||
return EC;
|
||||
ErrorOr<StringRef> sectionName = Obj.getSectionName(*sHdr);
|
||||
if (std::error_code ec = sectionName.getError())
|
||||
return ec;
|
||||
auto sHdr = Obj.getSection(groupMembers[i]);
|
||||
if (!sHdr)
|
||||
return errorToErrorCode(sHdr.takeError());
|
||||
auto sectionName = Obj.getSectionName(*sHdr);
|
||||
if (!sectionName)
|
||||
return errorToErrorCode(sectionName.takeError());
|
||||
s.sectionNameOrType = *sectionName;
|
||||
}
|
||||
S->Members.push_back(s);
|
||||
@ -421,9 +421,9 @@ ELFDumper<ELFT>::dumpMipsABIFlags(const Elf_Shdr *Shdr) {
|
||||
if (std::error_code EC = dumpCommonSection(Shdr, *S))
|
||||
return EC;
|
||||
|
||||
ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr);
|
||||
if (std::error_code EC = ContentOrErr.getError())
|
||||
return EC;
|
||||
auto ContentOrErr = Obj.getSectionContents(Shdr);
|
||||
if (!ContentOrErr)
|
||||
return errorToErrorCode(ContentOrErr.takeError());
|
||||
|
||||
auto *Flags = reinterpret_cast<const object::Elf_Mips_ABIFlags<ELFT> *>(
|
||||
ContentOrErr.get().data());
|
||||
|
Loading…
Reference in New Issue
Block a user