X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FTargetLoweringObjectFileImpl.cpp;h=e8ef63aa5a999746293f7dddd96e617afea75a70;hb=f3d745cdc916df5a5db78ac0a5c0efbd8925c097;hp=b9a3ad23d1f812c710196e1abde1f08d58550ec2;hpb=dfe88a08c7f595801e733d3e6f4504d2695d5309;p=oota-llvm.git diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index b9a3ad23d1f..e8ef63aa5a9 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -31,6 +31,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" @@ -71,12 +72,10 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer, const MCSection *Sec = getContext().getELFSection(NameData, ELF::SHT_PROGBITS, Flags, - SectionKind::getDataRel(), 0, Label->getName()); - unsigned Size = TM.getSubtargetImpl()->getDataLayout()->getPointerSize(); + unsigned Size = TM.getDataLayout()->getPointerSize(); Streamer.SwitchSection(Sec); - Streamer.EmitValueToAlignment( - TM.getSubtargetImpl()->getDataLayout()->getPointerABIAlignment()); + Streamer.EmitValueToAlignment(TM.getDataLayout()->getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::Create(Size, getContext()); Streamer.EmitELFSize(Label, E); @@ -166,9 +165,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) { return ELF::SHT_PROGBITS; } - -static unsigned -getELFSectionFlags(SectionKind K) { +static unsigned getELFSectionFlags(SectionKind K) { unsigned Flags = 0; if (!K.isMetadata()) @@ -183,9 +180,7 @@ getELFSectionFlags(SectionKind K) { if (K.isThreadLocal()) Flags |= ELF::SHF_TLS; - // K.isMergeableConst() is left out to honour PR4650 - if (K.isMergeableCString() || K.isMergeableConst4() || - K.isMergeableConst8() || K.isMergeableConst16()) + if (K.isMergeableCString() || K.isMergeableConst()) Flags |= ELF::SHF_MERGE; if (K.isMergeableCString()) @@ -222,116 +217,129 @@ const MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( } return getContext().getELFSection(SectionName, getELFSectionType(SectionName, Kind), Flags, - Kind, /*EntrySize=*/0, Group); + /*EntrySize=*/0, Group); } -/// getSectionPrefixForGlobal - Return the section prefix name used by options -/// FunctionsSections and DataSections. +/// Return the section prefix name used by options FunctionsSections and +/// DataSections. static StringRef getSectionPrefixForGlobal(SectionKind Kind) { - if (Kind.isText()) return ".text."; - if (Kind.isReadOnly()) return ".rodata."; - if (Kind.isBSS()) return ".bss."; - - if (Kind.isThreadData()) return ".tdata."; - if (Kind.isThreadBSS()) return ".tbss."; - - if (Kind.isDataNoRel()) return ".data."; - if (Kind.isDataRelLocal()) return ".data.rel.local."; - if (Kind.isDataRel()) return ".data.rel."; - if (Kind.isReadOnlyWithRelLocal()) return ".data.rel.ro.local."; - - assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); - return ".data.rel.ro."; -} - -const MCSection *TargetLoweringObjectFileELF:: -SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, - Mangler &Mang, const TargetMachine &TM) const { - // If we have -ffunction-section or -fdata-section then we should emit the - // global value to a uniqued section specifically for it. - bool EmitUniquedSection; if (Kind.isText()) - EmitUniquedSection = TM.getFunctionSections(); - else - EmitUniquedSection = TM.getDataSections(); - - // If this global is linkonce/weak and the target handles this by emitting it - // into a 'uniqued' section name, create and return the section now. - if ((EmitUniquedSection && !Kind.isCommon()) || GV->hasComdat()) { - StringRef Prefix = getSectionPrefixForGlobal(Kind); - - SmallString<128> Name(Prefix); - TM.getNameWithPrefix(Name, GV, Mang, true); - - StringRef Group = ""; - unsigned Flags = getELFSectionFlags(Kind); - if (const Comdat *C = getELFComdat(GV)) { - Flags |= ELF::SHF_GROUP; - Group = C->getName(); + return ".text"; + if (Kind.isReadOnly()) + return ".rodata"; + if (Kind.isBSS()) + return ".bss"; + if (Kind.isThreadData()) + return ".tdata"; + if (Kind.isThreadBSS()) + return ".tbss"; + if (Kind.isDataNoRel()) + return ".data"; + if (Kind.isDataRelLocal()) + return ".data.rel.local"; + if (Kind.isDataRel()) + return ".data.rel"; + if (Kind.isReadOnlyWithRelLocal()) + return ".data.rel.ro.local"; + assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); + return ".data.rel.ro"; +} + +static const MCSectionELF *selectELFSectionForGlobal( + MCContext &Ctx, const GlobalValue *GV, SectionKind Kind, Mangler &Mang, + const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags) { + unsigned EntrySize = 0; + if (Kind.isMergeableCString()) { + if (Kind.isMergeable2ByteCString()) { + EntrySize = 2; + } else if (Kind.isMergeable4ByteCString()) { + EntrySize = 4; + } else { + EntrySize = 1; + assert(Kind.isMergeable1ByteCString() && "unknown string width"); + } + } else if (Kind.isMergeableConst()) { + if (Kind.isMergeableConst4()) { + EntrySize = 4; + } else if (Kind.isMergeableConst8()) { + EntrySize = 8; + } else { + assert(Kind.isMergeableConst16() && "unknown data width"); + EntrySize = 16; } - - return getContext().getELFSection(Name.str(), - getELFSectionType(Name.str(), Kind), - Flags, Kind, 0, Group); } - if (Kind.isText()) return TextSection; - - if (Kind.isMergeable1ByteCString() || - Kind.isMergeable2ByteCString() || - Kind.isMergeable4ByteCString()) { + StringRef Group = ""; + if (const Comdat *C = getELFComdat(GV)) { + Flags |= ELF::SHF_GROUP; + Group = C->getName(); + } + bool UniqueSectionNames = TM.getUniqueSectionNames(); + SmallString<128> Name; + if (Kind.isMergeableCString()) { // We also need alignment here. // FIXME: this is getting the alignment of the character, not the // alignment of the global! unsigned Align = - TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( - cast(GV)); - - const char *SizeSpec = ".rodata.str1."; - if (Kind.isMergeable2ByteCString()) - SizeSpec = ".rodata.str2."; - else if (Kind.isMergeable4ByteCString()) - SizeSpec = ".rodata.str4."; - else - assert(Kind.isMergeable1ByteCString() && "unknown string width"); - + TM.getDataLayout()->getPreferredAlignment(cast(GV)); - std::string Name = SizeSpec + utostr(Align); - return getContext().getELFSection(Name, ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | - ELF::SHF_MERGE | - ELF::SHF_STRINGS, - Kind); + std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; + Name = SizeSpec + utostr(Align); + } else if (Kind.isMergeableConst()) { + Name = ".rodata.cst"; + Name += utostr(EntrySize); + } else { + Name = getSectionPrefixForGlobal(Kind); } - if (Kind.isMergeableConst()) { - if (Kind.isMergeableConst4() && MergeableConst4Section) - return MergeableConst4Section; - if (Kind.isMergeableConst8() && MergeableConst8Section) - return MergeableConst8Section; - if (Kind.isMergeableConst16() && MergeableConst16Section) - return MergeableConst16Section; - return ReadOnlySection; // .const + if (EmitUniqueSection && UniqueSectionNames) { + Name.push_back('.'); + TM.getNameWithPrefix(Name, GV, Mang, true); } + return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags, + EntrySize, Group, + EmitUniqueSection && !UniqueSectionNames); +} + +const MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( + const GlobalValue *GV, SectionKind Kind, Mangler &Mang, + const TargetMachine &TM) const { + unsigned Flags = getELFSectionFlags(Kind); - if (Kind.isReadOnly()) return ReadOnlySection; + // If we have -ffunction-section or -fdata-section then we should emit the + // global value to a uniqued section specifically for it. + bool EmitUniqueSection = false; + if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { + if (Kind.isText()) + EmitUniqueSection = TM.getFunctionSections(); + else + EmitUniqueSection = TM.getDataSections(); + } + EmitUniqueSection |= GV->hasComdat(); - if (Kind.isThreadData()) return TLSDataSection; - if (Kind.isThreadBSS()) return TLSBSSSection; + return selectELFSectionForGlobal(getContext(), GV, Kind, Mang, TM, + EmitUniqueSection, Flags); +} - // Note: we claim that common symbols are put in BSSSection, but they are - // really emitted with the magic .comm directive, which creates a symbol table - // entry but not a section. - if (Kind.isBSS() || Kind.isCommon()) return BSSSection; +const MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( + const Function &F, Mangler &Mang, const TargetMachine &TM) const { + // If the function can be removed, produce a unique section so that + // the table doesn't prevent the removal. + const Comdat *C = F.getComdat(); + bool EmitUniqueSection = TM.getFunctionSections() || C; + if (!EmitUniqueSection) + return ReadOnlySection; - if (Kind.isDataNoRel()) return DataSection; - if (Kind.isDataRelLocal()) return DataRelLocalSection; - if (Kind.isDataRel()) return DataRelSection; - if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; + return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), + Mang, TM, EmitUniqueSection, ELF::SHF_ALLOC); +} - assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); - return DataRelROSection; +bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( + bool UsesLabelDifference, const Function &F) const { + // We can always create relative relocations, so use another section + // that can be marked non-executable. + return false; } /// getSectionForConstant - Given a mergeable constant with the @@ -362,7 +370,6 @@ static const MCSectionELF *getStaticStructorSection(MCContext &Ctx, std::string Name; unsigned Type; unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE; - SectionKind Kind = SectionKind::getDataRel(); StringRef COMDAT = KeySym ? KeySym->getName() : ""; if (KeySym) @@ -394,7 +401,7 @@ static const MCSectionELF *getStaticStructorSection(MCContext &Ctx, Type = ELF::SHT_PROGBITS; } - return Ctx.getELFSection(Name, Type, Flags, Kind, 0, COMDAT); + return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT); } const MCSection *TargetLoweringObjectFileELF::getStaticCtorSection( @@ -415,22 +422,21 @@ TargetLoweringObjectFileELF::InitializeELF(bool UseInitArray_) { if (!UseInitArray) return; - StaticCtorSection = - getContext().getELFSection(".init_array", ELF::SHT_INIT_ARRAY, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getDataRel()); - StaticDtorSection = - getContext().getELFSection(".fini_array", ELF::SHT_FINI_ARRAY, - ELF::SHF_WRITE | - ELF::SHF_ALLOC, - SectionKind::getDataRel()); + StaticCtorSection = getContext().getELFSection( + ".init_array", ELF::SHT_INIT_ARRAY, ELF::SHF_WRITE | ELF::SHF_ALLOC); + StaticDtorSection = getContext().getELFSection( + ".fini_array", ELF::SHT_FINI_ARRAY, ELF::SHF_WRITE | ELF::SHF_ALLOC); } //===----------------------------------------------------------------------===// // MachO //===----------------------------------------------------------------------===// +TargetLoweringObjectFileMachO::TargetLoweringObjectFileMachO() + : TargetLoweringObjectFile() { + SupportIndirectSymViaGOTPCRel = true; +} + /// getDepLibFromLinkerOpt - Extract the dependent library name from a linker /// option string. Returns StringRef() if the option does not specify a library. StringRef TargetLoweringObjectFileMachO:: @@ -591,16 +597,14 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // FIXME: Alignment check should be handled by section classifier. if (Kind.isMergeable1ByteCString() && - TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( - cast(GV)) < 32) + TM.getDataLayout()->getPreferredAlignment(cast(GV)) < 32) return CStringSection; // Do not put 16-bit arrays in the UString section if they have an // externally visible label, this runs into issues with certain linker // versions. if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() && - TM.getSubtargetImpl()->getDataLayout()->getPreferredAlignment( - cast(GV)) < 32) + TM.getDataLayout()->getPreferredAlignment(cast(GV)) < 32) return UStringSection; // With MachO only variables whose corresponding symbol starts with 'l' or @@ -707,6 +711,66 @@ MCSymbol *TargetLoweringObjectFileMachO::getCFIPersonalitySymbol( return SSym; } +const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( + const MCSymbol *Sym, const MCValue &MV, int64_t Offset, + MachineModuleInfo *MMI, MCStreamer &Streamer) const { + // Although MachO 32-bit targets do not explictly have a GOTPCREL relocation + // as 64-bit do, we replace the GOT equivalent by accessing the final symbol + // through a non_lazy_ptr stub instead. One advantage is that it allows the + // computation of deltas to final external symbols. Example: + // + // _extgotequiv: + // .long _extfoo + // + // _delta: + // .long _extgotequiv-_delta + // + // is transformed to: + // + // _delta: + // .long L_extfoo$non_lazy_ptr-(_delta+0) + // + // .section __IMPORT,__pointers,non_lazy_symbol_pointers + // L_extfoo$non_lazy_ptr: + // .indirect_symbol _extfoo + // .long 0 + // + MachineModuleInfoMachO &MachOMMI = + MMI->getObjFileInfo(); + MCContext &Ctx = getContext(); + + // The offset must consider the original displacement from the base symbol + // since 32-bit targets don't have a GOTPCREL to fold the PC displacement. + Offset = -MV.getConstant(); + const MCSymbol *BaseSym = &MV.getSymB()->getSymbol(); + + // Access the final symbol via sym$non_lazy_ptr and generate the appropriated + // non_lazy_ptr stubs. + SmallString<128> Name; + StringRef Suffix = "$non_lazy_ptr"; + Name += DL->getPrivateGlobalPrefix(); + Name += Sym->getName(); + Name += Suffix; + MCSymbol *Stub = Ctx.GetOrCreateSymbol(Name); + + MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(Stub); + if (!StubSym.getPointer()) + StubSym = MachineModuleInfoImpl:: + StubValueTy(const_cast(Sym), true /* access indirectly */); + + const MCExpr *BSymExpr = + MCSymbolRefExpr::Create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); + const MCExpr *LHS = + MCSymbolRefExpr::Create(Stub, MCSymbolRefExpr::VK_None, Ctx); + + if (!Offset) + return MCBinaryExpr::CreateSub(LHS, BSymExpr, Ctx); + + const MCExpr *RHS = + MCBinaryExpr::CreateAdd(BSymExpr, MCConstantExpr::Create(Offset, Ctx), Ctx); + return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); +} + //===----------------------------------------------------------------------===// // COFF //===----------------------------------------------------------------------===// @@ -920,21 +984,10 @@ emitModuleFlags(MCStreamer &Streamer, MDNode *MDOptions = cast(LinkerOptions->getOperand(i)); for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { MDString *MDOption = cast(MDOptions->getOperand(ii)); - StringRef Op = MDOption->getString(); // Lead with a space for consistency with our dllexport implementation. - std::string Escaped(" "); - if (!Op.startswith("\"") && (Op.find(" ") != StringRef::npos)) { - // The PE-COFF spec says args with spaces must be quoted. It doesn't say - // how to escape quotes, but it probably uses this algorithm: - // http://msdn.microsoft.com/en-us/library/17w5ykft(v=vs.85).aspx - // FIXME: Reuse escaping code from Support/Windows/Program.inc - Escaped.push_back('\"'); - Escaped.append(Op); - Escaped.push_back('\"'); - } else { - Escaped.append(Op); - } - Streamer.EmitBytes(Escaped); + std::string Directive(" "); + Directive.append(MDOption->getString()); + Streamer.EmitBytes(Directive); } } }