diff options
-rw-r--r-- | include/llvm/CodeGen/FileWriters.h | 10 | ||||
-rw-r--r-- | include/llvm/Target/TargetMachine.h | 8 | ||||
-rw-r--r-- | lib/CodeGen/LLVMTargetMachine.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/MachO.h | 412 | ||||
-rw-r--r-- | lib/CodeGen/MachOCodeEmitter.cpp | 193 | ||||
-rw-r--r-- | lib/CodeGen/MachOCodeEmitter.h | 69 | ||||
-rw-r--r-- | lib/CodeGen/MachOWriter.cpp | 793 | ||||
-rw-r--r-- | lib/CodeGen/MachOWriter.h | 192 | ||||
-rw-r--r-- | tools/llc/llc.cpp | 2 | ||||
-rw-r--r-- | tools/lto/LTOCodeGenerator.cpp | 4 |
10 files changed, 144 insertions, 1556 deletions
diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h index a913d21eb2..9dba838a15 100644 --- a/include/llvm/CodeGen/FileWriters.h +++ b/include/llvm/CodeGen/FileWriters.h @@ -20,11 +20,17 @@ namespace llvm { class ObjectCodeEmitter; class TargetMachine; class raw_ostream; + class formatted_raw_ostream; + class MachineFunctionPass; + class MCAsmInfo; + class MCCodeEmitter; ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O, TargetMachine &TM); - ObjectCodeEmitter *AddMachOWriter(PassManagerBase &FPM, raw_ostream &O, - TargetMachine &TM); + MachineFunctionPass *createMachOWriter(formatted_raw_ostream &O, + TargetMachine &TM, + const MCAsmInfo *T, + MCCodeEmitter *MCE); } // end llvm namespace diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 84cd5b432b..5621e53270 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -452,6 +452,14 @@ public: bool addAssemblyEmitter(PassManagerBase &, CodeGenOpt::Level, bool /* VerboseAsmDefault */, formatted_raw_ostream &); + + /// addObjectFileEmitter - Helper function which creates a target specific + /// object files emitter, if available. This interface is temporary, for + /// bringing up MCAssembler-based object file emitters. + /// + /// \return Returns 'false' on success. + bool addObjectFileEmitter(PassManagerBase &, CodeGenOpt::Level, + formatted_raw_ostream &); }; } // End llvm namespace diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 2b5fd2c949..758c81dc59 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 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, 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 @@ bool LLVMTargetMachine::addAssemblyEmitter(PassManagerBase &PM, 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 f2b40fe58e..0000000000 --- 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 §) - : 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 13184772cd..0000000000 --- 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 475244646b..0000000000 --- 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 337eab1827..cab71cea0d 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 @@ ObjectCodeEmitter *AddMachOWriter(PassManagerBase &PM, 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); - - // 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, 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); - Mang = new Mangler(M); - return false; -} - -bool MachOWriter::runOnMachineFunction(MachineF |