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