14 #ifndef LLVM_OBJECT_ELF_H 15 #define LLVM_OBJECT_ELF_H 39 inline std::pair<unsigned char, unsigned char>
84 return reinterpret_cast<const uint8_t *
>(Buf.
data());
101 template <
typename T>
145 return makeArrayRef<Elf_Sym>(
nullptr,
nullptr);
146 return getSectionContentsAsArray<Elf_Sym>(Sec);
150 return getSectionContentsAsArray<Elf_Rela>(Sec);
154 return getSectionContentsAsArray<Elf_Rel>(Sec);
158 return getSectionContentsAsArray<Elf_Relr>(Sec);
172 return createError(
"program headers longer than binary");
187 Err =
createError(
"attempt to iterate notes of non-note program header");
190 if (Phdr.p_offset + Phdr.p_filesz >
getBufSize()) {
191 Err =
createError(
"invalid program header offset/size");
206 Err =
createError(
"attempt to iterate notes of non-note section");
209 if (Shdr.sh_offset + Shdr.sh_size >
getBufSize()) {
263 template <
typename T>
273 template <
class ELFT>
276 if (Index >= Sections.size())
278 return &Sections[
Index];
281 template <
class ELFT>
284 const typename ELFT::Sym *FirstSym,
287 unsigned Index = Sym - FirstSym;
288 if (Index >= ShndxTable.
size())
289 return createError(
"index past the end of the symbol table");
292 return ShndxTable[
Index];
295 template <
class ELFT>
301 auto ErrorOrIndex = getExtendedSymbolTableIndex<ELFT>(
302 Sym, Syms.begin(), ShndxTable);
304 return ErrorOrIndex.takeError();
305 return *ErrorOrIndex;
312 template <
class ELFT>
316 auto SymsOrErr =
symbols(SymTab);
318 return SymsOrErr.takeError();
319 return getSection(Sym, *SymsOrErr, ShndxTable);
322 template <
class ELFT>
328 return IndexOrErr.takeError();
335 template <
class ELFT>
338 if (Index >= Symbols.size())
340 return &Symbols[
Index];
343 template <
class ELFT>
346 auto SymtabOrErr =
symbols(Sec);
348 return SymtabOrErr.takeError();
349 return object::getSymbol<ELFT>(*SymtabOrErr,
Index);
352 template <
class ELFT>
353 template <
typename T>
356 if (Sec->sh_entsize !=
sizeof(
T) &&
sizeof(
T) != 1)
362 if (Size %
sizeof(
T))
363 return createError(
"size is not a multiple of sh_entsize");
365 Offset + Size > Buf.
size())
368 if (Offset %
alignof(
T))
371 const T *Start =
reinterpret_cast<const T *
>(
base() +
Offset);
375 template <
class ELFT>
378 return getSectionContentsAsArray<uint8_t>(Sec);
381 template <
class ELFT>
386 template <
class ELFT>
399 uint8_t Type1 = (Type >> 0) & 0xFF;
400 uint8_t
Type2 = (Type >> 8) & 0xFF;
401 uint8_t
Type3 = (Type >> 16) & 0xFF;
417 template <
class ELFT>
422 template <
class ELFT>
429 return getEntry<Elf_Sym>(SymTab,
Index);
432 template <
class ELFT>
437 Index = Sections[0].sh_link;
441 if (Index >= Sections.size())
448 template <
class ELFT>
455 template <
class ELFT>
458 if (SectionTableOffset == 0)
463 "invalid section header entry size (e_shentsize) in ELF header");
465 const uint64_t FileSize = Buf.
size();
467 if (SectionTableOffset +
sizeof(
Elf_Shdr) > FileSize)
468 return createError(
"section header table goes past the end of the file");
471 if (SectionTableOffset & (
alignof(
Elf_Shdr) - 1))
472 return createError(
"invalid alignment of section headers");
475 reinterpret_cast<const Elf_Shdr *
>(
base() + SectionTableOffset);
478 if (NumSections == 0)
479 NumSections = First->sh_size;
482 return createError(
"section table goes past the end of file");
484 const uint64_t SectionTableSize = NumSections *
sizeof(
Elf_Shdr);
487 if (SectionTableOffset + SectionTableSize > FileSize)
488 return createError(
"section table goes past the end of file");
493 template <
class ELFT>
494 template <
typename T>
499 return SecOrErr.takeError();
500 return getEntry<T>(*SecOrErr, Entry);
503 template <
class ELFT>
504 template <
typename T>
507 if (
sizeof(
T) != Section->sh_entsize)
509 size_t Pos = Section->sh_offset + Entry *
sizeof(
T);
510 if (Pos +
sizeof(
T) > Buf.
size())
512 return reinterpret_cast<const T *
>(
base() + Pos);
515 template <
class ELFT>
520 return TableOrErr.takeError();
521 return object::getSection<ELFT>(*TableOrErr,
Index);
524 template <
class ELFT>
529 return TableOrErr.takeError();
530 for (
auto &Sec : *TableOrErr) {
533 return SecNameOrErr.takeError();
534 if (*SecNameOrErr == SectionName)
540 template <
class ELFT>
544 return createError(
"invalid sh_type for string table, expected SHT_STRTAB");
545 auto V = getSectionContentsAsArray<char>(
Section);
547 return V.takeError();
551 if (Data.
back() !=
'\0')
552 return createError(
"string table non-null terminated");
556 template <
class ELFT>
561 return SectionsOrErr.takeError();
565 template <
class ELFT>
570 auto VOrErr = getSectionContentsAsArray<Elf_Word>(&
Section);
572 return VOrErr.takeError();
574 auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
576 return SymTableOrErr.takeError();
577 const Elf_Shdr &SymTable = **SymTableOrErr;
581 if (V.
size() != (SymTable.sh_size /
sizeof(
Elf_Sym)))
582 return createError(
"invalid section contents size");
586 template <
class ELFT>
591 return SectionsOrErr.takeError();
595 template <
class ELFT>
602 "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
603 auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
605 return SectionOrErr.takeError();
609 template <
class ELFT>
614 return SectionsOrErr.takeError();
617 return Table.takeError();
621 template <
class ELFT>
627 if (Offset >= DotShstrtab.
size())
637 for (
char C : SymbolName) {
650 #endif // LLVM_OBJECT_ELF_H typename ELFT::Dyn Elf_Dyn
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
const T & back() const
back - Get the last element.
typename ELFT::Rel Elf_Rel
iterator_range< Elf_Note_Iterator > notes(const Elf_Phdr &Phdr, Error &Err) const
Get an iterator range over notes of a program header.
Expected< const T * > getEntry(uint32_t Section, uint32_t Entry) const
This class represents lattice values for constants.
typename ELFT::Note Elf_Note
static Expected< ELFFile > create(StringRef Object)
typename ELFT::Vernaux Elf_Vernaux
StringRef getELFSectionTypeName(uint32_t Machine, uint32_t Type)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
StringRef getRelocationTypeName(uint32_t Type) const
Expected< StringRef > getSectionStringTable(Elf_Shdr_Range Sections) const
const char * getDynamicTagAsString(unsigned Arch, uint64_t Type) const
Expected< StringRef > getStringTable(const Elf_Shdr *Section) const
static Error createError(StringRef Err)
Expected< std::vector< Elf_Rela > > decode_relrs(Elf_Relr_Range relrs) const
unsigned hashSysV(StringRef SymbolName)
This function returns the hash value for a symbol in the .dynsym section Name of the API remains cons...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
typename ELFT::Sym Elf_Sym
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Expected< const uint8_t * > toMappedAddr(uint64_t VAddr) const
const uint8_t * base() const
Expected< const Elf_Shdr * > getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab, ArrayRef< Elf_Word > ShndxTable) const
amdgpu Simplify well known AMD library false Value Value const Twine & Name
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
iterator_range< Elf_Note_Iterator > notes(const Elf_Shdr &Shdr, Error &Err) const
Get an iterator range over notes of a section.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Expected< Elf_Shdr_Range > sections() const
typename ELFT::PhdrRange Elf_Phdr_Range
typename ELFT::Phdr Elf_Phdr
Tagged union holding either a T or a Error.
uint32_t getELFRelativeRelocationType(uint32_t Machine)
Expected< ArrayRef< uint8_t > > getSectionContents(const Elf_Shdr *Sec) const
typename ELFT::Relr Elf_Relr
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
typename ELFT::GnuHash Elf_GnuHash
COFF::MachineTypes Machine
typename ELFT::SymRange Elf_Sym_Range
Elf_Note_Iterator notes_end() const
Get the end iterator for notes.
Expected< ArrayRef< T > > getSectionContentsAsArray(const Elf_Shdr *Sec) const
Expected< Elf_Rel_Range > rels(const Elf_Shdr *Sec) const
Expected< ArrayRef< Elf_Word > > getSHNDXTable(const Elf_Shdr &Section) const
The instances of the Type class are immutable: once they are created, they are never changed...
Elf_Note_Iterator notes_begin(const Elf_Shdr &Shdr, Error &Err) const
Get an iterator over notes in a section.
size_t size() const
size - Get the array size.
Expected< StringRef > getStringTableForSymtab(const Elf_Shdr &Section) const
Expected< Elf_Rela_Range > relas(const Elf_Shdr *Sec) const
typename ELFT::uint uintX_t
Expected< uint32_t > getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, ArrayRef< Elf_Word > ShndxTable) const
Expected< Elf_Relr_Range > relrs(const Elf_Shdr *Sec) const
typename ELFT::NoteIterator Elf_Note_Iterator
typename ELFT::Nhdr Elf_Nhdr
typename ELFT::Verdaux Elf_Verdaux
typename ELFT::Ehdr Elf_Ehdr
typename ELFT::RelrRange Elf_Relr_Range
typename ELFT::Rela Elf_Rela
typename ELFT::Verneed Elf_Verneed
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)
Expected< uint32_t > getExtendedSymbolTableIndex(const typename ELFT::Sym *Sym, const typename ELFT::Sym *FirstSym, ArrayRef< typename ELFT::Word > ShndxTable)
size_t getBufSize() const
Expected< const Elf_Sym * > getRelocationSymbol(const Elf_Rel *Rel, const Elf_Shdr *SymTab) const
Get the symbol for a given relocation.
A range adaptor for a pair of iterators.
Elf_Note_Iterator notes_begin(const Elf_Phdr &Phdr, Error &Err) const
Get an iterator over notes in a program header.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
typename ELFT::DynRange Elf_Dyn_Range
Expected< std::vector< Elf_Rela > > android_relas(const Elf_Shdr *Sec) const
uint32_t getRelativeRelocationType() const
Expected< const Elf_Sym * > getSymbol(const Elf_Shdr *Sec, uint32_t Index) const
Expected< Elf_Sym_Range > symbols(const Elf_Shdr *Sec) const
typename ELFT::Verdef Elf_Verdef
Expected< Elf_Dyn_Range > dynamicEntries() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
typename ELFT::RelRange Elf_Rel_Range
typename ELFT::Versym Elf_Versym
typename ELFT::RelaRange Elf_Rela_Range
Lightweight error class with error context and mandatory checking.
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
StringRef - Represent a constant reference to a string, i.e.
typename ELFT::ShdrRange Elf_Shdr_Range
const Elf_Ehdr * getHeader() const
typename ELFT::Shdr Elf_Shdr
Expected< StringRef > getSectionName(const Elf_Shdr *Section) const
bool empty() const
empty - Check if the array is empty.
typename ELFT::Hash Elf_Hash