Mercurial > hg > CbC > CbC_llvm
comparison lld/MachO/Arch/ARM64Common.h @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | |
children | c4bab56944e8 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
1 //===- ARM64Common.h --------------------------------------------*- C++ -*-===// | |
2 // | |
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
4 // See https://llvm.org/LICENSE.txt for license information. | |
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
6 // | |
7 //===----------------------------------------------------------------------===// | |
8 | |
9 #ifndef LLD_MACHO_ARCH_ARM64COMMON_H | |
10 #define LLD_MACHO_ARCH_ARM64COMMON_H | |
11 | |
12 #include "InputFiles.h" | |
13 #include "Symbols.h" | |
14 #include "SyntheticSections.h" | |
15 #include "Target.h" | |
16 | |
17 #include "llvm/BinaryFormat/MachO.h" | |
18 | |
19 namespace lld { | |
20 namespace macho { | |
21 | |
22 struct ARM64Common : TargetInfo { | |
23 template <class LP> ARM64Common(LP lp) : TargetInfo(lp) {} | |
24 | |
25 int64_t getEmbeddedAddend(MemoryBufferRef, uint64_t offset, | |
26 const llvm::MachO::relocation_info) const override; | |
27 void relocateOne(uint8_t *loc, const Reloc &, uint64_t va, | |
28 uint64_t pc) const override; | |
29 | |
30 void relaxGotLoad(uint8_t *loc, uint8_t type) const override; | |
31 uint64_t getPageSize() const override { return 16 * 1024; } | |
32 }; | |
33 | |
34 inline uint64_t bitField(uint64_t value, int right, int width, int left) { | |
35 return ((value >> right) & ((1 << width) - 1)) << left; | |
36 } | |
37 | |
38 // 25 0 | |
39 // +-----------+---------------------------------------------------+ | |
40 // | | imm26 | | |
41 // +-----------+---------------------------------------------------+ | |
42 | |
43 inline uint64_t encodeBranch26(const Reloc &r, uint64_t base, uint64_t va) { | |
44 checkInt(r, va, 28); | |
45 // Since branch destinations are 4-byte aligned, the 2 least- | |
46 // significant bits are 0. They are right shifted off the end. | |
47 return (base | bitField(va, 2, 26, 0)); | |
48 } | |
49 | |
50 inline uint64_t encodeBranch26(SymbolDiagnostic d, uint64_t base, uint64_t va) { | |
51 checkInt(d, va, 28); | |
52 return (base | bitField(va, 2, 26, 0)); | |
53 } | |
54 | |
55 // 30 29 23 5 | |
56 // +-+---+---------+-------------------------------------+---------+ | |
57 // | |ilo| | immhi | | | |
58 // +-+---+---------+-------------------------------------+---------+ | |
59 | |
60 inline uint64_t encodePage21(const Reloc &r, uint64_t base, uint64_t va) { | |
61 checkInt(r, va, 35); | |
62 return (base | bitField(va, 12, 2, 29) | bitField(va, 14, 19, 5)); | |
63 } | |
64 | |
65 inline uint64_t encodePage21(SymbolDiagnostic d, uint64_t base, uint64_t va) { | |
66 checkInt(d, va, 35); | |
67 return (base | bitField(va, 12, 2, 29) | bitField(va, 14, 19, 5)); | |
68 } | |
69 | |
70 // 21 10 | |
71 // +-------------------+-----------------------+-------------------+ | |
72 // | | imm12 | | | |
73 // +-------------------+-----------------------+-------------------+ | |
74 | |
75 inline uint64_t encodePageOff12(uint32_t base, uint64_t va) { | |
76 int scale = 0; | |
77 if ((base & 0x3b00'0000) == 0x3900'0000) { // load/store | |
78 scale = base >> 30; | |
79 if (scale == 0 && (base & 0x0480'0000) == 0x0480'0000) // 128-bit variant | |
80 scale = 4; | |
81 } | |
82 | |
83 // TODO(gkm): extract embedded addend and warn if != 0 | |
84 // uint64_t addend = ((base & 0x003FFC00) >> 10); | |
85 return (base | bitField(va, scale, 12 - scale, 10)); | |
86 } | |
87 | |
88 inline uint64_t pageBits(uint64_t address) { | |
89 const uint64_t pageMask = ~0xfffull; | |
90 return address & pageMask; | |
91 } | |
92 | |
93 template <class LP> | |
94 inline void writeStub(uint8_t *buf8, const uint32_t stubCode[3], | |
95 const macho::Symbol &sym) { | |
96 auto *buf32 = reinterpret_cast<uint32_t *>(buf8); | |
97 constexpr size_t stubCodeSize = 3 * sizeof(uint32_t); | |
98 uint64_t pcPageBits = | |
99 pageBits(in.stubs->addr + sym.stubsIndex * stubCodeSize); | |
100 uint64_t lazyPointerVA = | |
101 in.lazyPointers->addr + sym.stubsIndex * LP::wordSize; | |
102 buf32[0] = encodePage21({&sym, "stub"}, stubCode[0], | |
103 pageBits(lazyPointerVA) - pcPageBits); | |
104 buf32[1] = encodePageOff12(stubCode[1], lazyPointerVA); | |
105 buf32[2] = stubCode[2]; | |
106 } | |
107 | |
108 template <class LP> | |
109 inline void writeStubHelperHeader(uint8_t *buf8, | |
110 const uint32_t stubHelperHeaderCode[6]) { | |
111 auto *buf32 = reinterpret_cast<uint32_t *>(buf8); | |
112 auto pcPageBits = [](int i) { | |
113 return pageBits(in.stubHelper->addr + i * sizeof(uint32_t)); | |
114 }; | |
115 uint64_t loaderVA = in.imageLoaderCache->getVA(); | |
116 SymbolDiagnostic d = {nullptr, "stub header helper"}; | |
117 buf32[0] = encodePage21(d, stubHelperHeaderCode[0], | |
118 pageBits(loaderVA) - pcPageBits(0)); | |
119 buf32[1] = encodePageOff12(stubHelperHeaderCode[1], loaderVA); | |
120 buf32[2] = stubHelperHeaderCode[2]; | |
121 uint64_t binderVA = | |
122 in.got->addr + in.stubHelper->stubBinder->gotIndex * LP::wordSize; | |
123 buf32[3] = encodePage21(d, stubHelperHeaderCode[3], | |
124 pageBits(binderVA) - pcPageBits(3)); | |
125 buf32[4] = encodePageOff12(stubHelperHeaderCode[4], binderVA); | |
126 buf32[5] = stubHelperHeaderCode[5]; | |
127 } | |
128 | |
129 inline void writeStubHelperEntry(uint8_t *buf8, | |
130 const uint32_t stubHelperEntryCode[3], | |
131 const DylibSymbol &sym, uint64_t entryVA) { | |
132 auto *buf32 = reinterpret_cast<uint32_t *>(buf8); | |
133 auto pcVA = [entryVA](int i) { return entryVA + i * sizeof(uint32_t); }; | |
134 uint64_t stubHelperHeaderVA = in.stubHelper->addr; | |
135 buf32[0] = stubHelperEntryCode[0]; | |
136 buf32[1] = encodeBranch26({&sym, "stub helper"}, stubHelperEntryCode[1], | |
137 stubHelperHeaderVA - pcVA(1)); | |
138 buf32[2] = sym.lazyBindOffset; | |
139 } | |
140 | |
141 } // namespace macho | |
142 } // namespace lld | |
143 | |
144 #endif |