diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 2b5fd2c..758c81d 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Assembly/PrintModulePass.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/FileWriters.h"
 #include "llvm/CodeGen/GCStrategy.h"
 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
 #include "llvm/Target/TargetOptions.h"
@@ -115,12 +116,11 @@
       return FileModel::Error;
     return FileModel::AsmFile;
   case TargetMachine::ObjectFile:
-    if (getMachOWriterInfo())
+    if (!addObjectFileEmitter(PM, OptLevel, Out))
       return FileModel::MachOFile;
     else if (getELFWriterInfo())
-      return FileModel::ElfFile;
+      return FileModel::ElfFile; 
   }
-
   return FileModel::Error;
 }
 
@@ -137,6 +137,17 @@
   return false;
 }
 
+bool LLVMTargetMachine::addObjectFileEmitter(PassManagerBase &PM,
+                                             CodeGenOpt::Level OptLevel,
+                                             formatted_raw_ostream &Out) {
+  MCCodeEmitter *Emitter = getTarget().createCodeEmitter(*this);
+  if (!Emitter)
+    return true;
+  
+  PM.add(createMachOWriter(Out, *this, getMCAsmInfo(), Emitter));
+  return false;
+}
+
 /// addPassesToEmitFileFinish - If the passes to emit the specified file had to
 /// be split up (e.g., to add an object writer pass), this method can be used to
 /// finish up adding passes to emit the file, if necessary.
