Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMMachObjectWriter.cpp - ARM Mach Object Writer ------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "MCTargetDesc/ARMBaseInfo.h"
10
#include "MCTargetDesc/ARMFixupKinds.h"
11
#include "MCTargetDesc/ARMMCTargetDesc.h"
12
#include "llvm/ADT/Twine.h"
13
#include "llvm/BinaryFormat/MachO.h"
14
#include "llvm/MC/MCAsmLayout.h"
15
#include "llvm/MC/MCAssembler.h"
16
#include "llvm/MC/MCContext.h"
17
#include "llvm/MC/MCExpr.h"
18
#include "llvm/MC/MCFixup.h"
19
#include "llvm/MC/MCFixupKindInfo.h"
20
#include "llvm/MC/MCMachObjectWriter.h"
21
#include "llvm/MC/MCSection.h"
22
#include "llvm/MC/MCValue.h"
23
#include "llvm/Support/ErrorHandling.h"
24
#include "llvm/Support/ScopedPrinter.h"
25
26
using namespace llvm;
27
28
namespace {
29
class ARMMachObjectWriter : public MCMachObjectTargetWriter {
30
  void RecordARMScatteredRelocation(MachObjectWriter *Writer,
31
                                    const MCAssembler &Asm,
32
                                    const MCAsmLayout &Layout,
33
                                    const MCFragment *Fragment,
34
                                    const MCFixup &Fixup,
35
                                    MCValue Target,
36
                                    unsigned Type,
37
                                    unsigned Log2Size,
38
                                    uint64_t &FixedValue);
39
  void RecordARMScatteredHalfRelocation(MachObjectWriter *Writer,
40
                                        const MCAssembler &Asm,
41
                                        const MCAsmLayout &Layout,
42
                                        const MCFragment *Fragment,
43
                                        const MCFixup &Fixup, MCValue Target,
44
                                        uint64_t &FixedValue);
45
46
  bool requiresExternRelocation(MachObjectWriter *Writer,
47
                                const MCAssembler &Asm,
48
                                const MCFragment &Fragment, unsigned RelocType,
49
                                const MCSymbol &S, uint64_t FixedValue);
50
51
public:
52
  ARMMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
53
3.72k
      : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype) {}
54
55
  void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
56
                        const MCAsmLayout &Layout, const MCFragment *Fragment,
57
                        const MCFixup &Fixup, MCValue Target,
58
                        uint64_t &FixedValue) override;
