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