diff --git a/lib/CodeGen/MachO.h b/lib/CodeGen/MachO.h
deleted file mode 100644
index f2b40fe..0000000
--- a/lib/CodeGen/MachO.h
+++ /dev/null
@@ -1,412 +0,0 @@
-//=== MachO.h - Mach-O structures and constants -----------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines MachO .
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MACHO_H
-#define MACHO_H
-
-#include "llvm/CodeGen/BinaryObject.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-
-class GlobalValue;
-class MCAsmInfo;
-
-/// MachOSym - This struct contains information about each symbol that is
-/// added to logical symbol table for the module.  This is eventually
-/// turned into a real symbol table in the file.
-struct MachOSym {
-  const GlobalValue *GV;    // The global value this corresponds to.
-  std::string GVName;       // The mangled name of the global value.
-  uint32_t    n_strx;       // index into the string table
-  uint8_t     n_type;       // type flag
-  uint8_t     n_sect;       // section number or NO_SECT
-  int16_t     n_desc;       // see <mach-o/stab.h>
-  uint64_t    n_value;      // value for this symbol (or stab offset)
-  
-  // Constants for the n_sect field
-  // see <mach-o/nlist.h>
-  enum { NO_SECT = 0 };   // symbol is not in any section
-
-  // Constants for the n_type field
-  // see <mach-o/nlist.h>
-  enum { N_UNDF  = 0x0,  // undefined, n_sect == NO_SECT
-         N_ABS   = 0x2,  // absolute, n_sect == NO_SECT
-         N_SECT  = 0xe,  // defined in section number n_sect
-         N_PBUD  = 0xc,  // prebound undefined (defined in a dylib)
-         N_INDR  = 0xa   // indirect
-  };
-  // The following bits are OR'd into the types above. For example, a type
-  // of 0x0f would be an external N_SECT symbol (0x0e | 0x01).
-  enum { N_EXT  = 0x01,   // external symbol bit
-         N_PEXT = 0x10    // private external symbol bit
-  };
-  
-  // Constants for the n_desc field
-  // see <mach-o/loader.h>
-  enum { REFERENCE_FLAG_UNDEFINED_NON_LAZY          = 0,
-         REFERENCE_FLAG_UNDEFINED_LAZY              = 1,
-         REFERENCE_FLAG_DEFINED                     = 2,
-         REFERENCE_FLAG_PRIVATE_DEFINED             = 3,
-         REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY  = 4,
-         REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY      = 5
-  };
-  enum { N_NO_DEAD_STRIP = 0x0020, // symbol is not to be dead stripped
-         N_WEAK_REF      = 0x0040, // symbol is weak referenced
-         N_WEAK_DEF      = 0x0080  // coalesced symbol is a weak definition
-  };
-  
-  MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
-           const MCAsmInfo *MAI);
-
-  struct SymCmp {
-    // FIXME: this does not appear to be sorting 'f' after 'F'
-    bool operator()(const MachOSym &LHS, const MachOSym &RHS) {
-      return LHS.GVName < RHS.GVName;
-    }
-  };
-
-
-  /// PartitionByLocal - Simple boolean predicate that returns true if Sym is
-  /// a local symbol rather than an external symbol.
-  
-  static inline bool PartitionByLocal(const MachOSym &Sym) {
-    return (Sym.n_type & (MachOSym::N_EXT | MachOSym::N_PEXT)) == 0;
-  }
-  
-  /// PartitionByDefined - Simple boolean predicate that returns true if Sym is
-  /// defined in this module.
-  
-  static inline bool PartitionByDefined(const MachOSym &Sym) {
-    // FIXME: Do N_ABS or N_INDR count as defined?
-    return (Sym.n_type & MachOSym::N_SECT) == MachOSym::N_SECT;
-  }
-
-}; // end struct MachOSym
-
-/// MachOHeader - This struct contains the header information about a
-/// specific architecture type/subtype pair that is emitted to the file.
-
-struct MachOHeader {
-  uint32_t  magic;      // mach magic number identifier
-  uint32_t  filetype;   // type of file
-  uint32_t  ncmds;      // number of load commands
-  uint32_t  sizeofcmds; // the size of all the load commands
-  uint32_t  flags;      // flags
-  uint32_t  reserved;   // 64-bit only
-  
-  /// HeaderData - The actual data for the header which we are building
-  /// up for emission to the file.
-  std::vector<unsigned char> HeaderData;
-
-  // Constants for the filetype field
-  // see <mach-o/loader.h> for additional info on the various types
-  enum { MH_OBJECT     = 1, // relocatable object file
-         MH_EXECUTE    = 2, // demand paged executable file
-         MH_FVMLIB     = 3, // fixed VM shared library file
-         MH_CORE       = 4, // core file
-         MH_PRELOAD    = 5, // preloaded executable file
-         MH_DYLIB      = 6, // dynamically bound shared library
-         MH_DYLINKER   = 7, // dynamic link editor
-         MH_BUNDLE     = 8, // dynamically bound bundle file
-         MH_DYLIB_STUB = 9, // shared library stub for static linking only
-         MH_DSYM       = 10 // companion file wiht only debug sections
-  };
-  
-  // Constants for the flags field
-  enum { MH_NOUNDEFS                = 1 << 0,
-            // the object file has no undefined references
-         MH_INCRLINK                = 1 << 1,
-            // the object file is the output of an incremental link against
-            // a base file and cannot be link edited again
-         MH_DYLDLINK                = 1 << 2,
-            // the object file is input for the dynamic linker and cannot be
-            // statically link edited again.
-         MH_BINDATLOAD              = 1 << 3,
-            // the object file's undefined references are bound by the
-            // dynamic linker when loaded.
-         MH_PREBOUND                = 1 << 4,
-            // the file has its dynamic undefined references prebound
-         MH_SPLIT_SEGS              = 1 << 5,
-            // the file has its read-only and read-write segments split
-            // see <mach/shared_memory_server.h>
-         MH_LAZY_INIT               = 1 << 6,
-            // the shared library init routine is to be run lazily via
-            // catching memory faults to its writable segments (obsolete)
-         MH_TWOLEVEL                = 1 << 7,
-            // the image is using two-level namespace bindings
-         MH_FORCE_FLAT              = 1 << 8,
-            // the executable is forcing all images to use flat namespace
-            // bindings.
-         MH_NOMULTIDEFS             = 1 << 8,
-            // this umbrella guarantees no multiple definitions of symbols
-            // in its sub-images so the two-level namespace hints can
-            // always be used.
-         MH_NOFIXPREBINDING         = 1 << 10,
-            // do not have dyld notify the prebidning agent about this
-            // executable.
-         MH_PREBINDABLE             = 1 << 11,
-            // the binary is not prebound but can have its prebinding
-            // redone.  only used when MH_PREBOUND is not set.
-         MH_ALLMODSBOUND            = 1 << 12,
-            // indicates that this binary binds to all two-level namespace
-            // modules of its dependent libraries.  Only used when
-            // MH_PREBINDABLE and MH_TWOLEVEL are both set.
-         MH_SUBSECTIONS_VIA_SYMBOLS = 1 << 13,
-            // safe to divide up the sections into sub-sections via symbols
-            // for dead code stripping.
-         MH_CANONICAL               = 1 << 14,
-            // the binary has been canonicalized via the unprebind operation
-         MH_WEAK_DEFINES            = 1 << 15,
-            // the final linked image contains external weak symbols
-         MH_BINDS_TO_WEAK           = 1 << 16,
-            // the final linked image uses weak symbols
-         MH_ALLOW_STACK_EXECUTION   = 1 << 17
-            // When this bit is set, all stacks in the task will be given
-            // stack execution privilege.  Only used in MH_EXECUTE filetype
-  };
-
-  MachOHeader() : magic(0), filetype(0), ncmds(0), sizeofcmds(0), flags(0),
-                  reserved(0) {}
-
-  /// cmdSize - This routine returns the size of the MachOSection as written
-  /// to disk, depending on whether the destination is a 64 bit Mach-O file.
-  unsigned cmdSize(bool is64Bit) const {
-    if (is64Bit)
-      return 8 * sizeof(uint32_t);
-    else
-      return 7 * sizeof(uint32_t);
-  }
-
-  /// setMagic - This routine sets the appropriate value for the 'magic'
-  /// field based on pointer size and endianness.
-  void setMagic(bool isLittleEndian, bool is64Bit) {
-    if (isLittleEndian)
-      if (is64Bit) magic = 0xcffaedfe;
-      else         magic = 0xcefaedfe;
-    else
-      if (is64Bit) magic = 0xfeedfacf;
-      else         magic = 0xfeedface;
-  }
-
-}; // end struct MachOHeader
-
-/// MachOSegment - This struct contains the necessary information to
-/// emit the load commands for each section in the file.
-struct MachOSegment {
-  uint32_t    cmd;      // LC_SEGMENT or LC_SEGMENT_64
-  uint32_t    cmdsize;  // Total size of this struct and section commands
-  std::string segname;  // segment name
-  uint64_t    vmaddr;   // address of this segment
-  uint64_t    vmsize;   // size of this segment, may be larger than filesize
-  uint64_t    fileoff;  // offset in file
-  uint64_t    filesize; // amount to read from file
-  uint32_t    maxprot;  // maximum VM protection
-  uint32_t    initprot; // initial VM protection
-  uint32_t    nsects;   // number of sections in this segment
-  uint32_t    flags;    // flags
-  
-  // The following constants are getting pulled in by one of the
-  // system headers, which creates a neat clash with the enum.
-#if !defined(VM_PROT_NONE)
-#define VM_PROT_NONE    0x00
-#endif
-#if !defined(VM_PROT_READ)
-#define VM_PROT_READ    0x01
-#endif
-#if !defined(VM_PROT_WRITE)
-#define VM_PROT_WRITE   0x02
-#endif
-#if !defined(VM_PROT_EXECUTE)
-#define VM_PROT_EXECUTE 0x04
-#endif
-#if !defined(VM_PROT_ALL)
-#define VM_PROT_ALL     0x07
-#endif
-
-  // Constants for the vm protection fields
-  // see <mach-o/vm_prot.h>
-  enum { SEG_VM_PROT_NONE     = VM_PROT_NONE, 
-         SEG_VM_PROT_READ     = VM_PROT_READ, // read permission
-         SEG_VM_PROT_WRITE    = VM_PROT_WRITE, // write permission
-         SEG_VM_PROT_EXECUTE  = VM_PROT_EXECUTE,
-         SEG_VM_PROT_ALL      = VM_PROT_ALL
-  };
-
-  // Constants for the cmd field
-  // see <mach-o/loader.h>
-  enum { LC_SEGMENT    = 0x01,  // segment of this file to be mapped
-         LC_SEGMENT_64 = 0x19   // 64-bit segment of this file to be mapped
-  };
-
-  /// cmdSize - This routine returns the size of the MachOSection as written
-  /// to disk, depending on whether the destination is a 64 bit Mach-O file.
-  unsigned cmdSize(bool is64Bit) const {
-    if (is64Bit)
-      return 6 * sizeof(uint32_t) + 4 * sizeof(uint64_t) + 16;
-    else
-      return 10 * sizeof(uint32_t) + 16;  // addresses only 32 bits
-  }
-
-  MachOSegment(const std::string &seg, bool is64Bit)
-    : cmd(is64Bit ? LC_SEGMENT_64 : LC_SEGMENT), cmdsize(0), segname(seg),
-      vmaddr(0), vmsize(0), fileoff(0), filesize(0), maxprot(VM_PROT_ALL),
-      initprot(VM_PROT_ALL), nsects(0), flags(0) { }
-};
-
-/// MachOSection - This struct contains information about each section in a 
-/// particular segment that is emitted to the file.  This is eventually
-/// turned into the SectionCommand in the load command for a particlar
-/// segment.
-
-struct MachOSection : public BinaryObject { 
-  std::string  sectname; // name of this section, 
-  std::string  segname;  // segment this section goes in
-  uint64_t  addr;        // memory address of this section
-  uint32_t  offset;      // file offset of this section
-  uint32_t  align;       // section alignment (power of 2)
-  uint32_t  reloff;      // file offset of relocation entries
-  uint32_t  nreloc;      // number of relocation entries
-  uint32_t  flags;       // flags (section type and attributes)
-  uint32_t  reserved1;   // reserved (for offset or index)
-  uint32_t  reserved2;   // reserved (for count or sizeof)
-  uint32_t  reserved3;   // reserved (64 bit only)
-
-  /// A unique number for this section, which will be used to match symbols
-  /// to the correct section.
-  uint32_t Index;
-
-  /// RelocBuffer - A buffer to hold the mach-o relocations before we write
-  /// them out at the appropriate location in the file.
-  std::vector<unsigned char> RelocBuffer;
-
-  // Constants for the section types (low 8 bits of flags field)
-  // see <mach-o/loader.h>
-  enum { S_REGULAR = 0,
-            // regular section
-         S_ZEROFILL = 1,
-            // zero fill on demand section
-         S_CSTRING_LITERALS = 2,
-            // section with only literal C strings
-         S_4BYTE_LITERALS = 3,
-            // section with only 4 byte literals
-         S_8BYTE_LITERALS = 4,
-            // section with only 8 byte literals
-         S_LITERAL_POINTERS = 5, 
-            // section with only pointers to literals
-         S_NON_LAZY_SYMBOL_POINTERS = 6,
-            // section with only non-lazy symbol pointers
-         S_LAZY_SYMBOL_POINTERS = 7,
-            // section with only lazy symbol pointers
-         S_SYMBOL_STUBS = 8,
-            // section with only symbol stubs
-            // byte size of stub in the reserved2 field
-         S_MOD_INIT_FUNC_POINTERS = 9,
-            // section with only function pointers for initialization
-         S_MOD_TERM_FUNC_POINTERS = 10,
-            // section with only function pointers for termination
-         S_COALESCED = 11,
-            // section contains symbols that are coalesced
-         S_GB_ZEROFILL = 12,
-            // zero fill on demand section (that can be larger than 4GB)
-         S_INTERPOSING = 13,
-            // section with only pairs of function pointers for interposing
-         S_16BYTE_LITERALS = 14
-            // section with only 16 byte literals
-  };
-  
-  // Constants for the section flags (high 24 bits of flags field)
-  // see <mach-o/loader.h>
-  enum { S_ATTR_PURE_INSTRUCTIONS   = 1 << 31,
-            // section contains only true machine instructions
-         S_ATTR_NO_TOC              = 1 << 30,
-            // section contains coalesced symbols that are not to be in a 
-            // ranlib table of contents
-         S_ATTR_STRIP_STATIC_SYMS   = 1 << 29,
-            // ok to strip static symbols in this section in files with the
-            // MY_DYLDLINK flag
-         S_ATTR_NO_DEAD_STRIP       = 1 << 28,
-            // no dead stripping
-         S_ATTR_LIVE_SUPPORT        = 1 << 27,
-            // blocks are live if they reference live blocks
-         S_ATTR_SELF_MODIFYING_CODE = 1 << 26,
-            // used with i386 code stubs written on by dyld
-         S_ATTR_DEBUG               = 1 << 25,
-            // a debug section
-         S_ATTR_SOME_INSTRUCTIONS   = 1 << 10,
-            // section contains some machine instructions
-         S_ATTR_EXT_RELOC           = 1 << 9,
-            // section has external relocation entries
-         S_ATTR_LOC_RELOC           = 1 << 8
-            // section has local relocation entries
-  };
-
-  /// cmdSize - This routine returns the size of the MachOSection as written
-  /// to disk, depending on whether the destination is a 64 bit Mach-O file.
-  unsigned cmdSize(bool is64Bit) const {
-    if (is64Bit)
-      return 7 * sizeof(uint32_t) + 2 * sizeof(uint64_t) + 32;
-    else
-      return 9 * sizeof(uint32_t) + 32;  // addresses only 32 bits
-  }
-
-  MachOSection(const std::string &seg, const std::string &sect)
-    : BinaryObject(), sectname(sect), segname(seg), addr(0), offset(0),
-      align(2), reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0),
-      reserved3(0) { }
-
-}; // end struct MachOSection
-
-/// MachOSymTab - This struct contains information about the offsets and 
-/// size of symbol table information.
-/// segment.
-struct MachODySymTab {
-  uint32_t cmd;             // LC_DYSYMTAB
-  uint32_t cmdsize;         // sizeof(MachODySymTab)
-  uint32_t ilocalsym;       // index to local symbols
-  uint32_t nlocalsym;       // number of local symbols
-  uint32_t iextdefsym;      // index to externally defined symbols
-  uint32_t nextdefsym;      // number of externally defined symbols
-  uint32_t iundefsym;       // index to undefined symbols
-  uint32_t nundefsym;       // number of undefined symbols
-  uint32_t tocoff;          // file offset to table of contents
-  uint32_t ntoc;            // number of entries in table of contents
-  uint32_t modtaboff;       // file offset to module table
-  uint32_t nmodtab;         // number of module table entries
-  uint32_t extrefsymoff;    // offset to referenced symbol table
-  uint32_t nextrefsyms;     // number of referenced symbol table entries
-  uint32_t indirectsymoff;  // file offset to the indirect symbol table
-  uint32_t nindirectsyms;   // number of indirect symbol table entries
-  uint32_t extreloff;       // offset to external relocation entries
-  uint32_t nextrel;         // number of external relocation entries
-  uint32_t locreloff;       // offset to local relocation entries
-  uint32_t nlocrel;         // number of local relocation entries
-
-  // Constants for the cmd field
-  // see <mach-o/loader.h>
-  enum { LC_DYSYMTAB = 0x0B  // dynamic link-edit symbol table info
-  };
-  
-  MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)),
-    ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0),
-    iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0),
-    nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0),
-    nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) {}
-
-}; // end struct MachODySymTab
-
-} // end namespace llvm
-
-#endif
-
diff --git a/lib/CodeGen/MachOCodeEmitter.cpp b/lib/CodeGen/MachOCodeEmitter.cpp
deleted file mode 100644
index 1318477..0000000
--- a/lib/CodeGen/MachOCodeEmitter.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-//===-- MachOEmitter.cpp - Target-independent Mach-O Emitter code --------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MachO.h"
-#include "MachOWriter.h"
-#include "MachOCodeEmitter.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Mangler.h"
-#include "llvm/Support/OutputBuffer.h"
-#include <vector>
-
-//===----------------------------------------------------------------------===//
-//                       MachOCodeEmitter Implementation
-//===----------------------------------------------------------------------===//
-
-namespace llvm {
-
-MachOCodeEmitter::MachOCodeEmitter(MachOWriter &mow, MachOSection &mos) :
-      ObjectCodeEmitter(&mos), MOW(mow), TM(MOW.TM) {
-  is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
-  isLittleEndian = TM.getTargetData()->isLittleEndian();
-  MAI = TM.getMCAsmInfo();
-}
-
-/// startFunction - This callback is invoked when a new machine function is
-/// about to be emitted.
-
-void MachOCodeEmitter::startFunction(MachineFunction &MF) {
-  const TargetData *TD = TM.getTargetData();
-  const Function *F = MF.getFunction();
-
-  // Align the output buffer to the appropriate alignment, power of 2.
-  unsigned FnAlign = F->getAlignment();
-  unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
-  unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
-  assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
-
-  // Get the Mach-O Section that this function belongs in.
-  MachOSection *MOS = MOW.getTextSection();
-  
-  // Upgrade the section alignment if required.
-  if (MOS->align < Align) MOS->align = Align;
-
-  MOS->emitAlignment(Align);
-
-  // Create symbol for function entry
-  const GlobalValue *FuncV = MF.getFunction();
-  MachOSym FnSym(FuncV, MOW.Mang->getMangledName(FuncV), MOS->Index, MAI);
-  FnSym.n_value = getCurrentPCOffset();
-
-  // add it to the symtab.
-  MOW.SymbolTable.push_back(FnSym);
-}
-
-/// finishFunction - This callback is invoked after the function is completely
-/// finished.
-
-bool MachOCodeEmitter::finishFunction(MachineFunction &MF) {
-    
-  // Get the Mach-O Section that this function belongs in.
-  MachOSection *MOS = MOW.getTextSection();
-
-  // Emit constant pool to appropriate section(s)
-  emitConstantPool(MF.getConstantPool());
-
-  // Emit jump tables to appropriate section
-  emitJumpTables(MF.getJumpTableInfo());
-  
-  // If we have emitted any relocations to function-specific objects such as 
-  // basic blocks, constant pools entries, or jump tables, record their
-  // addresses now so that we can rewrite them with the correct addresses
-  // later.
-  for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
-    MachineRelocation &MR = Relocations[i];
-    intptr_t Addr;
-
-    if (MR.isBasicBlock()) {
-      Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
-      MR.setConstantVal(MOS->Index);
-      MR.setResultPointer((void*)Addr);
-    } else if (MR.isJumpTableIndex()) {
-      Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
-      MR.setConstantVal(MOW.getJumpTableSection()->Index);
-      MR.setResultPointer((void*)Addr);
-    } else if (MR.isConstantPoolIndex()) {
-      Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
-      MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
-      MR.setResultPointer((void*)Addr);
-    } else if (MR.isGlobalValue()) {
-      // FIXME: This should be a set or something that uniques
-      MOW.PendingGlobals.push_back(MR.getGlobalValue());
-    } else {
-      llvm_unreachable("Unhandled relocation type");
-    }
-    MOS->addRelocation(MR);
-  }
-  Relocations.clear();
-
-  // Clear per-function data structures.
-  CPLocations.clear();
-  CPSections.clear();
-  JTLocations.clear();
-  MBBLocations.clear();
-
-  return false;
-}
-
-/// emitConstantPool - For each constant pool entry, figure out which section
-/// the constant should live in, allocate space for it, and emit it to the 
-/// Section data buffer.
-void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
-  const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
-  if (CP.empty()) return;
-
-  // FIXME: handle PIC codegen
-  assert(TM.getRelocationModel() != Reloc::PIC_ &&
-         "PIC codegen not yet handled for mach-o jump tables!");
-
-  // Although there is no strict necessity that I am aware of, we will do what
-  // gcc for OS X does and put each constant pool entry in a section of constant
-  // objects of a certain size.  That means that float constants go in the
-  // literal4 section, and double objects go in literal8, etc.
-  //
-  // FIXME: revisit this decision if we ever do the "stick everything into one
-  // "giant object for PIC" optimization.
-  for (unsigned i = 0, e = CP.size(); i != e; ++i) {
-    const Type *Ty = CP[i].getType();
-    unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
-
-    MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
-    OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
-
-    CPLocations.push_back(Sec->size());
-    CPSections.push_back(Sec->Index);
-
-    // Allocate space in the section for the global.
-    // FIXME: need alignment?
-    // FIXME: share between here and AddSymbolToSection?
-    for (unsigned j = 0; j < Size; ++j)
-      SecDataOut.outbyte(0);
-
-    MachOWriter::InitMem(CP[i].Val.ConstVal, CPLocations[i],
-                         TM.getTargetData(), Sec);
-  }
-}
-
-/// emitJumpTables - Emit all the jump tables for a given jump table info
-/// record to the appropriate section.
-void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
-  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
-  if (JT.empty()) return;
-
-  // FIXME: handle PIC codegen
-  assert(TM.getRelocationModel() != Reloc::PIC_ &&
-         "PIC codegen not yet handled for mach-o jump tables!");
-
-  MachOSection *Sec = MOW.getJumpTableSection();
-  unsigned TextSecIndex = MOW.getTextSection()->Index;
-  OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
-
-  for (unsigned i = 0, e = JT.size(); i != e; ++i) {
-    // For each jump table, record its offset from the start of the section,
-    // reserve space for the relocations to the MBBs, and add the relocations.
-    const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
-    JTLocations.push_back(Sec->size());
-    for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
-      MachineRelocation MR(MOW.GetJTRelocation(Sec->size(), MBBs[mi]));
-      MR.setResultPointer((void *)JTLocations[i]);
-      MR.setConstantVal(TextSecIndex);
-      Sec->addRelocation(MR);
-      SecDataOut.outaddr(0);
-    }
-  }
-}
-
-} // end namespace llvm
-
diff --git a/lib/CodeGen/MachOCodeEmitter.h b/lib/CodeGen/MachOCodeEmitter.h
deleted file mode 100644
index 4752446..0000000
--- a/lib/CodeGen/MachOCodeEmitter.h
+++ /dev/null
@@ -1,69 +0,0 @@
-//===-- MachOEmitter.h - Target-independent Mach-O Emitter class ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MACHOCODEEMITTER_H
-#define MACHOCODEEMITTER_H
-
-#include "llvm/CodeGen/ObjectCodeEmitter.h"
-#include <map>
-
-namespace llvm {
-
-class MachOWriter;
-
-/// MachOCodeEmitter - This class is used by the MachOWriter to emit the code 
-/// for functions to the Mach-O file.
-
-class MachOCodeEmitter : public ObjectCodeEmitter {
-  MachOWriter &MOW;
-
-  /// Target machine description.
-  TargetMachine &TM;
-
-  /// is64Bit/isLittleEndian - This information is inferred from the target
-  /// machine directly, indicating what header values and flags to set.
-  bool is64Bit, isLittleEndian;
-
-  const MCAsmInfo *MAI;
-
-  /// Relocations - These are the relocations that the function needs, as
-  /// emitted.
-  std::vector<MachineRelocation> Relocations;
-
-  std::map<uint64_t, uintptr_t> Labels;
-
-public:
-  MachOCodeEmitter(MachOWriter &mow, MachOSection &mos);
-
-  virtual void startFunction(MachineFunction &MF);
-  virtual bool finishFunction(MachineFunction &MF);
-
-  virtual void addRelocation(const MachineRelocation &MR) {
-    Relocations.push_back(MR);
-  }
-
-  void emitConstantPool(MachineConstantPool *MCP);
-  void emitJumpTables(MachineJumpTableInfo *MJTI);
-
-  virtual void emitLabel(uint64_t LabelID) {
-    Labels[LabelID] = getCurrentPCOffset();
-  }
-
-  virtual uintptr_t getLabelAddress(uint64_t Label) const {
-    return Labels.find(Label)->second;
-  }
-
-  virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
-
-}; // end class MachOCodeEmitter
-
-} // end namespace llvm
-
-#endif
-
diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp
index 337eab1..cab71ce 100644
--- a/lib/CodeGen/MachOWriter.cpp
+++ b/lib/CodeGen/MachOWriter.cpp
@@ -22,33 +22,31 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "MachO.h"
 #include "MachOWriter.h"