59
};
60
}
61
62
static bool getARMFixupKindMachOInfo(unsigned Kind, unsigned &RelocType,
63
179k
                              unsigned &Log2Size) {
64
179k
  RelocType = unsigned(MachO::ARM_RELOC_VANILLA);
65
179k
  Log2Size = ~0U;
66
179k
67
179k
  switch (Kind) {
68
179k
  default:
69
6
    return false;
70
179k
71
179k
  case FK_Data_1:
72
0
    Log2Size = llvm::Log2_32(1);
73
0
    return true;
74
179k
  case FK_Data_2:
75
0
    Log2Size = llvm::Log2_32(2);
76
0
    return true;
77
179k
  case FK_Data_4:
78
77.5k
    Log2Size = llvm::Log2_32(4);
79
77.5k
    return true;
80
179k
  case FK_Data_8:
81
0
    Log2Size = llvm::Log2_32(8);
82
0
    return true;
83
179k
84
179k
    // These fixups are expected to always be resolvable at assembly time and
85
179k
    // have no relocations supported.
86
179k
  case ARM::fixup_arm_ldst_pcrel_12:
87
2
  case ARM::fixup_arm_pcrel_10:
88
2
  case ARM::fixup_arm_adr_pcrel_12:
89
2
  case ARM::fixup_arm_thumb_br:
90
2
    return false;
91
2
92
2
    // Handle 24-bit branch kinds.
93
568
  case ARM::fixup_arm_condbranch:
94
568
  case ARM::fixup_arm_uncondbranch:
95
568
  case ARM::fixup_arm_uncondbl:
96
568
  case ARM::fixup_arm_condbl:
97
568
  case ARM::fixup_arm_blx:
98
568
    RelocType = unsigned(MachO::ARM_RELOC_BR24);
99
568
    // Report as 'long', even though that is not quite accurate.
100
568
    Log2Size = llvm::Log2_32(4);
101
568
    return true;
102
568
103
48.1k
  case ARM::fixup_t2_uncondbranch:
104
48.1k
  case ARM::fixup_arm_thumb_bl:
105
48.1k
  case ARM::fixup_arm_thumb_blx:
106
48.1k
    RelocType = unsigned(MachO::ARM_THUMB_RELOC_BR22);
107
48.1k
    Log2Size = llvm::Log2_32(4);
108
48.1k
    return true;
109
48.1k
110
48.1k
  // For movw/movt r_type relocations they always have a pair following them and
111
48.1k
  // the r_length bits are used differently.  The encoding of the r_length is as
112
48.1k
  // follows:
113
48.1k
  //   low bit of r_length:
114
48.1k
  //      0 - :lower16: for movw instructions
115
48.1k
  //      1 - :upper16: for movt instructions
116
48.1k
  //   high bit of r_length:
117
48.1k
  //      0 - arm instructions
118
48.1k
  //      1 - thumb instructions
119
48.1k
  case ARM::fixup_arm_movt_hi16:
120
8
    RelocType = unsigned(MachO::ARM_RELOC_HALF);
121
8
    Log2Size = 1;
122
8
    return true;
123
48.1k
  case ARM::fixup_t2_movt_hi16:
124
26.5k
    RelocType = unsigned(MachO::ARM_RELOC_HALF);
125
26.5k
    Log2Size = 3;
126
26.5k
    return true;
127
48.1k
128
48.1k
  case ARM::fixup_arm_movw_lo16:
129
9
    RelocType = unsigned(MachO::ARM_RELOC_HALF);
130
9
    Log2Size = 0;
131
9
    return true;
132
48.1k
  case ARM::fixup_t2_movw_lo16:
133
26.5k
    RelocType = unsigned(MachO::ARM_RELOC_HALF);
134
26.5k
    Log2Size = 2;
135
26.5k
    return true;
136
179k
  }
137
179k
}
138
139
void ARMMachObjectWriter::
140
RecordARMScatteredHalfRelocation(MachObjectWriter *Writer,
141
                                 const MCAssembler &Asm,
142
                                 const MCAsmLayout &Layout,
143
                                 const MCFragment *Fragment,
144
                                 const MCFixup &Fixup,
145
                                 MCValue Target,
146
53.1k
                                 uint64_t &FixedValue) {
147
53.1k
  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
148
53.1k
149
53.1k
  if (FixupOffset & 0xff000000) {
150
1
    Asm.getContext().reportError(Fixup.getLoc(),
151
1
                                 "can not encode offset '0x" +
152
1
                                     to_hexString(FixupOffset) +
153
1
                                     "' in resulting scattered relocation.");
154
1
    return;
155
1
  }
156
53.1k
157
53.1k
  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
158
53.1k
  unsigned Type = MachO::ARM_RELOC_HALF;
159
53.1k
160
53.1k
  // See <reloc.h>.
161
53.1k
  const MCSymbol *A = &Target.getSymA()->getSymbol();
162
53.1k
163
53.1k
  if (!A->getFragment()) {
164
0
    Asm.getContext().reportError(Fixup.getLoc(),
165
0
                       "symbol '" + A->getName() +
166
0
                       "' can not be undefined in a subtraction expression");
167
0
    return;
168
0
  }
169
53.1k
170
53.1k
  uint32_t Value = Writer->getSymbolAddress(*A, Layout);
171
53.1k
  uint32_t Value2 = 0;
172
53.1k
  uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent());
173
53.1k
  FixedValue += SecAddr;
174
53.1k
175
53.1k
  if (const MCSymbolRefExpr *B = Target.getSymB()) {
176
53.1k
    const MCSymbol *SB = &B->getSymbol();
177
53.1k
178
53.1k
    if (!SB->getFragment()) {
179
0
      Asm.getContext().reportError(Fixup.getLoc(),
180
0
                         "symbol '" + B->getSymbol().getName() +
181
0
                         "' can not be undefined in a subtraction expression");
182
0
      return;
183
0
    }
184
53.1k
185
53.1k
    // Select the appropriate difference relocation type.
186
53.1k
    Type = MachO::ARM_RELOC_HALF_SECTDIFF;
187
53.1k
    Value2 = Writer->getSymbolAddress(B->getSymbol(), Layout);
188
53.1k
    FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent());
