RuntimeDyldELF.h revision 280031
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_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
15#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H
16
17#include "RuntimeDyldImpl.h"
18#include "llvm/ADT/DenseMap.h"
19
20using namespace llvm;
21
22namespace llvm {
23namespace {
24// Helper for extensive error checking in debug builds.
25std::error_code Check(std::error_code Err) {
26  if (Err) {
27    report_fatal_error(Err.message());
28  }
29  return Err;
30}
31
32} // end anonymous namespace
33
34class RuntimeDyldELF : public RuntimeDyldImpl {
35
36  void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
37                         uint64_t Value, uint32_t Type, int64_t Addend,
38                         uint64_t SymOffset = 0);
39
40  void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,
41                               uint64_t Value, uint32_t Type, int64_t Addend,
42                               uint64_t SymOffset);
43
44  void resolveX86Relocation(const SectionEntry &Section, uint64_t Offset,
45                            uint32_t Value, uint32_t Type, int32_t Addend);
46
47  void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset,
48                                uint64_t Value, uint32_t Type, int64_t Addend);
49
50  void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,
51                            uint32_t Value, uint32_t Type, int32_t Addend);
52
53  void resolveMIPSRelocation(const SectionEntry &Section, uint64_t Offset,
54                             uint32_t Value, uint32_t Type, int32_t Addend);
55
56  void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset,
57                              uint64_t Value, uint32_t Type, int64_t Addend);
58
59  void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
60                                uint64_t Value, uint32_t Type, int64_t Addend);
61
62  unsigned getMaxStubSize() override {
63    if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)
64      return 20; // movz; movk; movk; movk; br
65    if (Arch == Triple::arm || Arch == Triple::thumb)
66      return 8; // 32-bit instruction and 32-bit address
67    else if (Arch == Triple::mipsel || Arch == Triple::mips)
68      return 16;
69    else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
70      return 44;
71    else if (Arch == Triple::x86_64)
72      return 6; // 2-byte jmp instruction + 32-bit relative address
73    else if (Arch == Triple::systemz)
74      return 16;
75    else
76      return 0;
77  }
78
79  unsigned getStubAlignment() override {
80    if (Arch == Triple::systemz)
81      return 8;
82    else
83      return 1;
84  }
85
86  void findPPC64TOCSection(const ObjectFile &Obj,
87                           ObjSectionToIDMap &LocalSections,
88                           RelocationValueRef &Rel);
89  void findOPDEntrySection(const ObjectFile &Obj,
90                           ObjSectionToIDMap &LocalSections,
91                           RelocationValueRef &Rel);
92
93  uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
94  size_t getGOTEntrySize();
95
96  void updateGOTEntries(StringRef Name, uint64_t Addr) override;
97
98  // Relocation entries for symbols whose position-independent offset is
99  // updated in a global offset table.
100  typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
101  GOTRelocations GOTEntries; // List of entries requiring finalization.
102  SmallVector<std::pair<SID, GOTRelocations>, 8> GOTs; // Allocated tables.
103
104  // When a module is loaded we save the SectionID of the EH frame section
105  // in a table until we receive a request to register all unregistered
106  // EH frame sections with the memory manager.
107  SmallVector<SID, 2> UnregisteredEHFrameSections;
108  SmallVector<SID, 2> RegisteredEHFrameSections;
109
110public:
111  RuntimeDyldELF(RTDyldMemoryManager *mm);
112  virtual ~RuntimeDyldELF();
113
114  std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
115  loadObject(const object::ObjectFile &O) override;
116
117  void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
118  relocation_iterator
119  processRelocationRef(unsigned SectionID, relocation_iterator RelI,
120                       const ObjectFile &Obj,
121                       ObjSectionToIDMap &ObjSectionToID,
122                       StubMap &Stubs) override;
123  bool isCompatibleFile(const object::ObjectFile &Obj) const override;
124  void registerEHFrames() override;
125  void deregisterEHFrames() override;
126  void finalizeLoad(const ObjectFile &Obj,
127                    ObjSectionToIDMap &SectionMap) override;
128};
129
130} // end namespace llvm
131
132#endif
133