-#include "MachOCodeEmitter.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
+#include "llvm/Function.h"
+#include "llvm/CodeGen/FileWriters.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetMachOWriterInfo.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Mangler.h"
-#include "llvm/Support/OutputBuffer.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCStreamer.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Mangler.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+using namespace llvm;
 
-namespace llvm {
-
-/// AddMachOWriter - Concrete function to add the Mach-O writer to the function
-/// pass manager.
-ObjectCodeEmitter *AddMachOWriter(PassManagerBase &PM,
-                                         raw_ostream &O,
-                                         TargetMachine &TM) {
-  MachOWriter *MOW = new MachOWriter(O, TM);
-  PM.add(MOW);
-  return MOW->getObjectCodeEmitter();
+namespace llvm { 
+MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O,
+                                       TargetMachine &TM,
+                                       const MCAsmInfo *T, 
+                                       MCCodeEmitter *MCE) { 
+  return new MachOWriter(O, TM, T, MCE);
+}
 }
 
 //===----------------------------------------------------------------------===//
@@ -57,722 +55,83 @@
 
 char MachOWriter::ID = 0;
 
-MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm)
-  : MachineFunctionPass(&ID), O(o), TM(tm) {
-  is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64;
-  isLittleEndian = TM.getTargetData()->isLittleEndian();
-
-  MAI = TM.getMCAsmInfo();
-
-  // Create the machine code emitter object for this target.
-  MachOCE = new MachOCodeEmitter(*this, *getTextSection(true));
+MachOWriter::MachOWriter(formatted_raw_ostream &o, TargetMachine &tm,
+                         const MCAsmInfo *T, MCCodeEmitter *MCE)
+  : MachineFunctionPass(&ID), O(o), TM(tm), MAI(T), MCCE(MCE),
+    OutContext(*new MCContext()),
+    OutStreamer(*createMachOStreamer(OutContext, O, MCCE)) { 
 }
 
 MachOWriter::~MachOWriter() {
-  delete MachOCE;
+  delete &OutStreamer;
+  delete &OutContext;
+  delete MCCE;
 }
 
 bool MachOWriter::doInitialization(Module &M) {
-  // Set the magic value, now that we know the pointer size and endianness
-  Header.setMagic(isLittleEndian, is64Bit);
+  Mang = new Mangler(M, MAI->getGlobalPrefix(), MAI->getPrivateGlobalPrefix(),
+                     MAI->getLinkerPrivateGlobalPrefix());
+  
+  if (MAI->doesAllowQuotesInName())
+    Mang->setUseQuotes(true);
+  
+  if (MAI->doesAllowNameToStartWithDigit())
+    Mang->setSymbolsCanStartWithDigit(true);
+  
+  // Initialize TargetLoweringObjectFile.
+  TM.getTargetLowering()->getObjFileLowering().Initialize(OutContext, TM);
 
-  // Set the file type
-  // FIXME: this only works for object files, we do not support the creation
-  //        of dynamic libraries or executables at this time.
-  Header.filetype = MachOHeader::MH_OBJECT;
-
-  Mang = new Mangler(M);
-  return false;
-}
-
-bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
   return false;
 }
 
 /// doFinalization - Now that the module has been completely processed, emit
 /// the Mach-O file to 'O'.
 bool MachOWriter::doFinalization(Module &M) {
-  // FIXME: we don't handle debug info yet, we should probably do that.
-  // Okay, the.text section has been completed, build the .data, .bss, and
-  // "common" sections next.
-
-  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
-       I != E; ++I)
-    EmitGlobal(I);
-
-  // Emit the header and load commands.
-  EmitHeaderAndLoadCommands();
-
-  // Emit the various sections and their relocation info.
-  EmitSections();
-  EmitRelocations();
-
-  // Write the symbol table and the string table to the end of the file.
-  O.write((char*)&SymT[0], SymT.size());
-  O.write((char*)&StrT[0], StrT.size());
-
-  // We are done with the abstract symbols.
-  SectionList.clear();
-  SymbolTable.clear();
-  DynamicSymbolTable.clear();
-
   // Release the name mangler object.
   delete Mang; Mang = 0;
