Coverage Report

Created: 2018-01-17 21:32

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