ARM.cpp revision 321238
1//===- ARM.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 "InputFiles.h"
12#include "Symbols.h"
13#include "SyntheticSections.h"
14#include "Target.h"
15#include "Thunks.h"
16#include "llvm/Object/ELF.h"
17#include "llvm/Support/Endian.h"
18
19using namespace llvm;
20using namespace llvm::support::endian;
21using namespace llvm::ELF;
22using namespace lld;
23using namespace lld::elf;
24
25namespace {
26class ARM final : public TargetInfo {
27public:
28  ARM();
29  RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
30                     const uint8_t *Loc) const override;
31  bool isPicRel(uint32_t Type) const override;
32  uint32_t getDynRel(uint32_t Type) const override;
33  int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override;
34  void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
35  void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override;
36  void writePltHeader(uint8_t *Buf) const override;
37  void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
38                int32_t Index, unsigned RelOff) const override;
39  void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override;
40  void addPltHeaderSymbols(InputSectionBase *ISD) const override;
41  bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
42                  const SymbolBody &S) const override;
43  bool inBranchRange(uint32_t RelocType, uint64_t Src,
44                     uint64_t Dst) const override;
45  void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
46};
47} // namespace
48
49ARM::ARM() {
50  CopyRel = R_ARM_COPY;
51  RelativeRel = R_ARM_RELATIVE;
52  IRelativeRel = R_ARM_IRELATIVE;
53  GotRel = R_ARM_GLOB_DAT;
54  PltRel = R_ARM_JUMP_SLOT;
55  TlsGotRel = R_ARM_TLS_TPOFF32;
56  TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
57  TlsOffsetRel = R_ARM_TLS_DTPOFF32;
58  GotEntrySize = 4;
59  GotPltEntrySize = 4;
60  PltEntrySize = 16;
61  PltHeaderSize = 20;
62  TrapInstr = 0xd4d4d4d4;
63  // ARM uses Variant 1 TLS
64  TcbSize = 8;
65  NeedsThunks = true;
66}
67
68RelExpr ARM::getRelExpr(uint32_t Type, const SymbolBody &S,
69                        const uint8_t *Loc) const {
70  switch (Type) {
71  default:
72    return R_ABS;
73  case R_ARM_THM_JUMP11:
74    return R_PC;
75  case R_ARM_CALL:
76  case R_ARM_JUMP24:
77  case R_ARM_PC24:
78  case R_ARM_PLT32:
79  case R_ARM_PREL31:
80  case R_ARM_THM_JUMP19:
81  case R_ARM_THM_JUMP24:
82  case R_ARM_THM_CALL:
83    return R_PLT_PC;
84  case R_ARM_GOTOFF32:
85    // (S + A) - GOT_ORG
86    return R_GOTREL;
87  case R_ARM_GOT_BREL:
88    // GOT(S) + A - GOT_ORG
89    return R_GOT_OFF;
90  case R_ARM_GOT_PREL:
91  case R_ARM_TLS_IE32:
92    // GOT(S) + A - P
93    return R_GOT_PC;
94  case R_ARM_SBREL32:
95    return R_ARM_SBREL;
96  case R_ARM_TARGET1:
97    return Config->Target1Rel ? R_PC : R_ABS;
98  case R_ARM_TARGET2:
99    if (Config->Target2 == Target2Policy::Rel)
100      return R_PC;
101    if (Config->Target2 == Target2Policy::Abs)
102      return R_ABS;
103    return R_GOT_PC;
104  case R_ARM_TLS_GD32:
105    return R_TLSGD_PC;
106  case R_ARM_TLS_LDM32:
107    return R_TLSLD_PC;
108  case R_ARM_BASE_PREL:
109    // B(S) + A - P
110    // FIXME: currently B(S) assumed to be .got, this may not hold for all
111    // platforms.
112    return R_GOTONLY_PC;
113  case R_ARM_MOVW_PREL_NC:
114  case R_ARM_MOVT_PREL:
115  case R_ARM_REL32:
116  case R_ARM_THM_MOVW_PREL_NC:
117  case R_ARM_THM_MOVT_PREL:
118    return R_PC;
119  case R_ARM_NONE:
120    return R_NONE;
121  case R_ARM_TLS_LE32:
122    return R_TLS;
123  }
124}
125
126bool ARM::isPicRel(uint32_t Type) const {
127  return (Type == R_ARM_TARGET1 && !Config->Target1Rel) ||
128         (Type == R_ARM_ABS32);
129}
130
131uint32_t ARM::getDynRel(uint32_t Type) const {
132  if (Type == R_ARM_TARGET1 && !Config->Target1Rel)
133    return R_ARM_ABS32;
134  if (Type == R_ARM_ABS32)
135    return Type;
136  // Keep it going with a dummy value so that we can find more reloc errors.
137  return R_ARM_ABS32;
138}
139
140void ARM::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
141  write32le(Buf, InX::Plt->getVA());
142}
143
144void ARM::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
145  // An ARM entry is the address of the ifunc resolver function.
146  write32le(Buf, S.getVA());
147}
148
149void ARM::writePltHeader(uint8_t *Buf) const {
150  const uint8_t PltData[] = {
151      0x04, 0xe0, 0x2d, 0xe5, //     str lr, [sp,#-4]!
152      0x04, 0xe0, 0x9f, 0xe5, //     ldr lr, L2
153      0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
154      0x08, 0xf0, 0xbe, 0xe5, //     ldr pc, [lr, #8]
155      0x00, 0x00, 0x00, 0x00, // L2: .word   &(.got.plt) - L1 - 8
156  };
157  memcpy(Buf, PltData, sizeof(PltData));
158  uint64_t GotPlt = InX::GotPlt->getVA();
159  uint64_t L1 = InX::Plt->getVA() + 8;
160  write32le(Buf + 16, GotPlt - L1 - 8);
161}
162
163void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const {
164  auto *IS = cast<InputSection>(ISD);
165  addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
166  addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
167}
168
169void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
170                   uint64_t PltEntryAddr, int32_t Index,
171                   unsigned RelOff) const {
172  // FIXME: Using simple code sequence with simple relocations.
173  // There is a more optimal sequence but it requires support for the group
174  // relocations. See ELF for the ARM Architecture Appendix A.3
175  const uint8_t PltData[] = {
176      0x04, 0xc0, 0x9f, 0xe5, //     ldr ip, L2
177      0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
178      0x00, 0xf0, 0x9c, 0xe5, //     ldr pc, [ip]
179      0x00, 0x00, 0x00, 0x00, // L2: .word   Offset(&(.plt.got) - L1 - 8
180  };
181  memcpy(Buf, PltData, sizeof(PltData));
182  uint64_t L1 = PltEntryAddr + 4;
183  write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
184}
185
186void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
187  auto *IS = cast<InputSection>(ISD);
188  addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
189  addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
190}
191
192bool ARM::needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
193                     const SymbolBody &S) const {
194  // If S is an undefined weak symbol in an executable we don't need a Thunk.
195  // In a DSO calls to undefined symbols, including weak ones get PLT entries
196  // which may need a thunk.
197  if (S.isUndefined() && !S.isLocal() && S.symbol()->isWeak() &&
198      !Config->Shared)
199    return false;
200  // A state change from ARM to Thumb and vice versa must go through an
201  // interworking thunk if the relocation type is not R_ARM_CALL or
202  // R_ARM_THM_CALL.
203  switch (RelocType) {
204  case R_ARM_PC24:
205  case R_ARM_PLT32:
206  case R_ARM_JUMP24:
207    // Source is ARM, all PLT entries are ARM so no interworking required.
208    // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
209    if (Expr == R_PC && ((S.getVA() & 1) == 1))
210      return true;
211    break;
212  case R_ARM_THM_JUMP19:
213  case R_ARM_THM_JUMP24:
214    // Source is Thumb, all PLT entries are ARM so interworking is required.
215    // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
216    if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0))
217      return true;
218    break;
219  }
220  return false;
221}
222
223bool ARM::inBranchRange(uint32_t RelocType, uint64_t Src, uint64_t Dst) const {
224  uint64_t Range;
225  uint64_t InstrSize;
226
227  switch (RelocType) {
228  case R_ARM_PC24:
229  case R_ARM_PLT32:
230  case R_ARM_JUMP24:
231  case R_ARM_CALL:
232    Range = 0x2000000;
233    InstrSize = 4;
234    break;
235  case R_ARM_THM_JUMP19:
236    Range = 0x100000;
237    InstrSize = 2;
238    break;
239  case R_ARM_THM_JUMP24:
240  case R_ARM_THM_CALL:
241    Range = 0x1000000;
242    InstrSize = 2;
243    break;
244  default:
245    return true;
246  }
247  // PC at Src is 2 instructions ahead, immediate of branch is signed
248  if (Src > Dst)
249    Range -= 2 * InstrSize;
250  else
251    Range += InstrSize;
252
253  if ((Dst & 0x1) == 0)
254    // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
255    // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
256    // destination will be 4 byte aligned.
257    Src &= ~0x3;
258  else
259    // Bit 0 == 1 denotes Thumb state, it is not part of the range
260    Dst &= ~0x1;
261
262  uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
263  return Distance <= Range;
264}
265
266void ARM::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
267  switch (Type) {
268  case R_ARM_ABS32:
269  case R_ARM_BASE_PREL:
270  case R_ARM_GLOB_DAT:
271  case R_ARM_GOTOFF32:
272  case R_ARM_GOT_BREL:
273  case R_ARM_GOT_PREL:
274  case R_ARM_REL32:
275  case R_ARM_RELATIVE:
276  case R_ARM_SBREL32:
277  case R_ARM_TARGET1:
278  case R_ARM_TARGET2:
279  case R_ARM_TLS_GD32:
280  case R_ARM_TLS_IE32:
281  case R_ARM_TLS_LDM32:
282  case R_ARM_TLS_LDO32:
283  case R_ARM_TLS_LE32:
284  case R_ARM_TLS_TPOFF32:
285  case R_ARM_TLS_DTPOFF32:
286    write32le(Loc, Val);
287    break;
288  case R_ARM_TLS_DTPMOD32:
289    write32le(Loc, 1);
290    break;
291  case R_ARM_PREL31:
292    checkInt<31>(Loc, Val, Type);
293    write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
294    break;
295  case R_ARM_CALL:
296    // R_ARM_CALL is used for BL and BLX instructions, depending on the
297    // value of bit 0 of Val, we must select a BL or BLX instruction
298    if (Val & 1) {
299      // If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
300      // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
301      checkInt<26>(Loc, Val, Type);
302      write32le(Loc, 0xfa000000 |                    // opcode
303                         ((Val & 2) << 23) |         // H
304                         ((Val >> 2) & 0x00ffffff)); // imm24
305      break;
306    }
307    if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
308      // BLX (always unconditional) instruction to an ARM Target, select an
309      // unconditional BL.
310      write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
311    // fall through as BL encoding is shared with B
312    LLVM_FALLTHROUGH;
313  case R_ARM_JUMP24:
314  case R_ARM_PC24:
315  case R_ARM_PLT32:
316    checkInt<26>(Loc, Val, Type);
317    write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
318    break;
319  case R_ARM_THM_JUMP11:
320    checkInt<12>(Loc, Val, Type);
321    write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
322    break;
323  case R_ARM_THM_JUMP19:
324    // Encoding T3: Val = S:J2:J1:imm6:imm11:0
325    checkInt<21>(Loc, Val, Type);
326    write16le(Loc,
327              (read16le(Loc) & 0xfbc0) |   // opcode cond
328                  ((Val >> 10) & 0x0400) | // S
329                  ((Val >> 12) & 0x003f)); // imm6
330    write16le(Loc + 2,
331              0x8000 |                    // opcode
332                  ((Val >> 8) & 0x0800) | // J2
333                  ((Val >> 5) & 0x2000) | // J1
334                  ((Val >> 1) & 0x07ff)); // imm11
335    break;
336  case R_ARM_THM_CALL:
337    // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
338    // value of bit 0 of Val, we must select a BL or BLX instruction
339    if ((Val & 1) == 0) {
340      // Ensure BLX destination is 4-byte aligned. As BLX instruction may
341      // only be two byte aligned. This must be done before overflow check
342      Val = alignTo(Val, 4);
343    }
344    // Bit 12 is 0 for BLX, 1 for BL
345    write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
346    // Fall through as rest of encoding is the same as B.W
347    LLVM_FALLTHROUGH;
348  case R_ARM_THM_JUMP24:
349    // Encoding B  T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
350    // FIXME: Use of I1 and I2 require v6T2ops
351    checkInt<25>(Loc, Val, Type);
352    write16le(Loc,
353              0xf000 |                     // opcode
354                  ((Val >> 14) & 0x0400) | // S
355                  ((Val >> 12) & 0x03ff)); // imm10
356    write16le(Loc + 2,
357              (read16le(Loc + 2) & 0xd000) |                  // opcode
358                  (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
359                  (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
360                  ((Val >> 1) & 0x07ff));                     // imm11
361    break;
362  case R_ARM_MOVW_ABS_NC:
363  case R_ARM_MOVW_PREL_NC:
364    write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
365                       (Val & 0x0fff));
366    break;
367  case R_ARM_MOVT_ABS:
368  case R_ARM_MOVT_PREL:
369    checkInt<32>(Loc, Val, Type);
370    write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
371                       (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
372    break;
373  case R_ARM_THM_MOVT_ABS:
374  case R_ARM_THM_MOVT_PREL:
375    // Encoding T1: A = imm4:i:imm3:imm8
376    checkInt<32>(Loc, Val, Type);
377    write16le(Loc,
378              0xf2c0 |                     // opcode
379                  ((Val >> 17) & 0x0400) | // i
380                  ((Val >> 28) & 0x000f)); // imm4
381    write16le(Loc + 2,
382              (read16le(Loc + 2) & 0x8f00) | // opcode
383                  ((Val >> 12) & 0x7000) |   // imm3
384                  ((Val >> 16) & 0x00ff));   // imm8
385    break;
386  case R_ARM_THM_MOVW_ABS_NC:
387  case R_ARM_THM_MOVW_PREL_NC:
388    // Encoding T3: A = imm4:i:imm3:imm8
389    write16le(Loc,
390              0xf240 |                     // opcode
391                  ((Val >> 1) & 0x0400) |  // i
392                  ((Val >> 12) & 0x000f)); // imm4
393    write16le(Loc + 2,
394              (read16le(Loc + 2) & 0x8f00) | // opcode
395                  ((Val << 4) & 0x7000) |    // imm3
396                  (Val & 0x00ff));           // imm8
397    break;
398  default:
399    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
400  }
401}
402
403int64_t ARM::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const {
404  switch (Type) {
405  default:
406    return 0;
407  case R_ARM_ABS32:
408  case R_ARM_BASE_PREL:
409  case R_ARM_GOTOFF32:
410  case R_ARM_GOT_BREL:
411  case R_ARM_GOT_PREL:
412  case R_ARM_REL32:
413  case R_ARM_TARGET1:
414  case R_ARM_TARGET2:
415  case R_ARM_TLS_GD32:
416  case R_ARM_TLS_LDM32:
417  case R_ARM_TLS_LDO32:
418  case R_ARM_TLS_IE32:
419  case R_ARM_TLS_LE32:
420    return SignExtend64<32>(read32le(Buf));
421  case R_ARM_PREL31:
422    return SignExtend64<31>(read32le(Buf));
423  case R_ARM_CALL:
424  case R_ARM_JUMP24:
425  case R_ARM_PC24:
426  case R_ARM_PLT32:
427    return SignExtend64<26>(read32le(Buf) << 2);
428  case R_ARM_THM_JUMP11:
429    return SignExtend64<12>(read16le(Buf) << 1);
430  case R_ARM_THM_JUMP19: {
431    // Encoding T3: A = S:J2:J1:imm10:imm6:0
432    uint16_t Hi = read16le(Buf);
433    uint16_t Lo = read16le(Buf + 2);
434    return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
435                            ((Lo & 0x0800) << 8) |  // J2
436                            ((Lo & 0x2000) << 5) |  // J1
437                            ((Hi & 0x003f) << 12) | // imm6
438                            ((Lo & 0x07ff) << 1));  // imm11:0
439  }
440  case R_ARM_THM_CALL:
441  case R_ARM_THM_JUMP24: {
442    // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
443    // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
444    // FIXME: I1 and I2 require v6T2ops
445    uint16_t Hi = read16le(Buf);
446    uint16_t Lo = read16le(Buf + 2);
447    return SignExtend64<24>(((Hi & 0x0400) << 14) |                    // S
448                            (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
449                            (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
450                            ((Hi & 0x003ff) << 12) |                   // imm0
451                            ((Lo & 0x007ff) << 1)); // imm11:0
452  }
453  // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
454  // MOVT is in the range -32768 <= A < 32768
455  case R_ARM_MOVW_ABS_NC:
456  case R_ARM_MOVT_ABS:
457  case R_ARM_MOVW_PREL_NC:
458  case R_ARM_MOVT_PREL: {
459    uint64_t Val = read32le(Buf) & 0x000f0fff;
460    return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
461  }
462  case R_ARM_THM_MOVW_ABS_NC:
463  case R_ARM_THM_MOVT_ABS:
464  case R_ARM_THM_MOVW_PREL_NC:
465  case R_ARM_THM_MOVT_PREL: {
466    // Encoding T3: A = imm4:i:imm3:imm8
467    uint16_t Hi = read16le(Buf);
468    uint16_t Lo = read16le(Buf + 2);
469    return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
470                            ((Hi & 0x0400) << 1) |  // i
471                            ((Lo & 0x7000) >> 4) |  // imm3
472                            (Lo & 0x00ff));         // imm8
473  }
474  }
475}
476
477TargetInfo *elf::getARMTargetInfo() {
478  static ARM Target;
479  return &Target;
480}
481