189
53.1k
  }
190
53.1k
191
53.1k
  // Relocations are written out in reverse order, so the PAIR comes first.
192
53.1k
  // ARM_RELOC_HALF and ARM_RELOC_HALF_SECTDIFF abuse the r_length field:
193
53.1k
  //
194
53.1k
  // For these two r_type relocations they always have a pair following them and
195
53.1k
  // the r_length bits are used differently.  The encoding of the r_length is as
196
53.1k
  // follows:
197
53.1k
  //   low bit of r_length:
198
53.1k
  //      0 - :lower16: for movw instructions
199
53.1k
  //      1 - :upper16: for movt instructions
200
53.1k
  //   high bit of r_length:
201
53.1k
  //      0 - arm instructions
202
53.1k
  //      1 - thumb instructions
203
53.1k
  // the other half of the relocated expression is in the following pair
204
53.1k
  // relocation entry in the low 16 bits of r_address field.
205
53.1k
  unsigned ThumbBit = 0;
206
53.1k
  unsigned MovtBit = 0;
207
53.1k
  switch ((unsigned)Fixup.getKind()) {
208
53.1k
  
default: break5
;
209
53.1k
  case ARM::fixup_arm_movt_hi16:
210
5
    MovtBit = 1;
211
5
    // The thumb bit shouldn't be set in the 'other-half' bit of the
212
5
    // relocation, but it will be set in FixedValue if the base symbol
213
5
    // is a thumb function. Clear it out here.
214
5
    if (Asm.isThumbFunc(A))
215
0
      FixedValue &= 0xfffffffe;
216
5
    break;
217
53.1k
  case ARM::fixup_t2_movt_hi16:
218
26.5k
    if (Asm.isThumbFunc(A))
219
202
      FixedValue &= 0xfffffffe;
220
26.5k
    MovtBit = 1;
221
26.5k
    LLVM_FALLTHROUGH;
222
53.1k
  case ARM::fixup_t2_movw_lo16:
223
53.1k
    ThumbBit = 1;
224
53.1k
    break;
225
53.1k
  }
226
53.1k
227
53.1k
  if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) {
228
53.1k
    uint32_t OtherHalf = MovtBit
229
53.1k
      ? 
(FixedValue & 0xffff)26.5k
:
((FixedValue & 0xffff0000) >> 16)26.5k
;
230
53.1k
231
53.1k
    MachO::any_relocation_info MRE;
232
53.1k
    MRE.r_word0 = ((OtherHalf             <<  0) |
233
53.1k
                   (MachO::ARM_RELOC_PAIR << 24) |
234
53.1k
                   (MovtBit               << 28) |
235
53.1k
                   (ThumbBit              << 29) |
236
53.1k
                   (IsPCRel               << 30) |
237
53.1k
                   MachO::R_SCATTERED);
238
53.1k
    MRE.r_word1 = Value2;
239
53.1k
    Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
240
53.1k
  }
241
53.1k
242
53.1k
  MachO::any_relocation_info MRE;
243
53.1k
  MRE.r_word0 = ((FixupOffset <<  0) |
244
53.1k
                 (Type        << 24) |
245
53.1k
                 (MovtBit     << 28) |
246
53.1k
                 (ThumbBit    << 29) |
247
53.1k
                 (IsPCRel     << 30) |
248
53.1k
                 MachO::R_SCATTERED);
249
53.1k
  MRE.r_word1 = Value;
250
53.1k
  Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
251
53.1k
}
252
253
void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer,
254
                                                    const MCAssembler &Asm,
255
                                                    const MCAsmLayout &Layout,
256
                                                    const MCFragment *Fragment,
257
                                                    const MCFixup &Fixup,
258
                                                    MCValue Target,
259
                                                    unsigned Type,
260
                                                    unsigned Log2Size,