+
+  OutStreamer.Finish();
   return false;
 }
 
-// getConstSection - Get constant section for Constant 'C'
-MachOSection *MachOWriter::getConstSection(Constant *C) {
-  const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
-  if (CVA && CVA->isCString())
-    return getSection("__TEXT", "__cstring", 
-                      MachOSection::S_CSTRING_LITERALS);
+bool MachOWriter::runOnMachineFunction(MachineFunction &MF) {
+  const Function *F = MF.getFunction();
+  TargetLoweringObjectFile &TLOF = TM.getTargetLowering()->getObjFileLowering();
+  const MCSection *S = TLOF.SectionForGlobal(F, Mang, TM);
+  OutStreamer.SwitchSection(S);
 
-  const Type *Ty = C->getType();
-  if (Ty->isPrimitiveType() || Ty->isInteger()) {
-    unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
-    switch(Size) {
-    default: break; // Fall through to __TEXT,__const
-    case 4:
-      return getSection("__TEXT", "__literal4",
-                        MachOSection::S_4BYTE_LITERALS);
-    case 8:
-      return getSection("__TEXT", "__literal8",
-                        MachOSection::S_8BYTE_LITERALS);
-    case 16:
-      return getSection("__TEXT", "__literal16",
-                        MachOSection::S_16BYTE_LITERALS);
-    }
-  }
-  return getSection("__TEXT", "__const");
-}
+  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
+       I != E; ++I) {
+    // Print a label for the basic block.
+    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
+         II != IE; ++II) {
+      const MachineInstr *MI = II;
+      MCInst OutMI;
+      OutMI.setOpcode(MI->getOpcode());
 
-// getJumpTableSection - Select the Jump Table section
-MachOSection *MachOWriter::getJumpTableSection() {
-  if (TM.getRelocationModel() == Reloc::PIC_)
-    return getTextSection(false);
-  else
-    return getSection("__TEXT", "__const");
-}
+      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+        const MachineOperand &MO = MI->getOperand(i);
+        MCOperand MCOp;
 
-// getSection - Return the section with the specified name, creating a new
-// section if one does not already exist.
-MachOSection *MachOWriter::getSection(const std::string &seg,
-                                      const std::string &sect,
-                                      unsigned Flags /* = 0 */ ) {
-  MachOSection *MOS = SectionLookup[seg+sect];
-  if (MOS) return MOS;
-
-  MOS = new MachOSection(seg, sect);
-  SectionList.push_back(MOS);
-  MOS->Index = SectionList.size();
-  MOS->flags = MachOSection::S_REGULAR | Flags;
-  SectionLookup[seg+sect] = MOS;
-  return MOS;
-}
-
-// getTextSection - Return text section with different flags for code/data
-MachOSection *MachOWriter::getTextSection(bool isCode /* = true */ ) {
-  if (isCode)
-    return getSection("__TEXT", "__text",
-                      MachOSection::S_ATTR_PURE_INSTRUCTIONS |
-                      MachOSection::S_ATTR_SOME_INSTRUCTIONS);
-  else
-    return getSection("__TEXT", "__text");
-}
-
-MachOSection *MachOWriter::getBSSSection() {
-  return getSection("__DATA", "__bss", MachOSection::S_ZEROFILL);
-}
-
-// GetJTRelocation - Get a relocation a new BB relocation based
-// on target information.
-MachineRelocation MachOWriter::GetJTRelocation(unsigned Offset,
-                                               MachineBasicBlock *MBB) const {
-  return TM.getMachOWriterInfo()->GetJTRelocation(Offset, MBB);
-}
-
-// GetTargetRelocation - Returns the number of relocations.
-unsigned MachOWriter::GetTargetRelocation(MachineRelocation &MR,
-                             unsigned FromIdx, unsigned ToAddr,
-                             unsigned ToIndex, OutputBuffer &RelocOut,
-                             OutputBuffer &SecOut, bool Scattered,
-                             bool Extern) {
-  return TM.getMachOWriterInfo()->GetTargetRelocation(MR, FromIdx, ToAddr,
-                                                      ToIndex, RelocOut,
-                                                      SecOut, Scattered,
-                                                      Extern);
-}
-
-void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
-  const Type *Ty = GV->getType()->getElementType();
-  unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
-  unsigned Align = TM.getTargetData()->getPreferredAlignment(GV);
-
-  // Reserve space in the .bss section for this symbol while maintaining the
-  // desired section alignment, which must be at least as much as required by
-  // this symbol.
-  OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian);
-
-  if (Align) {
-    Align = Log2_32(Align);
-    Sec->align = std::max(unsigned(Sec->align), Align);
-
-    Sec->emitAlignment(Sec->align);
-  }
-  // Globals without external linkage apparently do not go in the symbol table.
-  if (!GV->hasLocalLinkage()) {
-    MachOSym Sym(GV, Mang->getMangledName(GV), Sec->Index, MAI);
-    Sym.n_value = Sec->size();
-    SymbolTable.push_back(Sym);
-  }
-
-  // Record the offset of the symbol, and then allocate space for it.
-  // FIXME: remove when we have unified size + output buffer
-
-  // Now that we know what section the GlovalVariable is going to be emitted
-  // into, update our mappings.
-  // FIXME: We may also need to update this when outputting non-GlobalVariable
-  // GlobalValues such as functions.
-
-  GVSection[GV] = Sec;
-  GVOffset[GV] = Sec->size();
-
-  // Allocate space in the section for the global.
-  for (unsigned i = 0; i < Size; ++i)
-    SecDataOut.outbyte(0);
-}
-
-void MachOWriter::EmitGlobal(GlobalVariable *GV) {
-  const Type *Ty = GV->getType()->getElementType();
-  unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
-  bool NoInit = !GV->hasInitializer();
-
-  // If this global has a zero initializer, it is part of the .bss or common
-  // section.
-  if (NoInit || GV->getInitializer()->isNullValue()) {
-    // If this global is part of the common block, add it now.  Variables are
-    // part of the common block if they are zero initialized and allowed to be
-    // merged with other symbols.
-    if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
-        GV->hasCommonLinkage()) {
-      MachOSym ExtOrCommonSym(GV, Mang->getMangledName(GV),
-                              MachOSym::NO_SECT, MAI);
-      // For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
-      // bytes of the symbol.
-      ExtOrCommonSym.n_value = Size;
-      SymbolTable.push_back(ExtOrCommonSym);
-      // Remember that we've seen this symbol
-      GVOffset[GV] = Size;
-      return;
-    }
-    // Otherwise, this symbol is part of the .bss section.
-    MachOSection *BSS = getBSSSection();
-    AddSymbolToSection(BSS, GV);
-    return;
-  }
-
-  // Scalar read-only data goes in a literal section if the scalar is 4, 8, or
-  // 16 bytes, or a cstring.  Other read only data goes into a regular const
-  // section.  Read-write data goes in the data section.
-  MachOSection *Sec = GV->isConstant() ? getConstSection(GV->getInitializer()) :
-                                         getDataSection();
-  AddSymbolToSection(Sec, GV);
-  InitMem(GV->getInitializer(), GVOffset[GV], TM.getTargetData(), Sec);
-}
-
-
-
-void MachOWriter::EmitHeaderAndLoadCommands() {
-  // Step #0: Fill in the segment load command size, since we need it to figure
-  //          out the rest of the header fields
-
-  MachOSegment SEG("", is64Bit);
-  SEG.nsects  = SectionList.size();
-  SEG.cmdsize = SEG.cmdSize(is64Bit) +
-                SEG.nsects * SectionList[0]->cmdSize(is64Bit);
-
-  // Step #1: calculate the number of load commands.  We always have at least
-  //          one, for the LC_SEGMENT load command, plus two for the normal
-  //          and dynamic symbol tables, if there are any symbols.
-  Header.ncmds = SymbolTable.empty() ? 1 : 3;
-
-  // Step #2: calculate the size of the load commands
-  Header.sizeofcmds = SEG.cmdsize;
-  if (!SymbolTable.empty())
-    Header.sizeofcmds += SymTab.cmdsize + DySymTab.cmdsize;
-
-  // Step #3: write the header to the file
-  // Local alias to shortenify coming code.
-  std::vector<unsigned char> &FH = Header.HeaderData;
-  OutputBuffer FHOut(FH, is64Bit, isLittleEndian);
-
-  FHOut.outword(Header.magic);
-  FHOut.outword(TM.getMachOWriterInfo()->getCPUType());
-  FHOut.outword(TM.getMachOWriterInfo()->getCPUSubType());
-  FHOut.outword(Header.filetype);
-  FHOut.outword(Header.ncmds);
-  FHOut.outword(Header.sizeofcmds);
-  FHOut.outword(Header.flags);
-  if (is64Bit)
-    FHOut.outword(Header.reserved);
-
-  // Step #4: Finish filling in the segment load command and write it out
-  for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
-         E = SectionList.end(); I != E; ++I)
-    SEG.filesize += (*I)->size();
-
-  SEG.vmsize = SEG.filesize;
-  SEG.fileoff = Header.cmdSize(is64Bit) + Header.sizeofcmds;
-
-  FHOut.outword(SEG.cmd);
-  FHOut.outword(SEG.cmdsize);
-  FHOut.outstring(SEG.segname, 16);
-  FHOut.outaddr(SEG.vmaddr);
-  FHOut.outaddr(SEG.vmsize);
-  FHOut.outaddr(SEG.fileoff);
-  FHOut.outaddr(SEG.filesize);
-  FHOut.outword(SEG.maxprot);
-  FHOut.outword(SEG.initprot);
-  FHOut.outword(SEG.nsects);
-  FHOut.outword(SEG.flags);
-
-  // Step #5: Finish filling in the fields of the MachOSections
-  uint64_t currentAddr = 0;
-  for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
-         E = SectionList.end(); I != E; ++I) {
-    MachOSection *MOS = *I;
-    MOS->addr = currentAddr;
-    MOS->offset = currentAddr + SEG.fileoff;
-    // FIXME: do we need to do something with alignment here?
-    currentAddr += MOS->size();
-  }
-
-  // Step #6: Emit the symbol table to temporary buffers, so that we know the
-  // size of the string table when we write the next load command.  This also
-  // sorts and assigns indices to each of the symbols, which is necessary for
-  // emitting relocations to externally-defined objects.
-  BufferSymbolAndStringTable();
-
-  // Step #7: Calculate the number of relocations for each section and write out
-  // the section commands for each section
-  currentAddr += SEG.fileoff;
-  for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
-         E = SectionList.end(); I != E; ++I) {
-    MachOSection *MOS = *I;
-
-    // Convert the relocations to target-specific relocations, and fill in the
-    // relocation offset for this section.
-    CalculateRelocations(*MOS);
-    MOS->reloff = MOS->nreloc ? currentAddr : 0;
-    currentAddr += MOS->nreloc * 8;
-
-    // write the finalized section command to the output buffer
-    FHOut.outstring(MOS->sectname, 16);
-    FHOut.outstring(MOS->segname, 16);
-    FHOut.outaddr(MOS->addr);
-    FHOut.outaddr(MOS->size());
-    FHOut.outword(MOS->offset);
-    FHOut.outword(MOS->align);
-    FHOut.outword(MOS->reloff);
-    FHOut.outword(MOS->nreloc);
-    FHOut.outword(MOS->flags);
-    FHOut.outword(MOS->reserved1);
-    FHOut.outword(MOS->reserved2);
-    if (is64Bit)
-      FHOut.outword(MOS->reserved3);
-  }
-
-  // Step #8: Emit LC_SYMTAB/LC_DYSYMTAB load commands
-  SymTab.symoff  = currentAddr;
-  SymTab.nsyms   = SymbolTable.size();
-  SymTab.stroff  = SymTab.symoff + SymT.size();
-  SymTab.strsize = StrT.size();
-  FHOut.outword(SymTab.cmd);
-  FHOut.outword(SymTab.cmdsize);
-  FHOut.outword(SymTab.symoff);
-  FHOut.outword(SymTab.nsyms);
-  FHOut.outword(SymTab.stroff);
-  FHOut.outword(SymTab.strsize);
-
-  // FIXME: set DySymTab fields appropriately
-  // We should probably just update these in BufferSymbolAndStringTable since
-  // thats where we're partitioning up the different kinds of symbols.
-  FHOut.outword(DySymTab.cmd);
-  FHOut.outword(DySymTab.cmdsize);
-  FHOut.outword(DySymTab.ilocalsym);
-  FHOut.outword(DySymTab.nlocalsym);
-  FHOut.outword(DySymTab.iextdefsym);
-  FHOut.outword(DySymTab.nextdefsym);
-  FHOut.outword(DySymTab.iundefsym);
-  FHOut.outword(DySymTab.nundefsym);
-  FHOut.outword(DySymTab.tocoff);
-  FHOut.outword(DySymTab.ntoc);
-  FHOut.outword(DySymTab.modtaboff);
-  FHOut.outword(DySymTab.nmodtab);
-  FHOut.outword(DySymTab.extrefsymoff);
-  FHOut.outword(DySymTab.nextrefsyms);
-  FHOut.outword(DySymTab.indirectsymoff);
-  FHOut.outword(DySymTab.nindirectsyms);
-  FHOut.outword(DySymTab.extreloff);
-  FHOut.outword(DySymTab.nextrel);
-  FHOut.outword(DySymTab.locreloff);
-  FHOut.outword(DySymTab.nlocrel);
-
-  O.write((char*)&FH[0], FH.size());
-}
-
-/// EmitSections - Now that we have constructed the file header and load
-/// commands, emit the data for each section to the file.
-void MachOWriter::EmitSections() {
-  for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
-         E = SectionList.end(); I != E; ++I)
-    // Emit the contents of each section
-    if ((*I)->size())
-      O.write((char*)&(*I)->getData()[0], (*I)->size());
-}
-
-/// EmitRelocations - emit relocation data from buffer.
-void MachOWriter::EmitRelocations() {
-  for (std::vector<MachOSection*>::iterator I = SectionList.begin(),
-         E = SectionList.end(); I != E; ++I)
-    // Emit the relocation entry data for each section.
-    if ((*I)->RelocBuffer.size())
-      O.write((char*)&(*I)->RelocBuffer[0], (*I)->RelocBuffer.size());
-}
-
-/// BufferSymbolAndStringTable - Sort the symbols we encountered and assign them
-/// each a string table index so that they appear in the correct order in the
-/// output file.
-void MachOWriter::BufferSymbolAndStringTable() {
-  // The order of the symbol table is:
-  // 1. local symbols
-  // 2. defined external symbols (sorted by name)
-  // 3. undefined external symbols (sorted by name)
-
-  // Before sorting the symbols, check the PendingGlobals for any undefined
-  // globals that need to be put in the symbol table.
-  for (std::vector<GlobalValue*>::iterator I = PendingGlobals.begin(),
-         E = PendingGlobals.end(); I != E; ++I) {
-    if (GVOffset[*I] == 0 && GVSection[*I] == 0) {
-      MachOSym UndfSym(*I, Mang->getMangledName(*I), MachOSym::NO_SECT, MAI);
-      SymbolTable.push_back(UndfSym);
-      GVOffset[*I] = -1;
-    }
-  }
-
-  // Sort the symbols by name, so that when we partition the symbols by scope
-  // of definition, we won't have to sort by name within each partition.
-  std::sort(SymbolTable.begin(), SymbolTable.end(), MachOSym::SymCmp());
-
-  // Parition the symbol table entries so that all local symbols come before
-  // all symbols with external linkage. { 1 | 2 3 }
-  std::partition(SymbolTable.begin(), SymbolTable.end(),
-                 MachOSym::PartitionByLocal);
-
-  // Advance iterator to beginning of external symbols and partition so that
-  // all external symbols defined in this module come before all external
-  // symbols defined elsewhere. { 1 | 2 | 3 }
-  for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
-         E = SymbolTable.end(); I != E; ++I) {
-    if (!MachOSym::PartitionByLocal(*I)) {
-      std::partition(I, E, MachOSym::PartitionByDefined);
-      break;
-    }
-  }
-
-  // Calculate the starting index for each of the local, extern defined, and
-  // undefined symbols, as well as the number of each to put in the LC_DYSYMTAB
-  // load command.
-  for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
-         E = SymbolTable.end(); I != E; ++I) {
-    if (MachOSym::PartitionByLocal(*I)) {
-      ++DySymTab.nlocalsym;
-      ++DySymTab.iextdefsym;
-      ++DySymTab.iundefsym;
-    } else if (MachOSym::PartitionByDefined(*I)) {
-      ++DySymTab.nextdefsym;
-      ++DySymTab.iundefsym;
-    } else {
-      ++DySymTab.nundefsym;
-    }
-  }
-
-  // Write out a leading zero byte when emitting string table, for n_strx == 0
-  // which means an empty string.
-  OutputBuffer StrTOut(StrT, is64Bit, isLittleEndian);
-  StrTOut.outbyte(0);
-
-  // The order of the string table is:
-  // 1. strings for external symbols
-  // 2. strings for local symbols
-  // Since this is the opposite order from the symbol table, which we have just
-  // sorted, we can walk the symbol table backwards to output the string table.
-  for (std::vector<MachOSym>::reverse_iterator I = SymbolTable.rbegin(),
-        E = SymbolTable.rend(); I != E; ++I) {
-    if (I->GVName == "") {
-      I->n_strx = 0;
-    } else {
-      I->n_strx = StrT.size();
-      StrTOut.outstring(I->GVName, I->GVName.length()+1);
-    }
-  }
-
-  OutputBuffer SymTOut(SymT, is64Bit, isLittleEndian);
-
-  unsigned index = 0;
-  for (std::vector<MachOSym>::iterator I = SymbolTable.begin(),
-         E = SymbolTable.end(); I != E; ++I, ++index) {
-    // Add the section base address to the section offset in the n_value field
-    // to calculate the full address.
-    // FIXME: handle symbols where the n_value field is not the address
-    GlobalValue *GV = const_cast<GlobalValue*>(I->GV);
-    if (GV && GVSection[GV])
-      I->n_value += GVSection[GV]->addr;
-    if (GV && (GVOffset[GV] == -1))
-      GVOffset[GV] = index;
-
-    // Emit nlist to buffer
-    SymTOut.outword(I->n_strx);
-    SymTOut.outbyte(I->n_type);
-    SymTOut.outbyte(I->n_sect);
-    SymTOut.outhalf(I->n_desc);
-    SymTOut.outaddr(I->n_value);
-  }
-}
-
-/// CalculateRelocations - For each MachineRelocation in the current section,
-/// calculate the index of the section containing the object to be relocated,
-/// and the offset into that section.  From this information, create the
-/// appropriate target-specific MachORelocation type and add buffer it to be
-/// written out after we are finished writing out sections.
-void MachOWriter::CalculateRelocations(MachOSection &MOS) {
-  std::vector<MachineRelocation> Relocations =  MOS.getRelocations();
-  for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
-    MachineRelocation &MR = Relocations[i];
-    unsigned TargetSection = MR.getConstantVal();
-    unsigned TargetAddr = 0;
-    unsigned TargetIndex = 0;
-
-    // This is a scattered relocation entry if it points to a global value with
-    // a non-zero offset.
-    bool Scattered = false;
-    bool Extern = false;
-
-    // Since we may not have seen the GlobalValue we were interested in yet at
-    // the time we emitted the relocation for it, fix it up now so that it
-    // points to the offset into the correct section.
-    if (MR.isGlobalValue()) {
-      GlobalValue *GV = MR.getGlobalValue();
-      MachOSection *MOSPtr = GVSection[GV];
-      intptr_t Offset = GVOffset[GV];
-
-      // If we have never seen the global before, it must be to a symbol
-      // defined in another module (N_UNDF).
-      if (!MOSPtr) {
-        // FIXME: need to append stub suffix
-        Extern = true;
-        TargetAddr = 0;
-        TargetIndex = GVOffset[GV];
-      } else {
-        Scattered = TargetSection != 0;
-        TargetSection = MOSPtr->Index;
-      }
-      MR.setResultPointer((void*)Offset);
-    }
-
-    // If the symbol is locally defined, pass in the address of the section and
-    // the section index to the code which will generate the target relocation.
-    if (!Extern) {
-        MachOSection &To = *SectionList[TargetSection - 1];
-        TargetAddr = To.addr;
-        TargetIndex = To.Index;
-    }
-
-    OutputBuffer RelocOut(MOS.RelocBuffer, is64Bit, isLittleEndian);
-    OutputBuffer SecOut(MOS.getData(), is64Bit, isLittleEndian);
-
-    MOS.nreloc += GetTargetRelocation(MR, MOS.Index, TargetAddr, TargetIndex,
-                                      RelocOut, SecOut, Scattered, Extern);
-  }
-}
-
-// InitMem - Write the value of a Constant to the specified memory location,
-// converting it into bytes and relocations.
-void MachOWriter::InitMem(const Constant *C, uintptr_t Offset,
-                          const TargetData *TD, MachOSection* mos) {
-  typedef std::pair<const Constant*, intptr_t> CPair;
-  std::vector<CPair> WorkList;
-  uint8_t *Addr = &mos->getData()[0];
-
-  WorkList.push_back(CPair(C,(intptr_t)Addr + Offset));
-
-  intptr_t ScatteredOffset = 0;
-
-  while (!WorkList.empty()) {
-    const Constant *PC = WorkList.back().first;
-    intptr_t PA = WorkList.back().second;
-    WorkList.pop_back();
-
-    if (isa<UndefValue>(PC)) {
-      continue;
-    } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(PC)) {
-      unsigned ElementSize =
-        TD->getTypeAllocSize(CP->getType()->getElementType());
-      for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
-        WorkList.push_back(CPair(CP->getOperand(i), PA+i*ElementSize));
-    } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(PC)) {
-      //
-      // FIXME: Handle ConstantExpression.  See EE::getConstantValue()
-      //
-      switch (CE->getOpcode()) {
-      case Instruction::GetElementPtr: {
-        SmallVector<Value*, 8> Indices(CE->op_begin()+1, CE->op_end());
-        ScatteredOffset = TD->getIndexedOffset(CE->getOperand(0)->getType(),
-                                               &Indices[0], Indices.size());
-        WorkList.push_back(CPair(CE->getOperand(0), PA));
-        break;
-      }
-      case Instruction::Add:
-      default:
-        dbgs() << "ConstantExpr not handled as global var init: " << *CE <<"\n";
-        llvm_unreachable(0);
-      }
-    } else if (PC->getType()->isSingleValueType()) {
-      unsigned char *ptr = (unsigned char *)PA;
-      switch (PC->getType()->getTypeID()) {
-      case Type::IntegerTyID: {
-        unsigned NumBits = cast<IntegerType>(PC->getType())->getBitWidth();
-        uint64_t val = cast<ConstantInt>(PC)->getZExtValue();
-        if (NumBits <= 8)
-          ptr[0] = val;
-        else if (NumBits <= 16) {
-          if (TD->isBigEndian())
-            val = ByteSwap_16(val);
-          ptr[0] = val;
-          ptr[1] = val >> 8;
-        } else if (NumBits <= 32) {
-          if (TD->isBigEndian())
-            val = ByteSwap_32(val);
-          ptr[0] = val;
-          ptr[1] = val >> 8;
-          ptr[2] = val >> 16;
-          ptr[3] = val >> 24;
-        } else if (NumBits <= 64) {
-          if (TD->isBigEndian())
-            val = ByteSwap_64(val);
-          ptr[0] = val;
-          ptr[1] = val >> 8;
-          ptr[2] = val >> 16;
-          ptr[3] = val >> 24;
-          ptr[4] = val >> 32;
-          ptr[5] = val >> 40;
-          ptr[6] = val >> 48;
-          ptr[7] = val >> 56;
-        } else {
-          llvm_unreachable("Not implemented: bit widths > 64");
+        switch (MO.getType()) {
+          default:
+            MI->dump();
+            llvm_unreachable("unknown operand type");
+          case MachineOperand::MO_Register:
+            // Ignore all implicit register operands.
+            if (MO.isImplicit()) continue;
+            MCOp = MCOperand::CreateReg(MO.getReg());
+            break;
+          case MachineOperand::MO_Immediate:
+            MCOp = MCOperand::CreateImm(MO.getImm());
+            break;
         }
-        break;
+        OutMI.addOperand(MCOp);
       }
-      case Type::FloatTyID: {
-        uint32_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
-                        getZExtValue();
-        if (TD->isBigEndian())
-          val = ByteSwap_32(val);
-        ptr[0] = val;
-        ptr[1] = val >> 8;
-        ptr[2] = val >> 16;
-        ptr[3] = val >> 24;
-        break;
-      }
-      case Type::DoubleTyID: {
-        uint64_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
-                         getZExtValue();
-        if (TD->isBigEndian())
-          val = ByteSwap_64(val);
-        ptr[0] = val;
-        ptr[1] = val >> 8;
-        ptr[2] = val >> 16;
-        ptr[3] = val >> 24;
-        ptr[4] = val >> 32;
-        ptr[5] = val >> 40;
-        ptr[6] = val >> 48;
-        ptr[7] = val >> 56;
-        break;
-      }
-      case Type::PointerTyID:
-        if (isa<ConstantPointerNull>(PC))
-          memset(ptr, 0, TD->getPointerSize());
-        else if (const GlobalValue* GV = dyn_cast<GlobalValue>(PC)) {
-          // FIXME: what about function stubs?
-          mos->addRelocation(MachineRelocation::getGV(PA-(intptr_t)Addr,
-                                                 MachineRelocation::VANILLA,
-                                                 const_cast<GlobalValue*>(GV),
-                                                 ScatteredOffset));
-          ScatteredOffset = 0;
-        } else
-          llvm_unreachable("Unknown constant pointer type!");
-        break;
-      default:
-        std::string msg;
-        raw_string_ostream Msg(msg);
-        Msg << "ERROR: Constant unimp for type: " << *PC->getType();
-        llvm_report_error(Msg.str());
-      }
-    } else if (isa<ConstantAggregateZero>(PC)) {
-      memset((void*)PA, 0, (size_t)TD->getTypeAllocSize(PC->getType()));
-    } else if (const ConstantArray *CPA = dyn_cast<ConstantArray>(PC)) {
-      unsigned ElementSize =
-        TD->getTypeAllocSize(CPA->getType()->getElementType());
-      for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
-        WorkList.push_back(CPair(CPA->getOperand(i), PA+i*ElementSize));
-    } else if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(PC)) {
-      const StructLayout *SL =
-        TD->getStructLayout(cast<StructType>(CPS->getType()));
-      for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i)
-        WorkList.push_back(CPair(CPS->getOperand(i),
-                                 PA+SL->getElementOffset(i)));
-    } else {
-      dbgs() << "Bad Type: " << *PC->getType() << "\n";
-      llvm_unreachable("Unknown constant type to initialize memory with!");
+      
+      OutStreamer.EmitInstruction(OutMI);
     }
   }
