xref: /aosp_15_r20/external/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- RuntimeDyldImpl.h - Run-time dynamic linker for MC-JIT --*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Interface for the implementations of runtime dynamic linker facilities.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H
15*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringMap.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RuntimeDyld.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Format.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Host.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Mutex.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SwapByteOrder.h"
30*9880d681SAndroid Build Coastguard Worker #include <map>
31*9880d681SAndroid Build Coastguard Worker #include <unordered_map>
32*9880d681SAndroid Build Coastguard Worker #include <system_error>
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker using namespace llvm;
35*9880d681SAndroid Build Coastguard Worker using namespace llvm::object;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker namespace llvm {
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker class Twine;
40*9880d681SAndroid Build Coastguard Worker 
41*9880d681SAndroid Build Coastguard Worker #define UNIMPLEMENTED_RELOC(RelType) \
42*9880d681SAndroid Build Coastguard Worker   case RelType: \
43*9880d681SAndroid Build Coastguard Worker     return make_error<RuntimeDyldError>("Unimplemented relocation: " #RelType)
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker /// SectionEntry - represents a section emitted into memory by the dynamic
46*9880d681SAndroid Build Coastguard Worker /// linker.
47*9880d681SAndroid Build Coastguard Worker class SectionEntry {
48*9880d681SAndroid Build Coastguard Worker   /// Name - section name.
49*9880d681SAndroid Build Coastguard Worker   std::string Name;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   /// Address - address in the linker's memory where the section resides.
52*9880d681SAndroid Build Coastguard Worker   uint8_t *Address;
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker   /// Size - section size. Doesn't include the stubs.
55*9880d681SAndroid Build Coastguard Worker   size_t Size;
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker   /// LoadAddress - the address of the section in the target process's memory.
58*9880d681SAndroid Build Coastguard Worker   /// Used for situations in which JIT-ed code is being executed in the address
59*9880d681SAndroid Build Coastguard Worker   /// space of a separate process.  If the code executes in the same address
60*9880d681SAndroid Build Coastguard Worker   /// space where it was JIT-ed, this just equals Address.
61*9880d681SAndroid Build Coastguard Worker   uint64_t LoadAddress;
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker   /// StubOffset - used for architectures with stub functions for far
64*9880d681SAndroid Build Coastguard Worker   /// relocations (like ARM).
65*9880d681SAndroid Build Coastguard Worker   uintptr_t StubOffset;
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker   /// The total amount of space allocated for this section.  This includes the
68*9880d681SAndroid Build Coastguard Worker   /// section size and the maximum amount of space that the stubs can occupy.
69*9880d681SAndroid Build Coastguard Worker   size_t AllocationSize;
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   /// ObjAddress - address of the section in the in-memory object file.  Used
72*9880d681SAndroid Build Coastguard Worker   /// for calculating relocations in some object formats (like MachO).
73*9880d681SAndroid Build Coastguard Worker   uintptr_t ObjAddress;
74*9880d681SAndroid Build Coastguard Worker 
75*9880d681SAndroid Build Coastguard Worker public:
SectionEntry(StringRef name,uint8_t * address,size_t size,size_t allocationSize,uintptr_t objAddress)76*9880d681SAndroid Build Coastguard Worker   SectionEntry(StringRef name, uint8_t *address, size_t size,
77*9880d681SAndroid Build Coastguard Worker                size_t allocationSize, uintptr_t objAddress)
78*9880d681SAndroid Build Coastguard Worker       : Name(name), Address(address), Size(size),
79*9880d681SAndroid Build Coastguard Worker         LoadAddress(reinterpret_cast<uintptr_t>(address)), StubOffset(size),
80*9880d681SAndroid Build Coastguard Worker         AllocationSize(allocationSize), ObjAddress(objAddress) {
81*9880d681SAndroid Build Coastguard Worker     // AllocationSize is used only in asserts, prevent an "unused private field"
82*9880d681SAndroid Build Coastguard Worker     // warning:
83*9880d681SAndroid Build Coastguard Worker     (void)AllocationSize;
84*9880d681SAndroid Build Coastguard Worker   }
85*9880d681SAndroid Build Coastguard Worker 
getName()86*9880d681SAndroid Build Coastguard Worker   StringRef getName() const { return Name; }
87*9880d681SAndroid Build Coastguard Worker 
getAddress()88*9880d681SAndroid Build Coastguard Worker   uint8_t *getAddress() const { return Address; }
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker   /// \brief Return the address of this section with an offset.
getAddressWithOffset(unsigned OffsetBytes)91*9880d681SAndroid Build Coastguard Worker   uint8_t *getAddressWithOffset(unsigned OffsetBytes) const {
92*9880d681SAndroid Build Coastguard Worker     assert(OffsetBytes <= AllocationSize && "Offset out of bounds!");
93*9880d681SAndroid Build Coastguard Worker     return Address + OffsetBytes;
94*9880d681SAndroid Build Coastguard Worker   }
95*9880d681SAndroid Build Coastguard Worker 
getSize()96*9880d681SAndroid Build Coastguard Worker   size_t getSize() const { return Size; }
97*9880d681SAndroid Build Coastguard Worker 
getLoadAddress()98*9880d681SAndroid Build Coastguard Worker   uint64_t getLoadAddress() const { return LoadAddress; }
setLoadAddress(uint64_t LA)99*9880d681SAndroid Build Coastguard Worker   void setLoadAddress(uint64_t LA) { LoadAddress = LA; }
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker   /// \brief Return the load address of this section with an offset.
getLoadAddressWithOffset(unsigned OffsetBytes)102*9880d681SAndroid Build Coastguard Worker   uint64_t getLoadAddressWithOffset(unsigned OffsetBytes) const {
103*9880d681SAndroid Build Coastguard Worker     assert(OffsetBytes <= AllocationSize && "Offset out of bounds!");
104*9880d681SAndroid Build Coastguard Worker     return LoadAddress + OffsetBytes;
105*9880d681SAndroid Build Coastguard Worker   }
106*9880d681SAndroid Build Coastguard Worker 
getStubOffset()107*9880d681SAndroid Build Coastguard Worker   uintptr_t getStubOffset() const { return StubOffset; }
108*9880d681SAndroid Build Coastguard Worker 
advanceStubOffset(unsigned StubSize)109*9880d681SAndroid Build Coastguard Worker   void advanceStubOffset(unsigned StubSize) {
110*9880d681SAndroid Build Coastguard Worker     StubOffset += StubSize;
111*9880d681SAndroid Build Coastguard Worker     assert(StubOffset <= AllocationSize && "Not enough space allocated!");
112*9880d681SAndroid Build Coastguard Worker   }
113*9880d681SAndroid Build Coastguard Worker 
getObjAddress()114*9880d681SAndroid Build Coastguard Worker   uintptr_t getObjAddress() const { return ObjAddress; }
115*9880d681SAndroid Build Coastguard Worker };
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker /// RelocationEntry - used to represent relocations internally in the dynamic
118*9880d681SAndroid Build Coastguard Worker /// linker.
119*9880d681SAndroid Build Coastguard Worker class RelocationEntry {
120*9880d681SAndroid Build Coastguard Worker public:
121*9880d681SAndroid Build Coastguard Worker   /// SectionID - the section this relocation points to.
122*9880d681SAndroid Build Coastguard Worker   unsigned SectionID;
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   /// Offset - offset into the section.
125*9880d681SAndroid Build Coastguard Worker   uint64_t Offset;
126*9880d681SAndroid Build Coastguard Worker 
127*9880d681SAndroid Build Coastguard Worker   /// RelType - relocation type.
128*9880d681SAndroid Build Coastguard Worker   uint32_t RelType;
129*9880d681SAndroid Build Coastguard Worker 
130*9880d681SAndroid Build Coastguard Worker   /// Addend - the relocation addend encoded in the instruction itself.  Also
131*9880d681SAndroid Build Coastguard Worker   /// used to make a relocation section relative instead of symbol relative.
132*9880d681SAndroid Build Coastguard Worker   int64_t Addend;
133*9880d681SAndroid Build Coastguard Worker 
134*9880d681SAndroid Build Coastguard Worker   struct SectionPair {
135*9880d681SAndroid Build Coastguard Worker       uint32_t SectionA;
136*9880d681SAndroid Build Coastguard Worker       uint32_t SectionB;
137*9880d681SAndroid Build Coastguard Worker   };
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   /// SymOffset - Section offset of the relocation entry's symbol (used for GOT
140*9880d681SAndroid Build Coastguard Worker   /// lookup).
141*9880d681SAndroid Build Coastguard Worker   union {
142*9880d681SAndroid Build Coastguard Worker     uint64_t SymOffset;
143*9880d681SAndroid Build Coastguard Worker     SectionPair Sections;
144*9880d681SAndroid Build Coastguard Worker   };
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker   /// True if this is a PCRel relocation (MachO specific).
147*9880d681SAndroid Build Coastguard Worker   bool IsPCRel;
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   /// The size of this relocation (MachO specific).
150*9880d681SAndroid Build Coastguard Worker   unsigned Size;
151*9880d681SAndroid Build Coastguard Worker 
RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend)152*9880d681SAndroid Build Coastguard Worker   RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend)
153*9880d681SAndroid Build Coastguard Worker       : SectionID(id), Offset(offset), RelType(type), Addend(addend),
154*9880d681SAndroid Build Coastguard Worker         SymOffset(0), IsPCRel(false), Size(0) {}
155*9880d681SAndroid Build Coastguard Worker 
RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,uint64_t symoffset)156*9880d681SAndroid Build Coastguard Worker   RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
157*9880d681SAndroid Build Coastguard Worker                   uint64_t symoffset)
158*9880d681SAndroid Build Coastguard Worker       : SectionID(id), Offset(offset), RelType(type), Addend(addend),
159*9880d681SAndroid Build Coastguard Worker         SymOffset(symoffset), IsPCRel(false), Size(0) {}
160*9880d681SAndroid Build Coastguard Worker 
RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,bool IsPCRel,unsigned Size)161*9880d681SAndroid Build Coastguard Worker   RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
162*9880d681SAndroid Build Coastguard Worker                   bool IsPCRel, unsigned Size)
163*9880d681SAndroid Build Coastguard Worker       : SectionID(id), Offset(offset), RelType(type), Addend(addend),
164*9880d681SAndroid Build Coastguard Worker         SymOffset(0), IsPCRel(IsPCRel), Size(Size) {}
165*9880d681SAndroid Build Coastguard Worker 
RelocationEntry(unsigned id,uint64_t offset,uint32_t type,int64_t addend,unsigned SectionA,uint64_t SectionAOffset,unsigned SectionB,uint64_t SectionBOffset,bool IsPCRel,unsigned Size)166*9880d681SAndroid Build Coastguard Worker   RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend,
167*9880d681SAndroid Build Coastguard Worker                   unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB,
168*9880d681SAndroid Build Coastguard Worker                   uint64_t SectionBOffset, bool IsPCRel, unsigned Size)
169*9880d681SAndroid Build Coastguard Worker       : SectionID(id), Offset(offset), RelType(type),
170*9880d681SAndroid Build Coastguard Worker         Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel),
171*9880d681SAndroid Build Coastguard Worker         Size(Size) {
172*9880d681SAndroid Build Coastguard Worker     Sections.SectionA = SectionA;
173*9880d681SAndroid Build Coastguard Worker     Sections.SectionB = SectionB;
174*9880d681SAndroid Build Coastguard Worker   }
175*9880d681SAndroid Build Coastguard Worker };
176*9880d681SAndroid Build Coastguard Worker 
177*9880d681SAndroid Build Coastguard Worker class RelocationValueRef {
178*9880d681SAndroid Build Coastguard Worker public:
179*9880d681SAndroid Build Coastguard Worker   unsigned SectionID;
180*9880d681SAndroid Build Coastguard Worker   uint64_t Offset;
181*9880d681SAndroid Build Coastguard Worker   int64_t Addend;
182*9880d681SAndroid Build Coastguard Worker   const char *SymbolName;
RelocationValueRef()183*9880d681SAndroid Build Coastguard Worker   RelocationValueRef() : SectionID(0), Offset(0), Addend(0),
184*9880d681SAndroid Build Coastguard Worker                          SymbolName(nullptr) {}
185*9880d681SAndroid Build Coastguard Worker 
186*9880d681SAndroid Build Coastguard Worker   inline bool operator==(const RelocationValueRef &Other) const {
187*9880d681SAndroid Build Coastguard Worker     return SectionID == Other.SectionID && Offset == Other.Offset &&
188*9880d681SAndroid Build Coastguard Worker            Addend == Other.Addend && SymbolName == Other.SymbolName;
189*9880d681SAndroid Build Coastguard Worker   }
190*9880d681SAndroid Build Coastguard Worker   inline bool operator<(const RelocationValueRef &Other) const {
191*9880d681SAndroid Build Coastguard Worker     if (SectionID != Other.SectionID)
192*9880d681SAndroid Build Coastguard Worker       return SectionID < Other.SectionID;
193*9880d681SAndroid Build Coastguard Worker     if (Offset != Other.Offset)
194*9880d681SAndroid Build Coastguard Worker       return Offset < Other.Offset;
195*9880d681SAndroid Build Coastguard Worker     if (Addend != Other.Addend)
196*9880d681SAndroid Build Coastguard Worker       return Addend < Other.Addend;
197*9880d681SAndroid Build Coastguard Worker     return SymbolName < Other.SymbolName;
198*9880d681SAndroid Build Coastguard Worker   }
199*9880d681SAndroid Build Coastguard Worker };
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker /// @brief Symbol info for RuntimeDyld.
202*9880d681SAndroid Build Coastguard Worker class SymbolTableEntry : public JITSymbolBase {
203*9880d681SAndroid Build Coastguard Worker public:
SymbolTableEntry()204*9880d681SAndroid Build Coastguard Worker   SymbolTableEntry()
205*9880d681SAndroid Build Coastguard Worker     : JITSymbolBase(JITSymbolFlags::None), Offset(0), SectionID(0) {}
206*9880d681SAndroid Build Coastguard Worker 
SymbolTableEntry(unsigned SectionID,uint64_t Offset,JITSymbolFlags Flags)207*9880d681SAndroid Build Coastguard Worker   SymbolTableEntry(unsigned SectionID, uint64_t Offset, JITSymbolFlags Flags)
208*9880d681SAndroid Build Coastguard Worker     : JITSymbolBase(Flags), Offset(Offset), SectionID(SectionID) {}
209*9880d681SAndroid Build Coastguard Worker 
getSectionID()210*9880d681SAndroid Build Coastguard Worker   unsigned getSectionID() const { return SectionID; }
getOffset()211*9880d681SAndroid Build Coastguard Worker   uint64_t getOffset() const { return Offset; }
212*9880d681SAndroid Build Coastguard Worker 
213*9880d681SAndroid Build Coastguard Worker private:
214*9880d681SAndroid Build Coastguard Worker   uint64_t Offset;
215*9880d681SAndroid Build Coastguard Worker   unsigned SectionID;
216*9880d681SAndroid Build Coastguard Worker };
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker typedef StringMap<SymbolTableEntry> RTDyldSymbolTable;
219*9880d681SAndroid Build Coastguard Worker 
220*9880d681SAndroid Build Coastguard Worker class RuntimeDyldImpl {
221*9880d681SAndroid Build Coastguard Worker   friend class RuntimeDyld::LoadedObjectInfo;
222*9880d681SAndroid Build Coastguard Worker   friend class RuntimeDyldCheckerImpl;
223*9880d681SAndroid Build Coastguard Worker protected:
224*9880d681SAndroid Build Coastguard Worker   static const unsigned AbsoluteSymbolSection = ~0U;
225*9880d681SAndroid Build Coastguard Worker 
226*9880d681SAndroid Build Coastguard Worker   // The MemoryManager to load objects into.
227*9880d681SAndroid Build Coastguard Worker   RuntimeDyld::MemoryManager &MemMgr;
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker   // The symbol resolver to use for external symbols.
230*9880d681SAndroid Build Coastguard Worker   RuntimeDyld::SymbolResolver &Resolver;
231*9880d681SAndroid Build Coastguard Worker 
232*9880d681SAndroid Build Coastguard Worker   // Attached RuntimeDyldChecker instance. Null if no instance attached.
233*9880d681SAndroid Build Coastguard Worker   RuntimeDyldCheckerImpl *Checker;
234*9880d681SAndroid Build Coastguard Worker 
235*9880d681SAndroid Build Coastguard Worker   // A list of all sections emitted by the dynamic linker.  These sections are
236*9880d681SAndroid Build Coastguard Worker   // referenced in the code by means of their index in this list - SectionID.
237*9880d681SAndroid Build Coastguard Worker   typedef SmallVector<SectionEntry, 64> SectionList;
238*9880d681SAndroid Build Coastguard Worker   SectionList Sections;
239*9880d681SAndroid Build Coastguard Worker 
240*9880d681SAndroid Build Coastguard Worker   typedef unsigned SID; // Type for SectionIDs
241*9880d681SAndroid Build Coastguard Worker #define RTDYLD_INVALID_SECTION_ID ((RuntimeDyldImpl::SID)(-1))
242*9880d681SAndroid Build Coastguard Worker 
243*9880d681SAndroid Build Coastguard Worker   // Keep a map of sections from object file to the SectionID which
244*9880d681SAndroid Build Coastguard Worker   // references it.
245*9880d681SAndroid Build Coastguard Worker   typedef std::map<SectionRef, unsigned> ObjSectionToIDMap;
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker   // A global symbol table for symbols from all loaded modules.
248*9880d681SAndroid Build Coastguard Worker   RTDyldSymbolTable GlobalSymbolTable;
249*9880d681SAndroid Build Coastguard Worker 
250*9880d681SAndroid Build Coastguard Worker   // Keep a map of common symbols to their info pairs
251*9880d681SAndroid Build Coastguard Worker   typedef std::vector<SymbolRef> CommonSymbolList;
252*9880d681SAndroid Build Coastguard Worker 
253*9880d681SAndroid Build Coastguard Worker   // For each symbol, keep a list of relocations based on it. Anytime
254*9880d681SAndroid Build Coastguard Worker   // its address is reassigned (the JIT re-compiled the function, e.g.),
255*9880d681SAndroid Build Coastguard Worker   // the relocations get re-resolved.
256*9880d681SAndroid Build Coastguard Worker   // The symbol (or section) the relocation is sourced from is the Key
257*9880d681SAndroid Build Coastguard Worker   // in the relocation list where it's stored.
258*9880d681SAndroid Build Coastguard Worker   typedef SmallVector<RelocationEntry, 64> RelocationList;
259*9880d681SAndroid Build Coastguard Worker   // Relocations to sections already loaded. Indexed by SectionID which is the
260*9880d681SAndroid Build Coastguard Worker   // source of the address. The target where the address will be written is
261*9880d681SAndroid Build Coastguard Worker   // SectionID/Offset in the relocation itself.
262*9880d681SAndroid Build Coastguard Worker   std::unordered_map<unsigned, RelocationList> Relocations;
263*9880d681SAndroid Build Coastguard Worker 
264*9880d681SAndroid Build Coastguard Worker   // Relocations to external symbols that are not yet resolved.  Symbols are
265*9880d681SAndroid Build Coastguard Worker   // external when they aren't found in the global symbol table of all loaded
266*9880d681SAndroid Build Coastguard Worker   // modules.  This map is indexed by symbol name.
267*9880d681SAndroid Build Coastguard Worker   StringMap<RelocationList> ExternalSymbolRelocations;
268*9880d681SAndroid Build Coastguard Worker 
269*9880d681SAndroid Build Coastguard Worker 
270*9880d681SAndroid Build Coastguard Worker   typedef std::map<RelocationValueRef, uintptr_t> StubMap;
271*9880d681SAndroid Build Coastguard Worker 
272*9880d681SAndroid Build Coastguard Worker   Triple::ArchType Arch;
273*9880d681SAndroid Build Coastguard Worker   bool IsTargetLittleEndian;
274*9880d681SAndroid Build Coastguard Worker   bool IsMipsO32ABI;
275*9880d681SAndroid Build Coastguard Worker   bool IsMipsN64ABI;
276*9880d681SAndroid Build Coastguard Worker 
277*9880d681SAndroid Build Coastguard Worker   // True if all sections should be passed to the memory manager, false if only
278*9880d681SAndroid Build Coastguard Worker   // sections containing relocations should be. Defaults to 'false'.
279*9880d681SAndroid Build Coastguard Worker   bool ProcessAllSections;
280*9880d681SAndroid Build Coastguard Worker 
281*9880d681SAndroid Build Coastguard Worker   // This mutex prevents simultaneously loading objects from two different
282*9880d681SAndroid Build Coastguard Worker   // threads.  This keeps us from having to protect individual data structures
283*9880d681SAndroid Build Coastguard Worker   // and guarantees that section allocation requests to the memory manager
284*9880d681SAndroid Build Coastguard Worker   // won't be interleaved between modules.  It is also used in mapSectionAddress
285*9880d681SAndroid Build Coastguard Worker   // and resolveRelocations to protect write access to internal data structures.
286*9880d681SAndroid Build Coastguard Worker   //
287*9880d681SAndroid Build Coastguard Worker   // loadObject may be called on the same thread during the handling of of
288*9880d681SAndroid Build Coastguard Worker   // processRelocations, and that's OK.  The handling of the relocation lists
289*9880d681SAndroid Build Coastguard Worker   // is written in such a way as to work correctly if new elements are added to
290*9880d681SAndroid Build Coastguard Worker   // the end of the list while the list is being processed.
291*9880d681SAndroid Build Coastguard Worker   sys::Mutex lock;
292*9880d681SAndroid Build Coastguard Worker 
293*9880d681SAndroid Build Coastguard Worker   virtual unsigned getMaxStubSize() = 0;
294*9880d681SAndroid Build Coastguard Worker   virtual unsigned getStubAlignment() = 0;
295*9880d681SAndroid Build Coastguard Worker 
296*9880d681SAndroid Build Coastguard Worker   bool HasError;
297*9880d681SAndroid Build Coastguard Worker   std::string ErrorStr;
298*9880d681SAndroid Build Coastguard Worker 
getSectionLoadAddress(unsigned SectionID)299*9880d681SAndroid Build Coastguard Worker   uint64_t getSectionLoadAddress(unsigned SectionID) const {
300*9880d681SAndroid Build Coastguard Worker     return Sections[SectionID].getLoadAddress();
301*9880d681SAndroid Build Coastguard Worker   }
302*9880d681SAndroid Build Coastguard Worker 
getSectionAddress(unsigned SectionID)303*9880d681SAndroid Build Coastguard Worker   uint8_t *getSectionAddress(unsigned SectionID) const {
304*9880d681SAndroid Build Coastguard Worker     return Sections[SectionID].getAddress();
305*9880d681SAndroid Build Coastguard Worker   }
306*9880d681SAndroid Build Coastguard Worker 
writeInt16BE(uint8_t * Addr,uint16_t Value)307*9880d681SAndroid Build Coastguard Worker   void writeInt16BE(uint8_t *Addr, uint16_t Value) {
308*9880d681SAndroid Build Coastguard Worker     if (IsTargetLittleEndian)
309*9880d681SAndroid Build Coastguard Worker       sys::swapByteOrder(Value);
310*9880d681SAndroid Build Coastguard Worker     *Addr       = (Value >> 8) & 0xFF;
311*9880d681SAndroid Build Coastguard Worker     *(Addr + 1) = Value & 0xFF;
312*9880d681SAndroid Build Coastguard Worker   }
313*9880d681SAndroid Build Coastguard Worker 
writeInt32BE(uint8_t * Addr,uint32_t Value)314*9880d681SAndroid Build Coastguard Worker   void writeInt32BE(uint8_t *Addr, uint32_t Value) {
315*9880d681SAndroid Build Coastguard Worker     if (IsTargetLittleEndian)
316*9880d681SAndroid Build Coastguard Worker       sys::swapByteOrder(Value);
317*9880d681SAndroid Build Coastguard Worker     *Addr       = (Value >> 24) & 0xFF;
318*9880d681SAndroid Build Coastguard Worker     *(Addr + 1) = (Value >> 16) & 0xFF;
319*9880d681SAndroid Build Coastguard Worker     *(Addr + 2) = (Value >> 8) & 0xFF;
320*9880d681SAndroid Build Coastguard Worker     *(Addr + 3) = Value & 0xFF;
321*9880d681SAndroid Build Coastguard Worker   }
322*9880d681SAndroid Build Coastguard Worker 
writeInt64BE(uint8_t * Addr,uint64_t Value)323*9880d681SAndroid Build Coastguard Worker   void writeInt64BE(uint8_t *Addr, uint64_t Value) {
324*9880d681SAndroid Build Coastguard Worker     if (IsTargetLittleEndian)
325*9880d681SAndroid Build Coastguard Worker       sys::swapByteOrder(Value);
326*9880d681SAndroid Build Coastguard Worker     *Addr       = (Value >> 56) & 0xFF;
327*9880d681SAndroid Build Coastguard Worker     *(Addr + 1) = (Value >> 48) & 0xFF;
328*9880d681SAndroid Build Coastguard Worker     *(Addr + 2) = (Value >> 40) & 0xFF;
329*9880d681SAndroid Build Coastguard Worker     *(Addr + 3) = (Value >> 32) & 0xFF;
330*9880d681SAndroid Build Coastguard Worker     *(Addr + 4) = (Value >> 24) & 0xFF;
331*9880d681SAndroid Build Coastguard Worker     *(Addr + 5) = (Value >> 16) & 0xFF;
332*9880d681SAndroid Build Coastguard Worker     *(Addr + 6) = (Value >> 8) & 0xFF;
333*9880d681SAndroid Build Coastguard Worker     *(Addr + 7) = Value & 0xFF;
334*9880d681SAndroid Build Coastguard Worker   }
335*9880d681SAndroid Build Coastguard Worker 
setMipsABI(const ObjectFile & Obj)336*9880d681SAndroid Build Coastguard Worker   virtual void setMipsABI(const ObjectFile &Obj) {
337*9880d681SAndroid Build Coastguard Worker     IsMipsO32ABI = false;
338*9880d681SAndroid Build Coastguard Worker     IsMipsN64ABI = false;
339*9880d681SAndroid Build Coastguard Worker   }
340*9880d681SAndroid Build Coastguard Worker 
341*9880d681SAndroid Build Coastguard Worker   /// Endian-aware read Read the least significant Size bytes from Src.
342*9880d681SAndroid Build Coastguard Worker   uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const;
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker   /// Endian-aware write. Write the least significant Size bytes from Value to
345*9880d681SAndroid Build Coastguard Worker   /// Dst.
346*9880d681SAndroid Build Coastguard Worker   void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const;
347*9880d681SAndroid Build Coastguard Worker 
348*9880d681SAndroid Build Coastguard Worker   /// \brief Given the common symbols discovered in the object file, emit a
349*9880d681SAndroid Build Coastguard Worker   /// new section for them and update the symbol mappings in the object and
350*9880d681SAndroid Build Coastguard Worker   /// symbol table.
351*9880d681SAndroid Build Coastguard Worker   Error emitCommonSymbols(const ObjectFile &Obj,
352*9880d681SAndroid Build Coastguard Worker                           CommonSymbolList &CommonSymbols);
353*9880d681SAndroid Build Coastguard Worker 
354*9880d681SAndroid Build Coastguard Worker   /// \brief Emits section data from the object file to the MemoryManager.
355*9880d681SAndroid Build Coastguard Worker   /// \param IsCode if it's true then allocateCodeSection() will be
356*9880d681SAndroid Build Coastguard Worker   ///        used for emits, else allocateDataSection() will be used.
357*9880d681SAndroid Build Coastguard Worker   /// \return SectionID.
358*9880d681SAndroid Build Coastguard Worker   Expected<unsigned> emitSection(const ObjectFile &Obj,
359*9880d681SAndroid Build Coastguard Worker                                  const SectionRef &Section,
360*9880d681SAndroid Build Coastguard Worker                                  bool IsCode);
361*9880d681SAndroid Build Coastguard Worker 
362*9880d681SAndroid Build Coastguard Worker   /// \brief Find Section in LocalSections. If the secton is not found - emit
363*9880d681SAndroid Build Coastguard Worker   ///        it and store in LocalSections.
364*9880d681SAndroid Build Coastguard Worker   /// \param IsCode if it's true then allocateCodeSection() will be
365*9880d681SAndroid Build Coastguard Worker   ///        used for emmits, else allocateDataSection() will be used.
366*9880d681SAndroid Build Coastguard Worker   /// \return SectionID.
367*9880d681SAndroid Build Coastguard Worker   Expected<unsigned> findOrEmitSection(const ObjectFile &Obj,
368*9880d681SAndroid Build Coastguard Worker                                        const SectionRef &Section, bool IsCode,
369*9880d681SAndroid Build Coastguard Worker                                        ObjSectionToIDMap &LocalSections);
370*9880d681SAndroid Build Coastguard Worker 
371*9880d681SAndroid Build Coastguard Worker   // \brief Add a relocation entry that uses the given section.
372*9880d681SAndroid Build Coastguard Worker   void addRelocationForSection(const RelocationEntry &RE, unsigned SectionID);
373*9880d681SAndroid Build Coastguard Worker 
374*9880d681SAndroid Build Coastguard Worker   // \brief Add a relocation entry that uses the given symbol.  This symbol may
375*9880d681SAndroid Build Coastguard Worker   // be found in the global symbol table, or it may be external.
376*9880d681SAndroid Build Coastguard Worker   void addRelocationForSymbol(const RelocationEntry &RE, StringRef SymbolName);
377*9880d681SAndroid Build Coastguard Worker 
378*9880d681SAndroid Build Coastguard Worker   /// \brief Emits long jump instruction to Addr.
379*9880d681SAndroid Build Coastguard Worker   /// \return Pointer to the memory area for emitting target address.
380*9880d681SAndroid Build Coastguard Worker   uint8_t *createStubFunction(uint8_t *Addr, unsigned AbiVariant = 0);
381*9880d681SAndroid Build Coastguard Worker 
382*9880d681SAndroid Build Coastguard Worker   /// \brief Resolves relocations from Relocs list with address from Value.
383*9880d681SAndroid Build Coastguard Worker   void resolveRelocationList(const RelocationList &Relocs, uint64_t Value);
384*9880d681SAndroid Build Coastguard Worker 
385*9880d681SAndroid Build Coastguard Worker   /// \brief A object file specific relocation resolver
386*9880d681SAndroid Build Coastguard Worker   /// \param RE The relocation to be resolved
387*9880d681SAndroid Build Coastguard Worker   /// \param Value Target symbol address to apply the relocation action
388*9880d681SAndroid Build Coastguard Worker   virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value) = 0;
389*9880d681SAndroid Build Coastguard Worker 
390*9880d681SAndroid Build Coastguard Worker   /// \brief Parses one or more object file relocations (some object files use
391*9880d681SAndroid Build Coastguard Worker   ///        relocation pairs) and stores it to Relocations or SymbolRelocations
392*9880d681SAndroid Build Coastguard Worker   ///        (this depends on the object file type).
393*9880d681SAndroid Build Coastguard Worker   /// \return Iterator to the next relocation that needs to be parsed.
394*9880d681SAndroid Build Coastguard Worker   virtual Expected<relocation_iterator>
395*9880d681SAndroid Build Coastguard Worker   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
396*9880d681SAndroid Build Coastguard Worker                        const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID,
397*9880d681SAndroid Build Coastguard Worker                        StubMap &Stubs) = 0;
398*9880d681SAndroid Build Coastguard Worker 
399*9880d681SAndroid Build Coastguard Worker   /// \brief Resolve relocations to external symbols.
400*9880d681SAndroid Build Coastguard Worker   void resolveExternalSymbols();
401*9880d681SAndroid Build Coastguard Worker 
402*9880d681SAndroid Build Coastguard Worker   // \brief Compute an upper bound of the memory that is required to load all
403*9880d681SAndroid Build Coastguard Worker   // sections
404*9880d681SAndroid Build Coastguard Worker   Error computeTotalAllocSize(const ObjectFile &Obj,
405*9880d681SAndroid Build Coastguard Worker                               uint64_t &CodeSize, uint32_t &CodeAlign,
406*9880d681SAndroid Build Coastguard Worker                               uint64_t &RODataSize, uint32_t &RODataAlign,
407*9880d681SAndroid Build Coastguard Worker                               uint64_t &RWDataSize, uint32_t &RWDataAlign);
408*9880d681SAndroid Build Coastguard Worker 
409*9880d681SAndroid Build Coastguard Worker   // \brief Compute the stub buffer size required for a section
410*9880d681SAndroid Build Coastguard Worker   unsigned computeSectionStubBufSize(const ObjectFile &Obj,
411*9880d681SAndroid Build Coastguard Worker                                      const SectionRef &Section);
412*9880d681SAndroid Build Coastguard Worker 
413*9880d681SAndroid Build Coastguard Worker   // \brief Implementation of the generic part of the loadObject algorithm.
414*9880d681SAndroid Build Coastguard Worker   Expected<ObjSectionToIDMap> loadObjectImpl(const object::ObjectFile &Obj);
415*9880d681SAndroid Build Coastguard Worker 
416*9880d681SAndroid Build Coastguard Worker   // \brief Return true if the relocation R may require allocating a stub.
relocationNeedsStub(const RelocationRef & R)417*9880d681SAndroid Build Coastguard Worker   virtual bool relocationNeedsStub(const RelocationRef &R) const {
418*9880d681SAndroid Build Coastguard Worker     return true;    // Conservative answer
419*9880d681SAndroid Build Coastguard Worker   }
420*9880d681SAndroid Build Coastguard Worker 
421*9880d681SAndroid Build Coastguard Worker public:
RuntimeDyldImpl(RuntimeDyld::MemoryManager & MemMgr,RuntimeDyld::SymbolResolver & Resolver)422*9880d681SAndroid Build Coastguard Worker   RuntimeDyldImpl(RuntimeDyld::MemoryManager &MemMgr,
423*9880d681SAndroid Build Coastguard Worker                   RuntimeDyld::SymbolResolver &Resolver)
424*9880d681SAndroid Build Coastguard Worker     : MemMgr(MemMgr), Resolver(Resolver), Checker(nullptr),
425*9880d681SAndroid Build Coastguard Worker       ProcessAllSections(false), HasError(false) {
426*9880d681SAndroid Build Coastguard Worker   }
427*9880d681SAndroid Build Coastguard Worker 
428*9880d681SAndroid Build Coastguard Worker   virtual ~RuntimeDyldImpl();
429*9880d681SAndroid Build Coastguard Worker 
setProcessAllSections(bool ProcessAllSections)430*9880d681SAndroid Build Coastguard Worker   void setProcessAllSections(bool ProcessAllSections) {
431*9880d681SAndroid Build Coastguard Worker     this->ProcessAllSections = ProcessAllSections;
432*9880d681SAndroid Build Coastguard Worker   }
433*9880d681SAndroid Build Coastguard Worker 
setRuntimeDyldChecker(RuntimeDyldCheckerImpl * Checker)434*9880d681SAndroid Build Coastguard Worker   void setRuntimeDyldChecker(RuntimeDyldCheckerImpl *Checker) {
435*9880d681SAndroid Build Coastguard Worker     this->Checker = Checker;
436*9880d681SAndroid Build Coastguard Worker   }
437*9880d681SAndroid Build Coastguard Worker 
438*9880d681SAndroid Build Coastguard Worker   virtual std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
439*9880d681SAndroid Build Coastguard Worker   loadObject(const object::ObjectFile &Obj) = 0;
440*9880d681SAndroid Build Coastguard Worker 
getSymbolLocalAddress(StringRef Name)441*9880d681SAndroid Build Coastguard Worker   uint8_t* getSymbolLocalAddress(StringRef Name) const {
442*9880d681SAndroid Build Coastguard Worker     // FIXME: Just look up as a function for now. Overly simple of course.
443*9880d681SAndroid Build Coastguard Worker     // Work in progress.
444*9880d681SAndroid Build Coastguard Worker     RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
445*9880d681SAndroid Build Coastguard Worker     if (pos == GlobalSymbolTable.end())
446*9880d681SAndroid Build Coastguard Worker       return nullptr;
447*9880d681SAndroid Build Coastguard Worker     const auto &SymInfo = pos->second;
448*9880d681SAndroid Build Coastguard Worker     // Absolute symbols do not have a local address.
449*9880d681SAndroid Build Coastguard Worker     if (SymInfo.getSectionID() == AbsoluteSymbolSection)
450*9880d681SAndroid Build Coastguard Worker       return nullptr;
451*9880d681SAndroid Build Coastguard Worker     return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset();
452*9880d681SAndroid Build Coastguard Worker   }
453*9880d681SAndroid Build Coastguard Worker 
getSymbol(StringRef Name)454*9880d681SAndroid Build Coastguard Worker   RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
455*9880d681SAndroid Build Coastguard Worker     // FIXME: Just look up as a function for now. Overly simple of course.
456*9880d681SAndroid Build Coastguard Worker     // Work in progress.
457*9880d681SAndroid Build Coastguard Worker     RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name);
458*9880d681SAndroid Build Coastguard Worker     if (pos == GlobalSymbolTable.end())
459*9880d681SAndroid Build Coastguard Worker       return nullptr;
460*9880d681SAndroid Build Coastguard Worker     const auto &SymEntry = pos->second;
461*9880d681SAndroid Build Coastguard Worker     uint64_t SectionAddr = 0;
462*9880d681SAndroid Build Coastguard Worker     if (SymEntry.getSectionID() != AbsoluteSymbolSection)
463*9880d681SAndroid Build Coastguard Worker       SectionAddr = getSectionLoadAddress(SymEntry.getSectionID());
464*9880d681SAndroid Build Coastguard Worker     uint64_t TargetAddr = SectionAddr + SymEntry.getOffset();
465*9880d681SAndroid Build Coastguard Worker     return RuntimeDyld::SymbolInfo(TargetAddr, SymEntry.getFlags());
466*9880d681SAndroid Build Coastguard Worker   }
467*9880d681SAndroid Build Coastguard Worker 
468*9880d681SAndroid Build Coastguard Worker   void resolveRelocations();
469*9880d681SAndroid Build Coastguard Worker 
470*9880d681SAndroid Build Coastguard Worker   void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
471*9880d681SAndroid Build Coastguard Worker 
472*9880d681SAndroid Build Coastguard Worker   void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress);
473*9880d681SAndroid Build Coastguard Worker 
474*9880d681SAndroid Build Coastguard Worker   // Is the linker in an error state?
hasError()475*9880d681SAndroid Build Coastguard Worker   bool hasError() { return HasError; }
476*9880d681SAndroid Build Coastguard Worker 
477*9880d681SAndroid Build Coastguard Worker   // Mark the error condition as handled and continue.
clearError()478*9880d681SAndroid Build Coastguard Worker   void clearError() { HasError = false; }
479*9880d681SAndroid Build Coastguard Worker 
480*9880d681SAndroid Build Coastguard Worker   // Get the error message.
getErrorString()481*9880d681SAndroid Build Coastguard Worker   StringRef getErrorString() { return ErrorStr; }
482*9880d681SAndroid Build Coastguard Worker 
483*9880d681SAndroid Build Coastguard Worker   virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0;
484*9880d681SAndroid Build Coastguard Worker 
485*9880d681SAndroid Build Coastguard Worker   virtual void registerEHFrames();
486*9880d681SAndroid Build Coastguard Worker 
487*9880d681SAndroid Build Coastguard Worker   virtual void deregisterEHFrames();
488*9880d681SAndroid Build Coastguard Worker 
finalizeLoad(const ObjectFile & ObjImg,ObjSectionToIDMap & SectionMap)489*9880d681SAndroid Build Coastguard Worker   virtual Error finalizeLoad(const ObjectFile &ObjImg,
490*9880d681SAndroid Build Coastguard Worker                              ObjSectionToIDMap &SectionMap) {
491*9880d681SAndroid Build Coastguard Worker     return Error::success();
492*9880d681SAndroid Build Coastguard Worker   }
493*9880d681SAndroid Build Coastguard Worker };
494*9880d681SAndroid Build Coastguard Worker 
495*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
496*9880d681SAndroid Build Coastguard Worker 
497*9880d681SAndroid Build Coastguard Worker #endif
498