261
621
                                                    uint64_t &FixedValue) {
262
621
  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
263
621
264
621
  if (FixupOffset & 0xff000000) {
265
0
    Asm.getContext().reportError(Fixup.getLoc(),
266
0
                                 "can not encode offset '0x" +
267
0
                                     to_hexString(FixupOffset) +
268
0
                                     "' in resulting scattered relocation.");
269
0
    return;
270
0
  }
271
621
272
621
  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
273
621
274
621
  // See <reloc.h>.
275
621
  const MCSymbol *A = &Target.getSymA()->getSymbol();
276
621
277
621
  if (!A->getFragment()) {
278
1
    Asm.getContext().reportError(Fixup.getLoc(),
279
1
                       "symbol '" + A->getName() +
280
1
                       "' can not be undefined in a subtraction expression");
281
1
    return;
282
1
  }
283
620
284
620
  uint32_t Value = Writer->getSymbolAddress(*A, Layout);
285
620
  uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent());
286
620
  FixedValue += SecAddr;
287
620
  uint32_t Value2 = 0;
288
620
289
620
  if (const MCSymbolRefExpr *B = Target.getSymB()) {
290
613
    assert(Type == MachO::ARM_RELOC_VANILLA && "invalid reloc for 2 symbols");
291
613
    const MCSymbol *SB = &B->getSymbol();
292
613
293
613
    if (!SB->getFragment()) {
294
1
      Asm.getContext().reportError(Fixup.getLoc(),
295
1
                         "symbol '" + B->getSymbol().getName() +
296
1
                         "' can not be undefined in a subtraction expression");
297
1
      return;
298
1
    }
299
612
300
612
    // Select the appropriate difference relocation type.
301
612
    Type = MachO::ARM_RELOC_SECTDIFF;
302
612
    Value2 = Writer->getSymbolAddress(B->getSymbol(), Layout);
303
612
    FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent());
304
612
  }
305
620
306
620
  // Relocations are written out in reverse order, so the PAIR comes first.
307
620
  
if (619
Type == MachO::ARM_RELOC_SECTDIFF619
||
308
619
      
Type == MachO::ARM_RELOC_LOCAL_SECTDIFF7
) {
309
612
    MachO::any_relocation_info MRE;
310
612
    MRE.r_word0 = ((0                     <<  0) |
311
612
                   (MachO::ARM_RELOC_PAIR << 24) |
312
612
                   (Log2Size              << 28) |
313
612
                   (IsPCRel               << 30) |
314
612
                   MachO::R_SCATTERED);
315
612
    MRE.r_word1 = Value2;
316
612
    Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
317
612
  }
318
619
319
619
  MachO::any_relocation_info MRE;
320
619
  MRE.r_word0 = ((FixupOffset <<  0) |
321
619
                 (Type        << 24) |
322
619
                 (Log2Size    << 28) |
323
619
                 (IsPCRel     << 30) |
324
619
                 MachO::R_SCATTERED);
325
619
  MRE.r_word1 = Value;
326
619
  Writer->addRelocation(nullptr, Fragment->getParent(), MRE);
