Go to the documentation of this file.
9 #ifndef LLVM_OBJECT_ELFTYPES_H
10 #define LLVM_OBJECT_ELFTYPES_H
22 #include <type_traits>
48 template <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_Nhdr = typename ELFT::Nhdr; \
129 using Elf_Note = typename ELFT::Note; \
130 using Elf_Note_Iterator = typename ELFT::NoteIterator; \
131 using Elf_CGProfile = typename ELFT::CGProfile; \
132 using Elf_Dyn_Range = typename ELFT::DynRange; \
133 using Elf_Shdr_Range = typename ELFT::ShdrRange; \
134 using Elf_Sym_Range = typename ELFT::SymRange; \
135 using Elf_Rel_Range = typename ELFT::RelRange; \
136 using Elf_Rela_Range = typename ELFT::RelaRange; \
137 using Elf_Relr_Range = typename ELFT::RelrRange; \
138 using Elf_Phdr_Range = typename ELFT::PhdrRange;
140 #define LLVM_ELF_COMMA ,
141 #define LLVM_ELF_IMPORT_TYPES(E, W) \
142 LLVM_ELF_IMPORT_TYPES_ELFT(ELFType<E LLVM_ELF_COMMA W>)
147 template <endianness TargetEndianness>
158 Elf_Word sh_addralign;
173 Elf_Xword sh_addralign;
174 Elf_Xword sh_entsize;
177 template <class ELFT>
186 return sh_size / sh_entsize;
192 template <endianness TargetEndianness>
198 unsigned char st_info;
199 unsigned char st_other;
207 unsigned char st_info;
208 unsigned char st_other;
214 template <class ELFT>
224 unsigned char getType()
const {
return st_info & 0x0f; }
227 void setType(
unsigned char t) { setBindingAndType(getBinding(),
t); }
230 st_info = (
b << 4) + (
t & 0x0f);
240 assert(v < 4 &&
"Invalid value for visibility");
241 st_other = (st_other & ~0x3) | v;
275 template <
class ELFT>
278 if (Offset >= StrTab.
size())
280 "st_name (0x%" PRIx32
281 ") is past the end of the string table"
283 Offset, StrTab.
size());
289 template <
class ELFT>
297 template <class ELFT>
310 return reinterpret_cast<const Elf_Verdaux *
>((
const char *)
this + vd_aux);
316 template <
class ELFT>
317 struct Elf_Verdaux_Impl {
325 template <class ELFT>
337 template <class ELFT>
361 template <endianness TargetEndianness>
372 template <
class ELFT>
373 struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
374 using Elf_Dyn_Base<ELFT>::d_tag;
375 using Elf_Dyn_Base<ELFT>::d_un;
376 using intX_t = std::conditional_t<ELFT::Is64Bits, int64_t, int32_t>;
377 using uintX_t = std::conditional_t<ELFT::Is64Bits, uint64_t, uint32_t>;
383 template <endianness TargetEndianness>
405 return (
unsigned char)(this->getRInfo(
isMips64EL) & 0x0ff);
408 setSymbolAndType(
s,
getType(IsMips64EL), IsMips64EL);
411 setSymbolAndType(getSymbol(IsMips64EL),
t, IsMips64EL);
414 this->setRInfo((
s << 8) +
t, IsMips64EL);
418 template <endianness TargetEndianness>
420 :
public Elf_Rel_Impl<ELFType<TargetEndianness, false>, false> {
440 return (
t << 32) | ((
t >> 8) & 0xff000000) | ((
t >> 24) & 0x00ff0000) |
441 ((
t >> 40) & 0x0000ff00) | ((
t >> 56) & 0x000000ff);
446 r_info = (R >> 32) | ((R & 0xff000000) << 8) | ((R & 0x00ff0000) << 24) |
447 ((R & 0x0000ff00) << 40) | ((R & 0x000000ff) << 56);
461 setSymbolAndType(
s,
getType(IsMips64EL), IsMips64EL);
464 setSymbolAndType(getSymbol(IsMips64EL),
t, IsMips64EL);
467 this->setRInfo(((
uint64_t)
s << 32) + (
t & 0xffffffffL), IsMips64EL);
471 template <endianness TargetEndianness>
473 :
public Elf_Rel_Impl<ELFType<TargetEndianness, true>, false> {
479 template <class ELFT>
491 Elf_Half e_phentsize;
493 Elf_Half e_shentsize;
498 bool checkMagic()
const {
506 template <endianness TargetEndianness>
533 template <class ELFT>
545 &nbucket + 2 + nbucket + nchain);
550 template <
class ELFT>
551 struct Elf_GnuHash_Impl {
565 reinterpret_cast<const Elf_Word *
>(filter().
end()), nbuckets);
569 assert(DynamicSymCount >= symndx);
576 template <endianness TargetEndianness>
581 Elf_Word ch_addralign;
588 Elf_Word ch_reserved;
590 Elf_Xword ch_addralign;
594 template <class ELFT>
608 size_t getSize()
const {
609 return sizeof(*this) + alignTo<Align>(n_namesz) + alignTo<Align>(n_descsz);
617 template <
class ELFT>
618 class Elf_Note_Impl {
621 const Elf_Nhdr_Impl<ELFT> &Nhdr;
632 return StringRef(
reinterpret_cast<const char *
>(&Nhdr) +
sizeof(Nhdr),
641 reinterpret_cast<const uint8_t *
>(&Nhdr) +
sizeof(Nhdr) +
653 Elf_Word
getType()
const {
return Nhdr.n_type; }
656 template <
class ELFT>
class Elf_Note_Iterator_Impl {
667 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",
684 void advanceNhdr(
const uint8_t *NhdrPos,
size_t NoteSize) {
685 RemainingSize -= NoteSize;
686 if (RemainingSize == 0u) {
691 }
else if (
sizeof(*Nhdr) > RemainingSize)
692 stopWithOverflowError();
694 Nhdr =
reinterpret_cast<const Elf_Nhdr_Impl<ELFT> *
>(NhdrPos + NoteSize);
695 if (Nhdr->
getSize() > RemainingSize)
696 stopWithOverflowError();
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,
Error &Err)
705 : RemainingSize(
Size), Err(&Err) {
707 assert(Start &&
"ELF note iterator starting at NULL");
708 advanceNhdr(Start, 0u);
713 assert(Nhdr &&
"incremented ELF note end iterator");
714 const uint8_t *NhdrPos =
reinterpret_cast<const uint8_t *
>(Nhdr);
715 size_t NoteSize = Nhdr->
getSize();
716 advanceNhdr(NhdrPos, NoteSize);
720 if (!Nhdr &&
Other.Err)
721 (void)(
bool)(*
Other.Err);
722 if (!
Other.Nhdr && Err)
724 return Nhdr ==
Other.Nhdr;
727 return !(*
this ==
Other);
730 assert(Nhdr &&
"dereferenced ELF note end iterator");
735 template <
class ELFT>
struct Elf_CGProfile_Impl {
737 Elf_Xword cgp_weight;
741 template <class ELFT>
748 Elf_Word ri_cprmask[4];
749 Elf_Addr ri_gp_value;
757 Elf_Word ri_cprmask[4];
758 Elf_Addr ri_gp_value;
812 : Offset(Offset), Size(Size), HasReturn(
Metadata & 1),
814 CanFallThrough(
Metadata & (1 << 3)){};
817 return Offset ==
Other.Offset && Size ==
Other.Size &&
818 HasReturn ==
Other.HasReturn && HasTailCall ==
Other.HasTailCall &&
819 IsEHPad ==
Other.IsEHPad && CanFallThrough ==
Other.CanFallThrough;
827 Other.BBEntries.begin());
834 #endif // LLVM_OBJECT_ELFTYPES_H
const Elf_Mips_RegInfo< ELFT > & getRegInfo() const
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
uint32_t getSymbol(bool isMips64EL) const
static StringRef getName(Value *V)
This is an optimization pass for GlobalISel generic memory operations.
const MCInstrDesc & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned getEntityCount() const
Get the number of entities this section contains if it has any.
llvm::support::endianness endianness
void setSymbolAndType(uint32_t s, uint32_t t, bool IsMips64EL)
static const endianness TargetEndianness
unsigned char getType() const
static ErrorSuccess success()
Create a success value.
Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters.
bool isOSSpecific() const
Merge contiguous icmps into a memcmp
uint32_t getType(bool isMips64EL) const
void setRInfo(uint32_t R, bool IsMips64EL)
static const bool Is64Bits
#define LLVM_ELF_IMPORT_TYPES(E, W)
void setSymbol(uint32_t s, bool IsMips64EL)
const_iterator end(StringRef path)
Get end iterator over path.
uint64_t getValue() const
Elf_Note_Impl(const Elf_Nhdr_Impl< ELFT > &Nhdr)
Tagged union holding either a T or a Error.
Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef section (....
unsigned char getVisibility() const
Access to the STV_xxx flag stored in the first two bits of st_other.
void consumeError(Error Err)
Consume a Error without doing anything.
bool operator!=(Elf_Note_Iterator_Impl Other) const
void setType(unsigned char t)
void setSymbolAndType(uint32_t s, unsigned char t, bool IsMips64EL)
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
Elf_Versym: This is the structure of entries in the SHT_GNU_versym section (.gnu.version).
Expected< StringRef > getName(StringRef StrTab) const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::conditional_t< ELFT::Is64Bits, int64_t, int32_t > intX_t
ArrayRef< Elf_Word > buckets() const
bitcast float %x to i32 %s=and i32 %t, 2147483647 %d=bitcast i32 %s to float ret float %d } declare float @fabsf(float %n) define float @bar(float %x) nounwind { %d=call float @fabsf(float %x) ret float %d } This IR(from PR6194):target datalayout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple="x86_64-apple-darwin10.0.0" %0=type { double, double } %struct.float3=type { float, float, float } define void @test(%0, %struct.float3 *nocapture %res) nounwind noinline ssp { entry:%tmp18=extractvalue %0 %0, 0 t
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int b
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool operator==(const BBEntry &Other) const
void setBinding(unsigned char b)
bar al al movzbl eax ret Missed when stored in a memory object
multiplies can be turned into SHL s
std::conditional_t< Is64, uint64_t, uint32_t > uint
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Elf_Dyn_Base: This structure matches the form of entries in the dynamic table section (....
std::ptrdiff_t difference_type
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed section (.gnu....
static bool isMips64EL(const ELFYAML::Object &Obj)
Elf_Note_Impl< ELFT > operator*() const
void setVisibility(unsigned char v)
bool operator==(const BBAddrMap &Other) const
BBEntry(uint32_t Offset, uint32_t Size, uint32_t Metadata)
void setRInfo(uint64_t R, bool IsMips64EL)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool operator==(Elf_Note_Iterator_Impl Other) const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
uint32_t getSymbol(bool isMips64EL) const
StringRef - Represent a constant reference to a string, i.e.
ArrayRef< Elf_Word > chains() const
bool isProcessorSpecific() const
StringRef getDescAsStringRef() const
Get the note's descriptor as StringRef.
void setType(unsigned char t, bool IsMips64EL)
unsigned char getDataEncoding() const
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
unsigned char getBinding() const
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section (.gnu.version_d).
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
std::vector< BBEntry > BBEntries
Lightweight error class with error context and mandatory checking.
size_t getSize() const
Get the size of the note, including name, descriptor, and padding.
Elf_Note_Iterator_Impl & operator++()
Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed section (....
ArrayRef< uint8_t > getDesc() const
Get the note's descriptor.
unsigned char getType(bool isMips64EL) const
void setType(uint32_t t, bool IsMips64EL)
ArrayRef< Elf_Word > values(unsigned DynamicSymCount) const
static const char ElfMagic[]
std::conditional_t< ELFT::Is64Bits, uint64_t, uint32_t > uintX_t
void setBindingAndType(unsigned char b, unsigned char t)
std::forward_iterator_tag iterator_category
size_t size() const
size - Get the array size.
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
void setSymbol(uint32_t s, bool IsMips64EL)
unsigned char getFileClass() const
StringRef getName() const
Get the note's name, excluding the terminating null byte.
Elf_Word getType() const
Get the note's type.
Optional< std::vector< StOtherPiece > > Other