Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
35268 views
//===-- RuntimeDyldELF.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// ELF support for MC-JIT runtime dynamic linker.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H13#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H1415#include "RuntimeDyldImpl.h"16#include "llvm/ADT/DenseMap.h"1718using namespace llvm;1920namespace llvm {21namespace object {22class ELFObjectFileBase;23}2425class RuntimeDyldELF : public RuntimeDyldImpl {2627void resolveRelocation(const SectionEntry &Section, uint64_t Offset,28uint64_t Value, uint32_t Type, int64_t Addend,29uint64_t SymOffset = 0, SID SectionID = 0);3031void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,32uint64_t Value, uint32_t Type, int64_t Addend,33uint64_t SymOffset);3435void resolveX86Relocation(const SectionEntry &Section, uint64_t Offset,36uint32_t Value, uint32_t Type, int32_t Addend);3738void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset,39uint64_t Value, uint32_t Type, int64_t Addend);4041bool resolveAArch64ShortBranch(unsigned SectionID, relocation_iterator RelI,42const RelocationValueRef &Value);4344void resolveAArch64Branch(unsigned SectionID, const RelocationValueRef &Value,45relocation_iterator RelI, StubMap &Stubs);4647void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,48uint32_t Value, uint32_t Type, int32_t Addend);4950void resolvePPC32Relocation(const SectionEntry &Section, uint64_t Offset,51uint64_t Value, uint32_t Type, int64_t Addend);5253void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset,54uint64_t Value, uint32_t Type, int64_t Addend);5556void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,57uint64_t Value, uint32_t Type, int64_t Addend);5859void resolveBPFRelocation(const SectionEntry &Section, uint64_t Offset,60uint64_t Value, uint32_t Type, int64_t Addend);6162unsigned getMaxStubSize() const override {63if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)64return 20; // movz; movk; movk; movk; br65if (Arch == Triple::arm || Arch == Triple::thumb)66return 8; // 32-bit instruction and 32-bit address67else if (IsMipsO32ABI || IsMipsN32ABI)68return 16;69else if (IsMipsN64ABI)70return 32;71else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)72return 44;73else if (Arch == Triple::x86_64)74return 6; // 2-byte jmp instruction + 32-bit relative address75else if (Arch == Triple::systemz)76return 16;77else78return 0;79}8081Align getStubAlignment() override {82if (Arch == Triple::systemz)83return Align(8);84else85return Align(1);86}8788void setMipsABI(const ObjectFile &Obj) override;8990Error findPPC64TOCSection(const object::ELFObjectFileBase &Obj,91ObjSectionToIDMap &LocalSections,92RelocationValueRef &Rel);93Error findOPDEntrySection(const object::ELFObjectFileBase &Obj,94ObjSectionToIDMap &LocalSections,95RelocationValueRef &Rel);9697protected:98size_t getGOTEntrySize() override;99100private:101SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }102103// Allocate no GOT entries for use in the given section.104uint64_t allocateGOTEntries(unsigned no);105106// Find GOT entry corresponding to relocation or create new one.107uint64_t findOrAllocGOTEntry(const RelocationValueRef &Value,108unsigned GOTRelType);109110// Resolve the relative address of GOTOffset in Section ID and place111// it at the given Offset112void resolveGOTOffsetRelocation(unsigned SectionID, uint64_t Offset,113uint64_t GOTOffset, uint32_t Type);114115// For a GOT entry referenced from SectionID, compute a relocation entry116// that will place the final resolved value in the GOT slot117RelocationEntry computeGOTOffsetRE(uint64_t GOTOffset, uint64_t SymbolOffset,118unsigned Type);119120// Compute the address in memory where we can find the placeholder121void *computePlaceholderAddress(unsigned SectionID, uint64_t Offset) const;122123// Split out common case for creating the RelocationEntry for when the124// relocation requires no particular advanced processing.125void processSimpleRelocation(unsigned SectionID, uint64_t Offset, unsigned RelType, RelocationValueRef Value);126127// Return matching *LO16 relocation (Mips specific)128uint32_t getMatchingLoRelocation(uint32_t RelType,129bool IsLocal = false) const;130131// The tentative ID for the GOT section132unsigned GOTSectionID;133134// Records the current number of allocated slots in the GOT135// (This would be equivalent to GOTEntries.size() were it not for relocations136// that consume more than one slot)137unsigned CurrentGOTIndex;138139protected:140// A map from section to a GOT section that has entries for section's GOT141// relocations. (Mips64 specific)142DenseMap<SID, SID> SectionToGOTMap;143144private:145// A map to avoid duplicate got entries (Mips64 specific)146StringMap<uint64_t> GOTSymbolOffsets;147148// *HI16 relocations will be added for resolving when we find matching149// *LO16 part. (Mips specific)150SmallVector<std::pair<RelocationValueRef, RelocationEntry>, 8> PendingRelocs;151152// When a module is loaded we save the SectionID of the EH frame section153// in a table until we receive a request to register all unregistered154// EH frame sections with the memory manager.155SmallVector<SID, 2> UnregisteredEHFrameSections;156157// Map between GOT relocation value and corresponding GOT offset158std::map<RelocationValueRef, uint64_t> GOTOffsetMap;159160/// The ID of the current IFunc stub section161unsigned IFuncStubSectionID = 0;162/// The current offset into the IFunc stub section163uint64_t IFuncStubOffset = 0;164165/// A IFunc stub and its original symbol166struct IFuncStub {167/// The offset of this stub in the IFunc stub section168uint64_t StubOffset;169/// The symbol table entry of the original symbol170SymbolTableEntry OriginalSymbol;171};172173/// The IFunc stubs174SmallVector<IFuncStub, 2> IFuncStubs;175176/// Create the code for the IFunc resolver at the given address. This code177/// works together with the stubs created in createIFuncStub() to call the178/// resolver function and then jump to the real function address.179/// It must not be larger than 64B.180void createIFuncResolver(uint8_t *Addr) const;181/// Create the code for an IFunc stub for the IFunc that is defined in182/// section IFuncSectionID at offset IFuncOffset. The IFunc resolver created183/// by createIFuncResolver() is defined in the section IFuncStubSectionID at184/// offset IFuncResolverOffset. The code should be written into the section185/// with the id IFuncStubSectionID at the offset IFuncStubOffset.186void createIFuncStub(unsigned IFuncStubSectionID,187uint64_t IFuncResolverOffset, uint64_t IFuncStubOffset,188unsigned IFuncSectionID, uint64_t IFuncOffset);189/// Return the maximum size of a stub created by createIFuncStub()190unsigned getMaxIFuncStubSize() const;191192void processNewSymbol(const SymbolRef &ObjSymbol,193SymbolTableEntry &Entry) override;194bool relocationNeedsGot(const RelocationRef &R) const override;195bool relocationNeedsStub(const RelocationRef &R) const override;196197// Process a GOTTPOFF TLS relocation for x86-64198// NOLINTNEXTLINE(readability-identifier-naming)199void processX86_64GOTTPOFFRelocation(unsigned SectionID, uint64_t Offset,200RelocationValueRef Value,201int64_t Addend);202// Process a TLSLD/TLSGD relocation for x86-64203// NOLINTNEXTLINE(readability-identifier-naming)204void processX86_64TLSRelocation(unsigned SectionID, uint64_t Offset,205uint64_t RelType, RelocationValueRef Value,206int64_t Addend,207const RelocationRef &GetAddrRelocation);208209public:210RuntimeDyldELF(RuntimeDyld::MemoryManager &MemMgr,211JITSymbolResolver &Resolver);212~RuntimeDyldELF() override;213214static std::unique_ptr<RuntimeDyldELF>215create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr,216JITSymbolResolver &Resolver);217218std::unique_ptr<RuntimeDyld::LoadedObjectInfo>219loadObject(const object::ObjectFile &O) override;220221void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;222Expected<relocation_iterator>223processRelocationRef(unsigned SectionID, relocation_iterator RelI,224const ObjectFile &Obj,225ObjSectionToIDMap &ObjSectionToID,226StubMap &Stubs) override;227bool isCompatibleFile(const object::ObjectFile &Obj) const override;228void registerEHFrames() override;229Error finalizeLoad(const ObjectFile &Obj,230ObjSectionToIDMap &SectionMap) override;231};232233} // end namespace llvm234235#endif236237238