327
619
}
328
329
bool ARMMachObjectWriter::requiresExternRelocation(MachObjectWriter *Writer,
330
                                                   const MCAssembler &Asm,
331
                                                   const MCFragment &Fragment,
332
                                                   unsigned RelocType,
333
                                                   const MCSymbol &S,
334
125k
                                                   uint64_t FixedValue) {
335
125k
  // Most cases can be identified purely from the symbol.
336
125k
  if (Writer->doesSymbolRequireExternRelocation(S))
337
47.1k
    return true;
338
78.4k
  int64_t Value = (int64_t)FixedValue;  // The displacement is signed.
339
78.4k
  int64_t Range;
340
78.4k
  switch (RelocType) {
341
78.4k
  default:
342
75.6k
    return false;
343
78.4k
  case MachO::ARM_RELOC_BR24:
344
10
    // An ARM call might be to a Thumb function, in which case the offset may
345
10
    // not be encodable in the instruction and we must use an external
346
10
    // relocation that explicitly mentions the function. Not a problem if it's
347
10
    // to a temporary "Lwhatever" symbol though, and in fact trying to use an
348
10
    // external relocation there causes more issues.
349
10
    if (!S.isTemporary())
350
9
       return true;
351
1
352
1
    // PC pre-adjustment of 8 for these instructions.
353
1
    Value -= 8;
354
1
    // ARM BL/BLX has a 25-bit offset.
355
1
    Range = 0x1ffffff;
356
1
    break;
357
2.82k
  case MachO::ARM_THUMB_RELOC_BR22:
358
2.82k
    // PC pre-adjustment of 4 for these instructions.
359
2.82k
    Value -= 4;
360
2.82k
    // Thumb BL/BLX has a 24-bit offset.
361
2.82k
    Range = 0xffffff;
362
78.4k
  }
363
78.4k
  // BL/BLX also use external relocations when an internal relocation
364
78.4k
  // would result in the target being out of range. This gives the linker
365
78.4k
  // enough information to generate a branch island.
366
78.4k
  Value += Writer->getSectionAddress(&S.getSection());
367
2.82k
  Value -= Writer->getSectionAddress(Fragment.getParent());
368
2.82k
  // If the resultant value would be out of range for an internal relocation,
369
2.82k
  // use an external instead.
370
2.82k
  if (Value > Range || 
Value < -(Range + 1)2.82k
)
371
1
    return true;
372
2.82k
  return false;
373
2.82k
}
374
375
void ARMMachObjectWriter::recordRelocation(MachObjectWriter *Writer,
376
                                           MCAssembler &Asm,
377
                                           const MCAsmLayout &Layout,
378
                                           const MCFragment *Fragment,
379
                                           const MCFixup &Fixup, MCValue Target,
380
179k
                                           uint64_t &FixedValue) {
381
179k
  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
382
179k
  unsigned Log2Size;
383
179k
  unsigned RelocType = MachO::ARM_RELOC_VANILLA;
384
179k
  if (!getARMFixupKindMachOInfo(Fixup.getKind(), RelocType, Log2Size)) {
385
8
    // If we failed to get fixup kind info, it's because there's no legal
386
8
    // relocation type for the fixup kind. This happens when it's a fixup that's
387
8
    // expected to always be resolvable at assembly time and not have any
388
8
    // relocations needed.
389
8
    Asm.getContext().reportError(Fixup.getLoc(),
390
8
                                 "unsupported relocation on symbol");
391
8
    return;
392
8
  }
393
179k
394
179k
  // If this is a difference or a defined symbol plus an offset, then we need a
395
179k
  // scattered relocation entry.  Differences always require scattered
396
179k
  // relocations.
397
179k
  if (Target.getSymB()) {
398
53.7k
    if (RelocType == MachO::ARM_RELOC_HALF)
399
53.1k
      return RecordARMScatteredHalfRelocation(Writer, Asm, Layout, Fragment,
400
53.1k
                                              Fixup, Target, FixedValue);
401
614
    return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
402
614
                                        Target, RelocType, Log2Size,
403
614
                                        FixedValue);
404
614
  }
405
125k
406
125k
  // Get the symbol data, if any.
407
125k
  const MCSymbol *A = nullptr;
408
125k
  if (Target.getSymA())
409
125k
    A = &Target.getSymA()->getSymbol();
410
125k
411
125k
  // FIXME: For other platforms, we need to use scattered relocations for
412
125k
  // internal relocations with offsets.  If this is an internal relocation with
413
125k
  // an offset, it also needs a scattered relocation entry.
414
125k
  //
415
125k
  // Is this right for ARM?
416
125k
  uint32_t Offset = Target.getConstant();
417
125k
  if (IsPCRel && 
RelocType == MachO::ARM_RELOC_VANILLA48.6k
)
418
0
    Offset += 1 << Log2Size;
419
125k
  if (Offset && 
A99
&&
!Writer->doesSymbolRequireExternRelocation(*A)99
&&
420
125k
      
RelocType != MachO::ARM_RELOC_HALF7
)
421
7
    return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
422
7
                                        Target, RelocType, Log2Size,
423
7
                                        FixedValue);
424
125k
425
125k
  // See <reloc.h>.
426
125k
  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
427
125k
  unsigned Index = 0;
