RuntimeDyldELF.h revision 263508
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
20using namespace llvm;
21
22namespace llvm {
23
24namespace {
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
34class 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() {
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() {
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  virtual void updateGOTEntries(StringRef Name, uint64_t Addr);
118
119  // Relocation entries for symbols whose position-independant 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
131public:
132  RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm)
133                                          {}
134
135  virtual void resolveRelocation(const RelocationEntry &RE, uint64_t Value);
136  virtual void processRelocationRef(unsigned SectionID,
137                                    RelocationRef RelI,
138                                    ObjectImage &Obj,
139                                    ObjSectionToIDMap &ObjSectionToID,
140                                    const SymbolTableMap &Symbols,
141                                    StubMap &Stubs);
142  virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const;
143  virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
144  virtual void registerEHFrames();
145  virtual void deregisterEHFrames();
146  virtual void finalizeLoad(ObjSectionToIDMap &SectionMap);
147  virtual ~RuntimeDyldELF();
148};
149
150} // end namespace llvm
151
152#endif
153