13#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFAARCH64_H
14#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDCOFFAARCH64_H
22#define DEBUG_TYPE "dyld"
47 orig &= ~(0xFFF << 10);
48 write32le(
T, orig | ((imm & (0xFFF >> rangeLimit)) << 10));
57 if ((Inst & 0x04800000) == 0x04800000)
59 return static_cast<uint64_t
>((Inst >> 10) & 0xFFF) <<
Size;
69 if ((orig & 0x04800000) == 0x04800000)
71 if ((imm & ((1 <<
size) - 1)) != 0)
72 assert(0 &&
"misaligned ldr/str offset");
79 uint64_t
Imm = (s >> shift) - (p >> shift);
85 " delta=" +
Twine(s > p ? s - p : p - s) +
86 (s > p ?
" (target above pc)" :
" (target below pc)") +
87 " -- needs a 21-bit signed page offset (+/-4 GiB)");
91 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
106 uint64_t getImageBase() {
108 ImageBase = std::numeric_limits<uint64_t>::max();
115 if (Section.getLoadAddress() != 0)
116 ImageBase = std::min(ImageBase, Section.getLoadAddress());
136 bool CreateIfMissing) {
139 Key.SectionID = SectionID;
140 Key.Offset = ~uint64_t(0);
141 Key.SymbolName = Name.data();
145 for (
const auto &[StubKey, StubOffset] : Stubs)
146 if (StubKey.SectionID == SectionID && StubKey.Offset == ~uint64_t(0) &&
147 StubKey.SymbolName &&
StringRef(StubKey.SymbolName) == Name)
149 if (!CreateIfMissing)
155 Stubs[
Key] = EntryOffset;
162 LLVM_DEBUG(
dbgs() <<
" Created GOT entry for " << Name <<
" at offset "
163 << EntryOffset <<
"\n");
170 return (Inst & 0x7FC00000) == 0x11000000;
173 std::tuple<uint64_t, uint64_t, uint64_t>
175 uint64_t
Offset, uint64_t RelType, uint64_t Addend,
181 OriginalRelValueRef.
SectionID = SectionID;
183 OriginalRelValueRef.
Addend = Addend;
186 auto [Stub, Inserted] = Stubs.try_emplace(OriginalRelValueRef);
189 << TargetName.
data() <<
"\n");
191 StubOffset = Section.getStubOffset();
192 Stub->second = StubOffset;
198 StubOffset = Stub->second;
212 return std::make_tuple(
Offset, RelType, Addend);
223 if (Symbol == Obj.symbol_end())
227 if (!TargetNameOrErr)
231 auto SectionOrErr = Symbol->getSection();
234 auto Section = *SectionOrErr;
236 uint64_t RelType = RelI->
getType();
240 bool IsExtern = Section == Obj.section_end();
248 unsigned TargetSectionID = -1;
249 uint64_t TargetOffset = -1;
252 TargetSectionID = SectionID;
256 }
else if (!IsExtern) {
258 Obj, *Section, Section->isText(), ObjSectionToID))
259 TargetSectionID = *TargetSectionIDOrErr;
261 return TargetSectionIDOrErr.takeError();
275 Addend = (orig & 0x03FFFFFF) << 2;
279 SectionID, TargetName,
Offset, RelType, Addend, Stubs);
284 Addend = (orig & 0x00FFFFE0) >> 3;
289 Addend = (orig & 0x000FFFE0) >> 3;
295 Addend = ((orig >> 29) & 0x3) | ((orig >> 3) & 0x1FFFFC);
303 if (IsExtern && Addend == 0 &&
306 if (
isAddImmediate(NextInst) && ((NextInst >> 10) & 0xFFF) == 0) {
309 TargetSectionID = SectionID;
323 Addend = ((orig >> 10) & 0xFFF);
326 if (IsExtern && Addend == 0 &&
335 0xF9400000u | (Rn << 5) | Rd);
339 TargetOffset = GOTOffset;
340 TargetSectionID = SectionID;
362 <<
" RelType: " << RelTypeName <<
" TargetName: "
363 << TargetName <<
" Addend " << Addend <<
"\n");
381 uint64_t FinalAddress = Section.getLoadAddressWithOffset(RE.
Offset);
439 uint64_t PCRelVal =
Value + RE.
Addend - FinalAddress;
442 (PCRelVal & 0x0FFFFFFC) >> 2);
448 uint64_t PCRelVal =
Value + RE.
Addend - FinalAddress;
451 (PCRelVal & 0x001FFFFC) << 3);
457 uint64_t PCRelVal =
Value + RE.
Addend - FinalAddress;
460 (PCRelVal & 0x0000FFFC) << 3);
471 "relocation overflow");
478 "Relocation overflow");
480 "Relocation underflow");
486 uint64_t Result =
Value - FinalAddress - 4;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the SmallString class.
void write32le(void *P, uint32_t V)
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
Symbol resolution interface.
RelocationEntry - used to represent relocations internally in the dynamic linker.
uint32_t RelType
RelType - relocation type.
uint64_t Offset
Offset - offset into the section.
int64_t Addend
Addend - the relocation addend encoded in the instruction itself.
unsigned SectionID
SectionID - the section this relocation points to.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
Align getStubAlignment() override
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override
A object file specific relocation resolver.
unsigned getMaxStubSize() const override
RuntimeDyldCOFFAArch64(RuntimeDyld::MemoryManager &MM, JITSymbolResolver &Resolver)
void registerEHFrames() override
std::tuple< uint64_t, uint64_t, uint64_t > generateRelocationStub(unsigned SectionID, StringRef TargetName, uint64_t Offset, uint64_t RelType, uint64_t Addend, StubMap &Stubs)
Expected< object::relocation_iterator > processRelocationRef(unsigned SectionID, object::relocation_iterator RelI, const object::ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, StubMap &Stubs) override
Parses one or more object file relocations (some object files use relocation pairs) and stores it to ...
uint64_t getGOTEntryOffset(unsigned SectionID, StubMap &Stubs, StringRef Name, bool CreateIfMissing)
GOT slot in this section's stub area holding the address of Name, so an ADRP can reach external symbo...
static bool isAddImmediate(uint32_t Inst)
ADD (immediate, no shift): the second half of the ADRP+ADD idiom.
uint64_t getSymbolOffset(const SymbolRef &Sym)
static constexpr StringRef getImportSymbolPrefix()
RuntimeDyldCOFF(RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver, unsigned PointerSize, uint32_t PointerReloc)
uint64_t getDLLImportOffset(unsigned SectionID, StubMap &Stubs, StringRef Name, bool SetSectionIDMinus1=false)
std::map< SectionRef, unsigned > ObjSectionToIDMap
std::map< RelocationValueRef, uintptr_t > StubMap
void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName)
void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID)
Expected< unsigned > findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections)
Find Section in LocalSections.
uint8_t * createStubFunction(uint8_t *Addr, unsigned AbiVariant=0)
Emits long jump instruction to Addr.
SectionEntry - represents a section emitted into memory by the dynamic linker.
uint8_t * getAddressWithOffset(unsigned OffsetBytes) const
Return the address of this section with an offset.
void advanceStubOffset(unsigned StubSize)
uintptr_t getStubOffset() const
uintptr_t getObjAddress() const
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
This class is the base class for all object file types.
uint64_t getOffset() const
symbol_iterator getSymbol() const
void getTypeName(SmallVectorImpl< char > &Result) const
Get a string that represents the type of this relocation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_REL_ARM64_BRANCH19
@ IMAGE_REL_ARM64_SECTION
@ IMAGE_REL_ARM64_ABSOLUTE
@ IMAGE_REL_ARM64_PAGEOFFSET_12A
@ IMAGE_REL_ARM64_BRANCH14
@ IMAGE_REL_ARM64_BRANCH26
@ IMAGE_REL_ARM64_PAGEOFFSET_12L
@ IMAGE_REL_ARM64_ADDR32NB
@ IMAGE_REL_ARM64_PAGEBASE_REL21
content_iterator< RelocationRef > relocation_iterator
uint64_t read64le(const void *P)
uint16_t read16le(const void *P)
void write64le(void *P, uint64_t V)
void write16le(void *P, uint16_t V)
uint32_t read32le(const void *P)
This is an optimization pass for GlobalISel generic memory operations.
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.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ INTERNAL_REL_ARM64_LONG_BRANCH26
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
static uint64_t read32AArch64LdrAddend(uint32_t Inst)
Byte addend held in an LDR/STR (unsigned immediate) instruction.
static void write32AArch64Ldr(uint8_t *T, uint64_t imm)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
static void or32le(void *P, int32_t V)
static void add16(uint8_t *p, int16_t v)
static void write32AArch64Imm(uint8_t *T, uint64_t imm, uint32_t rangeLimit)
static void write32AArch64Addr(void *T, uint64_t s, uint64_t p, int shift)
This struct is a compact representation of a valid (non-zero power of two) alignment.