MachObjectWriter.cpp revision 2df4ceba15c130005967ee9e5fb4aa5568de1b0c
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 102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MachObjectWriter.h" 112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/ADT/StringMap.h" 122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/ADT/Twine.h" 132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCAssembler.h" 142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCExpr.h" 152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCObjectWriter.h" 162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCSectionMachO.h" 172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCSymbol.h" 182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/MC/MCValue.h" 192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/Support/ErrorHandling.h" 202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/Support/MachO.h" 212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "llvm/Target/TargetAsmBackend.h" 222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar// FIXME: Gross. 242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include "../Target/X86/X86FixupKinds.h" 252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar#include <vector> 272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarusing namespace llvm; 282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarstatic unsigned getFixupKindLog2Size(unsigned Kind) { 302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar switch (Kind) { 312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar default: llvm_unreachable("invalid fixup kind!"); 322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case X86::reloc_pcrel_1byte: 332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case FK_Data_1: return 0; 342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case FK_Data_2: return 1; 352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case X86::reloc_pcrel_4byte: 362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case X86::reloc_riprel_4byte: 372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case FK_Data_4: return 2; 382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case FK_Data_8: return 3; 392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarstatic bool isFixupKindPCRel(unsigned Kind) { 432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar switch (Kind) { 442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar default: 452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar return false; 462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case X86::reloc_pcrel_1byte: 472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case X86::reloc_pcrel_4byte: 482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar case X86::reloc_riprel_4byte: 492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar return true; 502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarnamespace { 542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarclass MachObjectWriterImpl { 562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // See <mach-o/loader.h>. 572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum { 582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Header_Magic32 = 0xFEEDFACE, 592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Header_Magic64 = 0xFEEDFACF 602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum { 632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Header32Size = 28, 642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Header64Size = 32, 652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SegmentLoadCommand32Size = 56, 662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SegmentLoadCommand64Size = 72, 672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Section32Size = 68, 682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Section64Size = 80, 692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SymtabLoadCommandSize = 24, 702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar DysymtabLoadCommandSize = 80, 712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Nlist32Size = 12, 722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Nlist64Size = 16, 732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RelocationInfoSize = 8 742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum HeaderFileType { 772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar HFT_Object = 0x1 782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum HeaderFlags { 812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar HF_SubsectionsViaSymbols = 0x2000 822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum LoadCommandType { 852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LCT_Segment = 0x1, 862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LCT_Symtab = 0x2, 872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LCT_Dysymtab = 0xb, 882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LCT_Segment64 = 0x19 892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // See <mach-o/nlist.h>. 922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum SymbolTypeType { 932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar STT_Undefined = 0x00, 942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar STT_Absolute = 0x02, 952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar STT_Section = 0x0e 962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum SymbolTypeFlags { 992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // If any of these bits are set, then the entry is a stab entry number (see 1002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // <mach-o/stab.h>. Otherwise the other masks apply. 1012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar STF_StabsEntryMask = 0xe0, 1022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar STF_TypeMask = 0x0e, 1042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar STF_External = 0x01, 1052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar STF_PrivateExtern = 0x10 1062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 1072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// IndirectSymbolFlags - Flags for encoding special values in the indirect 1092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// symbol entry. 1102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum IndirectSymbolFlags { 1112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ISF_Local = 0x80000000, 1122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ISF_Absolute = 0x40000000 1132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 1142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// RelocationFlags - Special flags for addresses. 1162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum RelocationFlags { 1172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RF_Scattered = 0x80000000 1182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 1192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar enum RelocationInfoType { 1212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RIT_Vanilla = 0, 1222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RIT_Pair = 1, 1232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RIT_Difference = 2, 1242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RIT_PreboundLazyPointer = 3, 1252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RIT_LocalDifference = 4 1262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 1272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// MachSymbolData - Helper struct for containing some precomputed information 1292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// on symbols. 1302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar struct MachSymbolData { 1312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MCSymbolData *SymbolData; 1322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t StringIndex; 1332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint8_t SectionIndex; 1342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Support lexicographic sorting. 1362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar bool operator<(const MachSymbolData &RHS) const { 1372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const std::string &Name = SymbolData->getSymbol().getName(); 1382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar return Name < RHS.SymbolData->getSymbol().getName(); 1392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 1402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 1412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// @name Relocation Data 1432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// @{ 1442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar struct MachRelocationEntry { 1462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Word0; 1472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Word1; 1482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar }; 1492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar llvm::DenseMap<const MCSectionData*, 1512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachRelocationEntry> > Relocations; 1522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// @} 1542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// @name Symbol Table Data 1552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// @{ 1562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SmallString<256> StringTable; 1582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachSymbolData> LocalSymbolData; 1592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachSymbolData> ExternalSymbolData; 1602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachSymbolData> UndefinedSymbolData; 1612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// @} 1632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MachObjectWriter *Writer; 1652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar raw_ostream &OS; 1672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Is64Bit : 1; 1692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarpublic: 1712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MachObjectWriterImpl(MachObjectWriter *_Writer, bool _Is64Bit) 1722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar : Writer(_Writer), OS(Writer->getStream()), Is64Bit(_Is64Bit) { 1732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 1742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void Write8(uint8_t Value) { Writer->Write8(Value); } 1762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void Write16(uint16_t Value) { Writer->Write16(Value); } 1772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void Write32(uint32_t Value) { Writer->Write32(Value); } 1782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void Write64(uint64_t Value) { Writer->Write64(Value); } 1792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteZeros(unsigned N) { Writer->WriteZeros(N); } 1802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) { 1812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Writer->WriteBytes(Str, ZeroFillSize); 1822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 1832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize, 1852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar bool SubsectionsViaSymbols) { 1862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Flags = 0; 1872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (SubsectionsViaSymbols) 1892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Flags |= HF_SubsectionsViaSymbols; 1902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct mach_header (28 bytes) or 1922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct mach_header_64 (32 bytes) 1932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t Start = OS.tell(); 1952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (void) Start; 1962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Is64Bit ? Header_Magic64 : Header_Magic32); 1982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 1992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Support cputype. 2002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Is64Bit ? MachO::CPUTypeX86_64 : MachO::CPUTypeI386); 2012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Support cpusubtype. 2022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(MachO::CPUSubType_I386_ALL); 2032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(HFT_Object); 2042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumLoadCommands); // Object files have a single load command, the 2052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // segment. 2062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(LoadCommandsSize); 2072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Flags); 2082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Is64Bit) 2092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // reserved 2102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(OS.tell() - Start == Is64Bit ? Header64Size : Header32Size); 2122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 2132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// WriteSegmentLoadCommand - Write a segment load command. 2152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// 2162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// \arg NumSections - The number of sections in this segment. 2172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// \arg SectionDataSize - The total size of the sections. 2182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteSegmentLoadCommand(unsigned NumSections, 2192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t VMSize, 2202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t SectionDataStartOffset, 2212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t SectionDataSize) { 2222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct segment_command (56 bytes) or 2232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct segment_command_64 (72 bytes) 2242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t Start = OS.tell(); 2262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (void) Start; 2272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned SegmentLoadCommandSize = Is64Bit ? SegmentLoadCommand64Size : 2292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SegmentLoadCommand32Size; 2302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Is64Bit ? LCT_Segment64 : LCT_Segment); 2312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(SegmentLoadCommandSize + 2322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar NumSections * (Is64Bit ? Section64Size : Section32Size)); 2332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteBytes("", 16); 2352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Is64Bit) { 2362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write64(0); // vmaddr 2372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write64(VMSize); // vmsize 2382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write64(SectionDataStartOffset); // file offset 2392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write64(SectionDataSize); // file size 2402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else { 2412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // vmaddr 2422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(VMSize); // vmsize 2432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(SectionDataStartOffset); // file offset 2442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(SectionDataSize); // file size 2452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 2462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0x7); // maxprot 2472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0x7); // initprot 2482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumSections); 2492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // flags 2502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(OS.tell() - Start == SegmentLoadCommandSize); 2522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 2532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteSection(const MCAssembler &Asm, const MCSectionData &SD, 2552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t FileOffset, uint64_t RelocationsStart, 2562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumRelocations) { 2572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The offset is unused for virtual sections. 2582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Asm.getBackend().isVirtualSection(SD.getSection())) { 2592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(SD.getFileSize() == 0 && "Invalid file size!"); 2602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar FileOffset = 0; 2612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 2622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct section (68 bytes) or 2642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct section_64 (80 bytes) 2652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t Start = OS.tell(); 2672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (void) Start; 2682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: cast<> support! 2702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSectionMachO &Section = 2712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar static_cast<const MCSectionMachO&>(SD.getSection()); 2722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteBytes(Section.getSectionName(), 16); 2732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteBytes(Section.getSegmentName(), 16); 2742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Is64Bit) { 2752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write64(SD.getAddress()); // address 2762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write64(SD.getSize()); // size 2772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else { 2782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(SD.getAddress()); // address 2792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(SD.getSize()); // size 2802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 2812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(FileOffset); 2822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Flags = Section.getTypeAndAttributes(); 2842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (SD.hasInstructions()) 2852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; 2862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); 2882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Log2_32(SD.getAlignment())); 2892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumRelocations ? RelocationsStart : 0); 2902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumRelocations); 2912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Flags); 2922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // reserved1 2932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Section.getStubSize()); // reserved2 2942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Is64Bit) 2952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // reserved3 2962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 2972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(OS.tell() - Start == Is64Bit ? Section64Size : Section32Size); 2982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 2992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, 3012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t StringTableOffset, 3022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t StringTableSize) { 3032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct symtab_command (24 bytes) 3042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t Start = OS.tell(); 3062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (void) Start; 3072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(LCT_Symtab); 3092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(SymtabLoadCommandSize); 3102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(SymbolOffset); 3112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumSymbols); 3122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(StringTableOffset); 3132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(StringTableSize); 3142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(OS.tell() - Start == SymtabLoadCommandSize); 3162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 3172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol, 3192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t NumLocalSymbols, 3202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t FirstExternalSymbol, 3212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t NumExternalSymbols, 3222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t FirstUndefinedSymbol, 3232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t NumUndefinedSymbols, 3242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t IndirectSymbolOffset, 3252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t NumIndirectSymbols) { 3262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct dysymtab_command (80 bytes) 3272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t Start = OS.tell(); 3292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (void) Start; 3302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(LCT_Dysymtab); 3322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(DysymtabLoadCommandSize); 3332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(FirstLocalSymbol); 3342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumLocalSymbols); 3352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(FirstExternalSymbol); 3362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumExternalSymbols); 3372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(FirstUndefinedSymbol); 3382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumUndefinedSymbols); 3392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // tocoff 3402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // ntoc 3412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // modtaboff 3422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // nmodtab 3432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // extrefsymoff 3442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // nextrefsyms 3452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(IndirectSymbolOffset); 3462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(NumIndirectSymbols); 3472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // extreloff 3482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // nextrel 3492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // locreloff 3502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(0); // nlocrel 3512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(OS.tell() - Start == DysymtabLoadCommandSize); 3532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 3542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void WriteNlist(MachSymbolData &MSD) { 3562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MCSymbolData &Data = *MSD.SymbolData; 3572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSymbol &Symbol = Data.getSymbol(); 3582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint8_t Type = 0; 3592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint16_t Flags = Data.getFlags(); 3602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Address = 0; 3612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Set the N_TYPE bits. See <mach-o/nlist.h>. 3632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 3642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Are the prebound or indirect fields possible here? 3652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Symbol.isUndefined()) 3662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type = STT_Undefined; 3672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar else if (Symbol.isAbsolute()) 3682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type = STT_Absolute; 3692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar else 3702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type = STT_Section; 3712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Set STAB bits. 3732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Data.isPrivateExtern()) 3752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type |= STF_PrivateExtern; 3762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Set external bit. 3782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Data.isExternal() || Symbol.isUndefined()) 3792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type |= STF_External; 3802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Compute the symbol address. 3822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Symbol.isDefined()) { 3832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Symbol.isAbsolute()) { 3842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar llvm_unreachable("FIXME: Not yet implemented!"); 3852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else { 3862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Address = Data.getAddress(); 3872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 3882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else if (Data.isCommon()) { 3892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Common symbols are encoded with the size in the address 3902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // field, and their alignment in the flags. 3912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Address = Data.getCommonSize(); 3922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 3932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Common alignment is packed into the 'desc' bits. 3942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (unsigned Align = Data.getCommonAlignment()) { 3952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Log2Size = Log2_32(Align); 3962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); 3972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Log2Size > 15) 3982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar llvm_report_error("invalid 'common' alignment '" + 3992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Twine(Align) + "'"); 4002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Keep this mask with the SymbolFlags enumeration. 4012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Flags = (Flags & 0xF0FF) | (Log2Size << 8); 4022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 4032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 4042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct nlist (12 bytes) 4062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(MSD.StringIndex); 4082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write8(Type); 4092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write8(MSD.SectionIndex); 4102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The Mach-O streamer uses the lowest 16-bits of the flags for the 'desc' 4122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // value. 4132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write16(Flags); 4142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Is64Bit) 4152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write64(Address); 4162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar else 4172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Address); 4182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 4192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void RecordScatteredRelocation(const MCAssembler &Asm, 4212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCFragment &Fragment, 4222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCAsmFixup &Fixup, MCValue Target, 4232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t &FixedValue) { 4242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Address = Fragment.getOffset() + Fixup.Offset; 4252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); 4262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); 4272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Type = RIT_Vanilla; 4282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // See <reloc.h>. 4302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSymbol *A = &Target.getSymA()->getSymbol(); 4312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MCSymbolData *A_SD = &Asm.getSymbolData(*A); 4322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (!A_SD->getFragment()) 4342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar llvm_report_error("symbol '" + A->getName() + 4352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar "' can not be undefined in a subtraction expression"); 4362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Value = A_SD->getAddress(); 4382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Value2 = 0; 4392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (const MCSymbolRefExpr *B = Target.getSymB()) { 4412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MCSymbolData *B_SD = &Asm.getSymbolData(B->getSymbol()); 4422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (!B_SD->getFragment()) 4442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar llvm_report_error("symbol '" + B->getSymbol().getName() + 4452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar "' can not be undefined in a subtraction expression"); 4462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Select the appropriate difference relocation type. 4482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 4492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Note that there is no longer any semantic difference between these two 4502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // relocation types from the linkers point of view, this is done solely 4512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // for pedantic compatibility with 'as'. 4522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type = A_SD->isExternal() ? RIT_Difference : RIT_LocalDifference; 4532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Value2 = B_SD->getAddress(); 4542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 4552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Relocations are written out in reverse order, so the PAIR comes first. 4572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Type == RIT_Difference || Type == RIT_LocalDifference) { 4582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MachRelocationEntry MRE; 4592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MRE.Word0 = ((0 << 0) | 4602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (RIT_Pair << 24) | 4612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (Log2Size << 28) | 4622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (IsPCRel << 30) | 4632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RF_Scattered); 4642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MRE.Word1 = Value2; 4652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Relocations[Fragment.getParent()].push_back(MRE); 4662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 4672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MachRelocationEntry MRE; 4692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MRE.Word0 = ((Address << 0) | 4702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (Type << 24) | 4712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (Log2Size << 28) | 4722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (IsPCRel << 30) | 4732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RF_Scattered); 4742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MRE.Word1 = Value; 4752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Relocations[Fragment.getParent()].push_back(MRE); 4762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 4772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar virtual void RecordRelocation(const MCAssembler &Asm, 4792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCDataFragment &Fragment, 4802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCAsmFixup &Fixup, MCValue Target, 4812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t &FixedValue) { 4822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned IsPCRel = isFixupKindPCRel(Fixup.Kind); 4832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind); 4842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // If this is a difference or a defined symbol plus an offset, then we need 4862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // a scattered relocation entry. 4872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Offset = Target.getConstant(); 4882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (IsPCRel) 4892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Offset += 1 << Log2Size; 4902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Target.getSymB() || 4912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (Target.getSymA() && !Target.getSymA()->getSymbol().isUndefined() && 4922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Offset)) { 4932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RecordScatteredRelocation(Asm, Fragment, Fixup, Target, FixedValue); 4942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar return; 4952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 4962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 4972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // See <reloc.h>. 4982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Address = Fragment.getOffset() + Fixup.Offset; 4992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Value = 0; 5002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Index = 0; 5012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned IsExtern = 0; 5022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Type = 0; 5032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Target.isAbsolute()) { // constant 5052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // SymbolNum of 0 indicates the absolute section. 5062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 5072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Currently, these are never generated (see code below). I cannot 5082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // find a case where they are actually emitted. 5092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type = RIT_Vanilla; 5102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Value = 0; 5112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else { 5122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSymbol *Symbol = &Target.getSymA()->getSymbol(); 5132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MCSymbolData *SD = &Asm.getSymbolData(*Symbol); 5142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Symbol->isUndefined()) { 5162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar IsExtern = 1; 5172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Index = SD->getIndex(); 5182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Value = 0; 5192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else { 5202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The index is the section ordinal. 5212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 5222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: O(N) 5232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Index = 1; 5242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 5252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (; it != ie; ++it, ++Index) 5262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (&*it == SD->getFragment()->getParent()) 5272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar break; 5282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(it != ie && "Unable to find section index!"); 5292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Value = SD->getAddress(); 5302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 5312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Type = RIT_Vanilla; 5332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 5342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // struct relocation_info (8 bytes) 5362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MachRelocationEntry MRE; 5372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MRE.Word0 = Address; 5382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MRE.Word1 = ((Index << 0) | 5392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (IsPCRel << 24) | 5402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (Log2Size << 25) | 5412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (IsExtern << 27) | 5422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar (Type << 28)); 5432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Relocations[Fragment.getParent()].push_back(MRE); 5442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 5452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void BindIndirectSymbols(MCAssembler &Asm) { 5472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // This is the point where 'as' creates actual symbols for indirect symbols 5482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // (in the following two passes). It would be easier for us to do this 5492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // sooner when we see the attribute, but that makes getting the order in the 5502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // symbol table much more complicated than it is worth. 5512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 5522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Revisit this when the dust settles. 5532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Bind non lazy symbol pointers first. 5552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 5562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 5572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: cast<> support! 5582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSectionMachO &Section = 5592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 5602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) 5622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 5632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Asm.getOrCreateSymbolData(*it->Symbol); 5652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 5662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Then lazy symbol pointers and symbol stubs. 5682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), 5692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 5702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: cast<> support! 5712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSectionMachO &Section = 5722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 5732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && 5752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) 5762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 5772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Set the symbol type to undefined lazy, but only on construction. 5792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 5802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Do not hardcode. 5812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar bool Created; 5822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MCSymbolData &Entry = Asm.getOrCreateSymbolData(*it->Symbol, &Created); 5832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Created) 5842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Entry.setFlags(Entry.getFlags() | 0x0001); 5852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 5862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 5872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 5882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// ComputeSymbolTable - Compute the symbol table data 5892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// 5902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// \param StringTable [out] - The string table data. 5912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// \param StringIndexMap [out] - Map from symbol names to offsets in the 5922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar /// string table. 5932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable, 5942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachSymbolData> &LocalSymbolData, 5952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachSymbolData> &ExternalSymbolData, 5962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachSymbolData> &UndefinedSymbolData) { 5972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Build section lookup table. 5982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar DenseMap<const MCSection*, uint8_t> SectionIndexMap; 5992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned Index = 1; 6002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::iterator it = Asm.begin(), 6012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.end(); it != ie; ++it, ++Index) 6022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SectionIndexMap[&it->getSection()] = Index; 6032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(Index <= 256 && "Too many sections!"); 6042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Index 0 is always the empty string. 6062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringMap<uint64_t> StringIndexMap; 6072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringTable += '\x00'; 6082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Build the symbol arrays and the string table, but only for non-local 6102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // symbols. 6112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 6122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The particular order that we collect the symbols and create the string 6132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // table, then sort the symbols is chosen to match 'as'. Even though it 6142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // doesn't matter for correctness, this is important for letting us diff .o 6152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // files. 6162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 6172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.symbol_end(); it != ie; ++it) { 6182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSymbol &Symbol = it->getSymbol(); 6192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Ignore non-linker visible symbols. 6212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (!Asm.isSymbolLinkerVisible(it)) 6222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 6232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (!it->isExternal() && !Symbol.isUndefined()) 6252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 6262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t &Entry = StringIndexMap[Symbol.getName()]; 6282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (!Entry) { 6292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Entry = StringTable.size(); 6302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringTable += Symbol.getName(); 6312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringTable += '\x00'; 6322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 6332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MachSymbolData MSD; 6352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.SymbolData = it; 6362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.StringIndex = Entry; 6372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Symbol.isUndefined()) { 6392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.SectionIndex = 0; 6402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar UndefinedSymbolData.push_back(MSD); 6412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else if (Symbol.isAbsolute()) { 6422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.SectionIndex = 0; 6432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ExternalSymbolData.push_back(MSD); 6442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else { 6452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 6462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(MSD.SectionIndex && "Invalid section index!"); 6472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ExternalSymbolData.push_back(MSD); 6482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 6492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 6502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Now add the data for local symbols. 6522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 6532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.symbol_end(); it != ie; ++it) { 6542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSymbol &Symbol = it->getSymbol(); 6552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Ignore non-linker visible symbols. 6572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (!Asm.isSymbolLinkerVisible(it)) 6582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 6592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (it->isExternal() || Symbol.isUndefined()) 6612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 6622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t &Entry = StringIndexMap[Symbol.getName()]; 6642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (!Entry) { 6652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Entry = StringTable.size(); 6662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringTable += Symbol.getName(); 6672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringTable += '\x00'; 6682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 6692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MachSymbolData MSD; 6712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.SymbolData = it; 6722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.StringIndex = Entry; 6732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Symbol.isAbsolute()) { 6752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.SectionIndex = 0; 6762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LocalSymbolData.push_back(MSD); 6772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } else { 6782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection()); 6792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar assert(MSD.SectionIndex && "Invalid section index!"); 6802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LocalSymbolData.push_back(MSD); 6812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 6822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 6832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // External and undefined symbols are required to be in lexicographic order. 6852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 6862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 6872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Set the symbol indices. 6892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Index = 0; 6902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 6912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LocalSymbolData[i].SymbolData->setIndex(Index++); 6922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 6932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ExternalSymbolData[i].SymbolData->setIndex(Index++); 6942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 6952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar UndefinedSymbolData[i].SymbolData->setIndex(Index++); 6962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 6972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The string table is padded to a multiple of 4. 6982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar while (StringTable.size() % 4) 6992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringTable += '\x00'; 7002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 7012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar virtual void ExecutePostLayoutBinding(MCAssembler &Asm) { 7032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Create symbol data for any indirect symbols. 7042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar BindIndirectSymbols(Asm); 7052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Compute symbol table information and bind symbol indices. 7072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ComputeSymbolTable(Asm, StringTable, LocalSymbolData, ExternalSymbolData, 7082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar UndefinedSymbolData); 7092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 7102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar virtual void WriteObject(const MCAssembler &Asm) { 7122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumSections = Asm.size(); 7132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The section data starts after the header, the segment load command (and 7152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // section headers) and the symbol table. 7162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumLoadCommands = 1; 7172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t LoadCommandsSize = Is64Bit ? 7182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SegmentLoadCommand64Size + NumSections * Section64Size : 7192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SegmentLoadCommand32Size + NumSections * Section32Size; 7202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Add the symbol table load command sizes, if used. 7222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() + 7232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar UndefinedSymbolData.size(); 7242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (NumSymbols) { 7252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar NumLoadCommands += 2; 7262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar LoadCommandsSize += SymtabLoadCommandSize + DysymtabLoadCommandSize; 7272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 7282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Compute the total size of the section data, as well as its file size and 7302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // vm size. 7312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t SectionDataStart = (Is64Bit ? Header64Size : Header32Size) 7322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar + LoadCommandsSize; 7332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t SectionDataSize = 0; 7342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t SectionDataFileSize = 0; 7352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t VMSize = 0; 7362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::const_iterator it = Asm.begin(), 7372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.end(); it != ie; ++it) { 7382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSectionData &SD = *it; 7392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar VMSize = std::max(VMSize, SD.getAddress() + SD.getSize()); 7412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Asm.getBackend().isVirtualSection(SD.getSection())) 7432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 7442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SectionDataSize = std::max(SectionDataSize, 7462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SD.getAddress() + SD.getSize()); 7472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SectionDataFileSize = std::max(SectionDataFileSize, 7482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SD.getAddress() + SD.getFileSize()); 7492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 7502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The section data is padded to 4 bytes. 7522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // 7532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Is this machine dependent? 7542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned SectionDataPadding = OffsetToAlignment(SectionDataFileSize, 4); 7552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SectionDataFileSize += SectionDataPadding; 7562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the prolog, starting with the header and load command... 7582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteHeader(NumLoadCommands, LoadCommandsSize, 7592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Asm.getSubsectionsViaSymbols()); 7602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteSegmentLoadCommand(NumSections, VMSize, 7612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SectionDataStart, SectionDataSize); 7622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // ... and then the section headers. 7642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize; 7652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::const_iterator it = Asm.begin(), 7662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.end(); it != ie; ++it) { 7672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachRelocationEntry> &Relocs = Relocations[it]; 7682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumRelocs = Relocs.size(); 7692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t SectionStart = SectionDataStart + it->getAddress(); 7702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteSection(Asm, *it, SectionStart, RelocTableEnd, NumRelocs); 7712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar RelocTableEnd += NumRelocs * RelocationInfoSize; 7722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 7732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the symbol table load command, if used. 7752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (NumSymbols) { 7762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned FirstLocalSymbol = 0; 7772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumLocalSymbols = LocalSymbolData.size(); 7782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned FirstExternalSymbol = FirstLocalSymbol + NumLocalSymbols; 7792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumExternalSymbols = ExternalSymbolData.size(); 7802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned FirstUndefinedSymbol = FirstExternalSymbol + NumExternalSymbols; 7812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumUndefinedSymbols = UndefinedSymbolData.size(); 7822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumIndirectSymbols = Asm.indirect_symbol_size(); 7832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar unsigned NumSymTabSymbols = 7842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar NumLocalSymbols + NumExternalSymbols + NumUndefinedSymbols; 7852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t IndirectSymbolSize = NumIndirectSymbols * 4; 7862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t IndirectSymbolOffset = 0; 7872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // If used, the indirect symbols are written after the section data. 7892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (NumIndirectSymbols) 7902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar IndirectSymbolOffset = RelocTableEnd; 7912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The symbol table is written after the indirect symbol data. 7932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t SymbolTableOffset = RelocTableEnd + IndirectSymbolSize; 7942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 7952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // The string table is written after symbol table. 7962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t StringTableOffset = 7972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar SymbolTableOffset + NumSymTabSymbols * (Is64Bit ? Nlist64Size : 7982df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Nlist32Size); 7992df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteSymtabLoadCommand(SymbolTableOffset, NumSymTabSymbols, 8002df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar StringTableOffset, StringTable.size()); 8012df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8022df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteDysymtabLoadCommand(FirstLocalSymbol, NumLocalSymbols, 8032df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar FirstExternalSymbol, NumExternalSymbols, 8042df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar FirstUndefinedSymbol, NumUndefinedSymbols, 8052df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar IndirectSymbolOffset, NumIndirectSymbols); 8062df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8072df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8082df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the actual section data. 8092df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::const_iterator it = Asm.begin(), 8102df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.end(); it != ie; ++it) 8112df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Asm.WriteSectionData(it, Writer); 8122df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8132df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the extra padding. 8142df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteZeros(SectionDataPadding); 8152df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8162df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the relocation entries. 8172df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::const_iterator it = Asm.begin(), 8182df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.end(); it != ie; ++it) { 8192df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the section relocation entries, in reverse order to match 'as' 8202df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // (approximately, the exact algorithm is more complicated than this). 8212df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar std::vector<MachRelocationEntry> &Relocs = Relocations[it]; 8222df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 8232df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Relocs[e - i - 1].Word0); 8242df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Relocs[e - i - 1].Word1); 8252df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8262df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8272df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8282df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the symbol table data, if used. 8292df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (NumSymbols) { 8302df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the indirect symbol entries. 8312df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (MCAssembler::const_indirect_symbol_iterator 8322df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar it = Asm.indirect_symbol_begin(), 8332df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ie = Asm.indirect_symbol_end(); it != ie; ++it) { 8342df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Indirect symbols in the non lazy symbol pointer section have some 8352df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // special handling. 8362df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCSectionMachO &Section = 8372df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar static_cast<const MCSectionMachO&>(it->SectionData->getSection()); 8382df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (Section.getType() == MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS) { 8392df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // If this symbol is defined and internal, mark it as such. 8402df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (it->Symbol->isDefined() && 8412df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar !Asm.getSymbolData(*it->Symbol).isExternal()) { 8422df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint32_t Flags = ISF_Local; 8432df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar if (it->Symbol->isAbsolute()) 8442df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Flags |= ISF_Absolute; 8452df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Flags); 8462df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar continue; 8472df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8482df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8492df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8502df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Write32(Asm.getSymbolData(*it->Symbol).getIndex()); 8512df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8522df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8532df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // FIXME: Check that offsets match computed ones. 8542df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8552df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the symbol table entries. 8562df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 8572df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteNlist(LocalSymbolData[i]); 8582df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 8592df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteNlist(ExternalSymbolData[i]); 8602df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 8612df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar WriteNlist(UndefinedSymbolData[i]); 8622df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8632df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar // Write the string table. 8642df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar OS << StringTable.str(); 8652df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8662df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar } 8672df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar}; 8682df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8692df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 8702df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8712df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel DunbarMachObjectWriter::MachObjectWriter(raw_ostream &OS, 8722df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar bool Is64Bit, 8732df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar bool IsLittleEndian) 8742df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar : MCObjectWriter(OS, IsLittleEndian) 8752df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar{ 8762df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Impl = new MachObjectWriterImpl(this, Is64Bit); 8772df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 8782df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8792df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel DunbarMachObjectWriter::~MachObjectWriter() { 8802df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar delete (MachObjectWriterImpl*) Impl; 8812df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 8822df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8832df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarvoid MachObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm) { 8842df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ((MachObjectWriterImpl*) Impl)->ExecutePostLayoutBinding(Asm); 8852df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 8862df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8872df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarvoid MachObjectWriter::RecordRelocation(const MCAssembler &Asm, 8882df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCDataFragment &Fragment, 8892df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar const MCAsmFixup &Fixup, MCValue Target, 8902df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar uint64_t &FixedValue) { 8912df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ((MachObjectWriterImpl*) Impl)->RecordRelocation(Asm, Fragment, Fixup, 8922df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar Target, FixedValue); 8932df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 8942df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar 8952df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbarvoid MachObjectWriter::WriteObject(const MCAssembler &Asm) { 8962df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar ((MachObjectWriterImpl*) Impl)->WriteObject(Asm); 8972df4ceba15c130005967ee9e5fb4aa5568de1b0cDaniel Dunbar} 898