1//===- ELFObjectFile.cpp - ELF object file implementation -----------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// Part of the ELFObjectFile class implementation. 11//===----------------------------------------------------------------------===// 48 {
"Unknown",
"<unknown>: 7", 7},
49 {
"Unknown",
"<unknown>: 8", 8},
50 {
"Unknown",
"<unknown>: 9", 9},
52 {
"OS Specific",
"<OS specific>: 11", 11},
53 {
"OS Specific",
"<OS specific>: 12", 12},
54 {
"Proc Specific",
"<processor specific>: 13", 13},
55 {
"Proc Specific",
"<processor specific>: 14", 14},
56 {
"Proc Specific",
"<processor specific>: 15", 15}
66if (
Error E = Ret.takeError())
68return std::make_unique<ELFObjectFile<ELFT>>(std::move(*Ret));
73 std::pair<unsigned char, unsigned char> Ident =
75 std::size_t MaxAlignment =
84return createPtr<ELF32LE>(Obj, InitContent);
86return createPtr<ELF32BE>(Obj, InitContent);
91return createPtr<ELF64LE>(Obj, InitContent);
93return createPtr<ELF64BE>(Obj, InitContent);
143// No feature associated with this value. 168// both ARMv7-M and R have to support thumb hardware div 170 std::optional<unsigned> Attr =
323// Return no attributes if none can be read. 324// This behavior is important for backwards compatibility. 328 std::optional<unsigned> Attr;
331if (std::optional<std::string> FeatureString =
337 std::optional<std::string> FeatureString =
339// There is no corresponding hvx arch for v5 and v55. 340if (FeatureString && *Attr >= 60)
380 std::optional<StringRef> Attr =
388if (ISAInfo->getXLen() == 32)
390elseif (ISAInfo->getXLen() == 64)
409// D implies F according to LoongArch ISA spec. 422return getMIPSFeatures();
424return getARMFeatures();
426return getRISCVFeatures();
428return getLoongArchFeatures();
430return getHexagonFeatures();
439return getAMDGPUCPUName();
441return getNVPTXCPUName();
452StringRef ELFObjectFileBase::getAMDGPUCPUName()
const{
457// Radeon HD 2000/3000 Series (R600). 467// Radeon HD 4000 Series (R700). 475// Radeon HD 5000 Series (Evergreen). 487// Radeon HD 6000 Series (Northern Islands). 605// Generic AMDGCN targets 609return"gfx9-4-generic";
611return"gfx10-1-generic";
613return"gfx10-3-generic";
615return"gfx11-generic";
617return"gfx12-generic";
623StringRef ELFObjectFileBase::getNVPTXCPUName()
const{
628// Fermi architecture. 634// Kepler architecture. 644// Maxwell architecture. 652// Pascal architecture. 660// Volta architecture. 666// Turing architecture. 670// Ampere architecture. 682// Hopper architecture. 690// FIXME Encode from a tablegen description or target parser. 697// TODO Propagate Error. 703// Default to ARM, but use the triple if it's been set. 709 std::optional<unsigned> Attr =
741 std::optional<unsigned> ArchProfileAttr =
743if (ArchProfileAttr &&
791uint32_t JumpSlotReloc = 0, GlobDatReloc = 0;
794 JumpSlotReloc = ELF::R_386_JUMP_SLOT;
795 GlobDatReloc = ELF::R_386_GLOB_DAT;
798 JumpSlotReloc = ELF::R_X86_64_JUMP_SLOT;
799 GlobDatReloc = ELF::R_X86_64_GLOB_DAT;
803 JumpSlotReloc = ELF::R_AARCH64_JUMP_SLOT;
808 std::unique_ptr<const MCInstrInfo> MII(
T->createMCInstrInfo());
809 std::unique_ptr<const MCInstrAnalysis> MIA(
810T->createMCInstrAnalysis(MII.get()));
813 std::vector<std::pair<uint64_t, uint64_t>> PltEntries;
814 std::optional<SectionRef> RelaPlt, RelaDyn;
824if (
Name ==
".rela.plt" ||
Name ==
".rel.plt") {
826 }
elseif (
Name ==
".rela.dyn" ||
Name ==
".rel.dyn") {
828 }
elseif (
Name ==
".got.plt") {
829 GotBaseVA = Section.getAddress();
830 }
elseif (
Name ==
".plt" ||
Name ==
".plt.got") {
838 MIA->findPltEntries(Section.getAddress(),
839 arrayRefFromStringRef(*PltContents),
Triple));
843// Build a map from GOT entry virtual address to PLT entry virtual address. 845for (
auto [Plt, GotPlt] : PltEntries) {
847// An x86-32 PIC PLT uses jmp DWORD PTR [ebx-offset]. Add 848// _GLOBAL_OFFSET_TABLE_ (EBX) to get the .got.plt (or .got) entry address. 849// See X86MCTargetDesc.cpp:findPltEntries for the 1 << 32 bit. 851 GotPltEntry =
static_cast<int32_t
>(GotPltEntry) + GotBaseVA;
852 GotToPlt.
insert(std::make_pair(GotPltEntry, Plt));
855// Find the relocations in the dynamic relocation table that point to 856// locations in the GOT for which we know the corresponding PLT entry. 857 std::vector<ELFPltEntry> Result;
860for (
constauto &R : Rels) {
861if (R.getType() != RelType)
863auto PltEntryIter = GotToPlt.
find(R.getOffset());
864if (PltEntryIter != GotToPlt.
end()) {
868ELFPltEntry{PltSec, std::nullopt, PltEntryIter->second});
871 PltEntryIter->second});
877 handleRels(RelaPlt->relocations(), JumpSlotReloc,
".plt");
879// If a symbol needing a PLT entry also needs a GLOB_DAT relocation, GNU ld's 880// x86 port places the PLT entry in the .plt.got section. 882 handleRels(RelaDyn->relocations(), GlobDatReloc,
".plt.got");
889constELFFile<ELFT> &EF, std::optional<unsigned> TextSectionIndex,
890 std::vector<PGOAnalysisMap> *PGOAnalyses) {
891usingElf_Shdr =
typename ELFT::Shdr;
893 std::vector<BBAddrMap> BBAddrMaps;
895 PGOAnalyses->clear();
902if (!TextSectionIndex)
906returncreateError(
"unable to get the linked-to section for " +
909assert(*TextSecOrErr >= Sections.begin() &&
910"Text section pointer outside of bounds");
911if (*TextSectionIndex !=
912 (
unsigned)std::distance(Sections.begin(), *TextSecOrErr))
919if (!SectionRelocMapOrErr)
922for (
autoconst &[Sec, RelocSec] : *SectionRelocMapOrErr) {
923if (IsRelocatable && !RelocSec)
924returncreateError(
"unable to get relocation section for " +
928if (!BBAddrMapOrErr) {
930 PGOAnalyses->clear();
934 std::move(BBAddrMapOrErr->begin(), BBAddrMapOrErr->end(),
935 std::back_inserter(BBAddrMaps));
938assert(PGOAnalyses->size() == BBAddrMaps.size() &&
939"The same number of BBAddrMaps and PGOAnalysisMaps should be " 940"returned when PGO information is requested");
948usingElf_Shdr =
typename ELFT::Shdr;
949const Elf_Shdr *VerSec =
nullptr;
950const Elf_Shdr *VerNeedSec =
nullptr;
951const Elf_Shdr *VerDefSec =
nullptr;
952// The user should ensure sections() can't fail here. 962return std::vector<VersionEntry>();
969 std::vector<VersionEntry> Ret;
974 EF.template getEntry<typename ELFT::Versym>(*VerSec,
I);
977" from " +
describe(EF, *VerSec) +
": " +
982returncreateError(
"unable to read flags for symbol with index " +
987 (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr,
991" of " +
describe(EF, *VerSec) +
": " +
994 Ret.push_back({(*VerOrErr).str(), IsDefault});
1003if (
constauto *Obj = dyn_cast<ELF32LEObjectFile>(
this))
1005if (
constauto *Obj = dyn_cast<ELF32BEObjectFile>(
this))
1007if (
constauto *Obj = dyn_cast<ELF64LEObjectFile>(
this))
1014 std::optional<unsigned> TextSectionIndex,
1015 std::vector<PGOAnalysisMap> *PGOAnalyses)
const{
1016if (
constauto *Obj = dyn_cast<ELF32LEObjectFile>(
this))
1018if (
constauto *Obj = dyn_cast<ELF64LEObjectFile>(
this))
1020if (
constauto *Obj = dyn_cast<ELF32BEObjectFile>(
this))
1023 TextSectionIndex, PGOAnalyses);
1028if (
constauto *Obj = dyn_cast<ELF32LEObjectFile>(
this))
1029return Obj->getCrelDecodeProblem(
Data);
1030if (
constauto *Obj = dyn_cast<ELF32BEObjectFile>(
this))
1031return Obj->getCrelDecodeProblem(
Data);
1032if (
constauto *Obj = dyn_cast<ELF64LEObjectFile>(
this))
1033return Obj->getCrelDecodeProblem(
Data);
1034return cast<ELF64BEObjectFile>(
this)->getCrelDecodeProblem(
Data);
static Expected< std::unique_ptr< ELFObjectFile< ELFT > > > createPtr(MemoryBufferRef Object, bool InitContent)
static Expected< std::vector< BBAddrMap > > readBBAddrMapImpl(const ELFFile< ELFT > &EF, std::optional< unsigned > TextSectionIndex, std::vector< PGOAnalysisMap > *PGOAnalyses)
static std::optional< std::string > hexagonAttrToFeatureString(unsigned Attr)
static Expected< std::vector< VersionEntry > > readDynsymVersionsImpl(const ELFFile< ELFT > &EF, ELFObjectFileBase::elf_symbol_iterator_range Symbols)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
const char * getBufferStart() const
StringRef getBuffer() const
This class represents success/failure for parsing-like operations that find it important to chain tog...
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseNormalizedArchString(StringRef Arch)
Parse RISC-V ISA info from an arch string that is already in normalized form (as defined in the psABI...
StringRef - Represent a constant reference to a string, i.e.
Manages the enabling and disabling of subtarget specific features.
void AddFeature(StringRef String, bool Enable=true)
Adds Features.
void addFeaturesVector(const ArrayRef< std::string > OtherFeatures)
Triple - Helper class for working with autoconf configuration names.
void setArchName(StringRef Str)
Set the architecture (first) component of the triple by name.
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
SubArchType getSubArch() const
get the parsed subarchitecture type for this triple.
ArchType getArch() const
Get the parsed architecture type of this triple.
const std::string & str() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
A range adaptor for a pair of iterators.
bool isLittleEndian() const
const Elf_Ehdr & getHeader() const
Expected< std::vector< BBAddrMap > > decodeBBAddrMap(const Elf_Shdr &Sec, const Elf_Shdr *RelaSec=nullptr, std::vector< PGOAnalysisMap > *PGOAnalyses=nullptr) const
Returns a vector of BBAddrMap structs corresponding to each function within the text section that the...
Expected< StringRef > getSymbolVersionByIndex(uint32_t SymbolVersionIndex, bool &IsDefault, SmallVector< std::optional< VersionEntry >, 0 > &VersionMap, std::optional< bool > IsSymHidden) const
Expected< Elf_Shdr_Range > sections() const
Expected< MapVector< const Elf_Shdr *, const Elf_Shdr * > > getSectionAndRelocations(std::function< Expected< bool >(const Elf_Shdr &)> IsMatch) const
Returns a map from every section matching IsMatch to its relocation section, or nullptr if it has no ...
Expected< SmallVector< std::optional< VersionEntry >, 0 > > loadVersionMap(const Elf_Shdr *VerNeedSec, const Elf_Shdr *VerDefSec) const
Expected< const Elf_Shdr * > getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab, DataRegion< Elf_Word > ShndxTable) const
virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const =0
Expected< std::vector< VersionEntry > > readDynsymVersions() const
Returns a vector containing a symbol version for each dynamic symbol.
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const =0
StringRef getCrelDecodeProblem(SectionRef Sec) const
std::vector< ELFPltEntry > getPltEntries() const
Expected< SubtargetFeatures > getFeatures() const override
std::optional< StringRef > tryGetCPUName() const override
virtual uint16_t getEMachine() const =0
virtual unsigned getPlatformFlags() const =0
Returns platform-specific object flags, if any.
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source)
void setARMSubArch(Triple &TheTriple) const override
Expected< std::vector< BBAddrMap > > readBBAddrMap(std::optional< unsigned > TextSectionIndex=std::nullopt, std::vector< PGOAnalysisMap > *PGOAnalyses=nullptr) const
Returns a vector of all BB address maps in the object file.
static Expected< ELFObjectFile< ELFT > > create(MemoryBufferRef Object, bool InitContent=true)
This class is the base class for all object file types.
static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)
Triple makeTriple() const
Create a triple from the data in this object file.
section_iterator_range sections() const
This is a value type class that represents a single section in the list of sections in the object fil...
DataRefImpl getRawDataRefImpl() const
virtual basic_symbol_iterator symbol_end() const =0
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ AllowMVEIntegerAndFloat
@ SHT_LLVM_BB_ADDR_MAP_V0
@ EF_AMDGPU_MACH_AMDGCN_GFX703
@ EF_AMDGPU_MACH_AMDGCN_GFX1035
@ EF_AMDGPU_MACH_AMDGCN_GFX1031
@ EF_AMDGPU_MACH_R600_CAYMAN
@ EF_AMDGPU_MACH_AMDGCN_GFX704
@ EF_AMDGPU_MACH_AMDGCN_GFX902
@ EF_AMDGPU_MACH_AMDGCN_GFX810
@ EF_AMDGPU_MACH_AMDGCN_GFX950
@ EF_AMDGPU_MACH_AMDGCN_GFX1036
@ EF_AMDGPU_MACH_AMDGCN_GFX1102
@ EF_AMDGPU_MACH_R600_RV730
@ EF_AMDGPU_MACH_R600_RV710
@ EF_AMDGPU_MACH_AMDGCN_GFX908
@ EF_AMDGPU_MACH_AMDGCN_GFX1011
@ EF_AMDGPU_MACH_R600_CYPRESS
@ EF_AMDGPU_MACH_AMDGCN_GFX1032
@ EF_AMDGPU_MACH_R600_R600
@ EF_AMDGPU_MACH_AMDGCN_GFX940
@ EF_AMDGPU_MACH_AMDGCN_GFX941
@ EF_AMDGPU_MACH_R600_TURKS
@ EF_AMDGPU_MACH_R600_JUNIPER
@ EF_AMDGPU_MACH_AMDGCN_GFX601
@ EF_AMDGPU_MACH_AMDGCN_GFX942
@ EF_AMDGPU_MACH_AMDGCN_GFX1152
@ EF_AMDGPU_MACH_R600_R630
@ EF_AMDGPU_MACH_R600_REDWOOD
@ EF_AMDGPU_MACH_R600_RV770
@ EF_AMDGPU_MACH_AMDGCN_GFX600
@ EF_AMDGPU_MACH_AMDGCN_GFX602
@ EF_AMDGPU_MACH_AMDGCN_GFX1101
@ EF_AMDGPU_MACH_AMDGCN_GFX1100
@ EF_AMDGPU_MACH_AMDGCN_GFX1033
@ EF_AMDGPU_MACH_AMDGCN_GFX801
@ EF_AMDGPU_MACH_AMDGCN_GFX705
@ EF_AMDGPU_MACH_AMDGCN_GFX9_4_GENERIC
@ EF_AMDGPU_MACH_AMDGCN_GFX1153
@ EF_AMDGPU_MACH_AMDGCN_GFX1010
@ EF_AMDGPU_MACH_R600_RV670
@ EF_AMDGPU_MACH_AMDGCN_GFX701
@ EF_AMDGPU_MACH_AMDGCN_GFX10_3_GENERIC
@ EF_AMDGPU_MACH_AMDGCN_GFX1012
@ EF_AMDGPU_MACH_AMDGCN_GFX1151
@ EF_AMDGPU_MACH_AMDGCN_GFX1030
@ EF_AMDGPU_MACH_R600_CEDAR
@ EF_AMDGPU_MACH_AMDGCN_GFX1200
@ EF_AMDGPU_MACH_AMDGCN_GFX700
@ EF_AMDGPU_MACH_AMDGCN_GFX11_GENERIC
@ EF_AMDGPU_MACH_AMDGCN_GFX803
@ EF_AMDGPU_MACH_AMDGCN_GFX802
@ EF_AMDGPU_MACH_AMDGCN_GFX90C
@ EF_AMDGPU_MACH_AMDGCN_GFX900
@ EF_AMDGPU_MACH_AMDGCN_GFX909
@ EF_AMDGPU_MACH_AMDGCN_GFX906
@ EF_AMDGPU_MACH_AMDGCN_GFX9_GENERIC
@ EF_AMDGPU_MACH_AMDGCN_GFX1103
@ EF_AMDGPU_MACH_R600_CAICOS
@ EF_AMDGPU_MACH_AMDGCN_GFX90A
@ EF_AMDGPU_MACH_AMDGCN_GFX1034
@ EF_AMDGPU_MACH_AMDGCN_GFX1013
@ EF_AMDGPU_MACH_AMDGCN_GFX12_GENERIC
@ EF_AMDGPU_MACH_AMDGCN_GFX10_1_GENERIC
@ EF_AMDGPU_MACH_AMDGCN_GFX904
@ EF_AMDGPU_MACH_R600_RS880
@ EF_AMDGPU_MACH_AMDGCN_GFX805
@ EF_AMDGPU_MACH_AMDGCN_GFX1201
@ EF_AMDGPU_MACH_AMDGCN_GFX1150
@ EF_AMDGPU_MACH_R600_SUMO
@ EF_AMDGPU_MACH_R600_BARTS
@ EF_AMDGPU_MACH_AMDGCN_GFX702
@ EF_LOONGARCH_ABI_SINGLE_FLOAT
@ EF_LOONGARCH_ABI_DOUBLE_FLOAT
@ EF_LOONGARCH_ABI_SOFT_FLOAT
@ EF_LOONGARCH_ABI_MODIFIER_MASK
Error createError(const Twine &Err)
constexpr int NumElfSymbolTypes
static std::string describe(const ELFFile< ELFT > &Obj, const typename ELFT::Shdr &Sec)
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
const llvm::EnumEntry< unsigned > ElfSymbolTypes[NumElfSymbolTypes]
This is an optimization pass for GlobalISel generic memory operations.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
const char * toString(DWARFSectionKind Kind)
void consumeError(Error Err)
Consume a Error without doing anything.
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.