ARM.cpp revision 327952
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 "InputFiles.h"
11#include "Symbols.h"
12#include "SyntheticSections.h"
13#include "Target.h"
14#include "Thunks.h"
15#include "lld/Common/ErrorHandler.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  uint32_t calcEFlags() const override;
30  RelExpr getRelExpr(RelType Type, const Symbol &S,
31                     const uint8_t *Loc) const override;
32  bool isPicRel(RelType Type) const override;
33  RelType getDynRel(RelType Type) const override;
34  int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
35  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
36  void writeIgotPlt(uint8_t *Buf, const Symbol &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(InputSection &IS, uint64_t Off) const override;
41  void addPltHeaderSymbols(InputSection &ISD) const override;
42  bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
43                  uint64_t BranchAddr, const Symbol &S) const override;
44  bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
45  void relocateOne(uint8_t *Loc, RelType 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 = 32;
62  TrapInstr = 0xd4d4d4d4;
63  // ARM uses Variant 1 TLS
64  TcbSize = 8;
65  NeedsThunks = true;
66
67  // The placing of pre-created ThunkSections is controlled by the
68  // ThunkSectionSpacing parameter. The aim is to place the
69  // ThunkSection such that all branches from the InputSections prior to the
70  // ThunkSection can reach a Thunk placed at the end of the ThunkSection.
71  // Graphically:
72  // | up to ThunkSectionSpacing .text input sections |
73  // | ThunkSection                                   |
74  // | up to ThunkSectionSpacing .text input sections |
75  // | ThunkSection                                   |
76
77  // Pre-created ThunkSections are spaced roughly 16MiB apart on ARM. This is to
78  // match the most common expected case of a Thumb 2 encoded BL, BLX or B.W
79  // ARM B, BL, BLX range +/- 32MiB
80  // Thumb B.W, BL, BLX range +/- 16MiB
81  // Thumb B<cc>.W range +/- 1MiB
82  // If a branch cannot reach a pre-created ThunkSection a new one will be
83  // created so we can handle the rare cases of a Thumb 2 conditional branch.
84  // We intentionally use a lower size for ThunkSectionSpacing than the maximum
85  // branch range so the end of the ThunkSection is more likely to be within
86  // range of the branch instruction that is furthest away. The value we shorten
87  // ThunkSectionSpacing by is set conservatively to allow us to create 16,384
88  // 12 byte Thunks at any offset in a ThunkSection without risk of a branch to
89  // one of the Thunks going out of range.
90
91  // FIXME: lld assumes that the Thumb BL and BLX encoding permits the J1 and
92  // J2 bits to be used to extend the branch range. On earlier Architectures
93  // such as ARMv4, ARMv5 and ARMv6 (except ARMv6T2) the range is +/- 4MiB. If
94  // support for the earlier encodings is added then when they are used the
95  // ThunkSectionSpacing will need lowering.
96  ThunkSectionSpacing = 0x1000000 - 0x30000;
97}
98
99uint32_t ARM::calcEFlags() const {
100  // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
101  // but we don't have any firm guarantees of conformance. Linux AArch64
102  // kernels (as of 2016) require an EABI version to be set.
103  return EF_ARM_EABI_VER5;
104}
105
106RelExpr ARM::getRelExpr(RelType Type, const Symbol &S,
107                        const uint8_t *Loc) const {
108  switch (Type) {
109  case R_ARM_THM_JUMP11:
110    return R_PC;
111  case R_ARM_CALL:
112  case R_ARM_JUMP24:
113  case R_ARM_PC24:
114  case R_ARM_PLT32:
115  case R_ARM_PREL31:
116  case R_ARM_THM_JUMP19:
117  case R_ARM_THM_JUMP24:
118  case R_ARM_THM_CALL:
119    return R_PLT_PC;
120  case R_ARM_GOTOFF32:
121    // (S + A) - GOT_ORG
122    return R_GOTREL;
123  case R_ARM_GOT_BREL:
124    // GOT(S) + A - GOT_ORG
125    return R_GOT_OFF;
126  case R_ARM_GOT_PREL:
127  case R_ARM_TLS_IE32:
128    // GOT(S) + A - P
129    return R_GOT_PC;
130  case R_ARM_SBREL32:
131    return R_ARM_SBREL;
132  case R_ARM_TARGET1:
133    return Config->Target1Rel ? R_PC : R_ABS;
134  case R_ARM_TARGET2:
135    if (Config->Target2 == Target2Policy::Rel)
136      return R_PC;
137    if (Config->Target2 == Target2Policy::Abs)
138      return R_ABS;
139    return R_GOT_PC;
140  case R_ARM_TLS_GD32:
141    return R_TLSGD_PC;
142  case R_ARM_TLS_LDM32:
143    return R_TLSLD_PC;
144  case R_ARM_BASE_PREL:
145    // B(S) + A - P
146    // FIXME: currently B(S) assumed to be .got, this may not hold for all
147    // platforms.
148    return R_GOTONLY_PC;
149  case R_ARM_MOVW_PREL_NC:
150  case R_ARM_MOVT_PREL:
151  case R_ARM_REL32:
152  case R_ARM_THM_MOVW_PREL_NC:
153  case R_ARM_THM_MOVT_PREL:
154    return R_PC;
155  case R_ARM_NONE:
156    return R_NONE;
157  case R_ARM_TLS_LE32:
158    return R_TLS;
159  default:
160    return R_ABS;
161  }
162}
163
164bool ARM::isPicRel(RelType Type) const {
165  return (Type == R_ARM_TARGET1 && !Config->Target1Rel) ||
166         (Type == R_ARM_ABS32);
167}
168
169RelType ARM::getDynRel(RelType Type) const {
170  if (Type == R_ARM_TARGET1 && !Config->Target1Rel)
171    return R_ARM_ABS32;
172  if (Type == R_ARM_ABS32)
173    return Type;
174  // Keep it going with a dummy value so that we can find more reloc errors.
175  return R_ARM_ABS32;
176}
177
178void ARM::writeGotPlt(uint8_t *Buf, const Symbol &) const {
179  write32le(Buf, InX::Plt->getVA());
180}
181
182void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) const {
183  // An ARM entry is the address of the ifunc resolver function.
184  write32le(Buf, S.getVA());
185}
186
187// Long form PLT Header that does not have any restrictions on the displacement
188// of the .plt from the .plt.got.
189static void writePltHeaderLong(uint8_t *Buf) {
190  const uint8_t PltData[] = {
191      0x04, 0xe0, 0x2d, 0xe5, //     str lr, [sp,#-4]!
192      0x04, 0xe0, 0x9f, 0xe5, //     ldr lr, L2
193      0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
194      0x08, 0xf0, 0xbe, 0xe5, //     ldr pc, [lr, #8]
195      0x00, 0x00, 0x00, 0x00, // L2: .word   &(.got.plt) - L1 - 8
196      0xd4, 0xd4, 0xd4, 0xd4, //     Pad to 32-byte boundary
197      0xd4, 0xd4, 0xd4, 0xd4, //     Pad to 32-byte boundary
198      0xd4, 0xd4, 0xd4, 0xd4};
199  memcpy(Buf, PltData, sizeof(PltData));
200  uint64_t GotPlt = InX::GotPlt->getVA();
201  uint64_t L1 = InX::Plt->getVA() + 8;
202  write32le(Buf + 16, GotPlt - L1 - 8);
203}
204
205// The default PLT header requires the .plt.got to be within 128 Mb of the
206// .plt in the positive direction.
207void ARM::writePltHeader(uint8_t *Buf) const {
208  // Use a similar sequence to that in writePlt(), the difference is the calling
209  // conventions mean we use lr instead of ip. The PLT entry is responsible for
210  // saving lr on the stack, the dynamic loader is responsible for reloading
211  // it.
212  const uint32_t PltData[] = {
213      0xe52de004, // L1: str lr, [sp,#-4]!
214      0xe28fe600, //     add lr, pc,  #0x0NN00000 &(.got.plt - L1 - 4)
215      0xe28eea00, //     add lr, lr,  #0x000NN000 &(.got.plt - L1 - 4)
216      0xe5bef000, //     ldr pc, [lr, #0x00000NNN] &(.got.plt -L1 - 4)
217  };
218
219  uint64_t Offset = InX::GotPlt->getVA() - InX::Plt->getVA() - 4;
220  if (!llvm::isUInt<27>(Offset)) {
221    // We cannot encode the Offset, use the long form.
222    writePltHeaderLong(Buf);
223    return;
224  }
225  write32le(Buf + 0, PltData[0]);
226  write32le(Buf + 4, PltData[1] | ((Offset >> 20) & 0xff));
227  write32le(Buf + 8, PltData[2] | ((Offset >> 12) & 0xff));
228  write32le(Buf + 12, PltData[3] | (Offset & 0xfff));
229  write32le(Buf + 16, TrapInstr); // Pad to 32-byte boundary
230  write32le(Buf + 20, TrapInstr);
231  write32le(Buf + 24, TrapInstr);
232  write32le(Buf + 28, TrapInstr);
233}
234
235void ARM::addPltHeaderSymbols(InputSection &IS) const {
236  addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
237  addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
238}
239
240// Long form PLT entries that do not have any restrictions on the displacement
241// of the .plt from the .plt.got.
242static void writePltLong(uint8_t *Buf, uint64_t GotPltEntryAddr,
243                         uint64_t PltEntryAddr, int32_t Index,
244                         unsigned RelOff) {
245  const uint8_t PltData[] = {
246      0x04, 0xc0, 0x9f, 0xe5, //     ldr ip, L2
247      0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
248      0x00, 0xf0, 0x9c, 0xe5, //     ldr pc, [ip]
249      0x00, 0x00, 0x00, 0x00, // L2: .word   Offset(&(.plt.got) - L1 - 8
250  };
251  memcpy(Buf, PltData, sizeof(PltData));
252  uint64_t L1 = PltEntryAddr + 4;
253  write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
254}
255
256// The default PLT entries require the .plt.got to be within 128 Mb of the
257// .plt in the positive direction.
258void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
259                   uint64_t PltEntryAddr, int32_t Index,
260                   unsigned RelOff) const {
261  // The PLT entry is similar to the example given in Appendix A of ELF for
262  // the Arm Architecture. Instead of using the Group Relocations to find the
263  // optimal rotation for the 8-bit immediate used in the add instructions we
264  // hard code the most compact rotations for simplicity. This saves a load
265  // instruction over the long plt sequences.
266  const uint32_t PltData[] = {
267      0xe28fc600, // L1: add ip, pc,  #0x0NN00000  Offset(&(.plt.got) - L1 - 8
268      0xe28cca00, //     add ip, ip,  #0x000NN000  Offset(&(.plt.got) - L1 - 8
269      0xe5bcf000, //     ldr pc, [ip, #0x00000NNN] Offset(&(.plt.got) - L1 - 8
270  };
271
272  uint64_t Offset = GotPltEntryAddr - PltEntryAddr - 8;
273  if (!llvm::isUInt<27>(Offset)) {
274    // We cannot encode the Offset, use the long form.
275    writePltLong(Buf, GotPltEntryAddr, PltEntryAddr, Index, RelOff);
276    return;
277  }
278  write32le(Buf + 0, PltData[0] | ((Offset >> 20) & 0xff));
279  write32le(Buf + 4, PltData[1] | ((Offset >> 12) & 0xff));
280  write32le(Buf + 8, PltData[2] | (Offset & 0xfff));
281  write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary
282}
283
284void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
285  addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
286  addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
287}
288
289bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
290                     uint64_t BranchAddr, const Symbol &S) const {
291  // If S is an undefined weak symbol and does not have a PLT entry then it
292  // will be resolved as a branch to the next instruction.
293  if (S.isUndefWeak() && !S.isInPlt())
294    return false;
295  // A state change from ARM to Thumb and vice versa must go through an
296  // interworking thunk if the relocation type is not R_ARM_CALL or
297  // R_ARM_THM_CALL.
298  switch (Type) {
299  case R_ARM_PC24:
300  case R_ARM_PLT32:
301  case R_ARM_JUMP24:
302    // Source is ARM, all PLT entries are ARM so no interworking required.
303    // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
304    if (Expr == R_PC && ((S.getVA() & 1) == 1))
305      return true;
306    LLVM_FALLTHROUGH;
307  case R_ARM_CALL: {
308    uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
309    return !inBranchRange(Type, BranchAddr, Dst);
310  }
311  case R_ARM_THM_JUMP19:
312  case R_ARM_THM_JUMP24:
313    // Source is Thumb, all PLT entries are ARM so interworking is required.
314    // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
315    if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0))
316      return true;
317    LLVM_FALLTHROUGH;
318  case R_ARM_THM_CALL: {
319    uint64_t Dst = (Expr == R_PLT_PC) ? S.getPltVA() : S.getVA();
320    return !inBranchRange(Type, BranchAddr, Dst);
321  }
322  }
323  return false;
324}
325
326bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const {
327  uint64_t Range;
328  uint64_t InstrSize;
329
330  switch (Type) {
331  case R_ARM_PC24:
332  case R_ARM_PLT32:
333  case R_ARM_JUMP24:
334  case R_ARM_CALL:
335    Range = 0x2000000;
336    InstrSize = 4;
337    break;
338  case R_ARM_THM_JUMP19:
339    Range = 0x100000;
340    InstrSize = 2;
341    break;
342  case R_ARM_THM_JUMP24:
343  case R_ARM_THM_CALL:
344    Range = 0x1000000;
345    InstrSize = 2;
346    break;
347  default:
348    return true;
349  }
350  // PC at Src is 2 instructions ahead, immediate of branch is signed
351  if (Src > Dst)
352    Range -= 2 * InstrSize;
353  else
354    Range += InstrSize;
355
356  if ((Dst & 0x1) == 0)
357    // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
358    // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
359    // destination will be 4 byte aligned.
360    Src &= ~0x3;
361  else
362    // Bit 0 == 1 denotes Thumb state, it is not part of the range
363    Dst &= ~0x1;
364
365  uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
366  return Distance <= Range;
367}
368
369void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
370  switch (Type) {
371  case R_ARM_ABS32:
372  case R_ARM_BASE_PREL:
373  case R_ARM_GLOB_DAT:
374  case R_ARM_GOTOFF32:
375  case R_ARM_GOT_BREL:
376  case R_ARM_GOT_PREL:
377  case R_ARM_REL32:
378  case R_ARM_RELATIVE:
379  case R_ARM_SBREL32:
380  case R_ARM_TARGET1:
381  case R_ARM_TARGET2:
382  case R_ARM_TLS_GD32:
383  case R_ARM_TLS_IE32:
384  case R_ARM_TLS_LDM32:
385  case R_ARM_TLS_LDO32:
386  case R_ARM_TLS_LE32:
387  case R_ARM_TLS_TPOFF32:
388  case R_ARM_TLS_DTPOFF32:
389    write32le(Loc, Val);
390    break;
391  case R_ARM_TLS_DTPMOD32:
392    write32le(Loc, 1);
393    break;
394  case R_ARM_PREL31:
395    checkInt<31>(Loc, Val, Type);
396    write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
397    break;
398  case R_ARM_CALL:
399    // R_ARM_CALL is used for BL and BLX instructions, depending on the
400    // value of bit 0 of Val, we must select a BL or BLX instruction
401    if (Val & 1) {
402      // If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
403      // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
404      checkInt<26>(Loc, Val, Type);
405      write32le(Loc, 0xfa000000 |                    // opcode
406                         ((Val & 2) << 23) |         // H
407                         ((Val >> 2) & 0x00ffffff)); // imm24
408      break;
409    }
410    if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
411      // BLX (always unconditional) instruction to an ARM Target, select an
412      // unconditional BL.
413      write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
414    // fall through as BL encoding is shared with B
415    LLVM_FALLTHROUGH;
416  case R_ARM_JUMP24:
417  case R_ARM_PC24:
418  case R_ARM_PLT32:
419    checkInt<26>(Loc, Val, Type);
420    write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
421    break;
422  case R_ARM_THM_JUMP11:
423    checkInt<12>(Loc, Val, Type);
424    write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
425    break;
426  case R_ARM_THM_JUMP19:
427    // Encoding T3: Val = S:J2:J1:imm6:imm11:0
428    checkInt<21>(Loc, Val, Type);
429    write16le(Loc,
430              (read16le(Loc) & 0xfbc0) |   // opcode cond
431                  ((Val >> 10) & 0x0400) | // S
432                  ((Val >> 12) & 0x003f)); // imm6
433    write16le(Loc + 2,
434              0x8000 |                    // opcode
435                  ((Val >> 8) & 0x0800) | // J2
436                  ((Val >> 5) & 0x2000) | // J1
437                  ((Val >> 1) & 0x07ff)); // imm11
438    break;
439  case R_ARM_THM_CALL:
440    // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
441    // value of bit 0 of Val, we must select a BL or BLX instruction
442    if ((Val & 1) == 0) {
443      // Ensure BLX destination is 4-byte aligned. As BLX instruction may
444      // only be two byte aligned. This must be done before overflow check
445      Val = alignTo(Val, 4);
446    }
447    // Bit 12 is 0 for BLX, 1 for BL
448    write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
449    // Fall through as rest of encoding is the same as B.W
450    LLVM_FALLTHROUGH;
451  case R_ARM_THM_JUMP24:
452    // Encoding B  T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
453    // FIXME: Use of I1 and I2 require v6T2ops
454    checkInt<25>(Loc, Val, Type);
455    write16le(Loc,
456              0xf000 |                     // opcode
457                  ((Val >> 14) & 0x0400) | // S
458                  ((Val >> 12) & 0x03ff)); // imm10
459    write16le(Loc + 2,
460              (read16le(Loc + 2) & 0xd000) |                  // opcode
461                  (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
462                  (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
463                  ((Val >> 1) & 0x07ff));                     // imm11
464    break;
465  case R_ARM_MOVW_ABS_NC:
466  case R_ARM_MOVW_PREL_NC:
467    write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
468                       (Val & 0x0fff));
469    break;
470  case R_ARM_MOVT_ABS:
471  case R_ARM_MOVT_PREL:
472    checkInt<32>(Loc, Val, Type);
473    write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
474                       (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
475    break;
476  case R_ARM_THM_MOVT_ABS:
477  case R_ARM_THM_MOVT_PREL:
478    // Encoding T1: A = imm4:i:imm3:imm8
479    checkInt<32>(Loc, Val, Type);
480    write16le(Loc,
481              0xf2c0 |                     // opcode
482                  ((Val >> 17) & 0x0400) | // i
483                  ((Val >> 28) & 0x000f)); // imm4
484    write16le(Loc + 2,
485              (read16le(Loc + 2) & 0x8f00) | // opcode
486                  ((Val >> 12) & 0x7000) |   // imm3
487                  ((Val >> 16) & 0x00ff));   // imm8
488    break;
489  case R_ARM_THM_MOVW_ABS_NC:
490  case R_ARM_THM_MOVW_PREL_NC:
491    // Encoding T3: A = imm4:i:imm3:imm8
492    write16le(Loc,
493              0xf240 |                     // opcode
494                  ((Val >> 1) & 0x0400) |  // i
495                  ((Val >> 12) & 0x000f)); // imm4
496    write16le(Loc + 2,
497              (read16le(Loc + 2) & 0x8f00) | // opcode
498                  ((Val << 4) & 0x7000) |    // imm3
499                  (Val & 0x00ff));           // imm8
500    break;
501  default:
502    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
503  }
504}
505
506int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
507  switch (Type) {
508  default:
509    return 0;
510  case R_ARM_ABS32:
511  case R_ARM_BASE_PREL:
512  case R_ARM_GOTOFF32:
513  case R_ARM_GOT_BREL:
514  case R_ARM_GOT_PREL:
515  case R_ARM_REL32:
516  case R_ARM_TARGET1:
517  case R_ARM_TARGET2:
518  case R_ARM_TLS_GD32:
519  case R_ARM_TLS_LDM32:
520  case R_ARM_TLS_LDO32:
521  case R_ARM_TLS_IE32:
522  case R_ARM_TLS_LE32:
523    return SignExtend64<32>(read32le(Buf));
524  case R_ARM_PREL31:
525    return SignExtend64<31>(read32le(Buf));
526  case R_ARM_CALL:
527  case R_ARM_JUMP24:
528  case R_ARM_PC24:
529  case R_ARM_PLT32:
530    return SignExtend64<26>(read32le(Buf) << 2);
531  case R_ARM_THM_JUMP11:
532    return SignExtend64<12>(read16le(Buf) << 1);
533  case R_ARM_THM_JUMP19: {
534    // Encoding T3: A = S:J2:J1:imm10:imm6:0
535    uint16_t Hi = read16le(Buf);
536    uint16_t Lo = read16le(Buf + 2);
537    return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
538                            ((Lo & 0x0800) << 8) |  // J2
539                            ((Lo & 0x2000) << 5) |  // J1
540                            ((Hi & 0x003f) << 12) | // imm6
541                            ((Lo & 0x07ff) << 1));  // imm11:0
542  }
543  case R_ARM_THM_CALL:
544  case R_ARM_THM_JUMP24: {
545    // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
546    // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
547    // FIXME: I1 and I2 require v6T2ops
548    uint16_t Hi = read16le(Buf);
549    uint16_t Lo = read16le(Buf + 2);
550    return SignExtend64<24>(((Hi & 0x0400) << 14) |                    // S
551                            (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
552                            (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
553                            ((Hi & 0x003ff) << 12) |                   // imm0
554                            ((Lo & 0x007ff) << 1)); // imm11:0
555  }
556  // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
557  // MOVT is in the range -32768 <= A < 32768
558  case R_ARM_MOVW_ABS_NC:
559  case R_ARM_MOVT_ABS:
560  case R_ARM_MOVW_PREL_NC:
561  case R_ARM_MOVT_PREL: {
562    uint64_t Val = read32le(Buf) & 0x000f0fff;
563    return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
564  }
565  case R_ARM_THM_MOVW_ABS_NC:
566  case R_ARM_THM_MOVT_ABS:
567  case R_ARM_THM_MOVW_PREL_NC:
568  case R_ARM_THM_MOVT_PREL: {
569    // Encoding T3: A = imm4:i:imm3:imm8
570    uint16_t Hi = read16le(Buf);
571    uint16_t Lo = read16le(Buf + 2);
572    return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
573                            ((Hi & 0x0400) << 1) |  // i
574                            ((Lo & 0x7000) >> 4) |  // imm3
575                            (Lo & 0x00ff));         // imm8
576  }
577  }
578}
579
580TargetInfo *elf::getARMTargetInfo() {
581  static ARM Target;
582  return &Target;
583}
584