blob: 53cf8f99ffb9af9f46a48dea0b0a9f52d0c45b5d [file] [log] [blame]
Eli Bendersky058d6472012-01-22 07:05:02 +00001//===-- 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"
Andrew Kaylor480dcb32013-10-05 01:52:09 +000018#include "llvm/ADT/DenseMap.h"
Eli Bendersky058d6472012-01-22 07:05:02 +000019
20using namespace llvm;
21
Eli Bendersky058d6472012-01-22 07:05:02 +000022namespace llvm {
Rafael Espindola3acea392014-06-12 21:46:39 +000023using std::error_code;
Tim Northover94bc73d2012-10-29 10:47:04 +000024
25namespace {
Juergen Ributzka7608dc02014-03-21 20:28:42 +000026// Helper for extensive error checking in debug builds.
27error_code Check(error_code Err) {
28 if (Err) {
29 report_fatal_error(Err.message());
Tim Northover94bc73d2012-10-29 10:47:04 +000030 }
Juergen Ributzka7608dc02014-03-21 20:28:42 +000031 return Err;
32}
Tim Northover94bc73d2012-10-29 10:47:04 +000033} // end anonymous namespace
34
Eli Bendersky058d6472012-01-22 07:05:02 +000035class RuntimeDyldELF : public RuntimeDyldImpl {
Juergen Ributzka7608dc02014-03-21 20:28:42 +000036 void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
37 uint64_t Value, uint32_t Type, int64_t Addend,
38 uint64_t SymOffset = 0);
Rafael Espindolaf1f1c622013-04-29 17:24:34 +000039
Juergen Ributzka7608dc02014-03-21 20:28:42 +000040 void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,
41 uint64_t Value, uint32_t Type, int64_t Addend,
Andrew Kaylor4612fed2013-08-19 23:27:43 +000042 uint64_t SymOffset);
Eli Bendersky058d6472012-01-22 07:05:02 +000043
Juergen Ributzka7608dc02014-03-21 20:28:42 +000044 void resolveX86Relocation(const SectionEntry &Section, uint64_t Offset,
45 uint32_t Value, uint32_t Type, int32_t Addend);
Eli Bendersky058d6472012-01-22 07:05:02 +000046
Juergen Ributzka7608dc02014-03-21 20:28:42 +000047 void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset,
48 uint64_t Value, uint32_t Type, int64_t Addend);
Tim Northoverfa1b2f82013-05-04 20:13:59 +000049
Juergen Ributzka7608dc02014-03-21 20:28:42 +000050 void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,
51 uint32_t Value, uint32_t Type, int32_t Addend);
Eli Bendersky058d6472012-01-22 07:05:02 +000052
Juergen Ributzka7608dc02014-03-21 20:28:42 +000053 void resolveMIPSRelocation(const SectionEntry &Section, uint64_t Offset,
54 uint32_t Value, uint32_t Type, int32_t Addend);
Akira Hatanaka111174b2012-08-17 21:28:04 +000055
Juergen Ributzka7608dc02014-03-21 20:28:42 +000056 void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset,
57 uint64_t Value, uint32_t Type, int64_t Addend);
Adhemerval Zanella5fc11b32012-10-25 13:13:48 +000058
Juergen Ributzka7608dc02014-03-21 20:28:42 +000059 void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
60 uint64_t Value, uint32_t Type, int64_t Addend);
Eli Bendersky058d6472012-01-22 07:05:02 +000061
Craig Topperb51ff602014-03-08 07:51:20 +000062 unsigned getMaxStubSize() override {
James Molloybd2ffa02014-04-30 10:15:41 +000063 if (Arch == Triple::aarch64 || Arch == Triple::arm64 ||
64 Arch == Triple::aarch64_be || Arch == Triple::arm64_be)
Andrew Kaylor2ba21c52013-10-15 21:32:56 +000065 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 (Arch == Triple::mipsel || Arch == Triple::mips)
69 return 16;
70 else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
71 return 44;
72 else if (Arch == Triple::x86_64)
73 return 6; // 2-byte jmp instruction + 32-bit relative address
74 else if (Arch == Triple::systemz)
75 return 16;
76 else
77 return 0;
78 }
79
Craig Topperb51ff602014-03-08 07:51:20 +000080 unsigned getStubAlignment() override {
Andrew Kaylor2ba21c52013-10-15 21:32:56 +000081 if (Arch == Triple::systemz)
82 return 8;
83 else
84 return 1;
85 }
86
Adhemerval Zanella5fc11b32012-10-25 13:13:48 +000087 uint64_t findPPC64TOC() const;
Juergen Ributzka7608dc02014-03-21 20:28:42 +000088 void findOPDEntrySection(ObjectImage &Obj, ObjSectionToIDMap &LocalSections,
Adhemerval Zanella5fc11b32012-10-25 13:13:48 +000089 RelocationValueRef &Rel);
90
Andrew Kaylor4612fed2013-08-19 23:27:43 +000091 uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset);
92 size_t getGOTEntrySize();
93
Craig Topperb51ff602014-03-08 07:51:20 +000094 void updateGOTEntries(StringRef Name, uint64_t Addr) override;
Andrew Kaylor4612fed2013-08-19 23:27:43 +000095
Alp Tokercb402912014-01-24 17:20:08 +000096 // Relocation entries for symbols whose position-independent offset is
Andrew Kaylor480dcb32013-10-05 01:52:09 +000097 // updated in a global offset table.
Andrew Kaylor480dcb32013-10-05 01:52:09 +000098 typedef SmallVector<RelocationValueRef, 2> GOTRelocations;
99 GOTRelocations GOTEntries; // List of entries requiring finalization.
100 SmallVector<std::pair<SID, GOTRelocations>, 8> GOTs; // Allocated tables.
Andrew Kaylor4612fed2013-08-19 23:27:43 +0000101
Andrew Kaylor7bb13442013-10-11 21:25:48 +0000102 // When a module is loaded we save the SectionID of the EH frame section
103 // in a table until we receive a request to register all unregistered
104 // EH frame sections with the memory manager.
105 SmallVector<SID, 2> UnregisteredEHFrameSections;
Andrew Kaylorc442a762013-10-16 00:14:21 +0000106 SmallVector<SID, 2> RegisteredEHFrameSections;
Andrew Kaylor7bb13442013-10-11 21:25:48 +0000107
Eli Bendersky058d6472012-01-22 07:05:02 +0000108public:
Juergen Ributzka7608dc02014-03-21 20:28:42 +0000109 RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {}
Preston Gurdcc31af92012-04-16 22:12:58 +0000110
Craig Topperb51ff602014-03-08 07:51:20 +0000111 void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
Juergen Ributzka046709f2014-03-21 07:26:41 +0000112 relocation_iterator
113 processRelocationRef(unsigned SectionID, relocation_iterator RelI,
114 ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID,
115 const SymbolTableMap &Symbols, StubMap &Stubs) override;
Craig Topperb51ff602014-03-08 07:51:20 +0000116 bool isCompatibleFormat(const ObjectBuffer *Buffer) const override;
117 bool isCompatibleFile(const object::ObjectFile *Buffer) const override;
Craig Topperb51ff602014-03-08 07:51:20 +0000118 void registerEHFrames() override;
119 void deregisterEHFrames() override;
Lang Hames36072da2014-05-12 21:39:59 +0000120 void finalizeLoad(ObjectImage &ObjImg,
121 ObjSectionToIDMap &SectionMap) override;
Preston Gurdcc31af92012-04-16 22:12:58 +0000122 virtual ~RuntimeDyldELF();
Lang Hames951b2352014-03-08 18:45:12 +0000123
124 static ObjectImage *createObjectImage(ObjectBuffer *InputBuffer);
David Blaikie7a1e7752014-04-29 21:52:46 +0000125 static ObjectImage *createObjectImageFromFile(std::unique_ptr<object::ObjectFile> Obj);
Eli Bendersky058d6472012-01-22 07:05:02 +0000126};
127
128} // end namespace llvm
129
Danil Malyshev70d22cc2012-03-30 16:45:19 +0000130#endif