X86MachObjectWriter.cpp revision 5510728d28bb1ee04abc32da3d21b7df12948053
1//===-- X86MachObjectWriter.cpp - X86 Mach-O Writer -----------------------===//
2//
3//                     The LLVM Compiler Infrastructure
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 "MCTargetDesc/X86MCTargetDesc.h"
11#include "MCTargetDesc/X86FixupKinds.h"
12#include "llvm/ADT/Twine.h"
13#include "llvm/MC/MCAsmLayout.h"
14#include "llvm/MC/MCAssembler.h"
15#include "llvm/MC/MCContext.h"
16#include "llvm/MC/MCMachObjectWriter.h"
17#include "llvm/MC/MCSectionMachO.h"
18#include "llvm/MC/MCValue.h"
19#include "llvm/Support/ErrorHandling.h"
20#include "llvm/Support/Format.h"
21#include "llvm/Support/MachO.h"
22
23using namespace llvm;
24
25namespace {
26class X86MachObjectWriter : public MCMachObjectTargetWriter {
27  bool RecordScatteredRelocation(MachObjectWriter *Writer,
28                                 const MCAssembler &Asm,
29                                 const MCAsmLayout &Layout,
30                                 const MCFragment *Fragment,
31                                 const MCFixup &Fixup,
32                                 MCValue Target,
33                                 unsigned Log2Size,
34                                 uint64_t &FixedValue);
35  void RecordTLVPRelocation(MachObjectWriter *Writer,
36                            const MCAssembler &Asm,
37                            const MCAsmLayout &Layout,
38                            const MCFragment *Fragment,
39                            const MCFixup &Fixup,
40                            MCValue Target,
41                            uint64_t &FixedValue);
42
43  void RecordX86Relocation(MachObjectWriter *Writer,
44                              const MCAssembler &Asm,
45                              const MCAsmLayout &Layout,
46                              const MCFragment *Fragment,
47                              const MCFixup &Fixup,
48                              MCValue Target,
49                              uint64_t &FixedValue);
50  void RecordX86_64Relocation(MachObjectWriter *Writer,
51                              const MCAssembler &Asm,
52                              const MCAsmLayout &Layout,
53                              const MCFragment *Fragment,
54                              const MCFixup &Fixup,
55                              MCValue Target,
56                              uint64_t &FixedValue);
57public:
58  X86MachObjectWriter(bool Is64Bit, uint32_t CPUType,
59                      uint32_t CPUSubtype)
60    : MCMachObjectTargetWriter(Is64Bit, CPUType, CPUSubtype,
61                               /*UseAggressiveSymbolFolding=*/Is64Bit) {}
62
63  void RecordRelocation(MachObjectWriter *Writer,
64                        const MCAssembler &Asm, const MCAsmLayout &Layout,
65                        const MCFragment *Fragment, const MCFixup &Fixup,
66                        MCValue Target, uint64_t &FixedValue) {
67    if (Writer->is64Bit())
68      RecordX86_64Relocation(Writer, Asm, Layout, Fragment, Fixup, Target,
69                             FixedValue);
70    else
71      RecordX86Relocation(Writer, Asm, Layout, Fragment, Fixup, Target,
72                          FixedValue);
73  }
74};
75}
76
77static bool isFixupKindRIPRel(unsigned Kind) {
78  return Kind == X86::reloc_riprel_4byte ||
79    Kind == X86::reloc_riprel_4byte_movq_load;
80}
81
82static unsigned getFixupKindLog2Size(unsigned Kind) {
83  switch (Kind) {
84  default:
85    llvm_unreachable("invalid fixup kind!");
86  case FK_PCRel_1:
87  case FK_Data_1: return 0;
88  case FK_PCRel_2:
89  case FK_Data_2: return 1;
90  case FK_PCRel_4:
91    // FIXME: Remove these!!!
92  case X86::reloc_riprel_4byte:
93  case X86::reloc_riprel_4byte_movq_load:
94  case X86::reloc_signed_4byte:
95  case FK_Data_4: return 2;
96  case FK_Data_8: return 3;
97  }
98}
99
100void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer,
101                                                 const MCAssembler &Asm,
102                                                 const MCAsmLayout &Layout,
103                                                 const MCFragment *Fragment,
104                                                 const MCFixup &Fixup,
105                                                 MCValue Target,
106                                                 uint64_t &FixedValue) {
107  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
108  unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind());
109  unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
110
111  // See <reloc.h>.
112  uint32_t FixupOffset =
113    Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
114  uint32_t FixupAddress =
115    Writer->getFragmentAddress(Fragment, Layout) + Fixup.getOffset();
116  int64_t Value = 0;
117  unsigned Index = 0;
118  unsigned IsExtern = 0;
119  unsigned Type = 0;
120
121  Value = Target.getConstant();
122
123  if (IsPCRel) {
124    // Compensate for the relocation offset, Darwin x86_64 relocations only have
125    // the addend and appear to have attempted to define it to be the actual
126    // expression addend without the PCrel bias. However, instructions with data
127    // following the relocation are not accommodated for (see comment below
128    // regarding SIGNED{1,2,4}), so it isn't exactly that either.
129    Value += 1LL << Log2Size;
130  }
131
132  if (Target.isAbsolute()) { // constant
133    // SymbolNum of 0 indicates the absolute section.
134    Type = MachO::X86_64_RELOC_UNSIGNED;
135    Index = 0;
136
137    // FIXME: I believe this is broken, I don't think the linker can understand
138    // it. I think it would require a local relocation, but I'm not sure if that
139    // would work either. The official way to get an absolute PCrel relocation
140    // is to use an absolute symbol (which we don't support yet).
141    if (IsPCRel) {
142      IsExtern = 1;
143      Type = MachO::X86_64_RELOC_BRANCH;
144    }
145  } else if (Target.getSymB()) { // A - B + constant
146    const MCSymbol *A = &Target.getSymA()->getSymbol();
147    MCSymbolData &A_SD = Asm.getSymbolData(*A);
148    const MCSymbolData *A_Base = Asm.getAtom(&A_SD);
149
150    const MCSymbol *B = &Target.getSymB()->getSymbol();
151    MCSymbolData &B_SD = Asm.getSymbolData(*B);
152    const MCSymbolData *B_Base = Asm.getAtom(&B_SD);
153
154    // Neither symbol can be modified.
155    if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None ||
156        Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None)
157      report_fatal_error("unsupported relocation of modified symbol");
158
159    // We don't support PCrel relocations of differences. Darwin 'as' doesn't
160    // implement most of these correctly.
161    if (IsPCRel)
162      report_fatal_error("unsupported pc-relative relocation of difference");
163
164    // The support for the situation where one or both of the symbols would
165    // require a local relocation is handled just like if the symbols were
166    // external.  This is certainly used in the case of debug sections where the
167    // section has only temporary symbols and thus the symbols don't have base
168    // symbols.  This is encoded using the section ordinal and non-extern
169    // relocation entries.
170
171    // Darwin 'as' doesn't emit correct relocations for this (it ends up with a
172    // single SIGNED relocation); reject it for now.  Except the case where both
173    // symbols don't have a base, equal but both NULL.
174    if (A_Base == B_Base && A_Base)
175      report_fatal_error("unsupported relocation with identical base");
176
177    // A subtraction expression where both symbols are undefined is a
178    // non-relocatable expression.
179    if (A->isUndefined() && B->isUndefined())
180      report_fatal_error("unsupported relocation with subtraction expression");
181
182    Value += Writer->getSymbolAddress(&A_SD, Layout) -
183      (A_Base == NULL ? 0 : Writer->getSymbolAddress(A_Base, Layout));
184    Value -= Writer->getSymbolAddress(&B_SD, Layout) -
185      (B_Base == NULL ? 0 : Writer->getSymbolAddress(B_Base, Layout));
186
187    if (A_Base) {
188      Index = A_Base->getIndex();
189      IsExtern = 1;
190    }
191    else {
192      Index = A_SD.getFragment()->getParent()->getOrdinal() + 1;
193      IsExtern = 0;
194    }
195    Type = MachO::X86_64_RELOC_UNSIGNED;
196
197    MachO::any_relocation_info MRE;
198    MRE.r_word0 = FixupOffset;
199    MRE.r_word1 = ((Index     <<  0) |
200                   (IsPCRel   << 24) |
201                   (Log2Size  << 25) |
202                   (IsExtern  << 27) |
203                   (Type      << 28));
204    Writer->addRelocation(Fragment->getParent(), MRE);
205
206    if (B_Base) {
207      Index = B_Base->getIndex();
208      IsExtern = 1;
209    }
210    else {
211      Index = B_SD.getFragment()->getParent()->getOrdinal() + 1;
212      IsExtern = 0;
213    }
214    Type = MachO::X86_64_RELOC_SUBTRACTOR;
215  } else {
216    const MCSymbol *Symbol = &Target.getSymA()->getSymbol();
217    MCSymbolData &SD = Asm.getSymbolData(*Symbol);
218    const MCSymbolData *Base = Asm.getAtom(&SD);
219
220    // Relocations inside debug sections always use local relocations when
221    // possible. This seems to be done because the debugger doesn't fully
222    // understand x86_64 relocation entries, and expects to find values that
223    // have already been fixed up.
224    if (Symbol->isInSection()) {
225      const MCSectionMachO &Section = static_cast<const MCSectionMachO&>(
226        Fragment->getParent()->getSection());
227      if (Section.hasAttribute(MCSectionMachO::S_ATTR_DEBUG))
228        Base = 0;
229    }
230
231    // x86_64 almost always uses external relocations, except when there is no
232    // symbol to use as a base address (a local symbol with no preceding
233    // non-local symbol).
234    if (Base) {
235      Index = Base->getIndex();
236      IsExtern = 1;
237
238      // Add the local offset, if needed.
239      if (Base != &SD)
240        Value += Layout.getSymbolOffset(&SD) - Layout.getSymbolOffset(Base);
241    } else if (Symbol->isInSection() && !Symbol->isVariable()) {
242      // The index is the section ordinal (1-based).
243      Index = SD.getFragment()->getParent()->getOrdinal() + 1;
244      IsExtern = 0;
245      Value += Writer->getSymbolAddress(&SD, Layout);
246
247      if (IsPCRel)
248        Value -= FixupAddress + (1 << Log2Size);
249    } else if (Symbol->isVariable()) {
250      const MCExpr *Value = Symbol->getVariableValue();
251      int64_t Res;
252      bool isAbs = Value->EvaluateAsAbsolute(Res, Layout,
253                                             Writer->getSectionAddressMap());
254      if (isAbs) {
255        FixedValue = Res;
256        return;
257      } else {
258        report_fatal_error("unsupported relocation of variable '" +
259                           Symbol->getName() + "'");
260      }
261    } else {
262      report_fatal_error("unsupported relocation of undefined symbol '" +
263                         Symbol->getName() + "'");
264    }
265
266    MCSymbolRefExpr::VariantKind Modifier = Target.getSymA()->getKind();
267    if (IsPCRel) {
268      if (IsRIPRel) {
269        if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) {
270          // x86_64 distinguishes movq foo@GOTPCREL so that the linker can
271          // rewrite the movq to an leaq at link time if the symbol ends up in
272          // the same linkage unit.
273          if (unsigned(Fixup.getKind()) == X86::reloc_riprel_4byte_movq_load)
274            Type = MachO::X86_64_RELOC_GOT_LOAD;
275          else
276            Type = MachO::X86_64_RELOC_GOT;
277        }  else if (Modifier == MCSymbolRefExpr::VK_TLVP) {
278          Type = MachO::X86_64_RELOC_TLV;
279        }  else if (Modifier != MCSymbolRefExpr::VK_None) {
280          report_fatal_error("unsupported symbol modifier in relocation");
281        } else {
282          Type = MachO::X86_64_RELOC_SIGNED;
283
284          // The Darwin x86_64 relocation format has a problem where it cannot
285          // encode an address (L<foo> + <constant>) which is outside the atom
286          // containing L<foo>. Generally, this shouldn't occur but it does
287          // happen when we have a RIPrel instruction with data following the
288          // relocation entry (e.g., movb $012, L0(%rip)). Even with the PCrel
289          // adjustment Darwin x86_64 uses, the offset is still negative and the
290          // linker has no way to recognize this.
291          //
292          // To work around this, Darwin uses several special relocation types
293          // to indicate the offsets. However, the specification or
294          // implementation of these seems to also be incomplete; they should
295          // adjust the addend as well based on the actual encoded instruction
296          // (the additional bias), but instead appear to just look at the final
297          // offset.
298          switch (-(Target.getConstant() + (1LL << Log2Size))) {
299          case 1: Type = MachO::X86_64_RELOC_SIGNED_1; break;
300          case 2: Type = MachO::X86_64_RELOC_SIGNED_2; break;
301          case 4: Type = MachO::X86_64_RELOC_SIGNED_4; break;
302          }
303        }
304      } else {
305        if (Modifier != MCSymbolRefExpr::VK_None)
306          report_fatal_error("unsupported symbol modifier in branch "
307                             "relocation");
308
309        Type = MachO::X86_64_RELOC_BRANCH;
310      }
311    } else {
312      if (Modifier == MCSymbolRefExpr::VK_GOT) {
313        Type = MachO::X86_64_RELOC_GOT;
314      } else if (Modifier == MCSymbolRefExpr::VK_GOTPCREL) {
315        // GOTPCREL is allowed as a modifier on non-PCrel instructions, in which
316        // case all we do is set the PCrel bit in the relocation entry; this is
317        // used with exception handling, for example. The source is required to
318        // include any necessary offset directly.
319        Type = MachO::X86_64_RELOC_GOT;
320        IsPCRel = 1;
321      } else if (Modifier == MCSymbolRefExpr::VK_TLVP) {
322        report_fatal_error("TLVP symbol modifier should have been rip-rel");
323      } else if (Modifier != MCSymbolRefExpr::VK_None)
324        report_fatal_error("unsupported symbol modifier in relocation");
325      else {
326        Type = MachO::X86_64_RELOC_UNSIGNED;
327        unsigned Kind = Fixup.getKind();
328        if (Kind == X86::reloc_signed_4byte)
329          report_fatal_error("32-bit absolute addressing is not supported in "
330                             "64-bit mode");
331      }
332    }
333  }
334
335  // x86_64 always writes custom values into the fixups.
336  FixedValue = Value;
337
338  // struct relocation_info (8 bytes)
339  MachO::any_relocation_info MRE;
340  MRE.r_word0 = FixupOffset;
341  MRE.r_word1 = ((Index     <<  0) |
342                 (IsPCRel   << 24) |
343                 (Log2Size  << 25) |
344                 (IsExtern  << 27) |
345                 (Type      << 28));
346  Writer->addRelocation(Fragment->getParent(), MRE);
347}
348
349bool X86MachObjectWriter::RecordScatteredRelocation(MachObjectWriter *Writer,
350                                                    const MCAssembler &Asm,
351                                                    const MCAsmLayout &Layout,
352                                                    const MCFragment *Fragment,
353                                                    const MCFixup &Fixup,
354                                                    MCValue Target,
355                                                    unsigned Log2Size,
356                                                    uint64_t &FixedValue) {
357  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
358  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
359  unsigned Type = MachO::GENERIC_RELOC_VANILLA;
360
361  // See <reloc.h>.
362  const MCSymbol *A = &Target.getSymA()->getSymbol();
363  MCSymbolData *A_SD = &Asm.getSymbolData(*A);
364
365  if (!A_SD->getFragment())
366    report_fatal_error("symbol '" + A->getName() +
367                       "' can not be undefined in a subtraction expression");
368
369  uint32_t Value = Writer->getSymbolAddress(A_SD, Layout);
370  uint64_t SecAddr = Writer->getSectionAddress(A_SD->getFragment()->getParent());
371  FixedValue += SecAddr;
372  uint32_t Value2 = 0;
373
374  if (const MCSymbolRefExpr *B = Target.getSymB()) {
375    MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol());
376
377    if (!B_SD->getFragment())
378      report_fatal_error("symbol '" + B->getSymbol().getName() +
379                         "' can not be undefined in a subtraction expression");
380
381    // Select the appropriate difference relocation type.
382    //
383    // Note that there is no longer any semantic difference between these two
384    // relocation types from the linkers point of view, this is done solely for
385    // pedantic compatibility with 'as'.
386    Type = A_SD->isExternal() ? (unsigned)MachO::GENERIC_RELOC_SECTDIFF :
387      (unsigned)MachO::GENERIC_RELOC_LOCAL_SECTDIFF;
388    Value2 = Writer->getSymbolAddress(B_SD, Layout);
389    FixedValue -= Writer->getSectionAddress(B_SD->getFragment()->getParent());
390  }
391
392  // Relocations are written out in reverse order, so the PAIR comes first.
393  if (Type == MachO::GENERIC_RELOC_SECTDIFF ||
394      Type == MachO::GENERIC_RELOC_LOCAL_SECTDIFF) {
395    // If the offset is too large to fit in a scattered relocation,
396    // we're hosed. It's an unfortunate limitation of the MachO format.
397    if (FixupOffset > 0xffffff) {
398      char Buffer[32];
399      format("0x%x", FixupOffset).print(Buffer, sizeof(Buffer));
400      Asm.getContext().FatalError(Fixup.getLoc(),
401                         Twine("Section too large, can't encode "
402                                "r_address (") + Buffer +
403                         ") into 24 bits of scattered "
404                         "relocation entry.");
405      llvm_unreachable("fatal error returned?!");
406    }
407
408    MachO::any_relocation_info MRE;
409    MRE.r_word0 = ((0                         <<  0) | // r_address
410                   (MachO::GENERIC_RELOC_PAIR << 24) | // r_type
411                   (Log2Size                  << 28) |
412                   (IsPCRel                   << 30) |
413                   MachO::R_SCATTERED);
414    MRE.r_word1 = Value2;
415    Writer->addRelocation(Fragment->getParent(), MRE);
416  } else {
417    // If the offset is more than 24-bits, it won't fit in a scattered
418    // relocation offset field, so we fall back to using a non-scattered
419    // relocation. This is a bit risky, as if the offset reaches out of
420    // the block and the linker is doing scattered loading on this
421    // symbol, things can go badly.
422    //
423    // Required for 'as' compatibility.
424    if (FixupOffset > 0xffffff)
425      return false;
426  }
427
428  MachO::any_relocation_info MRE;
429  MRE.r_word0 = ((FixupOffset <<  0) |
430                 (Type        << 24) |
431                 (Log2Size    << 28) |
432                 (IsPCRel     << 30) |
433                 MachO::R_SCATTERED);
434  MRE.r_word1 = Value;
435  Writer->addRelocation(Fragment->getParent(), MRE);
436  return true;
437}
438
439void X86MachObjectWriter::RecordTLVPRelocation(MachObjectWriter *Writer,
440                                               const MCAssembler &Asm,
441                                               const MCAsmLayout &Layout,
442                                               const MCFragment *Fragment,
443                                               const MCFixup &Fixup,
444                                               MCValue Target,
445                                               uint64_t &FixedValue) {
446  assert(Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP &&
447         !is64Bit() &&
448         "Should only be called with a 32-bit TLVP relocation!");
449
450  unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
451  uint32_t Value = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
452  unsigned IsPCRel = 0;
453
454  // Get the symbol data.
455  MCSymbolData *SD_A = &Asm.getSymbolData(Target.getSymA()->getSymbol());
456  unsigned Index = SD_A->getIndex();
457
458  // We're only going to have a second symbol in pic mode and it'll be a
459  // subtraction from the picbase. For 32-bit pic the addend is the difference
460  // between the picbase and the next address.  For 32-bit static the addend is
461  // zero.
462  if (Target.getSymB()) {
463    // If this is a subtraction then we're pcrel.
464    uint32_t FixupAddress =
465      Writer->getFragmentAddress(Fragment, Layout) + Fixup.getOffset();
466    MCSymbolData *SD_B = &Asm.getSymbolData(Target.getSymB()->getSymbol());
467    IsPCRel = 1;
468    FixedValue = (FixupAddress - Writer->getSymbolAddress(SD_B, Layout) +
469                  Target.getConstant());
470    FixedValue += 1ULL << Log2Size;
471  } else {
472    FixedValue = 0;
473  }
474
475  // struct relocation_info (8 bytes)
476  MachO::any_relocation_info MRE;
477  MRE.r_word0 = Value;
478  MRE.r_word1 = ((Index                    <<  0) |
479                 (IsPCRel                  << 24) |
480                 (Log2Size                 << 25) |
481                 (1                        << 27) | // r_extern
482                 (MachO::GENERIC_RELOC_TLV << 28)); // r_type
483  Writer->addRelocation(Fragment->getParent(), MRE);
484}
485
486void X86MachObjectWriter::RecordX86Relocation(MachObjectWriter *Writer,
487                                              const MCAssembler &Asm,
488                                              const MCAsmLayout &Layout,
489                                              const MCFragment *Fragment,
490                                              const MCFixup &Fixup,
491                                              MCValue Target,
492                                              uint64_t &FixedValue) {
493  unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind());
494  unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind());
495
496  // If this is a 32-bit TLVP reloc it's handled a bit differently.
497  if (Target.getSymA() &&
498      Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP) {
499    RecordTLVPRelocation(Writer, Asm, Layout, Fragment, Fixup, Target,
500                         FixedValue);
501    return;
502  }
503
504  // If this is a difference or a defined symbol plus an offset, then we need a
505  // scattered relocation entry. Differences always require scattered
506  // relocations.
507  if (Target.getSymB()) {
508    RecordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
509                              Target, Log2Size, FixedValue);
510    return;
511  }
512
513  // Get the symbol data, if any.
514  MCSymbolData *SD = 0;
515  if (Target.getSymA())
516    SD = &Asm.getSymbolData(Target.getSymA()->getSymbol());
517
518  // If this is an internal relocation with an offset, it also needs a scattered
519  // relocation entry.
520  uint32_t Offset = Target.getConstant();
521  if (IsPCRel)
522    Offset += 1 << Log2Size;
523  // Try to record the scattered relocation if needed. Fall back to non
524  // scattered if necessary (see comments in RecordScatteredRelocation()
525  // for details).
526  if (Offset && SD && !Writer->doesSymbolRequireExternRelocation(SD) &&
527      RecordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup,
528                                Target, Log2Size, FixedValue))
529    return;
530
531  // See <reloc.h>.
532  uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset();
533  unsigned Index = 0;
534  unsigned IsExtern = 0;
535  unsigned Type = 0;
536
537  if (Target.isAbsolute()) { // constant
538    // SymbolNum of 0 indicates the absolute section.
539    //
540    // FIXME: Currently, these are never generated (see code below). I cannot
541    // find a case where they are actually emitted.
542    Type = MachO::GENERIC_RELOC_VANILLA;
543  } else {
544    // Resolve constant variables.
545    if (SD->getSymbol().isVariable()) {
546      int64_t Res;
547      if (SD->getSymbol().getVariableValue()->EvaluateAsAbsolute(
548            Res, Layout, Writer->getSectionAddressMap())) {
549        FixedValue = Res;
550        return;
551      }
552    }
553
554    // Check whether we need an external or internal relocation.
555    if (Writer->doesSymbolRequireExternRelocation(SD)) {
556      IsExtern = 1;
557      Index = SD->getIndex();
558      // For external relocations, make sure to offset the fixup value to
559      // compensate for the addend of the symbol address, if it was
560      // undefined. This occurs with weak definitions, for example.
561      if (!SD->Symbol->isUndefined())
562        FixedValue -= Layout.getSymbolOffset(SD);
563    } else {
564      // The index is the section ordinal (1-based).
565      const MCSectionData &SymSD = Asm.getSectionData(
566        SD->getSymbol().getSection());
567      Index = SymSD.getOrdinal() + 1;
568      FixedValue += Writer->getSectionAddress(&SymSD);
569    }
570    if (IsPCRel)
571      FixedValue -= Writer->getSectionAddress(Fragment->getParent());
572
573    Type = MachO::GENERIC_RELOC_VANILLA;
574  }
575
576  // struct relocation_info (8 bytes)
577  MachO::any_relocation_info MRE;
578  MRE.r_word0 = FixupOffset;
579  MRE.r_word1 = ((Index     <<  0) |
580                 (IsPCRel   << 24) |
581                 (Log2Size  << 25) |
582                 (IsExtern  << 27) |
583                 (Type      << 28));
584  Writer->addRelocation(Fragment->getParent(), MRE);
585}
586
587MCObjectWriter *llvm::createX86MachObjectWriter(raw_ostream &OS,
588                                                bool Is64Bit,
589                                                uint32_t CPUType,
590                                                uint32_t CPUSubtype) {
591  return createMachObjectWriter(new X86MachObjectWriter(Is64Bit,
592                                                        CPUType,
593                                                        CPUSubtype),
594                                OS, /*IsLittleEndian=*/true);
595}
596