[RuntimeDyld] Allow processRelocationRef to process more than one relocation entry...
[oota-llvm.git] / lib / ExecutionEngine / RuntimeDyld / RuntimeDyldELF.h
1 //===-- RuntimeDyldELF.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // ELF support for MC-JIT runtime dynamic linker.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_RUNTIME_DYLD_ELF_H
15 #define LLVM_RUNTIME_DYLD_ELF_H
16
17 #include "RuntimeDyldImpl.h"
18 #include "llvm/ADT/DenseMap.h"
19
20 using namespace llvm;
21
22 namespace llvm {
23
24 namespace {
25   // Helper for extensive error checking in debug builds.
26   error_code Check(error_code Err) {
27     if (Err) {
28       report_fatal_error(Err.message());
29     }
30     return Err;
31   }
32 } // end anonymous namespace
33
34 class RuntimeDyldELF : public RuntimeDyldImpl {
35   void resolveRelocation(const SectionEntry &Section,
36                          uint64_t Offset,
37                          uint64_t Value,
38                          uint32_t Type,
39                          int64_t Addend,
40                          uint64_t SymOffset=0);
41
42   void resolveX86_64Relocation(const SectionEntry &Section,
43                                uint64_t Offset,
44                                uint64_t Value,
45                                uint32_t Type,
46                                int64_t  Addend,
47                                uint64_t SymOffset);
48
49   void resolveX86Relocation(const SectionEntry &Section,
50                             uint64_t Offset,
51                             uint32_t Value,
52                             uint32_t Type,
53                             int32_t Addend);
54
55   void resolveAArch64Relocation(const SectionEntry &Section,
56                                 uint64_t Offset,
57                                 uint64_t Value,
58                                 uint32_t Type,
59                                 int64_t Addend);
60
61   void resolveARMRelocation(const SectionEntry &Section,
62                             uint64_t Offset,
63                             uint32_t Value,
64                             uint32_t Type,
65                             int32_t Addend);
66
67   void resolveMIPSRelocation(const SectionEntry &Section,
68                              uint64_t Offset,
69                              uint32_t Value,
70                              uint32_t Type,
71                              int32_t Addend);
72
73   void resolvePPC64Relocation(const SectionEntry &Section,
74                               uint64_t Offset,
75                               uint64_t Value,
76                               uint32_t Type,
77                               int64_t Addend);
78
79   void resolveSystemZRelocation(const SectionEntry &Section,
80                                 uint64_t Offset,
81                                 uint64_t Value,
82                                 uint32_t Type,
83                                 int64_t Addend);
84
85   unsigned getMaxStubSize() override {
86     if (Arch == Triple::aarch64)
87       return 20; // movz; movk; movk; movk; br
88     if (Arch == Triple::arm || Arch == Triple::thumb)
89       return 8; // 32-bit instruction and 32-bit address
90     else if (Arch == Triple::mipsel || Arch == Triple::mips)
91       return 16;
92     else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
93       return 44;
94     else if (Arch == Triple::x86_64)
95       return 6; // 2-byte jmp instruction + 32-bit relative address
96     else if (Arch == Triple::systemz)
97       return 16;
98     else
99       return 0;
100   }
101
102   unsigned getStubAlignment() override {
103     if (Arch == Triple::systemz)
104       return 8;
105     else
106       return 1;
107   }
108
109   uint64_t findPPC64TOC() const;
110   void findOPDEntrySection(ObjectImage &Obj,
111                            ObjSectionToIDMap &LocalSections,
112                            RelocationValueRef &Rel);
113
114   uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
115   size_t getGOTEntrySize();
116
117   void updateGOTEntries(StringRef Name, uint64_t Addr) override;
118
119   // Relocation entries for symbols whose position-independent offset is
120   // updated in a global offset table.
121   typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
122   GOTRelocations GOTEntries; // List of entries requiring finalization.
123   SmallVector<std::pair<SID, GOTRelocations>, 8> GOTs; // Allocated tables.
124
125   // When a module is loaded we save the SectionID of the EH frame section
126   // in a table until we receive a request to register all unregistered
127   // EH frame sections with the memory manager.
128   SmallVector<SID, 2> UnregisteredEHFrameSections;
129   SmallVector<SID, 2> RegisteredEHFrameSections;
130
131 public:
132   RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm)
133                                           {}
134
135   void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
136   relocation_iterator
137   processRelocationRef(unsigned SectionID, relocation_iterator RelI,
138                        ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
139                        const SymbolTableMap &Symbols, StubMap &Stubs) override;
140   bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
141   bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
142   void registerEHFrames() override;
143   void deregisterEHFrames() override;
144   void finalizeLoad(ObjSectionToIDMap &SectionMap) override;
145   virtual ~RuntimeDyldELF();
146
147   static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
148   static ObjectImage *createObjectImageFromFile(object::ObjectFile *Obj);
149 };
150
151 } // end namespace llvm
152
153 #endif