1 //===-- RuntimeDyldELF.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-===//
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 // ELF support for MC-JIT runtime dynamic linker.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
14 #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
16 #include "RuntimeDyldImpl.h"
17 #include "llvm/ADT/DenseMap.h"
23 class ELFObjectFileBase
;
26 class RuntimeDyldELF
: public RuntimeDyldImpl
{
28 void resolveRelocation(const SectionEntry
&Section
, uint64_t Offset
,
29 uint64_t Value
, uint32_t Type
, int64_t Addend
,
30 uint64_t SymOffset
= 0, SID SectionID
= 0);
32 void resolveX86_64Relocation(const SectionEntry
&Section
, uint64_t Offset
,
33 uint64_t Value
, uint32_t Type
, int64_t Addend
,
36 void resolveX86Relocation(const SectionEntry
&Section
, uint64_t Offset
,
37 uint32_t Value
, uint32_t Type
, int32_t Addend
);
39 void resolveAArch64Relocation(const SectionEntry
&Section
, uint64_t Offset
,
40 uint64_t Value
, uint32_t Type
, int64_t Addend
);
42 bool resolveAArch64ShortBranch(unsigned SectionID
, relocation_iterator RelI
,
43 const RelocationValueRef
&Value
);
45 void resolveAArch64Branch(unsigned SectionID
, const RelocationValueRef
&Value
,
46 relocation_iterator RelI
, StubMap
&Stubs
);
48 void resolveARMRelocation(const SectionEntry
&Section
, uint64_t Offset
,
49 uint32_t Value
, uint32_t Type
, int32_t Addend
);
51 void resolvePPC32Relocation(const SectionEntry
&Section
, uint64_t Offset
,
52 uint64_t Value
, uint32_t Type
, int64_t Addend
);
54 void resolvePPC64Relocation(const SectionEntry
&Section
, uint64_t Offset
,
55 uint64_t Value
, uint32_t Type
, int64_t Addend
);
57 void resolveSystemZRelocation(const SectionEntry
&Section
, uint64_t Offset
,
58 uint64_t Value
, uint32_t Type
, int64_t Addend
);
60 void resolveBPFRelocation(const SectionEntry
&Section
, uint64_t Offset
,
61 uint64_t Value
, uint32_t Type
, int64_t Addend
);
63 unsigned getMaxStubSize() const override
{
64 if (Arch
== Triple::aarch64
|| Arch
== Triple::aarch64_be
)
65 return 20; // movz; movk; movk; movk; br
66 if (Arch
== Triple::arm
|| Arch
== Triple::thumb
)
67 return 8; // 32-bit instruction and 32-bit address
68 else if (IsMipsO32ABI
|| IsMipsN32ABI
)
70 else if (IsMipsN64ABI
)
72 else if (Arch
== Triple::ppc64
|| Arch
== Triple::ppc64le
)
74 else if (Arch
== Triple::x86_64
)
75 return 6; // 2-byte jmp instruction + 32-bit relative address
76 else if (Arch
== Triple::systemz
)
82 Align
getStubAlignment() override
{
83 if (Arch
== Triple::systemz
)
89 void setMipsABI(const ObjectFile
&Obj
) override
;
91 Error
findPPC64TOCSection(const object::ELFObjectFileBase
&Obj
,
92 ObjSectionToIDMap
&LocalSections
,
93 RelocationValueRef
&Rel
);
94 Error
findOPDEntrySection(const object::ELFObjectFileBase
&Obj
,
95 ObjSectionToIDMap
&LocalSections
,
96 RelocationValueRef
&Rel
);
99 size_t getGOTEntrySize() override
;
102 SectionEntry
&getSection(unsigned SectionID
) { return Sections
[SectionID
]; }
104 // Allocate no GOT entries for use in the given section.
105 uint64_t allocateGOTEntries(unsigned no
);
107 // Find GOT entry corresponding to relocation or create new one.
108 uint64_t findOrAllocGOTEntry(const RelocationValueRef
&Value
,
109 unsigned GOTRelType
);
111 // Resolve the relative address of GOTOffset in Section ID and place
112 // it at the given Offset
113 void resolveGOTOffsetRelocation(unsigned SectionID
, uint64_t Offset
,
114 uint64_t GOTOffset
, uint32_t Type
);
116 // For a GOT entry referenced from SectionID, compute a relocation entry
117 // that will place the final resolved value in the GOT slot
118 RelocationEntry
computeGOTOffsetRE(uint64_t GOTOffset
, uint64_t SymbolOffset
,
121 // Compute the address in memory where we can find the placeholder
122 void *computePlaceholderAddress(unsigned SectionID
, uint64_t Offset
) const;
124 // Split out common case for creating the RelocationEntry for when the
125 // relocation requires no particular advanced processing.
126 void processSimpleRelocation(unsigned SectionID
, uint64_t Offset
, unsigned RelType
, RelocationValueRef Value
);
128 // Return matching *LO16 relocation (Mips specific)
129 uint32_t getMatchingLoRelocation(uint32_t RelType
,
130 bool IsLocal
= false) const;
132 // The tentative ID for the GOT section
133 unsigned GOTSectionID
;
135 // Records the current number of allocated slots in the GOT
136 // (This would be equivalent to GOTEntries.size() were it not for relocations
137 // that consume more than one slot)
138 unsigned CurrentGOTIndex
;
141 // A map from section to a GOT section that has entries for section's GOT
142 // relocations. (Mips64 specific)
143 DenseMap
<SID
, SID
> SectionToGOTMap
;
146 // A map to avoid duplicate got entries (Mips64 specific)
147 StringMap
<uint64_t> GOTSymbolOffsets
;
149 // *HI16 relocations will be added for resolving when we find matching
150 // *LO16 part. (Mips specific)
151 SmallVector
<std::pair
<RelocationValueRef
, RelocationEntry
>, 8> PendingRelocs
;
153 // When a module is loaded we save the SectionID of the EH frame section
154 // in a table until we receive a request to register all unregistered
155 // EH frame sections with the memory manager.
156 SmallVector
<SID
, 2> UnregisteredEHFrameSections
;
158 // Map between GOT relocation value and corresponding GOT offset
159 std::map
<RelocationValueRef
, uint64_t> GOTOffsetMap
;
161 /// The ID of the current IFunc stub section
162 unsigned IFuncStubSectionID
= 0;
163 /// The current offset into the IFunc stub section
164 uint64_t IFuncStubOffset
= 0;
166 /// A IFunc stub and its original symbol
168 /// The offset of this stub in the IFunc stub section
170 /// The symbol table entry of the original symbol
171 SymbolTableEntry OriginalSymbol
;
175 SmallVector
<IFuncStub
, 2> IFuncStubs
;
177 /// Create the code for the IFunc resolver at the given address. This code
178 /// works together with the stubs created in createIFuncStub() to call the
179 /// resolver function and then jump to the real function address.
180 /// It must not be larger than 64B.
181 void createIFuncResolver(uint8_t *Addr
) const;
182 /// Create the code for an IFunc stub for the IFunc that is defined in
183 /// section IFuncSectionID at offset IFuncOffset. The IFunc resolver created
184 /// by createIFuncResolver() is defined in the section IFuncStubSectionID at
185 /// offset IFuncResolverOffset. The code should be written into the section
186 /// with the id IFuncStubSectionID at the offset IFuncStubOffset.
187 void createIFuncStub(unsigned IFuncStubSectionID
,
188 uint64_t IFuncResolverOffset
, uint64_t IFuncStubOffset
,
189 unsigned IFuncSectionID
, uint64_t IFuncOffset
);
190 /// Return the maximum size of a stub created by createIFuncStub()
191 unsigned getMaxIFuncStubSize() const;
193 void processNewSymbol(const SymbolRef
&ObjSymbol
,
194 SymbolTableEntry
&Entry
) override
;
195 bool relocationNeedsGot(const RelocationRef
&R
) const override
;
196 bool relocationNeedsStub(const RelocationRef
&R
) const override
;
198 // Process a GOTTPOFF TLS relocation for x86-64
199 // NOLINTNEXTLINE(readability-identifier-naming)
200 void processX86_64GOTTPOFFRelocation(unsigned SectionID
, uint64_t Offset
,
201 RelocationValueRef Value
,
203 // Process a TLSLD/TLSGD relocation for x86-64
204 // NOLINTNEXTLINE(readability-identifier-naming)
205 void processX86_64TLSRelocation(unsigned SectionID
, uint64_t Offset
,
206 uint64_t RelType
, RelocationValueRef Value
,
208 const RelocationRef
&GetAddrRelocation
);
211 RuntimeDyldELF(RuntimeDyld::MemoryManager
&MemMgr
,
212 JITSymbolResolver
&Resolver
);
213 ~RuntimeDyldELF() override
;
215 static std::unique_ptr
<RuntimeDyldELF
>
216 create(Triple::ArchType Arch
, RuntimeDyld::MemoryManager
&MemMgr
,
217 JITSymbolResolver
&Resolver
);
219 std::unique_ptr
<RuntimeDyld::LoadedObjectInfo
>
220 loadObject(const object::ObjectFile
&O
) override
;
222 void resolveRelocation(const RelocationEntry
&RE
, uint64_t Value
) override
;
223 Expected
<relocation_iterator
>
224 processRelocationRef(unsigned SectionID
, relocation_iterator RelI
,
225 const ObjectFile
&Obj
,
226 ObjSectionToIDMap
&ObjSectionToID
,
227 StubMap
&Stubs
) override
;
228 bool isCompatibleFile(const object::ObjectFile
&Obj
) const override
;
229 void registerEHFrames() override
;
230 Error
finalizeLoad(const ObjectFile
&Obj
,
231 ObjSectionToIDMap
&SectionMap
) override
;
234 } // end namespace llvm