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