+
+  return false;
 }
-
-//===----------------------------------------------------------------------===//
-//                          MachOSym Implementation
-//===----------------------------------------------------------------------===//
-
-MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
-                   const MCAsmInfo *MAI) :
-  GV(gv), n_strx(0), n_type(sect == NO_SECT ? N_UNDF : N_SECT), n_sect(sect),
-  n_desc(0), n_value(0) {
-
-  // FIXME: This is completely broken, it should use the mangler interface.
-  switch (GV->getLinkage()) {
-  default:
-    llvm_unreachable("Unexpected linkage type!");
-    break;
-  case GlobalValue::WeakAnyLinkage:
-  case GlobalValue::WeakODRLinkage:
-  case GlobalValue::LinkOnceAnyLinkage:
-  case GlobalValue::LinkOnceODRLinkage:
-  case GlobalValue::CommonLinkage:
-    assert(!isa<Function>(gv) && "Unexpected linkage type for Function!");
-  case GlobalValue::ExternalLinkage:
-    GVName = MAI->getGlobalPrefix() + name;
-    n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT;
-    break;
-  case GlobalValue::PrivateLinkage:
-    GVName = MAI->getPrivateGlobalPrefix() + name;
-    break;
-  case GlobalValue::LinkerPrivateLinkage:
-    GVName = MAI->getLinkerPrivateGlobalPrefix() + name;
-    break;
-  case GlobalValue::InternalLinkage:
-    GVName = MAI->getGlobalPrefix() + name;
-    break;
-  }
-}
-
-} // end namespace llvm
diff --git a/lib/CodeGen/MachOWriter.h b/lib/CodeGen/MachOWriter.h
index 9273f38..2e7e67d 100644
--- a/lib/CodeGen/MachOWriter.h
+++ b/lib/CodeGen/MachOWriter.h
@@ -15,191 +15,73 @@
 #define MACHOWRITER_H
 
 #include "llvm/CodeGen/MachineFunctionPass.h"
