]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/Arch/AArch64.cpp
Merge ACPICA 20170929 (take 2).
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / Arch / AArch64.cpp
1 //===- AArch64.cpp --------------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "Error.h"
11 #include "Symbols.h"
12 #include "SyntheticSections.h"
13 #include "Target.h"
14 #include "Thunks.h"
15 #include "llvm/Object/ELF.h"
16 #include "llvm/Support/Endian.h"
17
18 using namespace llvm;
19 using namespace llvm::support::endian;
20 using namespace llvm::ELF;
21 using namespace lld;
22 using namespace lld::elf;
23
24 // Page(Expr) is the page address of the expression Expr, defined
25 // as (Expr & ~0xFFF). (This applies even if the machine page size
26 // supported by the platform has a different value.)
27 uint64_t elf::getAArch64Page(uint64_t Expr) {
28   return Expr & ~static_cast<uint64_t>(0xFFF);
29 }
30
31 namespace {
32 class AArch64 final : public TargetInfo {
33 public:
34   AArch64();
35   RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
36                      const uint8_t *Loc) const override;
37   bool isPicRel(uint32_t Type) const override;
38   void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
39   void writePltHeader(uint8_t *Buf) const override;
40   void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
41                 int32_t Index, unsigned RelOff) const override;
42   bool usesOnlyLowPageBits(uint32_t Type) const override;
43   void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
44   RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
45                           RelExpr Expr) const override;
46   void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
47   void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
48   void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
49 };
50 } // namespace
51
52 AArch64::AArch64() {
53   CopyRel = R_AARCH64_COPY;
54   RelativeRel = R_AARCH64_RELATIVE;
55   IRelativeRel = R_AARCH64_IRELATIVE;
56   GotRel = R_AARCH64_GLOB_DAT;
57   PltRel = R_AARCH64_JUMP_SLOT;
58   TlsDescRel = R_AARCH64_TLSDESC;
59   TlsGotRel = R_AARCH64_TLS_TPREL64;
60   GotEntrySize = 8;
61   GotPltEntrySize = 8;
62   PltEntrySize = 16;
63   PltHeaderSize = 32;
64   DefaultMaxPageSize = 65536;
65
66   // It doesn't seem to be documented anywhere, but tls on aarch64 uses variant
67   // 1 of the tls structures and the tcb size is 16.
68   TcbSize = 16;
69 }
70
71 RelExpr AArch64::getRelExpr(uint32_t Type, const SymbolBody &S,
72                             const uint8_t *Loc) const {
73   switch (Type) {
74   default:
75     return R_ABS;
76   case R_AARCH64_TLSDESC_ADR_PAGE21:
77     return R_TLSDESC_PAGE;
78   case R_AARCH64_TLSDESC_LD64_LO12:
79   case R_AARCH64_TLSDESC_ADD_LO12:
80     return R_TLSDESC;
81   case R_AARCH64_TLSDESC_CALL:
82     return R_TLSDESC_CALL;
83   case R_AARCH64_TLSLE_ADD_TPREL_HI12:
84   case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
85     return R_TLS;
86   case R_AARCH64_CALL26:
87   case R_AARCH64_CONDBR19:
88   case R_AARCH64_JUMP26:
89   case R_AARCH64_TSTBR14:
90     return R_PLT_PC;
91   case R_AARCH64_PREL16:
92   case R_AARCH64_PREL32:
93   case R_AARCH64_PREL64:
94   case R_AARCH64_ADR_PREL_LO21:
95     return R_PC;
96   case R_AARCH64_ADR_PREL_PG_HI21:
97     return R_PAGE_PC;
98   case R_AARCH64_LD64_GOT_LO12_NC:
99   case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
100     return R_GOT;
101   case R_AARCH64_ADR_GOT_PAGE:
102   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
103     return R_GOT_PAGE_PC;
104   case R_AARCH64_NONE:
105     return R_NONE;
106   }
107 }
108
109 RelExpr AArch64::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
110                                  RelExpr Expr) const {
111   if (Expr == R_RELAX_TLS_GD_TO_IE) {
112     if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)
113       return R_RELAX_TLS_GD_TO_IE_PAGE_PC;
114     return R_RELAX_TLS_GD_TO_IE_ABS;
115   }
116   return Expr;
117 }
118
119 bool AArch64::usesOnlyLowPageBits(uint32_t Type) const {
120   switch (Type) {
121   default:
122     return false;
123   case R_AARCH64_ADD_ABS_LO12_NC:
124   case R_AARCH64_LD64_GOT_LO12_NC:
125   case R_AARCH64_LDST128_ABS_LO12_NC:
126   case R_AARCH64_LDST16_ABS_LO12_NC:
127   case R_AARCH64_LDST32_ABS_LO12_NC:
128   case R_AARCH64_LDST64_ABS_LO12_NC:
129   case R_AARCH64_LDST8_ABS_LO12_NC:
130   case R_AARCH64_TLSDESC_ADD_LO12:
131   case R_AARCH64_TLSDESC_LD64_LO12:
132   case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
133     return true;
134   }
135 }
136
137 bool AArch64::isPicRel(uint32_t Type) const {
138   return Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64;
139 }
140
141 void AArch64::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
142   write64le(Buf, InX::Plt->getVA());
143 }
144
145 void AArch64::writePltHeader(uint8_t *Buf) const {
146   const uint8_t PltData[] = {
147       0xf0, 0x7b, 0xbf, 0xa9, // stp    x16, x30, [sp,#-16]!
148       0x10, 0x00, 0x00, 0x90, // adrp   x16, Page(&(.plt.got[2]))
149       0x11, 0x02, 0x40, 0xf9, // ldr    x17, [x16, Offset(&(.plt.got[2]))]
150       0x10, 0x02, 0x00, 0x91, // add    x16, x16, Offset(&(.plt.got[2]))
151       0x20, 0x02, 0x1f, 0xd6, // br     x17
152       0x1f, 0x20, 0x03, 0xd5, // nop
153       0x1f, 0x20, 0x03, 0xd5, // nop
154       0x1f, 0x20, 0x03, 0xd5  // nop
155   };
156   memcpy(Buf, PltData, sizeof(PltData));
157
158   uint64_t Got = InX::GotPlt->getVA();
159   uint64_t Plt = InX::Plt->getVA();
160   relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
161               getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
162   relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
163   relocateOne(Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, Got + 16);
164 }
165
166 void AArch64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
167                        uint64_t PltEntryAddr, int32_t Index,
168                        unsigned RelOff) const {
169   const uint8_t Inst[] = {
170       0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
171       0x11, 0x02, 0x40, 0xf9, // ldr  x17, [x16, Offset(&(.plt.got[n]))]
172       0x10, 0x02, 0x00, 0x91, // add  x16, x16, Offset(&(.plt.got[n]))
173       0x20, 0x02, 0x1f, 0xd6  // br   x17
174   };
175   memcpy(Buf, Inst, sizeof(Inst));
176
177   relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
178               getAArch64Page(GotPltEntryAddr) - getAArch64Page(PltEntryAddr));
179   relocateOne(Buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, GotPltEntryAddr);
180   relocateOne(Buf + 8, R_AARCH64_ADD_ABS_LO12_NC, GotPltEntryAddr);
181 }
182
183 static void write32AArch64Addr(uint8_t *L, uint64_t Imm) {
184   uint32_t ImmLo = (Imm & 0x3) << 29;
185   uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
186   uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
187   write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
188 }
189
190 // Return the bits [Start, End] from Val shifted Start bits.
191 // For instance, getBits(0xF0, 4, 8) returns 0xF.
192 static uint64_t getBits(uint64_t Val, int Start, int End) {
193   uint64_t Mask = ((uint64_t)1 << (End + 1 - Start)) - 1;
194   return (Val >> Start) & Mask;
195 }
196
197 static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
198
199 // Update the immediate field in a AARCH64 ldr, str, and add instruction.
200 static void or32AArch64Imm(uint8_t *L, uint64_t Imm) {
201   or32le(L, (Imm & 0xFFF) << 10);
202 }
203
204 void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
205   switch (Type) {
206   case R_AARCH64_ABS16:
207   case R_AARCH64_PREL16:
208     checkIntUInt<16>(Loc, Val, Type);
209     write16le(Loc, Val);
210     break;
211   case R_AARCH64_ABS32:
212   case R_AARCH64_PREL32:
213     checkIntUInt<32>(Loc, Val, Type);
214     write32le(Loc, Val);
215     break;
216   case R_AARCH64_ABS64:
217   case R_AARCH64_GLOB_DAT:
218   case R_AARCH64_PREL64:
219     write64le(Loc, Val);
220     break;
221   case R_AARCH64_ADD_ABS_LO12_NC:
222     or32AArch64Imm(Loc, Val);
223     break;
224   case R_AARCH64_ADR_GOT_PAGE:
225   case R_AARCH64_ADR_PREL_PG_HI21:
226   case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
227   case R_AARCH64_TLSDESC_ADR_PAGE21:
228     checkInt<33>(Loc, Val, Type);
229     write32AArch64Addr(Loc, Val >> 12);
230     break;
231   case R_AARCH64_ADR_PREL_LO21:
232     checkInt<21>(Loc, Val, Type);
233     write32AArch64Addr(Loc, Val);
234     break;
235   case R_AARCH64_CALL26:
236   case R_AARCH64_JUMP26:
237     checkInt<28>(Loc, Val, Type);
238     or32le(Loc, (Val & 0x0FFFFFFC) >> 2);
239     break;
240   case R_AARCH64_CONDBR19:
241     checkInt<21>(Loc, Val, Type);
242     or32le(Loc, (Val & 0x1FFFFC) << 3);
243     break;
244   case R_AARCH64_LD64_GOT_LO12_NC:
245   case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
246   case R_AARCH64_TLSDESC_LD64_LO12:
247     checkAlignment<8>(Loc, Val, Type);
248     or32le(Loc, (Val & 0xFF8) << 7);
249     break;
250   case R_AARCH64_LDST8_ABS_LO12_NC:
251     or32AArch64Imm(Loc, getBits(Val, 0, 11));
252     break;
253   case R_AARCH64_LDST16_ABS_LO12_NC:
254     or32AArch64Imm(Loc, getBits(Val, 1, 11));
255     break;
256   case R_AARCH64_LDST32_ABS_LO12_NC:
257     or32AArch64Imm(Loc, getBits(Val, 2, 11));
258     break;
259   case R_AARCH64_LDST64_ABS_LO12_NC:
260     or32AArch64Imm(Loc, getBits(Val, 3, 11));
261     break;
262   case R_AARCH64_LDST128_ABS_LO12_NC:
263     or32AArch64Imm(Loc, getBits(Val, 4, 11));
264     break;
265   case R_AARCH64_MOVW_UABS_G0_NC:
266     or32le(Loc, (Val & 0xFFFF) << 5);
267     break;
268   case R_AARCH64_MOVW_UABS_G1_NC:
269     or32le(Loc, (Val & 0xFFFF0000) >> 11);
270     break;
271   case R_AARCH64_MOVW_UABS_G2_NC:
272     or32le(Loc, (Val & 0xFFFF00000000) >> 27);
273     break;
274   case R_AARCH64_MOVW_UABS_G3:
275     or32le(Loc, (Val & 0xFFFF000000000000) >> 43);
276     break;
277   case R_AARCH64_TSTBR14:
278     checkInt<16>(Loc, Val, Type);
279     or32le(Loc, (Val & 0xFFFC) << 3);
280     break;
281   case R_AARCH64_TLSLE_ADD_TPREL_HI12:
282     checkInt<24>(Loc, Val, Type);
283     or32AArch64Imm(Loc, Val >> 12);
284     break;
285   case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
286   case R_AARCH64_TLSDESC_ADD_LO12:
287     or32AArch64Imm(Loc, Val);
288     break;
289   default:
290     error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
291   }
292 }
293
294 void AArch64::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
295   // TLSDESC Global-Dynamic relocation are in the form:
296   //   adrp    x0, :tlsdesc:v             [R_AARCH64_TLSDESC_ADR_PAGE21]
297   //   ldr     x1, [x0, #:tlsdesc_lo12:v  [R_AARCH64_TLSDESC_LD64_LO12]
298   //   add     x0, x0, :tlsdesc_los:v     [R_AARCH64_TLSDESC_ADD_LO12]
299   //   .tlsdesccall                       [R_AARCH64_TLSDESC_CALL]
300   //   blr     x1
301   // And it can optimized to:
302   //   movz    x0, #0x0, lsl #16
303   //   movk    x0, #0x10
304   //   nop
305   //   nop
306   checkUInt<32>(Loc, Val, Type);
307
308   switch (Type) {
309   case R_AARCH64_TLSDESC_ADD_LO12:
310   case R_AARCH64_TLSDESC_CALL:
311     write32le(Loc, 0xd503201f); // nop
312     return;
313   case R_AARCH64_TLSDESC_ADR_PAGE21:
314     write32le(Loc, 0xd2a00000 | (((Val >> 16) & 0xffff) << 5)); // movz
315     return;
316   case R_AARCH64_TLSDESC_LD64_LO12:
317     write32le(Loc, 0xf2800000 | ((Val & 0xffff) << 5)); // movk
318     return;
319   default:
320     llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
321   }
322 }
323
324 void AArch64::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
325   // TLSDESC Global-Dynamic relocation are in the form:
326   //   adrp    x0, :tlsdesc:v             [R_AARCH64_TLSDESC_ADR_PAGE21]
327   //   ldr     x1, [x0, #:tlsdesc_lo12:v  [R_AARCH64_TLSDESC_LD64_LO12]
328   //   add     x0, x0, :tlsdesc_los:v     [R_AARCH64_TLSDESC_ADD_LO12]
329   //   .tlsdesccall                       [R_AARCH64_TLSDESC_CALL]
330   //   blr     x1
331   // And it can optimized to:
332   //   adrp    x0, :gottprel:v
333   //   ldr     x0, [x0, :gottprel_lo12:v]
334   //   nop
335   //   nop
336
337   switch (Type) {
338   case R_AARCH64_TLSDESC_ADD_LO12:
339   case R_AARCH64_TLSDESC_CALL:
340     write32le(Loc, 0xd503201f); // nop
341     break;
342   case R_AARCH64_TLSDESC_ADR_PAGE21:
343     write32le(Loc, 0x90000000); // adrp
344     relocateOne(Loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, Val);
345     break;
346   case R_AARCH64_TLSDESC_LD64_LO12:
347     write32le(Loc, 0xf9400000); // ldr
348     relocateOne(Loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, Val);
349     break;
350   default:
351     llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
352   }
353 }
354
355 void AArch64::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
356   checkUInt<32>(Loc, Val, Type);
357
358   if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
359     // Generate MOVZ.
360     uint32_t RegNo = read32le(Loc) & 0x1f;
361     write32le(Loc, (0xd2a00000 | RegNo) | (((Val >> 16) & 0xffff) << 5));
362     return;
363   }
364   if (Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
365     // Generate MOVK.
366     uint32_t RegNo = read32le(Loc) & 0x1f;
367     write32le(Loc, (0xf2800000 | RegNo) | ((Val & 0xffff) << 5));
368     return;
369   }
370   llvm_unreachable("invalid relocation for TLS IE to LE relaxation");
371 }
372
373 TargetInfo *elf::getAArch64TargetInfo() {
374   static AArch64 Target;
375   return &Target;
376 }