14 #ifndef LLVM_OBJECT_ELF_H
15 #define LLVM_OBJECT_ELF_H
27 inline std::pair<unsigned char, unsigned char>
67 return reinterpret_cast<const uint8_t *
>(Buf.
data());
121 return makeArrayRef<Elf_Sym>(
nullptr,
nullptr);
122 return getSectionContentsAsArray<Elf_Sym>(Sec);
126 return getSectionContentsAsArray<Elf_Rela>(Sec);
130 return getSectionContentsAsArray<Elf_Rel>(Sec);
159 template <
typename T>
169 template <
class ELFT>
172 if (Index >= Sections.size())
174 return &Sections[Index];
177 template <
class ELFT>
180 const typename ELFT::Sym *FirstSym,
183 unsigned Index = Sym - FirstSym;
184 if (Index >= ShndxTable.
size())
185 return createError(
"index past the end of the symbol table");
188 return ShndxTable[Index];
191 template <
class ELFT>
197 auto ErrorOrIndex = object::getExtendedSymbolTableIndex<ELFT>(
198 Sym, Syms.begin(), ShndxTable);
200 return ErrorOrIndex.takeError();
201 return *ErrorOrIndex;
208 template <
class ELFT>
212 auto SymsOrErr = symbols(SymTab);
214 return SymsOrErr.takeError();
215 return getSection(Sym, *SymsOrErr, ShndxTable);
218 template <
class ELFT>
222 auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable);
224 return IndexOrErr.takeError();
228 auto SectionsOrErr = sections();
230 return SectionsOrErr.takeError();
231 return object::getSection<ELFT>(*SectionsOrErr, Index);
234 template <
class ELFT>
237 if (Index >= Symbols.size())
239 return &Symbols[Index];
242 template <
class ELFT>
245 auto SymtabOrErr = symbols(Sec);
247 return SymtabOrErr.takeError();
248 return object::getSymbol<ELFT>(*SymtabOrErr, Index);
251 template <
class ELFT>
252 template <
typename T>
255 if (Sec->sh_entsize !=
sizeof(
T) &&
sizeof(
T) != 1)
261 if (Size %
sizeof(
T))
262 return createError(
"size is not a multiple of sh_entsize");
263 if ((std::numeric_limits<uintX_t>::max() - Offset < Size) ||
264 Offset + Size > Buf.size())
267 const T *Start =
reinterpret_cast<const T *
>(base() +
Offset);
271 template <
class ELFT>
274 return getSectionContentsAsArray<uint8_t>(Sec);
277 template <
class ELFT>
282 template <
class ELFT>
285 if (!isMipsELF64()) {
295 uint8_t Type1 = (Type >> 0) & 0xFF;
296 uint8_t
Type2 = (Type >> 8) & 0xFF;
297 uint8_t
Type3 = (Type >> 16) & 0xFF;
303 Name = getRelocationTypeName(Type2);
307 Name = getRelocationTypeName(Type3);
313 template <
class ELFT>
317 uint32_t Index = Rel->getSymbol(isMips64EL());
320 return getEntry<Elf_Sym>(SymTab, Index);
323 template <
class ELFT>
326 uint32_t Index = getHeader()->e_shstrndx;
328 Index = Sections[0].sh_link;
332 if (Index >= Sections.size())
334 return getStringTable(&Sections[Index]);
337 template <
class ELFT>
342 template <
class ELFT>
344 return VAddr < Phdr->p_vaddr;
347 template <
class ELFT>
349 const uintX_t SectionTableOffset = getHeader()->e_shoff;
350 if (SectionTableOffset == 0)
353 if (getHeader()->e_shentsize !=
sizeof(
Elf_Shdr))
355 "invalid section header entry size (e_shentsize) in ELF header");
357 const uint64_t FileSize = Buf.size();
359 if (SectionTableOffset +
sizeof(
Elf_Shdr) > FileSize)
360 return createError(
"section header table goes past the end of the file");
363 if (SectionTableOffset & (
alignof(
Elf_Shdr) - 1))
364 return createError(
"invalid alignment of section headers");
367 reinterpret_cast<const Elf_Shdr *
>(base() + SectionTableOffset);
369 uintX_t NumSections = getHeader()->e_shnum;
370 if (NumSections == 0)
371 NumSections = First->sh_size;
373 if (NumSections > UINT64_MAX /
sizeof(
Elf_Shdr))
374 return createError(
"section table goes past the end of file");
376 const uint64_t SectionTableSize = NumSections *
sizeof(
Elf_Shdr);
379 if (SectionTableOffset + SectionTableSize > FileSize)
380 return createError(
"section table goes past the end of file");
385 template <
class ELFT>
386 template <
typename T>
391 return SecOrErr.takeError();
392 return getEntry<T>(*SecOrErr, Entry);
395 template <
class ELFT>
396 template <
typename T>
399 if (
sizeof(
T) != Section->sh_entsize)
401 size_t Pos = Section->sh_offset + Entry *
sizeof(
T);
402 if (Pos +
sizeof(
T) > Buf.size())
404 return reinterpret_cast<const T *
>(base() + Pos);
407 template <
class ELFT>
410 auto TableOrErr = sections();
412 return TableOrErr.takeError();
413 return object::getSection<ELFT>(*TableOrErr, Index);
416 template <
class ELFT>
420 return createError(
"invalid sh_type for string table, expected SHT_STRTAB");
421 auto V = getSectionContentsAsArray<char>(
Section);
423 return V.takeError();
427 if (Data.
back() !=
'\0')
428 return createError(
"string table non-null terminated");
432 template <
class ELFT>
435 auto SectionsOrErr = sections();
437 return SectionsOrErr.takeError();
438 return getSHNDXTable(Section, *SectionsOrErr);
441 template <
class ELFT>
446 auto VOrErr = getSectionContentsAsArray<Elf_Word>(&
Section);
448 return VOrErr.takeError();
450 auto SymTableOrErr = object::getSection<ELFT>(Sections, Section.sh_link);
452 return SymTableOrErr.takeError();
453 const Elf_Shdr &SymTable = **SymTableOrErr;
457 if (V.
size() != (SymTable.sh_size /
sizeof(
Elf_Sym)))
458 return createError(
"invalid section contents size");
462 template <
class ELFT>
465 auto SectionsOrErr = sections();
467 return SectionsOrErr.takeError();
468 return getStringTableForSymtab(Sec, *SectionsOrErr);
471 template <
class ELFT>
478 "invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
479 auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
481 return SectionOrErr.takeError();
482 return getStringTable(*SectionOrErr);
485 template <
class ELFT>
488 auto SectionsOrErr = sections();
490 return SectionsOrErr.takeError();
491 auto Table = getSectionStringTable(*SectionsOrErr);
493 return Table.takeError();
494 return getSectionName(Section, *Table);
497 template <
class ELFT>
503 if (Offset >= DotShstrtab.
size())
513 for (
char C : SymbolName) {
StringRef getRelocationTypeName(uint32_t Type) const
Expected< StringRef > getSectionName(const Elf_Shdr *Section) const
size_t getBufSize() const
ELFFile< ELFType< support::big, true > > ELF64BEFile
ELFFile< ELFType< support::little, false > > ELF32LEFile
const uint8_t * base() const
static Error createError(StringRef Err)
unsigned hashSysV(StringRef SymbolName)
This function returns the hash value for a symbol in the .dynsym section Name of the API remains cons...
ELFT::SymRange Elf_Sym_Range
ELFT::RelRange Elf_Rel_Range
Expected< StringRef > getSectionStringTable(Elf_Shdr_Range Sections) const
ELFT::Verneed Elf_Verneed
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Tagged union holding either a T or a Error.
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Expected< const Elf_Sym * > getSymbol(const Elf_Shdr *Sec, uint32_t Index) const
Expected< const Elf_Sym * > getRelocationSymbol(const Elf_Rel *Rel, const Elf_Shdr *SymTab) const
Get the symbol for a given relocation.
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
COFF::MachineTypes Machine
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
size_t size() const
size - Get the array size.
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Expected< uint32_t > getSectionIndex(const Elf_Sym *Sym, Elf_Sym_Range Syms, ArrayRef< Elf_Word > ShndxTable) const
ELFT::Verdaux Elf_Verdaux
ELFT::GnuHash Elf_GnuHash
The instances of the Type class are immutable: once they are created, they are never changed...
ELFT::ShdrRange Elf_Shdr_Range
Expected< const T * > getEntry(uint32_t Section, uint32_t Entry) const
static bool compareAddr(uint64_t VAddr, const Elf_Phdr_Impl< ELFT > *Phdr)
Expected< ArrayRef< Elf_Word > > getSHNDXTable(const Elf_Shdr &Section) const
Expected< StringRef > getStringTable(const Elf_Shdr *Section) const
bool empty() const
empty - Check if the array is empty.
Expected< Elf_Sym_Range > symbols(const Elf_Shdr *Sec) const
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
ELFT::RelaRange Elf_Rela_Range
Expected< ArrayRef< T > > getSectionContentsAsArray(const Elf_Shdr *Sec) const
const T & back() const
back - Get the last element.
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)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
ELFFile(StringRef Object)
ELFT::DynRange Elf_Dyn_Range
ELFFile< ELFType< support::little, true > > ELF64LEFile
Expected< const Elf_Shdr * > getSection(const Elf_Sym *Sym, const Elf_Shdr *SymTab, ArrayRef< Elf_Word > ShndxTable) const
void VerifyStrTab(const Elf_Shdr *sh) const
Expected< Elf_Shdr_Range > sections() const
ELFT::PhdrRange Elf_Phdr_Range
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Expected< ArrayRef< uint8_t > > getSectionContents(const Elf_Shdr *Sec) const
Expected< Elf_Phdr_Range > program_headers() const
Iterate over program header table.
Expected< Elf_Rela_Range > relas(const Elf_Shdr *Sec) const
Lightweight error class with error context and mandatory checking.
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).
std::string Hash(const Unit &U)
#define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
StringRef - Represent a constant reference to a string, i.e.
Expected< StringRef > getStringTableForSymtab(const Elf_Shdr &Section) const
const Elf_Ehdr * getHeader() const
Expected< Elf_Rel_Range > rels(const Elf_Shdr *Sec) const
ELFFile< ELFType< support::big, false > > ELF32BEFile
ELFT::Vernaux Elf_Vernaux