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