X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FMachOWriter.cpp;h=22c21578ec0cb45b7c858e051fad483e48accd09;hb=ef4cfc749a61d0d0252196c957697436ba7ec068;hp=de81e5fd6a1b2aff1fc09a908ff61ae46a41066e;hpb=fec910c3b9ba5790e5a627e1801fce25fbdddbaa;p=oota-llvm.git diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp index de81e5fd6a1..22c21578ec0 100644 --- a/lib/CodeGen/MachOWriter.cpp +++ b/lib/CodeGen/MachOWriter.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Nate Begeman and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -31,23 +31,24 @@ #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetJITInfo.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/OutputBuffer.h" #include "llvm/Support/Streams.h" +#include "llvm/Support/raw_ostream.h" #include +#include using namespace llvm; /// AddMachOWriter - Concrete function to add the Mach-O writer to the function /// pass manager. -MachineCodeEmitter *llvm::AddMachOWriter(FunctionPassManager &FPM, - std::ostream &O, +MachineCodeEmitter *llvm::AddMachOWriter(PassManagerBase &PM, + raw_ostream &O, TargetMachine &TM) { MachOWriter *MOW = new MachOWriter(O, TM); - FPM.add(MOW); + PM.add(MOW); return &MOW->getMachineCodeEmitter(); } @@ -74,7 +75,7 @@ namespace llvm { /// CPLocations - This is a map of constant pool indices to offsets from the /// start of the section for that constant pool index. - std::vector CPLocations; + std::vector CPLocations; /// CPSections - This is a map of constant pool indices to the MachOSection /// containing the constant pool entry for that index. @@ -82,12 +83,12 @@ namespace llvm { /// JTLocations - This is a map of jump table indices to offsets from the /// start of the section for that jump table index. - std::vector JTLocations; + std::vector JTLocations; /// MBBLocations - This vector is a mapping from MBB ID's to their address. /// It is filled in by the StartMachineBasicBlock callback and queried by /// the getMachineBasicBlockAddress callback. - std::vector MBBLocations; + std::vector MBBLocations; public: MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM) { @@ -105,11 +106,11 @@ namespace llvm { void emitConstantPool(MachineConstantPool *MCP); void emitJumpTables(MachineJumpTableInfo *MJTI); - virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const { + virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const { assert(CPLocations.size() > Index && "CP not emitted!"); - return CPLocations[Index];\ + return CPLocations[Index]; } - virtual intptr_t getJumpTableEntryAddress(unsigned Index) const { + virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const { assert(JTLocations.size() > Index && "JT not emitted!"); return JTLocations[Index]; } @@ -120,18 +121,38 @@ namespace llvm { MBBLocations[MBB->getNumber()] = getCurrentPCOffset(); } - virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { + virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { assert(MBBLocations.size() > (unsigned)MBB->getNumber() && MBBLocations[MBB->getNumber()] && "MBB not emitted!"); return MBBLocations[MBB->getNumber()]; } + virtual uintptr_t getLabelAddress(uint64_t Label) const { + assert(0 && "get Label not implemented"); + abort(); + return 0; + } + + virtual void emitLabel(uint64_t LabelID) { + assert(0 && "emit Label not implemented"); + abort(); + } + + + virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { } + /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE! - virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) { + virtual void startGVStub(const GlobalValue* F, unsigned StubSize, + unsigned Alignment = 1) { + assert(0 && "JIT specific function called!"); + abort(); + } + virtual void startGVStub(const GlobalValue* F, void *Buffer, + unsigned StubSize) { assert(0 && "JIT specific function called!"); abort(); } - virtual void *finishFunctionStub(const Function *F) { + virtual void *finishGVStub(const GlobalValue* F) { assert(0 && "JIT specific function called!"); abort(); return 0; @@ -248,8 +269,8 @@ void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) { if (CP.empty()) return; // FIXME: handle PIC codegen - bool isPIC = TM.getRelocationModel() == Reloc::PIC_; - assert(!isPIC && "PIC codegen not yet handled for mach-o jump tables!"); + 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 @@ -260,7 +281,7 @@ void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) { // "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()->getTypeSize(Ty); + unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); MachOWriter::MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal); OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian); @@ -289,8 +310,8 @@ void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) { if (JT.empty()) return; // FIXME: handle PIC codegen - bool isPIC = TM.getRelocationModel() == Reloc::PIC_; - assert(!isPIC && "PIC codegen not yet handled for mach-o jump tables!"); + assert(TM.getRelocationModel() != Reloc::PIC_ && + "PIC codegen not yet handled for mach-o jump tables!"); MachOWriter::MachOSection *Sec = MOW.getJumpTableSection(); unsigned TextSecIndex = MOW.getTextSection()->Index; @@ -318,7 +339,9 @@ void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) { // MachOWriter Implementation //===----------------------------------------------------------------------===// -MachOWriter::MachOWriter(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { +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(); @@ -332,11 +355,9 @@ MachOWriter::~MachOWriter() { void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) { const Type *Ty = GV->getType()->getElementType(); - unsigned Size = TM.getTargetData()->getTypeSize(Ty); - unsigned Align = GV->getAlignment(); - if (Align == 0) - Align = TM.getTargetData()->getPrefTypeAlignment(Ty); - + unsigned Size = TM.getTargetData()->getTypePaddedSize(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. @@ -355,7 +376,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) { SecDataOut.outbyte(0); } // Globals without external linkage apparently do not go in the symbol table. - if (GV->getLinkage() != GlobalValue::InternalLinkage) { + if (!GV->hasLocalLinkage()) { MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM); Sym.n_value = Sec->size; SymbolTable.push_back(Sym); @@ -379,7 +400,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) { void MachOWriter::EmitGlobal(GlobalVariable *GV) { const Type *Ty = GV->getType()->getElementType(); - unsigned Size = TM.getTargetData()->getTypeSize(Ty); + unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty); bool NoInit = !GV->hasInitializer(); // If this global has a zero initializer, it is part of the .bss or common @@ -388,7 +409,8 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) { // 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()) { + if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() || + GV->hasCommonLinkage()) { MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT,TM); // For undefined (N_UNDF) external (N_EXT) types, n_value is the size in // bytes of the symbol. @@ -736,14 +758,14 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) { for (unsigned i = 0, e = MOS.Relocations.size(); i != e; ++i) { MachineRelocation &MR = MOS.Relocations[i]; unsigned TargetSection = MR.getConstantVal(); - unsigned TargetAddr; - unsigned TargetIndex; + 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. @@ -762,11 +784,16 @@ void MachOWriter::CalculateRelocations(MachOSection &MOS) { } 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; - } - MR.setResultPointer((void*)Offset); } OutputBuffer RelocOut(MOS.RelocBuffer, is64Bit, isLittleEndian); @@ -797,7 +824,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, if (isa(PC)) { continue; } else if (const ConstantVector *CP = dyn_cast(PC)) { - unsigned ElementSize = TD->getTypeSize(CP->getType()->getElementType()); + unsigned ElementSize = + TD->getTypePaddedSize(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(PC)) { @@ -818,7 +846,7 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, abort(); break; } - } else if (PC->getType()->isFirstClassType()) { + } else if (PC->getType()->isSingleValueType()) { unsigned char *ptr = (unsigned char *)PA; switch (PC->getType()->getTypeID()) { case Type::IntegerTyID: { @@ -855,7 +883,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, break; } case Type::FloatTyID: { - uint64_t val = FloatToBits(cast(PC)->getValue()); + uint32_t val = cast(PC)->getValueAPF().bitcastToAPInt(). + getZExtValue(); if (TD->isBigEndian()) val = ByteSwap_32(val); ptr[0] = val; @@ -865,7 +894,8 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, break; } case Type::DoubleTyID: { - uint64_t val = DoubleToBits(cast(PC)->getValue()); + uint64_t val = cast(PC)->getValueAPF().bitcastToAPInt(). + getZExtValue(); if (TD->isBigEndian()) val = ByteSwap_64(val); ptr[0] = val; @@ -896,9 +926,10 @@ void MachOWriter::InitMem(const Constant *C, void *Addr, intptr_t Offset, abort(); } } else if (isa(PC)) { - memset((void*)PA, 0, (size_t)TD->getTypeSize(PC->getType())); + memset((void*)PA, 0, (size_t)TD->getTypePaddedSize(PC->getType())); } else if (const ConstantArray *CPA = dyn_cast(PC)) { - unsigned ElementSize = TD->getTypeSize(CPA->getType()->getElementType()); + unsigned ElementSize = + TD->getTypePaddedSize(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(PC)) { @@ -927,11 +958,15 @@ MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect, break; case GlobalValue::WeakLinkage: case GlobalValue::LinkOnceLinkage: + case GlobalValue::CommonLinkage: assert(!isa(gv) && "Unexpected linkage type for Function!"); case GlobalValue::ExternalLinkage: GVName = TAI->getGlobalPrefix() + name; n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT; break; + case GlobalValue::PrivateLinkage: + GVName = TAI->getPrivateGlobalPrefix() + name; + break; case GlobalValue::InternalLinkage: GVName = TAI->getGlobalPrefix() + name; break;