428
125k
  unsigned Type = 0;
429
125k
  const MCSymbol *RelSymbol = nullptr;
430
125k
431
125k
  if (Target.isAbsolute()) { // constant
432
0
    // FIXME!
433
0
    report_fatal_error("FIXME: relocations to absolute targets "
434
0
                       "not yet implemented");
435
125k
  } else {
436
125k
    // Resolve constant variables.
437
125k
    if (A->isVariable()) {
438
0
      int64_t Res;
439
0
      if (A->getVariableValue()->evaluateAsAbsolute(
440
0
              Res, Layout, Writer->getSectionAddressMap())) {
441
0
        FixedValue = Res;
442
0
        return;
443
0
      }
444
125k
    }
445
125k
446
125k
    // Check whether we need an external or internal relocation.
447
125k
    if (requiresExternRelocation(Writer, Asm, *Fragment, RelocType, *A,
448
125k
                                 FixedValue)) {
449
47.1k
      RelSymbol = A;
450
47.1k
451
47.1k
      // For external relocations, make sure to offset the fixup value to
452
47.1k
      // compensate for the addend of the symbol address, if it was
453
47.1k
      // undefined. This occurs with weak definitions, for example.
454
47.1k
      if (!A->isUndefined())
455
2.43k
        FixedValue -= Layout.getSymbolOffset(*A);
456
78.4k
    } else {
457
78.4k
      // The index is the section ordinal (1-based).
458
78.4k
      const MCSection &Sec = A->getSection();
459
78.4k
      Index = Sec.getOrdinal() + 1;
460
78.4k
      FixedValue += Writer->getSectionAddress(&Sec);
461
78.4k
    }
462
125k
    if (IsPCRel)
463
48.6k
      FixedValue -= Writer->getSectionAddress(Fragment->getParent());
464
125k
465
125k
    // The type is determined by the fixup kind.
466
125k
    Type = RelocType;
467
125k
  }
468
125k
469
125k
  // struct relocation_info (8 bytes)
470
125k
  MachO::any_relocation_info MRE;
471
125k
  MRE.r_word0 = FixupOffset;
472
125k
  MRE.r_word1 =
473
125k
      (Index << 0) | (IsPCRel << 24) | (Log2Size << 25) | (Type << 28);
474
125k
475
125k
  // Even when it's not a scattered relocation, movw/movt always uses
476
125k
  // a PAIR relocation.
477
125k
  if (Type == MachO::ARM_RELOC_HALF) {
478
18
    // The entire addend is needed to correctly apply a relocation. One half is
479
18
    // extracted from the instruction itself, the other comes from this
480
18
    // PAIR. I.e. it's correct that we insert the high bits of the addend in the
481
18
    // MOVW case here.  relocation entries.
482
18
    uint32_t Value = 0;
483
18
    switch ((unsigned)Fixup.getKind()) {
484
18
    
default: break0
;
485
18
    case ARM::fixup_arm_movw_lo16:
486
9
    case ARM::fixup_t2_movw_lo16:
487
9
      Value = (FixedValue >> 16) & 0xffff;
488
9
      break;
489
9
    case ARM::fixup_arm_movt_hi16:
490
9
    case ARM::fixup_t2_movt_hi16:
491
9
      Value = FixedValue & 0xffff;
492
9
      break;
493
18
    }
494
18
    MachO::any_relocation_info MREPair;
495
18
    MREPair.r_word0 = Value;
496
18
    MREPair.r_word1 = ((0xffffff              <<  0) |
497
18
                       (Log2Size              << 25) |
498
18
                       (MachO::ARM_RELOC_PAIR << 28));
499
18
500
18
    Writer->addRelocation(nullptr, Fragment->getParent(), MREPair);
501
18
  }
502
125k
503
125k
  Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE);
504
125k
}
505
506
std::unique_ptr<MCObjectTargetWriter>
507
llvm::createARMMachObjectWriter(bool Is64Bit, uint32_t CPUType,
508
3.72k
                                uint32_t CPUSubtype) {
509
3.72k
  return llvm::make_unique<ARMMachObjectWriter>(Is64Bit, CPUType, CPUSubtype);
510
3.72k
}