9#ifndef LLVM_OBJECT_ELFTYPES_H
10#define LLVM_OBJECT_ELFTYPES_H
29template <
class ELFT>
struct Elf_Ehdr_Impl;
30template <
class ELFT>
struct Elf_Shdr_Impl;
31template <
class ELFT>
struct Elf_Sym_Impl;
32template <
class ELFT>
struct Elf_Dyn_Impl;
48template <endianness E,
bool Is64>
struct ELFType {
50 template <
typename Ty>
57 using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
104#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \
105 using Elf_Addr = typename ELFT::Addr; \
106 using Elf_Off = typename ELFT::Off; \
107 using Elf_Half = typename ELFT::Half; \
108 using Elf_Word = typename ELFT::Word; \
109 using Elf_Sword = typename ELFT::Sword; \
110 using Elf_Xword = typename ELFT::Xword; \
111 using Elf_Sxword = typename ELFT::Sxword; \
112 using uintX_t = typename ELFT::uint; \
113 using Elf_Ehdr = typename ELFT::Ehdr; \
114 using Elf_Shdr = typename ELFT::Shdr; \
115 using Elf_Sym = typename ELFT::Sym; \
116 using Elf_Dyn = typename ELFT::Dyn; \
117 using Elf_Phdr = typename ELFT::Phdr; \
118 using Elf_Rel = typename ELFT::Rel; \
119 using Elf_Rela = typename ELFT::Rela; \
120 using Elf_Relr = typename ELFT::Relr; \
121 using Elf_Verdef = typename ELFT::Verdef; \
122 using Elf_Verdaux = typename ELFT::Verdaux; \
123 using Elf_Verneed = typename ELFT::Verneed; \
124 using Elf_Vernaux = typename ELFT::Vernaux; \
125 using Elf_Versym = typename ELFT::Versym; \
126 using Elf_Hash = typename ELFT::Hash; \
127 using Elf_GnuHash = typename ELFT::GnuHash; \
128 using Elf_Chdr = typename ELFT::Chdr; \
129 using Elf_Nhdr = typename ELFT::Nhdr; \
130 using Elf_Note = typename ELFT::Note; \
131 using Elf_Note_Iterator = typename ELFT::NoteIterator; \
132 using Elf_CGProfile = typename ELFT::CGProfile; \
133 using Elf_Dyn_Range = typename ELFT::DynRange; \
134 using Elf_Shdr_Range = typename ELFT::ShdrRange; \
135 using Elf_Sym_Range = typename ELFT::SymRange; \
136 using Elf_Rel_Range = typename ELFT::RelRange; \
137 using Elf_Rela_Range = typename ELFT::RelaRange; \
138 using Elf_Relr_Range = typename ELFT::RelrRange; \
139 using Elf_Phdr_Range = typename ELFT::PhdrRange;
141#define LLVM_ELF_COMMA ,
142#define LLVM_ELF_IMPORT_TYPES(E, W) \
143 LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
148template <endianness TargetEndianness>
159 Elf_Word sh_addralign;
163template <endianness TargetEndianness>
174 Elf_Xword sh_addralign;
175 Elf_Xword sh_entsize;
187 return sh_size / sh_entsize;
193template <endianness TargetEndianness>
199 unsigned char st_info;
200 unsigned char st_other;
208 unsigned char st_info;
209 unsigned char st_other;
225 unsigned char getType()
const {
return st_info & 0x0f; }
228 void setType(
unsigned char t) { setBindingAndType(getBinding(), t); }
231 st_info = (b << 4) + (t & 0x0f);
241 assert(v < 4 &&
"Invalid value for visibility");
242 st_other = (st_other & ~0x3) | v;
248 return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON;
254 return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC;
258 return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS;
264 return st_shndx >= ELF::SHN_LORESERVE;
270 return getBinding() != ELF::STB_LOCAL;
281 "st_name (0x%" PRIx32
282 ") is past the end of the string table"
311 return reinterpret_cast<const Elf_Verdaux *
>((
const char *)
this + vd_aux);
362template <endianness TargetEndianness>
377 using intX_t = std::conditional_t<ELFT::Is64Bits, int64_t, int32_t>;
378 using uintX_t = std::conditional_t<ELFT::Is64Bits, uint64_t, uint32_t>;
384template <endianness TargetEndianness>
406 return (
unsigned char)(this->getRInfo(
isMips64EL) & 0x0ff);
409 setSymbolAndType(s,
getType(IsMips64EL), IsMips64EL);
411 void setType(
unsigned char t,
bool IsMips64EL) {
412 setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
415 this->setRInfo((s << 8) + t, IsMips64EL);
419template <endianness TargetEndianness>
421 :
public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
441 return (t << 32) | ((t >> 8) & 0xff000000) | ((t >> 24) & 0x00ff0000) |
442 ((t >> 40) & 0x0000ff00) | ((t >> 56) & 0x000000ff);
447 r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
448 ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
462 setSymbolAndType(s,
getType(IsMips64EL), IsMips64EL);
465 setSymbolAndType(getSymbol(IsMips64EL), t, IsMips64EL);
468 this->setRInfo(((
uint64_t)s << 32) + (t & 0xffffffffL), IsMips64EL);
472template <endianness TargetEndianness>
474 :
public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
492 Elf_Half e_phentsize;
494 Elf_Half e_shentsize;
499 bool checkMagic()
const {
500 return (
memcmp(e_ident, ELF::ElfMagic, strlen(ELF::ElfMagic))) == 0;
507template <endianness TargetEndianness>
546 &nbucket + 2 + nbucket + nchain);
566 reinterpret_cast<const Elf_Word *
>(filter().end()), nbuckets);
570 assert(DynamicSymCount >= symndx);
577template <endianness TargetEndianness>
582 Elf_Word ch_addralign;
589 Elf_Word ch_reserved;
591 Elf_Xword ch_addralign;
631 return StringRef(
reinterpret_cast<const char *
>(&Nhdr) +
sizeof(Nhdr),
640 reinterpret_cast<const uint8_t *
>(&Nhdr) +
666 size_t RemainingSize = 0u;
668 Error *Err =
nullptr;
670 template <
class ELFFileELFT>
friend class ELFFile;
673 void stopWithOverflowError() {
675 *Err = make_error<StringError>(
"ELF note overflows container",
676 object_error::parse_failed);
684 void advanceNhdr(
const uint8_t *NhdrPos,
size_t NoteSize) {
685 RemainingSize -= NoteSize;
686 if (RemainingSize == 0u) {
689 *Err = Error::success();
691 }
else if (
sizeof(*Nhdr) > RemainingSize)
692 stopWithOverflowError();
694 Nhdr =
reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *
>(NhdrPos + NoteSize);
696 stopWithOverflowError();
698 *Err = Error::success();
702 Elf_Note_Iterator_Impl() =
default;
703 explicit Elf_Note_Iterator_Impl(Error &Err) : Err(&Err) {}
704 Elf_Note_Iterator_Impl(
const uint8_t *Start,
size_t Size,
size_t Align,
708 assert(Start &&
"ELF note iterator starting at NULL");
709 advanceNhdr(Start, 0u);
714 assert(Nhdr &&
"incremented ELF note end iterator");
715 const uint8_t *NhdrPos =
reinterpret_cast<const uint8_t *
>(Nhdr);
717 advanceNhdr(NhdrPos, NoteSize);
721 if (!Nhdr &&
Other.Err)
722 (void)(
bool)(*
Other.Err);
723 if (!
Other.Nhdr && Err)
725 return Nhdr ==
Other.Nhdr;
728 return !(*
this ==
Other);
731 assert(Nhdr &&
"dereferenced ELF note end iterator");
738 Elf_Xword cgp_weight;
745template <support::
endianness TargetEndianness>
749 Elf_Word ri_cprmask[4];
750 Elf_Addr ri_gp_value;
753template <support::
endianness TargetEndianness>
758 Elf_Word ri_cprmask[4];
759 Elf_Addr ri_gp_value;
772 assert(kind == ELF::ODK_REGINFO);
812 return HasReturn ==
Other.HasReturn &&
813 HasTailCall ==
Other.HasTailCall && IsEHPad ==
Other.IsEHPad &&
814 CanFallThrough ==
Other.CanFallThrough &&
815 HasIndirectBranch ==
Other.HasIndirectBranch;
820 return static_cast<uint32_t>(HasReturn) |
821 (
static_cast<uint32_t>(HasTailCall) << 1) |
822 (
static_cast<uint32_t>(IsEHPad) << 2) |
823 (
static_cast<uint32_t>(CanFallThrough) << 3) |
824 (
static_cast<uint32_t>(HasIndirectBranch) << 4);
829 Metadata MD{
static_cast<bool>(V & 1),
830 static_cast<bool>(V & (1 << 1)),
831 static_cast<bool>(V & (1 << 2)),
832 static_cast<bool>(V & (1 << 3)),
833 static_cast<bool>(V & (1 << 4))};
834 if (MD.encode() != V)
836 std::error_code(),
"invalid encoding for BBEntry::Metadata: 0x%x",
864 return Addr ==
Other.Addr && std::equal(BBEntries.begin(), BBEntries.end(),
865 Other.BBEntries.begin());
llvm::support::endianness endianness
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool isMips64EL(const ELFYAML::Object &Obj)
#define LLVM_ELF_IMPORT_TYPES(E, W)
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
std::optional< std::vector< StOtherPiece > > Other
Merge contiguous icmps into a memcmp
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static SymbolRef::Type getType(const Symbol *Sym)
static unsigned getSize(unsigned Kind)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
StringRef getDescAsStringRef(size_t Align) const
Get the note's descriptor as StringRef.
Elf_Word getType() const
Get the note's type.
Elf_Note_Impl(const Elf_Nhdr_Impl< ELFT > &Nhdr)
StringRef getName() const
Get the note's name, excluding the terminating null byte.
ArrayRef< uint8_t > getDesc(size_t Align) const
Get the note's descriptor.
bool operator!=(Elf_Note_Iterator_Impl Other) const
std::forward_iterator_tag iterator_category
std::ptrdiff_t difference_type
Elf_Note_Impl< ELFT > operator*() const
Elf_Note_Iterator_Impl & operator++()
bool operator==(Elf_Note_Iterator_Impl Other) const
This is an optimization pass for GlobalISel generic memory operations.
uint64_t alignToPowerOf2(uint64_t Value, uint64_t Align)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
void consumeError(Error Err)
Consume a Error without doing anything.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static Expected< Metadata > decode(uint32_t V)
bool operator==(const Metadata &Other) const
bool canFallThrough() const
bool operator==(const BBEntry &Other) const
BBEntry(uint32_t ID, uint32_t Offset, uint32_t Size, Metadata MD)
std::vector< BBEntry > BBEntries
bool operator==(const BBAddrMap &Other) const
std::conditional_t< Is64, uint64_t, uint32_t > uint
static const bool Is64Bits
static const endianness TargetEndianness
Elf_Dyn_Base: This structure matches the form of entries in the dynamic table section (....
Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
std::conditional_t< ELFT::Is64Bits, int64_t, int32_t > intX_t
std::conditional_t< ELFT::Is64Bits, uint64_t, uint32_t > uintX_t
unsigned char getFileClass() const
unsigned char getDataEncoding() const
ArrayRef< Elf_Word > values(unsigned DynamicSymCount) const
ArrayRef< Elf_Word > buckets() const
ArrayRef< Elf_Word > chains() const
const Elf_Mips_RegInfo< ELFT > & getRegInfo() const
size_t getSize(size_t Align) const
Get the size of the note, including name, descriptor, and padding.
void setSymbol(uint32_t s, bool IsMips64EL)
void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL)
void setType(unsigned char t, bool IsMips64EL)
uint32_t getSymbol(bool isMips64EL) const
unsigned char getType(bool isMips64EL) const
void setRInfo(uint32_t R, bool IsMips64EL)
void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL)
void setRInfo(uint64_t R, bool IsMips64EL)
uint32_t getSymbol(bool isMips64EL) const
void setSymbol(uint32_t s, bool IsMips64EL)
void setType(uint32_t t, bool IsMips64EL)
uint32_t getType(bool isMips64EL) const
unsigned getEntityCount() const
Get the number of entities this section contains if it has any.
void setBindingAndType(unsigned char b, unsigned char t)
bool isProcessorSpecific() const
void setBinding(unsigned char b)
unsigned char getBinding() const
bool isOSSpecific() const
unsigned char getType() const
uint64_t getValue() const
void setVisibility(unsigned char v)
void setType(unsigned char t)
unsigned char getVisibility() const
Access to the STV_xxx flag stored in the first two bits of st_other.
Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef section (....
Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section (.gnu.version_d).
Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed section (....
Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed section (.gnu....
Elf_Versym: This is the structure of entries in the SHT_GNU_versym section (.gnu.version).