12df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//===- lib/MC/MachObjectWriter.cpp - Mach-O File Writer -------------------===// 22df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// 32df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// The LLVM Compiler Infrastructure 42df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// 52df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// This file is distributed under the University of Illinois Open Source 62df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// License. See LICENSE.TXT for details. 72df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// 82df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar//===----------------------------------------------------------------------===// 92df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 10ae5abd595f5442767313a4c8a24008ad19323cebDaniel Dunbar#include "llvm/MC/MCMachObjectWriter.h" 112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/ADT/StringMap.h" 122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/ADT/Twine.h" 1378c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h" 14207e06ea0446c51cb1d89f6400ec7becc46487f8Daniel Dunbar#include "llvm/MC/MCAsmLayout.h" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCAssembler.h" 162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCExpr.h" 17f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCMachOSymbolFlags.h" 192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCObjectWriter.h" 202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCSectionMachO.h" 212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCSymbol.h" 222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCValue.h" 233e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach#include "llvm/Support/Debug.h" 242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/Support/ErrorHandling.h" 255510728d28bb1ee04abc32da3d21b7df12948053Charles Davis#include "llvm/Support/MachO.h" 262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include <vector> 272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarusing namespace llvm; 282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mc" 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3199cbdde6198623ff014c776743caec2cf48f4840Pedro Artigasvoid MachObjectWriter::reset() { 3299cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas Relocations.clear(); 3399cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas IndirectSymBase.clear(); 3499cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas StringTable.clear(); 3599cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas LocalSymbolData.clear(); 3699cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas ExternalSymbolData.clear(); 3799cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas UndefinedSymbolData.clear(); 3899cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas MCObjectWriter::reset(); 3999cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas} 4099cbdde6198623ff014c776743caec2cf48f4840Pedro Artigas 41ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachbool MachObjectWriter:: 42ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim GrosbachdoesSymbolRequireExternRelocation(const MCSymbolData *SD) { 43e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar // Undefined symbols are always extern. 44e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar if (SD->Symbol->isUndefined()) 45e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar return true; 46e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar 47e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar // References to weak definitions require external relocation entries; the 48e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar // definition may not always be the one in the same object file. 49e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar if (SD->getFlags() & SF_WeakDefinition) 50e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar return true; 51e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar 52e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar // Otherwise, we can use an internal relocation. 53e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar return false; 54e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar} 55e9460ec0577dc82d1fb1f8c92e20f47a3c75abc9Daniel Dunbar 56ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachbool MachObjectWriter:: 57ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim GrosbachMachSymbolData::operator<(const MachSymbolData &RHS) const { 58ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach return SymbolData->getSymbol().getName() < 59ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach RHS.SymbolData->getSymbol().getName(); 60ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach} 61f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 62ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachbool MachObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 63ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach const MCFixupKindInfo &FKI = Asm.getBackend().getFixupKindInfo( 64ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach (MCFixupKind) Kind); 65f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 66ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 67ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach} 68f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 69ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbachuint64_t MachObjectWriter::getFragmentAddress(const MCFragment *Fragment, 70ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach const MCAsmLayout &Layout) const { 71ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach return getSectionAddress(Fragment->getParent()) + 72ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach Layout.getFragmentOffset(Fragment); 73ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach} 74f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 75bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlinguint64_t MachObjectWriter::getSymbolAddress(const MCSymbolData* SD, 76bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCAsmLayout &Layout) const { 77bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSymbol &S = SD->getSymbol(); 78f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 79bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // If this is a variable, then recursively evaluate now. 80bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (S.isVariable()) { 8145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach if (const MCConstantExpr *C = 8245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach dyn_cast<const MCConstantExpr>(S.getVariableValue())) 8345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach return C->getValue(); 8445d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach 8545d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach 86bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MCValue Target; 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!S.getVariableValue()->EvaluateAsRelocatable(Target, &Layout)) 88bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling report_fatal_error("unable to evaluate offset for variable '" + 89bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling S.getName() + "'"); 90f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 91bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Verify that any used symbols are defined. 92bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Target.getSymA() && Target.getSymA()->getSymbol().isUndefined()) 93bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling report_fatal_error("unable to evaluate offset to undefined symbol '" + 94bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Target.getSymA()->getSymbol().getName() + "'"); 95bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Target.getSymB() && Target.getSymB()->getSymbol().isUndefined()) 96bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling report_fatal_error("unable to evaluate offset to undefined symbol '" + 97bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Target.getSymB()->getSymbol().getName() + "'"); 98f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 99bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Address = Target.getConstant(); 100bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Target.getSymA()) 101bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( 102bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Target.getSymA()->getSymbol()), Layout); 103bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Target.getSymB()) 104bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Address += getSymbolAddress(&Layout.getAssembler().getSymbolData( 105bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Target.getSymB()->getSymbol()), Layout); 106bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return Address; 107bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 108f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 109bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return getSectionAddress(SD->getFragment()->getParent()) + 110bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Layout.getSymbolOffset(SD); 111bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 112f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 113bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlinguint64_t MachObjectWriter::getPaddingSize(const MCSectionData *SD, 114bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCAsmLayout &Layout) const { 115bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t EndAddr = getSectionAddress(SD) + Layout.getSectionAddressSize(SD); 116bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned Next = SD->getLayoutOrder() + 1; 117bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Next >= Layout.getSectionOrder().size()) 118bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return 0; 119bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 120bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionData &NextSD = *Layout.getSectionOrder()[Next]; 121bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (NextSD.getSection().isVirtualSection()) 122bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return 0; 123bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return OffsetToAlignment(EndAddr, NextSD.getAlignment()); 124bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 125f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 126bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteHeader(unsigned NumLoadCommands, 127bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned LoadCommandsSize, 128bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling bool SubsectionsViaSymbols) { 129bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t Flags = 0; 130f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 131bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (SubsectionsViaSymbols) 1325510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Flags |= MachO::MH_SUBSECTIONS_VIA_SYMBOLS; 133bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 134bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct mach_header (28 bytes) or 135bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct mach_header_64 (32 bytes) 136bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 137bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Start = OS.tell(); 138bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling (void) Start; 139bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 1405510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(is64Bit() ? MachO::MH_MAGIC_64 : MachO::MH_MAGIC); 141bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 142bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(TargetObjectWriter->getCPUType()); 143bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(TargetObjectWriter->getCPUSubtype()); 144bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 1455510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(MachO::MH_OBJECT); 146bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumLoadCommands); 147bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(LoadCommandsSize); 148bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(Flags); 149bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (is64Bit()) 150bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // reserved 151bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 152bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert(OS.tell() - Start == 1535510728d28bb1ee04abc32da3d21b7df12948053Charles Davis (is64Bit()?sizeof(MachO::mach_header_64): sizeof(MachO::mach_header))); 154bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 155bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 156bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// WriteSegmentLoadCommand - Write a segment load command. 157bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// 158c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \param NumSections The number of sections in this segment. 159c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \param SectionDataSize The total size of the sections. 160bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteSegmentLoadCommand(unsigned NumSections, 161bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t VMSize, 162bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t SectionDataStartOffset, 163bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t SectionDataSize) { 164bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct segment_command (56 bytes) or 165bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct segment_command_64 (72 bytes) 166bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 167bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Start = OS.tell(); 168bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling (void) Start; 169bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 170bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned SegmentLoadCommandSize = 1715510728d28bb1ee04abc32da3d21b7df12948053Charles Davis is64Bit() ? sizeof(MachO::segment_command_64): 1725510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::segment_command); 1735510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(is64Bit() ? MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT); 174bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(SegmentLoadCommandSize + 1755510728d28bb1ee04abc32da3d21b7df12948053Charles Davis NumSections * (is64Bit() ? sizeof(MachO::section_64) : 1765510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::section))); 177bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 178bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteBytes("", 16); 179bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (is64Bit()) { 180bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write64(0); // vmaddr 181bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write64(VMSize); // vmsize 182bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write64(SectionDataStartOffset); // file offset 183bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write64(SectionDataSize); // file size 184bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } else { 185bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // vmaddr 186bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(VMSize); // vmsize 187bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(SectionDataStartOffset); // file offset 188bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(SectionDataSize); // file size 189f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng } 190a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik // maxprot 191a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik Write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE); 192a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik // initprot 193a38c27be0ff5dd35fcd20cfce827f9dbdb24d1eaNick Kledzik Write32(MachO::VM_PROT_READ | MachO::VM_PROT_WRITE | MachO::VM_PROT_EXECUTE); 194bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumSections); 195bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // flags 196f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 197bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert(OS.tell() - Start == SegmentLoadCommandSize); 198bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 1993c3849297bd9b4aedbac52417061e1da779cc412Jim Grosbach 200bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteSection(const MCAssembler &Asm, 201bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCAsmLayout &Layout, 202bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionData &SD, 203bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t FileOffset, 204bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t RelocationsStart, 205bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumRelocations) { 206bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t SectionSize = Layout.getSectionAddressSize(&SD); 207bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 208bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The offset is unused for virtual sections. 209bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (SD.getSection().isVirtualSection()) { 210bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!"); 211bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling FileOffset = 0; 212c9ada472c87d262713b0d2df0a225e867533586cEric Christopher } 2133c3849297bd9b4aedbac52417061e1da779cc412Jim Grosbach 214bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct section (68 bytes) or 215bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct section_64 (80 bytes) 216bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 217bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Start = OS.tell(); 218bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling (void) Start; 219bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 220bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection()); 221bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteBytes(Section.getSectionName(), 16); 222bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteBytes(Section.getSegmentName(), 16); 223bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (is64Bit()) { 224bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write64(getSectionAddress(&SD)); // address 225bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write64(SectionSize); // size 226bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } else { 227bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(getSectionAddress(&SD)); // address 228bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(SectionSize); // size 229bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 230bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(FileOffset); 231bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 232bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned Flags = Section.getTypeAndAttributes(); 233bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (SD.hasInstructions()) 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Flags |= MachO::S_ATTR_SOME_INSTRUCTIONS; 235bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 236bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); 237bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(Log2_32(SD.getAlignment())); 238bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumRelocations ? RelocationsStart : 0); 239bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumRelocations); 240bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(Flags); 241bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(IndirectSymBase.lookup(&SD)); // reserved1 242bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(Section.getStubSize()); // reserved2 243bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (is64Bit()) 244bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // reserved3 245bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 2465510728d28bb1ee04abc32da3d21b7df12948053Charles Davis assert(OS.tell() - Start == (is64Bit() ? sizeof(MachO::section_64) : 2475510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::section))); 248bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 2493664564395ede7681fac8888a213ce3bf947bbb3Daniel Dunbar 250bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteSymtabLoadCommand(uint32_t SymbolOffset, 251bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t NumSymbols, 252bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t StringTableOffset, 253bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t StringTableSize) { 254bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct symtab_command (24 bytes) 255294e67861c9a497f4b7529a410d8817d36354d5aDaniel Dunbar 256bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Start = OS.tell(); 257bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling (void) Start; 2583664564395ede7681fac8888a213ce3bf947bbb3Daniel Dunbar 2595510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(MachO::LC_SYMTAB); 2605510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(sizeof(MachO::symtab_command)); 261bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(SymbolOffset); 262bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumSymbols); 263bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(StringTableOffset); 264bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(StringTableSize); 2654010dd72b81b760daaa0361084de6dca8ed86fa1Daniel Dunbar 2665510728d28bb1ee04abc32da3d21b7df12948053Charles Davis assert(OS.tell() - Start == sizeof(MachO::symtab_command)); 267bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 268f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 269bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, 270bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t NumLocalSymbols, 271bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t FirstExternalSymbol, 272bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t NumExternalSymbols, 273bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t FirstUndefinedSymbol, 274bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t NumUndefinedSymbols, 275bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t IndirectSymbolOffset, 276bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint32_t NumIndirectSymbols) { 277bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct dysymtab_command (80 bytes) 278bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 279bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Start = OS.tell(); 280bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling (void) Start; 281bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 2825510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(MachO::LC_DYSYMTAB); 2835510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(sizeof(MachO::dysymtab_command)); 284bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(FirstLocalSymbol); 285bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumLocalSymbols); 286bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(FirstExternalSymbol); 287bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumExternalSymbols); 288bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(FirstUndefinedSymbol); 289bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumUndefinedSymbols); 290bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // tocoff 291bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // ntoc 292bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // modtaboff 293bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // nmodtab 294bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // extrefsymoff 295bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // nextrefsyms 296bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(IndirectSymbolOffset); 297bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(NumIndirectSymbols); 298bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // extreloff 299bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // nextrel 300bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // locreloff 301bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(0); // nlocrel 302bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 3035510728d28bb1ee04abc32da3d21b7df12948053Charles Davis assert(OS.tell() - Start == sizeof(MachO::dysymtab_command)); 304bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 305f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng 306cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMachObjectWriter::MachSymbolData * 307cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMachObjectWriter::findSymbolData(const MCSymbol &Sym) { 308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto &Entry : LocalSymbolData) 309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (&Entry.SymbolData->getSymbol() == &Sym) 310cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return &Entry; 311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto &Entry : ExternalSymbolData) 313cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (&Entry.SymbolData->getSymbol() == &Sym) 314cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return &Entry; 315cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 316cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (auto &Entry : UndefinedSymbolData) 317cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (&Entry.SymbolData->getSymbol() == &Sym) 318cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return &Entry; 319cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 320cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return nullptr; 321cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 322cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 3233f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingvoid MachObjectWriter::WriteNlist(MachSymbolData &MSD, 3243f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling const MCAsmLayout &Layout) { 325bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MCSymbolData &Data = *MSD.SymbolData; 326cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCSymbol *Symbol = &Data.getSymbol(); 327cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCSymbol *AliasedSymbol = &Symbol->AliasedSymbol(); 328cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint8_t SectionIndex = MSD.SectionIndex; 329bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint8_t Type = 0; 330bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint16_t Flags = Data.getFlags(); 331739b5576adbf991cdcc49df61c1a3de3d63747f6Jim Grosbach uint64_t Address = 0; 332cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool IsAlias = Symbol != AliasedSymbol; 333cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 334cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MachSymbolData *AliaseeInfo; 335cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (IsAlias) { 336cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines AliaseeInfo = findSymbolData(*AliasedSymbol); 337cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (AliaseeInfo) 338cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SectionIndex = AliaseeInfo->SectionIndex; 339cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Symbol = AliasedSymbol; 340cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 341bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 342bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Set the N_TYPE bits. See <mach-o/nlist.h>. 343bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // 344bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // FIXME: Are the prebound or indirect fields possible here? 345cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (IsAlias && Symbol->isUndefined()) 346cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Type = MachO::N_INDR; 347cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (Symbol->isUndefined()) 3485510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Type = MachO::N_UNDF; 349cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (Symbol->isAbsolute()) 3505510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Type = MachO::N_ABS; 351bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling else 3525510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Type = MachO::N_SECT; 353bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 354bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // FIXME: Set STAB bits. 355bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 356bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Data.isPrivateExtern()) 3575510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Type |= MachO::N_PEXT; 358bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 359bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Set external bit. 360cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Data.isExternal() || (!IsAlias && Symbol->isUndefined())) 3615510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Type |= MachO::N_EXT; 362bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 363bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Compute the symbol address. 364cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (IsAlias && Symbol->isUndefined()) 365cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Address = AliaseeInfo->StringIndex; 366cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (Symbol->isDefined()) 36745d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach Address = getSymbolAddress(&Data, Layout); 368cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else if (Data.isCommon()) { 369bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Common symbols are encoded with the size in the address 370bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // field, and their alignment in the flags. 371bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Address = Data.getCommonSize(); 372bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 373bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Common alignment is packed into the 'desc' bits. 374bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (unsigned Align = Data.getCommonAlignment()) { 375bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned Log2Size = Log2_32(Align); 376bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); 377bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Log2Size > 15) 378bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling report_fatal_error("invalid 'common' alignment '" + 379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Twine(Align) + "' for '" + Symbol->getName() + "'", 380a26f4283826894ac00665f9d24fa99cacc5192abJim Grosbach false); 381bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // FIXME: Keep this mask with the SymbolFlags enumeration. 382bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Flags = (Flags & 0xF0FF) | (Log2Size << 8); 383294e67861c9a497f4b7529a410d8817d36354d5aDaniel Dunbar } 384bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 3854d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar 386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Layout.getAssembler().isThumbFunc(Symbol)) 387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Flags |= SF_ThumbFunc; 388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 389bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // struct nlist (12 bytes) 3904d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar 391bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(MSD.StringIndex); 392bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write8(Type); 393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Write8(SectionIndex); 3944d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar 395bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' 396bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // value. 397bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write16(Flags); 398bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (is64Bit()) 399bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write64(Address); 400bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling else 401bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(Address); 402bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 4034d74305a1f55f458d401a79db4deeed726567195Daniel Dunbar 4043e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbachvoid MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type, 4053e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach uint32_t DataOffset, 4063e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach uint32_t DataSize) { 4073e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach uint64_t Start = OS.tell(); 4083e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach (void) Start; 4093e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 4103e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach Write32(Type); 4115510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(sizeof(MachO::linkedit_data_command)); 4123e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach Write32(DataOffset); 4133e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach Write32(DataSize); 4143e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 4155510728d28bb1ee04abc32da3d21b7df12948053Charles Davis assert(OS.tell() - Start == sizeof(MachO::linkedit_data_command)); 4163e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach} 4173e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 418a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbarstatic unsigned ComputeLinkerOptionsLoadCommandSize( 419849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar const std::vector<std::string> &Options, bool is64Bit) 420a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar{ 4215510728d28bb1ee04abc32da3d21b7df12948053Charles Davis unsigned Size = sizeof(MachO::linker_options_command); 422a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar for (unsigned i = 0, e = Options.size(); i != e; ++i) 423a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar Size += Options[i].size() + 1; 424849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar return RoundUpToAlignment(Size, is64Bit ? 8 : 4); 425a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar} 426a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 427a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbarvoid MachObjectWriter::WriteLinkerOptionsLoadCommand( 428a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar const std::vector<std::string> &Options) 429a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar{ 430849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit()); 431a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar uint64_t Start = OS.tell(); 432a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar (void) Start; 433a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 4345510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(MachO::LC_LINKER_OPTIONS); 435a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar Write32(Size); 436a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar Write32(Options.size()); 4375510728d28bb1ee04abc32da3d21b7df12948053Charles Davis uint64_t BytesWritten = sizeof(MachO::linker_options_command); 438a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar for (unsigned i = 0, e = Options.size(); i != e; ++i) { 439a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar // Write each string, including the null byte. 440a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar const std::string &Option = Options[i]; 441a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar WriteBytes(Option.c_str(), Option.size() + 1); 442a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar BytesWritten += Option.size() + 1; 443a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar } 444a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 445849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar // Pad to a multiple of the pointer size. 446849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar WriteBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4)); 447a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 448a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar assert(OS.tell() - Start == Size); 449a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar} 450a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 4513e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 452bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::RecordRelocation(const MCAssembler &Asm, 453bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCAsmLayout &Layout, 454bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCFragment *Fragment, 455bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCFixup &Fixup, 456bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MCValue Target, 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool &IsPCRel, 458bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t &FixedValue) { 459ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach TargetObjectWriter->RecordRelocation(this, Asm, Layout, Fragment, Fixup, 460ba8297ec08cdf7ae0c1e0c18ce07922e1f822643Jim Grosbach Target, FixedValue); 461bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 46232c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cacDaniel Dunbar 463bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { 464bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // This is the point where 'as' creates actual symbols for indirect symbols 465bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // (in the following two passes). It would be easier for us to do this sooner 466bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // when we see the attribute, but that makes getting the order in the symbol 467bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // table much more complicated than it is worth. 468bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // 469bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // FIXME: Revisit this when the dust settles. 47032c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cacDaniel Dunbar 4714f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby // Report errors for use of .indirect_symbol not in a symbol pointer section 4724f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby // or stub section. 4734f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 4744f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby ie = Asm.indirect_symbol_end(); it != ie; ++it) { 4754f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby const MCSectionMachO &Section = 4764f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby cast<MCSectionMachO>(it->SectionData->getSection()); 4774f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby 47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS && 47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS && 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Section.getType() != MachO::S_SYMBOL_STUBS) { 4814f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby MCSymbol &Symbol = *it->Symbol; 4824f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby report_fatal_error("indirect symbol '" + Symbol.getName() + 4834f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby "' not in a symbol pointer or stub section"); 4844f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby } 4854f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby } 4864f066b6db8a7a95b206725aecf99a64fd6e9415cKevin Enderby 48736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Bind non-lazy symbol pointers first. 488bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned IndirectIndex = 0; 489bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 490bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { 491bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionMachO &Section = 492bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling cast<MCSectionMachO>(it->SectionData->getSection()); 49332c1c5ae5f2bbf0c13bb1aed71384b86ee6b7cacDaniel Dunbar 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS) 495bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 496bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 497bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Initialize the section indirect symbol base, if necessary. 49805d96f98cbd96dab7f4ea1ea4ebe4285597e7e88Benjamin Kramer IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); 499bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 500bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Asm.getOrCreateSymbolData(*it->Symbol); 5011f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar } 5021f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar 503bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Then lazy symbol pointers and symbol stubs. 504bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling IndirectIndex = 0; 505bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 506bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.indirect_symbol_end(); it != ie; ++it, ++IndirectIndex) { 507bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionMachO &Section = 508bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling cast<MCSectionMachO>(it->SectionData->getSection()); 5092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS && 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Section.getType() != MachO::S_SYMBOL_STUBS) 512bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 513bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 514bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Initialize the section indirect symbol base, if necessary. 51505d96f98cbd96dab7f4ea1ea4ebe4285597e7e88Benjamin Kramer IndirectSymBase.insert(std::make_pair(it->SectionData, IndirectIndex)); 5162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 517bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Set the symbol type to undefined lazy, but only on construction. 5182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 519bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // FIXME: Do not hardcode. 520bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling bool Created; 521bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created); 522bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Created) 523bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Entry.setFlags(Entry.getFlags() | 0x0001); 524bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 525bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 526bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 527bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// ComputeSymbolTable - Compute the symbol table data 528bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// 529bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// \param StringTable [out] - The string table data. 530bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// \param StringIndexMap [out] - Map from symbol names to offsets in the 531bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling/// string table. 5323f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingvoid MachObjectWriter:: 5333f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill WendlingComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, 5343f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling std::vector<MachSymbolData> &LocalSymbolData, 5353f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling std::vector<MachSymbolData> &ExternalSymbolData, 5363f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling std::vector<MachSymbolData> &UndefinedSymbolData) { 537bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Build section lookup table. 538bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling DenseMap<const MCSection*, uint8_t> SectionIndexMap; 539bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned Index = 1; 540bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::iterator it = Asm.begin(), 541bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.end(); it != ie; ++it, ++Index) 542bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling SectionIndexMap[&it->getSection()] = Index; 543bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert(Index <= 256 && "Too many sections!"); 544bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 545bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Index 0 is always the empty string. 546bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringMap<uint64_t> StringIndexMap; 547bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringTable += '\x00'; 548bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 549bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Build the symbol arrays and the string table, but only for non-local 550bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // symbols. 551bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // 552bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The particular order that we collect the symbols and create the string 553bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // table, then sort the symbols is chosen to match 'as'. Even though it 554bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // doesn't matter for correctness, this is important for letting us diff .o 555bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // files. 556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (MCSymbolData &SD : Asm.symbols()) { 557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbol &Symbol = SD.getSymbol(); 558bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 559bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Ignore non-linker visible symbols. 560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Asm.isSymbolLinkerVisible(SD.getSymbol())) 561bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 562bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!SD.isExternal() && !Symbol.isUndefined()) 564bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 565bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 566bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t &Entry = StringIndexMap[Symbol.getName()]; 567bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (!Entry) { 568bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Entry = StringTable.size(); 569bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringTable += Symbol.getName(); 570bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringTable += '\x00'; 5712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 5722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 573bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MachSymbolData MSD; 574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MSD.SymbolData = &SD; 575bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MSD.StringIndex = Entry; 576bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 577bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Symbol.isUndefined()) { 578bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MSD.SectionIndex = 0; 579bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling UndefinedSymbolData.push_back(MSD); 580bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } else if (Symbol.isAbsolute()) { 581bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MSD.SectionIndex = 0; 582bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ExternalSymbolData.push_back(MSD); 583bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } else { 584bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 585bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert(MSD.SectionIndex && "Invalid section index!"); 586bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ExternalSymbolData.push_back(MSD); 5872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 588bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 589bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 590bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Now add the data for local symbols. 591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (MCSymbolData &SD : Asm.symbols()) { 592dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbol &Symbol = SD.getSymbol(); 593bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 594bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Ignore non-linker visible symbols. 595dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Asm.isSymbolLinkerVisible(SD.getSymbol())) 596bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 5972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 598dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (SD.isExternal() || Symbol.isUndefined()) 599bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 6002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 601bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t &Entry = StringIndexMap[Symbol.getName()]; 602bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (!Entry) { 603bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Entry = StringTable.size(); 604bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringTable += Symbol.getName(); 605bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringTable += '\x00'; 60685f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola } 60785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola 608bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MachSymbolData MSD; 609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MSD.SymbolData = &SD; 610bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MSD.StringIndex = Entry; 611bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 612bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (Symbol.isAbsolute()) { 613bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MSD.SectionIndex = 0; 614bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling LocalSymbolData.push_back(MSD); 615bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } else { 616bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 617bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling assert(MSD.SectionIndex && "Invalid section index!"); 618bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling LocalSymbolData.push_back(MSD); 6192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 620bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 6212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 622bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // External and undefined symbols are required to be in lexicographic order. 623bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 624bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 625bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 626bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Set the symbol indices. 627bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Index = 0; 628bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 629bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling LocalSymbolData[i].SymbolData->setIndex(Index++); 630bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 631bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ExternalSymbolData[i].SymbolData->setIndex(Index++); 632bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 633bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling UndefinedSymbolData[i].SymbolData->setIndex(Index++); 634bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 635bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The string table is padded to a multiple of 4. 636bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling while (StringTable.size() % 4) 637bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringTable += '\x00'; 638bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 6392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 640bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendlingvoid MachObjectWriter::computeSectionAddresses(const MCAssembler &Asm, 641bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCAsmLayout &Layout) { 642bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t StartAddress = 0; 643bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const SmallVectorImpl<MCSectionData*> &Order = Layout.getSectionOrder(); 644bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (int i = 0, n = Order.size(); i != n ; ++i) { 645bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionData *SD = Order[i]; 646bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment()); 647bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling SectionAddress[SD] = StartAddress; 648bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StartAddress += Layout.getSectionAddressSize(SD); 649bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 650bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Explicitly pad the section to match the alignment requirements of the 651bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // following one. This is for 'gas' compatibility, it shouldn't 652bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling /// strictly be necessary. 653bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StartAddress += getPaddingSize(SD, Layout); 654bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 655bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 6562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 65745d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbachvoid MachObjectWriter::markAbsoluteVariableSymbols(MCAssembler &Asm, 65845d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach const MCAsmLayout &Layout) { 659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (MCSymbolData &SD : Asm.symbols()) { 66045d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach if (!SD.getSymbol().isVariable()) 66145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach continue; 66245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach 66345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach // Is the variable is a symbol difference (SA - SB + C) expression, 66445d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach // and neither symbol is external, mark the variable as absolute. 66545d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach const MCExpr *Expr = SD.getSymbol().getVariableValue(); 66645d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach MCValue Value; 66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Expr->EvaluateAsRelocatable(Value, &Layout)) { 66845d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach if (Value.getSymA() && Value.getSymB()) 66945d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach const_cast<MCSymbol*>(&SD.getSymbol())->setAbsolute(); 67045d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach } 67145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach } 67245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach} 67345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach 6743f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingvoid MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 6753f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling const MCAsmLayout &Layout) { 676bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling computeSectionAddresses(Asm, Layout); 6772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 678bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Create symbol data for any indirect symbols. 679bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling BindIndirectSymbols(Asm); 6802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 68145d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach // Mark symbol difference expressions in variables (from .set or = directives) 68245d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach // as absolute. 68345d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach markAbsoluteVariableSymbols(Asm, Layout); 68445d81bdde87a38c21facf2ec3b82b0589e9de7e9Jim Grosbach 685bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Compute symbol table information and bind symbol indices. 686bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, 687bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling UndefinedSymbolData); 688bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 689bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 6903f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendlingbool MachObjectWriter:: 6913f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill WendlingIsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 6923f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling const MCSymbolData &DataA, 6933f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling const MCFragment &FB, 6943f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling bool InSet, 6953f2ea825bdf8cbe002ac542a5bdd775bd30470c9Bill Wendling bool IsPCRel) const { 696bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (InSet) 697bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return true; 698bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 699bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The effective address is 700bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // addr(atom(A)) + offset(A) 701bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // - addr(atom(B)) - offset(B) 702bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // and the offsets are not relocatable, so the fixup is fully resolved when 703bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // addr(atom(A)) - addr(atom(B)) == 0. 704dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbolData *A_Base = nullptr, *B_Base = nullptr; 705bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 706bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSymbol &SA = DataA.getSymbol().AliasedSymbol(); 707bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSection &SecA = SA.getSection(); 708bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSection &SecB = FB.getParent()->getSection(); 709bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 710bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (IsPCRel) { 711bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The simple (Darwin, except on x86_64) way of dealing with this was to 712bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // assume that any reference to a temporary symbol *must* be a temporary 713bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // symbol in the same atom, unless the sections differ. Therefore, any PCrel 714bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // relocation to a temporary symbol (in the same section) is fully 715bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // resolved. This also works in conjunction with absolutized .set, which 716bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // requires the compiler to use .set to absolutize the differences between 717bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // symbols which the compiler knows to be assembly time constants, so we 718bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // don't need to worry about considering symbol differences fully resolved. 719577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach // 720577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach // If the file isn't using sub-sections-via-symbols, we can make the 721577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach // same assumptions about any symbol that we normally make about 722577b09155f9a6fa38e5a7918da9701e120b3642fJim Grosbach // assembler locals. 723bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool hasReliableSymbolDifference = isX86_64(); 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!hasReliableSymbolDifference) { 7268b9300b972745a6d89b482cbcd4206c01359f7dfJim Grosbach if (!SA.isInSection() || &SecA != &SecB || 727ec4ceb797a963b2d24b02d40fad6cc456fac3e5bJim Grosbach (!SA.isTemporary() && 728c389af94b66d0c5a917f81617bd07ff0864790a0Jim Grosbach FB.getAtom() != Asm.getSymbolData(SA).getFragment()->getAtom() && 729c389af94b66d0c5a917f81617bd07ff0864790a0Jim Grosbach Asm.getSubsectionsViaSymbols())) 730bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return false; 731bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return true; 7322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 7335afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby // For Darwin x86_64, there is one special case when the reference IsPCRel. 7345afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby // If the fragment with the reference does not have a base symbol but meets 7355afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby // the simple way of dealing with this, in that it is a temporary symbol in 7365afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby // the same atom then it is assumed to be fully resolved. This is needed so 737d1e002a0a3c1c38bae064f3f3cc22b1653d47659Eric Christopher // a relocation entry is not created and so the static linker does not 7385afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby // mess up the reference later. 7395afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby else if(!FB.getAtom() && 7405afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby SA.isTemporary() && SA.isInSection() && &SecA == &SecB){ 7415afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby return true; 7425afc19002e7a6b949619a5073d8c746985e8d6f2Kevin Enderby } 743bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } else { 744bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (!TargetObjectWriter->useAggressiveSymbolFolding()) 745bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return false; 746bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 747bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 7480d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer const MCFragment *FA = Asm.getSymbolData(SA).getFragment(); 749bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 7500d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer // Bail if the symbol has no fragment. 7510d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer if (!FA) 7520d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer return false; 7530d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer 7540d46ccfc5c2f5d0894e340907f6e58067cce5b03Benjamin Kramer A_Base = FA->getAtom(); 755bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (!A_Base) 756bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return false; 757bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 758bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling B_Base = FB.getAtom(); 759bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (!B_Base) 760bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return false; 761bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 762bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // If the atoms are the same, they are guaranteed to have the same address. 763bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (A_Base == B_Base) 764bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return true; 765bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 766bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Otherwise, we can't prove this is fully resolved. 767bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling return false; 768bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling} 769bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 770d1e002a0a3c1c38bae064f3f3cc22b1653d47659Eric Christophervoid MachObjectWriter::WriteObject(MCAssembler &Asm, 771f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach const MCAsmLayout &Layout) { 772bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumSections = Asm.size(); 77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCAssembler::VersionMinInfoType &VersionInfo = 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Layout.getAssembler().getVersionMinInfo(); 775bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 776bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The section data starts after the header, the segment load command (and 777bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // section headers) and the symbol table. 778bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumLoadCommands = 1; 779bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t LoadCommandsSize = is64Bit() ? 7805510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::segment_command_64) + NumSections * sizeof(MachO::section_64): 7815510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::segment_command) + NumSections * sizeof(MachO::section); 782bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Add the deployment target version info load command size, if used. 78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (VersionInfo.Major != 0) { 78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++NumLoadCommands; 78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LoadCommandsSize += sizeof(MachO::version_min_command); 78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 789a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar // Add the data-in-code load command size, if used. 790a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar unsigned NumDataRegions = Asm.getDataRegions().size(); 791a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar if (NumDataRegions) { 792a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar ++NumLoadCommands; 7935510728d28bb1ee04abc32da3d21b7df12948053Charles Davis LoadCommandsSize += sizeof(MachO::linkedit_data_command); 794a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar } 795a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Add the loh load command size, if used. 79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout); 79836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4); 79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LOHSize) { 80036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++NumLoadCommands; 80136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LoadCommandsSize += sizeof(MachO::linkedit_data_command); 80236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 804bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Add the symbol table load command sizes, if used. 805bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() + 806bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling UndefinedSymbolData.size(); 807bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (NumSymbols) { 808bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling NumLoadCommands += 2; 8095510728d28bb1ee04abc32da3d21b7df12948053Charles Davis LoadCommandsSize += (sizeof(MachO::symtab_command) + 8105510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::dysymtab_command)); 8112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 813a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar // Add the linker option load commands sizes. 814a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar const std::vector<std::vector<std::string> > &LinkerOptions = 815a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar Asm.getLinkerOptions(); 816a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) { 8173e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach ++NumLoadCommands; 818849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(LinkerOptions[i], 819849209686f778e5d6fce675bea9a8300aa596d25Daniel Dunbar is64Bit()); 8203e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 821a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 822bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Compute the total size of the section data, as well as its file size and vm 823bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // size. 8245510728d28bb1ee04abc32da3d21b7df12948053Charles Davis uint64_t SectionDataStart = (is64Bit() ? sizeof(MachO::mach_header_64) : 8255510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::mach_header)) + LoadCommandsSize; 826bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t SectionDataSize = 0; 827bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t SectionDataFileSize = 0; 828bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t VMSize = 0; 829bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::const_iterator it = Asm.begin(), 830bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.end(); it != ie; ++it) { 831bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionData &SD = *it; 832bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Address = getSectionAddress(&SD); 833bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Size = Layout.getSectionAddressSize(&SD); 834bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t FileSize = Layout.getSectionFileSize(&SD); 835bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling FileSize += getPaddingSize(&SD, Layout); 836bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 837bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling VMSize = std::max(VMSize, Address + Size); 838bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 839bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (SD.getSection().isVirtualSection()) 840bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 841bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 842bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling SectionDataSize = std::max(SectionDataSize, Address + Size); 843bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling SectionDataFileSize = std::max(SectionDataFileSize, Address + FileSize); 844bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 845bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 846bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The section data is padded to 4 bytes. 847bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // 848bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // FIXME: Is this machine dependent? 849bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); 850bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling SectionDataFileSize += SectionDataPadding; 851bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 852bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the prolog, starting with the header and load command... 853bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteHeader(NumLoadCommands, LoadCommandsSize, 854bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Asm.getSubsectionsViaSymbols()); 855bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteSegmentLoadCommand(NumSections, VMSize, 856bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling SectionDataStart, SectionDataSize); 857bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 858bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // ... and then the section headers. 859bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; 860bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::const_iterator it = Asm.begin(), 861bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.end(); it != ie; ++it) { 8625510728d28bb1ee04abc32da3d21b7df12948053Charles Davis std::vector<MachO::any_relocation_info> &Relocs = Relocations[it]; 863bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumRelocs = Relocs.size(); 864bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t SectionStart = SectionDataStart + getSectionAddress(it); 865bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteSection(Asm, Layout, *it, SectionStart, RelocTableEnd, NumRelocs); 8665510728d28bb1ee04abc32da3d21b7df12948053Charles Davis RelocTableEnd += NumRelocs * sizeof(MachO::any_relocation_info); 867bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 868bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Write out the deployment target information, if it's available. 87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (VersionInfo.Major != 0) { 87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(VersionInfo.Update < 256 && "unencodable update target version"); 87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(VersionInfo.Minor < 256 && "unencodable minor target version"); 87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(VersionInfo.Major < 65536 && "unencodable major target version"); 87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) | 87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (VersionInfo.Major << 16); 87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Write32(VersionInfo.Kind == MCVM_OSXVersionMin ? MachO::LC_VERSION_MIN_MACOSX : 87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachO::LC_VERSION_MIN_IPHONEOS); 87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Write32(sizeof(MachO::version_min_command)); 87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Write32(EncodedVersion); 88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Write32(0); // reserved. 88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8833e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // Write the data-in-code load command, if used. 8843e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach uint64_t DataInCodeTableEnd = RelocTableEnd + NumDataRegions * 8; 8853e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach if (NumDataRegions) { 8863e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach uint64_t DataRegionsOffset = RelocTableEnd; 8873e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach uint64_t DataRegionsSize = NumDataRegions * 8; 8885510728d28bb1ee04abc32da3d21b7df12948053Charles Davis WriteLinkeditLoadCommand(MachO::LC_DATA_IN_CODE, DataRegionsOffset, 8893e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach DataRegionsSize); 8903e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 8913e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Write the loh load command, if used. 89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize; 89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LOHSize) 89536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines WriteLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT, 89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataInCodeTableEnd, LOHSize); 89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 898bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the symbol table load command, if used. 899bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (NumSymbols) { 900bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned FirstLocalSymbol = 0; 901bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumLocalSymbols = LocalSymbolData.size(); 902bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; 903bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumExternalSymbols = ExternalSymbolData.size(); 904bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; 905bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); 906bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); 907bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling unsigned NumSymTabSymbols = 908bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; 909bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; 910bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t IndirectSymbolOffset = 0; 911bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 912bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // If used, the indirect symbols are written after the section data. 913bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (NumIndirectSymbols) 91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IndirectSymbolOffset = LOHTableEnd; 915bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 916bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The symbol table is written after the indirect symbol data. 91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize; 918bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 919bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // The string table is written after symbol table. 920bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t StringTableOffset = 9215510728d28bb1ee04abc32da3d21b7df12948053Charles Davis SymbolTableOffset + NumSymTabSymbols * (is64Bit() ? 9225510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::nlist_64) : 9235510728d28bb1ee04abc32da3d21b7df12948053Charles Davis sizeof(MachO::nlist)); 924bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, 925bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling StringTableOffset, StringTable.size()); 926bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 927bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, 928bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling FirstExternalSymbol, NumExternalSymbols, 929bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling FirstUndefinedSymbol, NumUndefinedSymbols, 930bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling IndirectSymbolOffset, NumIndirectSymbols); 931bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 932bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 933a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar // Write the linker options load commands. 934a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) { 935a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar WriteLinkerOptionsLoadCommand(LinkerOptions[i]); 936a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar } 937a94c33942373cb504b6e64c95415165907a89d34Daniel Dunbar 938bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the actual section data. 939bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::const_iterator it = Asm.begin(), 940bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.end(); it != ie; ++it) { 941f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach Asm.writeSectionData(it, Layout); 942bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 943bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling uint64_t Pad = getPaddingSize(it, Layout); 944bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned int i = 0; i < Pad; ++i) 945bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write8(0); 946bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 947bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 948bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the extra padding. 949bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteZeros(SectionDataPadding); 950bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 951bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the relocation entries. 952bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::const_iterator it = Asm.begin(), 953bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.end(); it != ie; ++it) { 954bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the section relocation entries, in reverse order to match 'as' 955bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // (approximately, the exact algorithm is more complicated than this). 9565510728d28bb1ee04abc32da3d21b7df12948053Charles Davis std::vector<MachO::any_relocation_info> &Relocs = Relocations[it]; 957bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 9585510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(Relocs[e - i - 1].r_word0); 9595510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Write32(Relocs[e - i - 1].r_word1); 960bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 961bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 962bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 9633e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach // Write out the data-in-code region payload, if there is one. 9643e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach for (MCAssembler::const_data_region_iterator 9653e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach it = Asm.data_region_begin(), ie = Asm.data_region_end(); 9663e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach it != ie; ++it) { 9673e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach const DataRegionData *Data = &(*it); 968e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach uint64_t Start = 969e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->Start), 970e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach Layout); 971e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach uint64_t End = 972e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach getSymbolAddress(&Layout.getAssembler().getSymbolData(*Data->End), 973e75a98320e5d0dff0fc29d2aa39d4c70f70b9da8Jim Grosbach Layout); 9743e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach DEBUG(dbgs() << "data in code region-- kind: " << Data->Kind 9753e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach << " start: " << Start << "(" << Data->Start->getName() << ")" 9763e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach << " end: " << End << "(" << Data->End->getName() << ")" 9773e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach << " size: " << End - Start 9783e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach << "\n"); 9793e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach Write32(Start); 9803e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach Write16(End - Start); 9813e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach Write16(Data->Kind); 9823e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach } 9833e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach 98436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Write out the loh commands, if there is one. 98536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LOHSize) { 98636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef NDEBUG 98736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Start = OS.tell(); 98836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif 98936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Asm.getLOHContainer().Emit(*this, Layout); 99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Pad to a multiple of the pointer size. 99136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines WriteBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4)); 99236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(OS.tell() - Start == LOHSize); 99336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 99436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 995bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the symbol table data, if used. 996bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (NumSymbols) { 997bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the indirect symbol entries. 998bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (MCAssembler::const_indirect_symbol_iterator 999bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling it = Asm.indirect_symbol_begin(), 1000bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling ie = Asm.indirect_symbol_end(); it != ie; ++it) { 100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Indirect symbols in the non-lazy symbol pointer section have some 1002bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // special handling. 1003bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling const MCSectionMachO &Section = 1004bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Section.getType() == MachO::S_NON_LAZY_SYMBOL_POINTERS) { 1006bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // If this symbol is defined and internal, mark it as such. 1007bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (it->Symbol->isDefined() && 1008bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling !Asm.getSymbolData(*it->Symbol).isExternal()) { 10095510728d28bb1ee04abc32da3d21b7df12948053Charles Davis uint32_t Flags = MachO::INDIRECT_SYMBOL_LOCAL; 1010bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling if (it->Symbol->isAbsolute()) 10115510728d28bb1ee04abc32da3d21b7df12948053Charles Davis Flags |= MachO::INDIRECT_SYMBOL_ABS; 1012bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(Flags); 1013bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling continue; 1014bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 1015bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 1016bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 1017bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling Write32(Asm.getSymbolData(*it->Symbol).getIndex()); 1018bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 1019bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 1020bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // FIXME: Check that offsets match computed ones. 1021bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 1022bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the symbol table entries. 1023bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 1024bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteNlist(LocalSymbolData[i], Layout); 1025bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 1026bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteNlist(ExternalSymbolData[i], Layout); 1027bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 1028bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling WriteNlist(UndefinedSymbolData[i], Layout); 1029bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling 1030bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling // Write the string table. 1031bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling OS << StringTable.str(); 1032bbdffa9ab0597b64689c51f2c4a87a781f3bf79dBill Wendling } 10332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 10342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1035ae5abd595f5442767313a4c8a24008ad19323cebDaniel DunbarMCObjectWriter *llvm::createMachObjectWriter(MCMachObjectTargetWriter *MOTW, 10365d05d9769ec98cdee359fd934a56c9455e21232bDaniel Dunbar raw_ostream &OS, 1037115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool IsLittleEndian) { 10385d05d9769ec98cdee359fd934a56c9455e21232bDaniel Dunbar return new MachObjectWriter(MOTW, OS, IsLittleEndian); 10392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 1040