-#include <vector>
-#include <map>
+#include "llvm/Target/TargetMachine.h"
 
 namespace llvm {
-  class Constant;
   class GlobalVariable;
   class Mangler;
-  class MachineBasicBlock;
-  class MachineRelocation;
-  class MachOCodeEmitter;
-  struct MachODySymTab;
-  struct MachOHeader;
-  struct MachOSection;
-  struct MachOSym;
-  class TargetData;
-  class TargetMachine;
-  class MCAsmInfo;
-  class ObjectCodeEmitter;
-  class OutputBuffer;
-  class raw_ostream;
-
+  class MCCodeEmitter;
+  class MCContext;
+  class MCStreamer;
+  
   /// MachOWriter - This class implements the common target-independent code for
   /// writing Mach-O files.  Targets should derive a class from this to
   /// parameterize the output format.
   ///
   class MachOWriter : public MachineFunctionPass {
-    friend class MachOCodeEmitter;
-  public:
     static char ID;
 
-    ObjectCodeEmitter *getObjectCodeEmitter() {
-      return reinterpret_cast<ObjectCodeEmitter*>(MachOCE);
-    }
-
-    MachOWriter(raw_ostream &O, TargetMachine &TM);
-    virtual ~MachOWriter();
-
-    virtual const char *getPassName() const {
-      return "Mach-O Writer";
-    }
-
   protected:
     /// Output stream to send the resultant object file to.
     ///
-    raw_ostream &O;
+    formatted_raw_ostream &O;
 
     /// Target machine description.
     ///
     TargetMachine &TM;
 
-    /// Mang - The object used to perform name mangling for this module.
+    /// Target Asm Printer information.
+    ///
+    const MCAsmInfo *MAI;
+    
+    /// MCCE - The MCCodeEmitter object that we are exposing to emit machine
+    /// code for functions to the .o file.
+    MCCodeEmitter *MCCE;
+    
+    /// OutContext - This is the context for the output file that we are
+    /// streaming.  This owns all of the global MC-related objects for the
+    /// generated translation unit.
+    MCContext &OutContext;
+    
+    /// OutStreamer - This is the MCStreamer object for the file we are
+    /// generating.  This contains the transient state for the current
+    /// translation unit that we are generating (such as the current section
+    /// etc).
+    MCStreamer &OutStreamer;
+    
+    /// Name-mangler for global names.
     ///
     Mangler *Mang;
-
-    /// MachOCE - The MachineCodeEmitter object that we are exposing to emit
-    /// machine code for functions to the .o file.
-    MachOCodeEmitter *MachOCE;
-
-    /// is64Bit/isLittleEndian - This information is inferred from the target
-    /// machine directly, indicating what header values and flags to set.
-    bool is64Bit, isLittleEndian;
-
-    // Target Asm Info
-    const MCAsmInfo *MAI;
-
-    /// Header - An instance of MachOHeader that we will update while we build
-    /// the file, and then emit during finalization.
-    MachOHeader Header;
-
+    
     /// doInitialization - Emit the file header and all of the global variables
     /// for the module to the Mach-O file.
     bool doInitialization(Module &M);
 
-    bool runOnMachineFunction(MachineFunction &MF);
-
     /// doFinalization - Now that the module has been completely processed, emit
     /// the Mach-O file to 'O'.
     bool doFinalization(Module &M);
 
-  private:
-
-    /// SectionList - This is the list of sections that we have emitted to the
-    /// file.  Once the file has been completely built, the segment load command
-    /// SectionCommands are constructed from this info.
-    std::vector<MachOSection*> SectionList;
-
-    /// SectionLookup - This is a mapping from section name to SectionList entry
-    std::map<std::string, MachOSection*> SectionLookup;
-
-    /// GVSection - This is a mapping from a GlobalValue to a MachOSection,
-    /// to aid in emitting relocations.
-    std::map<GlobalValue*, MachOSection*> GVSection;
-
-    /// GVOffset - This is a mapping from a GlobalValue to an offset from the
-    /// start of the section in which the GV resides, to aid in emitting
-    /// relocations.
-    std::map<GlobalValue*, intptr_t> GVOffset;
-
-    /// getSection - Return the section with the specified name, creating a new
-    /// section if one does not already exist.
-    MachOSection *getSection(const std::string &seg, const std::string &sect,
-                             unsigned Flags = 0);
-
-    /// getTextSection - Return text section with different flags for code/data
-    MachOSection *getTextSection(bool isCode = true);
-
-    MachOSection *getDataSection() {
-      return getSection("__DATA", "__data");
+    bool runOnMachineFunction(MachineFunction &MF);
+    
+  public:
+    explicit MachOWriter(formatted_raw_ostream &O, TargetMachine &TM,
+                         const MCAsmInfo *T, MCCodeEmitter *MCE);
+    
+    virtual ~MachOWriter();
+    
+    virtual const char *getPassName() const {
+      return "Mach-O Writer";
     }
-
-    MachOSection *getBSSSection();
-    MachOSection *getConstSection(Constant *C);
-    MachOSection *getJumpTableSection();
-
-    /// MachOSymTab - This struct contains information about the offsets and
-    /// size of symbol table information.
-    /// segment.
-    struct MachOSymTab {
-      uint32_t cmd;     // LC_SYMTAB
-      uint32_t cmdsize; // sizeof( MachOSymTab )
-      uint32_t symoff;  // symbol table offset
-      uint32_t nsyms;   // number of symbol table entries
-      uint32_t stroff;  // string table offset
-      uint32_t strsize; // string table size in bytes
-
-      // Constants for the cmd field
-      // see <mach-o/loader.h>
-      enum { LC_SYMTAB = 0x02  // link-edit stab symbol table info
-      };
-
-      MachOSymTab() : cmd(LC_SYMTAB), cmdsize(6 * sizeof(uint32_t)), symoff(0),
-        nsyms(0), stroff(0), strsize(0) { }
-    };
-
-    /// SymTab - The "stab" style symbol table information
-    MachOSymTab SymTab;
-    /// DySymTab - symbol table info for the dynamic link editor
-    MachODySymTab DySymTab;
-
-  protected:
-
-    /// SymbolTable - This is the list of symbols we have emitted to the file.
-    /// This actually gets rearranged before emission to the file (to put the
-    /// local symbols first in the list).
-    std::vector<MachOSym> SymbolTable;
-
-    /// SymT - A buffer to hold the symbol table before we write it out at the
-    /// appropriate location in the file.
-    std::vector<unsigned char> SymT;
-
-    /// StrT - A buffer to hold the string table before we write it out at the
-    /// appropriate location in the file.
-    std::vector<unsigned char> StrT;
-
-    /// PendingSyms - This is a list of externally defined symbols that we have
-    /// been asked to emit, but have not seen a reference to.  When a reference
-    /// is seen, the symbol will move from this list to the SymbolTable.
-    std::vector<GlobalValue*> PendingGlobals;
-
-    /// DynamicSymbolTable - This is just a vector of indices into
-    /// SymbolTable to aid in emitting the DYSYMTAB load command.
-    std::vector<unsigned> DynamicSymbolTable;
-
-    static void InitMem(const Constant *C, uintptr_t Offset,
-                        const TargetData *TD, MachOSection* mos);
-
-  private:
-    void AddSymbolToSection(MachOSection *MOS, GlobalVariable *GV);
-    void EmitGlobal(GlobalVariable *GV);
-    void EmitHeaderAndLoadCommands();
-    void EmitSections();
-    void EmitRelocations();
-    void BufferSymbolAndStringTable();
-    void CalculateRelocations(MachOSection &MOS);
-
-    // GetJTRelocation - Get a relocation a new BB relocation based
-    // on target information.
-    MachineRelocation GetJTRelocation(unsigned Offset,
-                                      MachineBasicBlock *MBB) const;
-
-    /// GetTargetRelocation - Returns the number of relocations.
-    unsigned GetTargetRelocation(MachineRelocation &MR, unsigned FromIdx,
-                                 unsigned ToAddr, unsigned ToIndex,
-                                 OutputBuffer &RelocOut, OutputBuffer &SecOut,
-                                 bool Scattered, bool Extern);
   };
 }
 
