Update prebuilt Clang to r416183b from Android.
https://android.googlesource.com/platform/prebuilts/clang/host/
linux-x86/+/06a71ddac05c22edb2d10b590e1769b3f8619bef
clang 12.0.5 (based on r416183b) from build 7284624.
Change-Id: I277a316abcf47307562d8b748b84870f31a72866
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/linux-x64/clang/include/llvm/Object/ELFObjectFile.h b/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
index 86c015e..fed53ee 100644
--- a/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
+++ b/linux-x64/clang/include/llvm/Object/ELFObjectFile.h
@@ -28,8 +28,8 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/ARMAttributeParser.h"
-#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/ELFAttributes.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
@@ -41,7 +41,7 @@
namespace llvm {
namespace object {
-constexpr int NumElfSymbolTypes = 8;
+constexpr int NumElfSymbolTypes = 16;
extern const llvm::EnumEntry<unsigned> ElfSymbolTypes[NumElfSymbolTypes];
class elf_symbol_iterator;
@@ -51,6 +51,12 @@
friend class ELFSectionRef;
friend class ELFSymbolRef;
+ SubtargetFeatures getMIPSFeatures() const;
+ SubtargetFeatures getARMFeatures() const;
+ SubtargetFeatures getRISCVFeatures() const;
+
+ StringRef getAMDGPUCPUName() const;
+
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
@@ -64,7 +70,7 @@
virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
- virtual Error getBuildAttributes(ARMAttributeParser &Attributes) const = 0;
+ virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const = 0;
public:
using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
@@ -80,11 +86,7 @@
SubtargetFeatures getFeatures() const override;
- SubtargetFeatures getMIPSFeatures() const;
-
- SubtargetFeatures getARMFeatures() const;
-
- SubtargetFeatures getRISCVFeatures() const;
+ Optional<StringRef> tryGetCPUName() const override;
void setARMSubArch(Triple &TheTriple) const override;
@@ -92,7 +94,8 @@
virtual uint16_t getEMachine() const = 0;
- std::vector<std::pair<DataRefImpl, uint64_t>> getPltAddresses() const;
+ std::vector<std::pair<Optional<DataRefImpl>, uint64_t>>
+ getPltAddresses() const;
};
class ELFSectionRef : public SectionRef {
@@ -230,26 +233,31 @@
public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
- using uintX_t = typename ELFT::uint;
+ SectionRef toSectionRef(const Elf_Shdr *Sec) const {
+ return SectionRef(toDRI(Sec), this);
+ }
- using Elf_Sym = typename ELFT::Sym;
- using Elf_Shdr = typename ELFT::Shdr;
- using Elf_Ehdr = typename ELFT::Ehdr;
- using Elf_Rel = typename ELFT::Rel;
- using Elf_Rela = typename ELFT::Rela;
- using Elf_Dyn = typename ELFT::Dyn;
+ ELFSymbolRef toSymbolRef(const Elf_Shdr *SymTable, unsigned SymbolNum) const {
+ return ELFSymbolRef({toDRI(SymTable, SymbolNum), this});
+ }
+
+ bool IsContentValid() const { return ContentValid; }
private:
ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
const Elf_Shdr *DotDynSymSec, const Elf_Shdr *DotSymtabSec,
- ArrayRef<Elf_Word> ShndxTable);
+ const Elf_Shdr *DotSymtabShndxSec);
+
+ bool ContentValid = false;
protected:
ELFFile<ELFT> EF;
const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section.
const Elf_Shdr *DotSymtabSec = nullptr; // Symbol table section.
- ArrayRef<Elf_Word> ShndxTable;
+ const Elf_Shdr *DotSymtabShndxSec = nullptr; // SHT_SYMTAB_SHNDX section.
+
+ Error initContent() override;
void moveSymbolNext(DataRefImpl &Symb) const override;
Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
@@ -257,7 +265,7 @@
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
uint8_t getSymbolBinding(DataRefImpl Symb) const override;
uint8_t getSymbolOther(DataRefImpl Symb) const override;
uint8_t getSymbolELFType(DataRefImpl Symb) const override;
@@ -281,10 +289,12 @@
bool isSectionVirtual(DataRefImpl Sec) const override;
bool isBerkeleyText(DataRefImpl Sec) const override;
bool isBerkeleyData(DataRefImpl Sec) const override;
+ bool isDebugSection(StringRef SectionName) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
std::vector<SectionRef> dynamic_relocation_sections() const override;
- section_iterator getRelocatedSection(DataRefImpl Sec) const override;
+ Expected<section_iterator>
+ getRelocatedSection(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
@@ -298,14 +308,6 @@
uint64_t getSectionOffset(DataRefImpl Sec) const override;
StringRef getRelocationTypeName(uint32_t Type) const;
- /// Get the relocation section that contains \a Rel.
- const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
- 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 DRI;
if (!SymTable) {
@@ -360,22 +362,24 @@
(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
}
- Error getBuildAttributes(ARMAttributeParser &Attributes) const override {
+ Error getBuildAttributes(ELFAttributeParser &Attributes) const override {
auto SectionsOrErr = EF.sections();
if (!SectionsOrErr)
return SectionsOrErr.takeError();
for (const Elf_Shdr &Sec : *SectionsOrErr) {
- if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
- auto ErrorOrContents = EF.getSectionContents(&Sec);
+ if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
+ Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
+ auto ErrorOrContents = EF.getSectionContents(Sec);
if (!ErrorOrContents)
return ErrorOrContents.takeError();
auto Contents = ErrorOrContents.get();
- if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
+ if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1)
return Error::success();
- Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
+ if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness))
+ return E;
break;
}
}
@@ -389,16 +393,22 @@
public:
ELFObjectFile(ELFObjectFile<ELFT> &&Other);
- static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object);
+ static Expected<ELFObjectFile<ELFT>> create(MemoryBufferRef Object,
+ bool InitContent = true);
const Elf_Rel *getRel(DataRefImpl Rel) const;
const Elf_Rela *getRela(DataRefImpl Rela) const;
- const Elf_Sym *getSymbol(DataRefImpl Sym) const {
- auto Ret = EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
- if (!Ret)
- report_fatal_error(errorToErrorCode(Ret.takeError()).message());
- return *Ret;
+ Expected<const Elf_Sym *> getSymbol(DataRefImpl Sym) const {
+ return EF.template getEntry<Elf_Sym>(Sym.d.a, Sym.d.b);
+ }
+
+ /// Get the relocation section that contains \a Rel.
+ const Elf_Shdr *getRelSection(DataRefImpl Rel) const {
+ auto RelSecOrErr = EF.getSection(Rel.d.a);
+ if (!RelSecOrErr)
+ report_fatal_error(errorToErrorCode(RelSecOrErr.takeError()).message());
+ return *RelSecOrErr;
}
const Elf_Shdr *getSection(DataRefImpl Sec) const {
@@ -421,9 +431,9 @@
Triple::ArchType getArch() const override;
Expected<uint64_t> getStartAddress() const override;
- unsigned getPlatformFlags() const override { return EF.getHeader()->e_flags; }
+ unsigned getPlatformFlags() const override { return EF.getHeader().e_flags; }
- const ELFFile<ELFT> *getELFFile() const { return &EF; }
+ const ELFFile<ELFT> &getELFFile() const { return EF; }
bool isDyldType() const { return isDyldELFObject; }
static bool classof(const Binary *v) {
@@ -446,9 +456,40 @@
++Sym.d.b;
}
+template <class ELFT> Error ELFObjectFile<ELFT>::initContent() {
+ auto SectionsOrErr = EF.sections();
+ if (!SectionsOrErr)
+ return SectionsOrErr.takeError();
+
+ for (const Elf_Shdr &Sec : *SectionsOrErr) {
+ switch (Sec.sh_type) {
+ case ELF::SHT_DYNSYM: {
+ if (!DotDynSymSec)
+ DotDynSymSec = &Sec;
+ break;
+ }
+ case ELF::SHT_SYMTAB: {
+ if (!DotSymtabSec)
+ DotSymtabSec = &Sec;
+ break;
+ }
+ case ELF::SHT_SYMTAB_SHNDX: {
+ if (!DotSymtabShndxSec)
+ DotSymtabShndxSec = &Sec;
+ break;
+ }
+ }
+ }
+
+ ContentValid = true;
+ return Error::success();
+}
+
template <class ELFT>
Expected<StringRef> ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Sym) const {
- const Elf_Sym *ESym = getSymbol(Sym);
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
auto SymTabOrErr = EF.getSection(Sym.d.a);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
@@ -457,17 +498,19 @@
if (!StrTabOrErr)
return StrTabOrErr.takeError();
const Elf_Shdr *StringTableSec = *StrTabOrErr;
- auto SymStrTabOrErr = EF.getStringTable(StringTableSec);
+ auto SymStrTabOrErr = EF.getStringTable(*StringTableSec);
if (!SymStrTabOrErr)
return SymStrTabOrErr.takeError();
- Expected<StringRef> Name = ESym->getName(*SymStrTabOrErr);
+ Expected<StringRef> Name = (*SymOrErr)->getName(*SymStrTabOrErr);
+ if (Name && !Name->empty())
+ return Name;
// If the symbol name is empty use the section name.
- if ((!Name || Name->empty()) && ESym->getType() == ELF::STT_SECTION) {
- StringRef SecName;
- Expected<section_iterator> Sec = getSymbolSection(Sym);
- if (Sec && !(*Sec)->getName(SecName))
- return SecName;
+ if ((*SymOrErr)->getType() == ELF::STT_SECTION) {
+ if (Expected<section_iterator> SecOrErr = getSymbolSection(Sym)) {
+ consumeError(Name.takeError());
+ return (*SecOrErr)->getName();
+ }
}
return Name;
}
@@ -489,15 +532,18 @@
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
- const Elf_Sym *ESym = getSymbol(Symb);
- uint64_t Ret = ESym->st_value;
- if (ESym->st_shndx == ELF::SHN_ABS)
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+
+ uint64_t Ret = (*SymOrErr)->st_value;
+ if ((*SymOrErr)->st_shndx == ELF::SHN_ABS)
return Ret;
- const Elf_Ehdr *Header = EF.getHeader();
+ const Elf_Ehdr &Header = EF.getHeader();
// Clear the ARM/Thumb or microMIPS indicator flag.
- if ((Header->e_machine == ELF::EM_ARM || Header->e_machine == ELF::EM_MIPS) &&
- ESym->getType() == ELF::STT_FUNC)
+ if ((Header.e_machine == ELF::EM_ARM || Header.e_machine == ELF::EM_MIPS) &&
+ (*SymOrErr)->getType() == ELF::STT_FUNC)
Ret &= ~1;
return Ret;
@@ -506,23 +552,40 @@
template <class ELFT>
Expected<uint64_t>
ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
- uint64_t Result = getSymbolValue(Symb);
- const Elf_Sym *ESym = getSymbol(Symb);
- switch (ESym->st_shndx) {
+ Expected<uint64_t> SymbolValueOrErr = getSymbolValue(Symb);
+ if (!SymbolValueOrErr)
+ // TODO: Test this error.
+ return SymbolValueOrErr.takeError();
+
+ uint64_t Result = *SymbolValueOrErr;
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
+
+ switch ((*SymOrErr)->st_shndx) {
case ELF::SHN_COMMON:
case ELF::SHN_UNDEF:
case ELF::SHN_ABS:
return Result;
}
- const Elf_Ehdr *Header = EF.getHeader();
auto SymTabOrErr = EF.getSection(Symb.d.a);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
- const Elf_Shdr *SymTab = *SymTabOrErr;
- if (Header->e_type == ELF::ET_REL) {
- auto SectionOrErr = EF.getSection(ESym, SymTab, ShndxTable);
+ if (EF.getHeader().e_type == ELF::ET_REL) {
+ ArrayRef<Elf_Word> ShndxTable;
+ if (DotSymtabShndxSec) {
+ // TODO: Test this error.
+ if (Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
+ EF.getSHNDXTable(*DotSymtabShndxSec))
+ ShndxTable = *ShndxTableOrErr;
+ else
+ return ShndxTableOrErr.takeError();
+ }
+
+ Expected<const Elf_Shdr *> SectionOrErr =
+ EF.getSection(**SymOrErr, *SymTabOrErr, ShndxTable);
if (!SectionOrErr)
return SectionOrErr.takeError();
const Elf_Shdr *Section = *SectionOrErr;
@@ -535,52 +598,68 @@
template <class ELFT>
uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
- const Elf_Sym *Sym = getSymbol(Symb);
- if (Sym->st_shndx == ELF::SHN_COMMON)
- return Sym->st_value;
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ if ((*SymOrErr)->st_shndx == ELF::SHN_COMMON)
+ return (*SymOrErr)->st_value;
return 0;
}
template <class ELFT>
uint16_t ELFObjectFile<ELFT>::getEMachine() const {
- return EF.getHeader()->e_machine;
+ return EF.getHeader().e_machine;
}
template <class ELFT> uint16_t ELFObjectFile<ELFT>::getEType() const {
- return EF.getHeader()->e_type;
+ return EF.getHeader().e_type;
}
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
- return getSymbol(Sym)->st_size;
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->st_size;
}
template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
- return getSymbol(Symb)->st_size;
+ return getSymbolSize(Symb);
}
template <class ELFT>
uint8_t ELFObjectFile<ELFT>::getSymbolBinding(DataRefImpl Symb) const {
- return getSymbol(Symb)->getBinding();
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->getBinding();
}
template <class ELFT>
uint8_t ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb) const {
- return getSymbol(Symb)->st_other;
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->st_other;
}
template <class ELFT>
uint8_t ELFObjectFile<ELFT>::getSymbolELFType(DataRefImpl Symb) const {
- return getSymbol(Symb)->getType();
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ report_fatal_error(SymOrErr.takeError());
+ return (*SymOrErr)->getType();
}
template <class ELFT>
Expected<SymbolRef::Type>
ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
- const Elf_Sym *ESym = getSymbol(Symb);
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
- switch (ESym->getType()) {
+ switch ((*SymOrErr)->getType()) {
case ELF::STT_NOTYPE:
return SymbolRef::ST_Unknown;
case ELF::STT_SECTION:
@@ -599,9 +678,12 @@
}
template <class ELFT>
-uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
- const Elf_Sym *ESym = getSymbol(Sym);
+Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Sym);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
+ const Elf_Sym *ESym = *SymOrErr;
uint32_t Result = SymbolRef::SF_None;
if (ESym->getBinding() != ELF::STB_LOCAL)
@@ -616,14 +698,25 @@
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 (Expected<typename ELFT::SymRange> SymbolsOrErr =
+ EF.symbols(DotSymtabSec)) {
+ // Set the SF_FormatSpecific flag for the 0-index null symbol.
+ if (ESym == SymbolsOrErr->begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else
+ // TODO: Test this error.
+ return SymbolsOrErr.takeError();
- if (EF.getHeader()->e_machine == ELF::EM_ARM) {
+ if (Expected<typename ELFT::SymRange> SymbolsOrErr =
+ EF.symbols(DotDynSymSec)) {
+ // Set the SF_FormatSpecific flag for the 0-index null symbol.
+ if (ESym == SymbolsOrErr->begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else
+ // TODO: Test this error.
+ return SymbolsOrErr.takeError();
+
+ if (EF.getHeader().e_machine == ELF::EM_ARM) {
if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
StringRef Name = *NameOrErr;
if (Name.startswith("$d") || Name.startswith("$t") ||
@@ -656,7 +749,17 @@
Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(const Elf_Sym *ESym,
const Elf_Shdr *SymTab) const {
- auto ESecOrErr = EF.getSection(ESym, SymTab, ShndxTable);
+ ArrayRef<Elf_Word> ShndxTable;
+ if (DotSymtabShndxSec) {
+ // TODO: Test this error.
+ Expected<ArrayRef<Elf_Word>> ShndxTableOrErr =
+ EF.getSHNDXTable(*DotSymtabShndxSec);
+ if (!ShndxTableOrErr)
+ return ShndxTableOrErr.takeError();
+ ShndxTable = *ShndxTableOrErr;
+ }
+
+ auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable);
if (!ESecOrErr)
return ESecOrErr.takeError();
@@ -672,12 +775,14 @@
template <class ELFT>
Expected<section_iterator>
ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb) const {
- const Elf_Sym *Sym = getSymbol(Symb);
+ Expected<const Elf_Sym *> SymOrErr = getSymbol(Symb);
+ if (!SymOrErr)
+ return SymOrErr.takeError();
+
auto SymTabOrErr = EF.getSection(Symb.d.a);
if (!SymTabOrErr)
return SymTabOrErr.takeError();
- const Elf_Shdr *SymTab = *SymTabOrErr;
- return getSymbolSection(Sym, SymTab);
+ return getSymbolSection(*SymOrErr, *SymTabOrErr);
}
template <class ELFT>
@@ -688,7 +793,7 @@
template <class ELFT>
Expected<StringRef> ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec) const {
- return EF.getSectionName(&*getSection(Sec));
+ return EF.getSectionName(*getSection(Sec));
}
template <class ELFT>
@@ -716,10 +821,12 @@
Expected<ArrayRef<uint8_t>>
ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
const Elf_Shdr *EShdr = getSection(Sec);
- if (std::error_code EC =
+ if (EShdr->sh_type == ELF::SHT_NOBITS)
+ return makeArrayRef((const uint8_t *)base(), 0);
+ if (Error E =
checkOffset(getMemoryBufferRef(),
(uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
- return errorCodeToError(EC);
+ return std::move(E);
return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
EShdr->sh_size);
}
@@ -803,6 +910,12 @@
}
template <class ELFT>
+bool ELFObjectFile<ELFT>::isDebugSection(StringRef SectionName) const {
+ return SectionName.startswith(".debug") ||
+ SectionName.startswith(".zdebug") || SectionName == ".gdb_index";
+}
+
+template <class ELFT>
relocation_iterator
ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
DataRefImpl RelData;
@@ -810,7 +923,7 @@
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;
return relocation_iterator(RelocationRef(RelData, this));
}
@@ -835,9 +948,9 @@
}
template <class ELFT>
-section_iterator
+Expected<section_iterator>
ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
- if (EF.getHeader()->e_type != ELF::ET_REL)
+ if (EF.getHeader().e_type != ELF::ET_REL)
return section_end();
const Elf_Shdr *EShdr = getSection(Sec);
@@ -845,10 +958,10 @@
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
return section_end();
- auto R = EF.getSection(EShdr->sh_info);
- if (!R)
- report_fatal_error(errorToErrorCode(R.takeError()).message());
- return section_iterator(SectionRef(toDRI(*R), this));
+ Expected<const Elf_Shdr *> SecOrErr = EF.getSection(EShdr->sh_info);
+ if (!SecOrErr)
+ return SecOrErr.takeError();
+ return section_iterator(SectionRef(toDRI(*SecOrErr), this));
}
// Relocations
@@ -896,7 +1009,7 @@
template <class ELFT>
StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const {
- return getELFRelocationTypeName(EF.getHeader()->e_machine, Type);
+ return getELFRelocationTypeName(EF.getHeader().e_machine, Type);
}
template <class ELFT>
@@ -936,59 +1049,34 @@
template <class ELFT>
Expected<ELFObjectFile<ELFT>>
-ELFObjectFile<ELFT>::create(MemoryBufferRef Object) {
+ELFObjectFile<ELFT>::create(MemoryBufferRef Object, bool InitContent) {
auto EFOrErr = ELFFile<ELFT>::create(Object.getBuffer());
if (Error E = EFOrErr.takeError())
return std::move(E);
- auto EF = std::move(*EFOrErr);
- auto SectionsOrErr = EF.sections();
- if (!SectionsOrErr)
- return SectionsOrErr.takeError();
-
- const Elf_Shdr *DotDynSymSec = nullptr;
- const Elf_Shdr *DotSymtabSec = nullptr;
- ArrayRef<Elf_Word> ShndxTable;
- for (const Elf_Shdr &Sec : *SectionsOrErr) {
- switch (Sec.sh_type) {
- case ELF::SHT_DYNSYM: {
- if (!DotDynSymSec)
- DotDynSymSec = &Sec;
- break;
- }
- case ELF::SHT_SYMTAB: {
- if (!DotSymtabSec)
- DotSymtabSec = &Sec;
- break;
- }
- case ELF::SHT_SYMTAB_SHNDX: {
- auto TableOrErr = EF.getSHNDXTable(Sec);
- if (!TableOrErr)
- return TableOrErr.takeError();
- ShndxTable = *TableOrErr;
- break;
- }
- }
- }
- return ELFObjectFile<ELFT>(Object, EF, DotDynSymSec, DotSymtabSec,
- ShndxTable);
+ ELFObjectFile<ELFT> Obj = {Object, std::move(*EFOrErr), nullptr, nullptr,
+ nullptr};
+ if (InitContent)
+ if (Error E = Obj.initContent())
+ return std::move(E);
+ return std::move(Obj);
}
template <class ELFT>
ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, ELFFile<ELFT> EF,
const Elf_Shdr *DotDynSymSec,
const Elf_Shdr *DotSymtabSec,
- ArrayRef<Elf_Word> ShndxTable)
+ const Elf_Shdr *DotSymtabShndx)
: ELFObjectFileBase(
getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits),
Object),
EF(EF), DotDynSymSec(DotDynSymSec), DotSymtabSec(DotSymtabSec),
- ShndxTable(ShndxTable) {}
+ DotSymtabShndxSec(DotSymtabShndx) {}
template <class ELFT>
ELFObjectFile<ELFT>::ELFObjectFile(ELFObjectFile<ELFT> &&Other)
: ELFObjectFile(Other.Data, Other.EF, Other.DotDynSymSec,
- Other.DotSymtabSec, Other.ShndxTable) {}
+ Other.DotSymtabSec, Other.DotSymtabShndxSec) {}
template <class ELFT>
basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin() const {
@@ -1009,8 +1097,12 @@
template <class ELFT>
elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
- DataRefImpl Sym = toDRI(DotDynSymSec, 0);
- return symbol_iterator(SymbolRef(Sym, this));
+ if (!DotDynSymSec || DotDynSymSec->sh_size < sizeof(Elf_Sym))
+ // Ignore errors here where the dynsym is empty or sh_size less than the
+ // size of one symbol. These should be handled elsewhere.
+ return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 0), this));
+ // Skip 0-index NULL symbol.
+ return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 1), this));
}
template <class ELFT>
@@ -1046,63 +1138,67 @@
template <class ELFT>
StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
bool IsLittleEndian = ELFT::TargetEndianness == support::little;
- switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
- switch (EF.getHeader()->e_machine) {
+ switch (EF.getHeader().e_machine) {
case ELF::EM_386:
- return "ELF32-i386";
+ return "elf32-i386";
case ELF::EM_IAMCU:
- return "ELF32-iamcu";
+ return "elf32-iamcu";
case ELF::EM_X86_64:
- return "ELF32-x86-64";
+ return "elf32-x86-64";
case ELF::EM_ARM:
- return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
+ return (IsLittleEndian ? "elf32-littlearm" : "elf32-bigarm");
case ELF::EM_AVR:
- return "ELF32-avr";
+ return "elf32-avr";
case ELF::EM_HEXAGON:
- return "ELF32-hexagon";
+ return "elf32-hexagon";
case ELF::EM_LANAI:
- return "ELF32-lanai";
+ return "elf32-lanai";
case ELF::EM_MIPS:
- return "ELF32-mips";
+ return "elf32-mips";
case ELF::EM_MSP430:
- return "ELF32-msp430";
+ return "elf32-msp430";
case ELF::EM_PPC:
- return "ELF32-ppc";
+ return (IsLittleEndian ? "elf32-powerpcle" : "elf32-powerpc");
case ELF::EM_RISCV:
- return "ELF32-riscv";
+ return "elf32-littleriscv";
+ case ELF::EM_CSKY:
+ return "elf32-csky";
case ELF::EM_SPARC:
case ELF::EM_SPARC32PLUS:
- return "ELF32-sparc";
+ return "elf32-sparc";
case ELF::EM_AMDGPU:
- return "ELF32-amdgpu";
+ return "elf32-amdgpu";
default:
- return "ELF32-unknown";
+ return "elf32-unknown";
}
case ELF::ELFCLASS64:
- switch (EF.getHeader()->e_machine) {
+ switch (EF.getHeader().e_machine) {
case ELF::EM_386:
- return "ELF64-i386";
+ return "elf64-i386";
case ELF::EM_X86_64:
- return "ELF64-x86-64";
+ return "elf64-x86-64";
case ELF::EM_AARCH64:
- return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
+ return (IsLittleEndian ? "elf64-littleaarch64" : "elf64-bigaarch64");
case ELF::EM_PPC64:
- return "ELF64-ppc64";
+ return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
case ELF::EM_RISCV:
- return "ELF64-riscv";
+ return "elf64-littleriscv";
case ELF::EM_S390:
- return "ELF64-s390";
+ return "elf64-s390";
case ELF::EM_SPARCV9:
- return "ELF64-sparc";
+ return "elf64-sparc";
case ELF::EM_MIPS:
- return "ELF64-mips";
+ return "elf64-mips";
case ELF::EM_AMDGPU:
- return "ELF64-amdgpu";
+ return "elf64-amdgpu";
case ELF::EM_BPF:
- return "ELF64-BPF";
+ return "elf64-bpf";
+ case ELF::EM_VE:
+ return "elf64-ve";
default:
- return "ELF64-unknown";
+ return "elf64-unknown";
}
default:
// FIXME: Proper error handling.
@@ -1112,7 +1208,7 @@
template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
bool IsLittleEndian = ELFT::TargetEndianness == support::little;
- switch (EF.getHeader()->e_machine) {
+ switch (EF.getHeader().e_machine) {
case ELF::EM_386:
case ELF::EM_IAMCU:
return Triple::x86;
@@ -1129,7 +1225,7 @@
case ELF::EM_LANAI:
return Triple::lanai;
case ELF::EM_MIPS:
- switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
return IsLittleEndian ? Triple::mipsel : Triple::mips;
case ELF::ELFCLASS64:
@@ -1140,11 +1236,11 @@
case ELF::EM_MSP430:
return Triple::msp430;
case ELF::EM_PPC:
- return Triple::ppc;
+ return IsLittleEndian ? Triple::ppcle : Triple::ppc;
case ELF::EM_PPC64:
return IsLittleEndian ? Triple::ppc64le : Triple::ppc64;
case ELF::EM_RISCV:
- switch (EF.getHeader()->e_ident[ELF::EI_CLASS]) {
+ switch (EF.getHeader().e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
return Triple::riscv32;
case ELF::ELFCLASS64:
@@ -1165,7 +1261,7 @@
if (!IsLittleEndian)
return Triple::UnknownArch;
- unsigned MACH = EF.getHeader()->e_flags & ELF::EF_AMDGPU_MACH;
+ unsigned MACH = EF.getHeader().e_flags & ELF::EF_AMDGPU_MACH;
if (MACH >= ELF::EF_AMDGPU_MACH_R600_FIRST &&
MACH <= ELF::EF_AMDGPU_MACH_R600_LAST)
return Triple::r600;
@@ -1179,6 +1275,10 @@
case ELF::EM_BPF:
return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
+ case ELF::EM_VE:
+ return Triple::ve;
+ case ELF::EM_CSKY:
+ return Triple::csky;
default:
return Triple::UnknownArch;
}
@@ -1186,7 +1286,7 @@
template <class ELFT>
Expected<uint64_t> ELFObjectFile<ELFT>::getStartAddress() const {
- return EF.getHeader()->e_entry;
+ return EF.getHeader().e_entry;
}
template <class ELFT>
@@ -1196,7 +1296,7 @@
}
template <class ELFT> bool ELFObjectFile<ELFT>::isRelocatableObject() const {
- return EF.getHeader()->e_type == ELF::ET_REL;
+ return EF.getHeader().e_type == ELF::ET_REL;
}
} // end namespace object