diff options
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 454 |
1 files changed, 337 insertions, 117 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 8cb9814300d1..27bebe503ce6 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -21,12 +21,16 @@ #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/IR/Comdat.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalObject.h" @@ -52,8 +56,8 @@ #include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CodeGen.h" -#include "llvm/Support/Format.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include <cassert> @@ -84,6 +88,15 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, } else if (Key == "Objective-C Image Info Section") { Section = cast<MDString>(MFE.Val)->getString(); } + // Backend generates L_OBJC_IMAGE_INFO from Swift ABI version + major + minor + + // "Objective-C Garbage Collection". + else if (Key == "Swift ABI Version") { + Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 8; + } else if (Key == "Swift Major Version") { + Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 24; + } else if (Key == "Swift Minor Version") { + Flags |= (mdconst::extract<ConstantInt>(MFE.Val)->getZExtValue()) << 16; + } } } @@ -97,6 +110,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, TM = &TgtM; CodeModel::Model CM = TgtM.getCodeModel(); + InitializeELF(TgtM.Options.UseInitArray); switch (TgtM.getTargetTriple().getArch()) { case Triple::arm: @@ -277,8 +291,8 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, if (cast<MDNode>(Operand)->getNumOperands() != 2) report_fatal_error("invalid llvm.linker.options"); for (const auto &Option : cast<MDNode>(Operand)->operands()) { - Streamer.EmitBytes(cast<MDString>(Option)->getString()); - Streamer.EmitIntValue(0, 1); + Streamer.emitBytes(cast<MDString>(Option)->getString()); + Streamer.emitInt8(0); } } } @@ -290,9 +304,9 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, Streamer.SwitchSection(S); for (const auto *Operand : DependentLibraries->operands()) { - Streamer.EmitBytes( + Streamer.emitBytes( cast<MDString>(cast<MDNode>(Operand)->getOperand(0))->getString()); - Streamer.EmitIntValue(0, 1); + Streamer.emitInt8(0); } } @@ -304,9 +318,9 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, if (!Section.empty()) { auto *S = C.getELFSection(Section, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); Streamer.SwitchSection(S); - Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); - Streamer.EmitIntValue(Version, 4); - Streamer.EmitIntValue(Flags, 4); + Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); + Streamer.emitInt32(Version); + Streamer.emitInt32(Flags); Streamer.AddBlankLine(); } @@ -370,20 +384,20 @@ void TargetLoweringObjectFileELF::emitPersonalityValue( NameData += Sym->getName(); MCSymbolELF *Label = cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); - Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); - Streamer.EmitSymbolAttribute(Label, MCSA_Weak); + Streamer.emitSymbolAttribute(Label, MCSA_Hidden); + Streamer.emitSymbolAttribute(Label, MCSA_Weak); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), ELF::SHT_PROGBITS, Flags, 0); unsigned Size = DL.getPointerSize(); Streamer.SwitchSection(Sec); - Streamer.EmitValueToAlignment(DL.getPointerABIAlignment(0).value()); - Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); + Streamer.emitValueToAlignment(DL.getPointerABIAlignment(0).value()); + Streamer.emitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::create(Size, getContext()); Streamer.emitELFSize(Label, E); - Streamer.EmitLabel(Label); + Streamer.emitLabel(Label); - Streamer.EmitSymbolValue(Sym, Size); + Streamer.emitSymbolValue(Sym, Size); } const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( @@ -420,6 +434,8 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { // .section .eh_frame,"a",@progbits if (Name == getInstrProfSectionName(IPSK_covmap, Triple::ELF, + /*AddSegmentInfo=*/false) || + Name == getInstrProfSectionName(IPSK_covfun, Triple::ELF, /*AddSegmentInfo=*/false)) return SectionKind::getMetadata(); @@ -512,8 +528,8 @@ static const Comdat *getELFComdat(const GlobalValue *GV) { return C; } -static const MCSymbolELF *getAssociatedSymbol(const GlobalObject *GO, - const TargetMachine &TM) { +static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO, + const TargetMachine &TM) { MDNode *MD = GO->getMetadata(LLVMContext::MD_associated); if (!MD) return nullptr; @@ -554,6 +570,75 @@ static unsigned getEntrySizeForKind(SectionKind Kind) { } } +/// 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.isData()) + return ".data"; + if (Kind.isReadOnlyWithRel()) + return ".data.rel.ro"; + llvm_unreachable("Unknown section kind"); +} + +static SmallString<128> +getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind, + Mangler &Mang, const TargetMachine &TM, + unsigned EntrySize, bool UniqueSectionName) { + 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! + Align Alignment = GO->getParent()->getDataLayout().getPreferredAlign( + cast<GlobalVariable>(GO)); + + std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; + Name = SizeSpec + utostr(Alignment.value()); + } else if (Kind.isMergeableConst()) { + Name = ".rodata.cst"; + Name += utostr(EntrySize); + } else { + Name = getSectionPrefixForGlobal(Kind); + } + + bool HasPrefix = false; + if (const auto *F = dyn_cast<Function>(GO)) { + if (Optional<StringRef> Prefix = F->getSectionPrefix()) { + Name += *Prefix; + HasPrefix = true; + } + } + + if (UniqueSectionName) { + Name.push_back('.'); + TM.getNameWithPrefix(Name, GO, Mang, /*MayAlwaysUsePrivate*/true); + } else if (HasPrefix) + Name.push_back('.'); + return Name; +} + +namespace { +class LoweringDiagnosticInfo : public DiagnosticInfo { + const Twine &Msg; + +public: + LoweringDiagnosticInfo(const Twine &DiagMsg, + DiagnosticSeverity Severity = DS_Error) + : DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {} + void print(DiagnosticPrinter &DP) const override { DP << Msg; } +}; +} + MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { StringRef SectionName = GO->getSection(); @@ -589,42 +674,84 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( Flags |= ELF::SHF_GROUP; } + unsigned EntrySize = getEntrySizeForKind(Kind); + // A section can have at most one associated section. Put each global with // MD_associated in a unique section. unsigned UniqueID = MCContext::GenericSectionID; - const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); - if (AssociatedSymbol) { + const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); + if (LinkedToSym) { UniqueID = NextUniqueID++; Flags |= ELF::SHF_LINK_ORDER; + } else { + if (getContext().getAsmInfo()->useIntegratedAssembler()) { + // Symbols must be placed into sections with compatible entry + // sizes. Generate unique sections for symbols that have not + // been assigned to compatible sections. + if (Flags & ELF::SHF_MERGE) { + auto maybeID = getContext().getELFUniqueIDForEntsize(SectionName, Flags, + EntrySize); + if (maybeID) + UniqueID = *maybeID; + else { + // If the user has specified the same section name as would be created + // implicitly for this symbol e.g. .rodata.str1.1, then we don't need + // to unique the section as the entry size for this symbol will be + // compatible with implicitly created sections. + SmallString<128> ImplicitSectionNameStem = getELFSectionNameForGlobal( + GO, Kind, getMangler(), TM, EntrySize, false); + if (!(getContext().isELFImplicitMergeableSectionNamePrefix( + SectionName) && + SectionName.startswith(ImplicitSectionNameStem))) + UniqueID = NextUniqueID++; + } + } else { + // We need to unique the section if the user has explicity + // assigned a non-mergeable symbol to a section name for + // a generic mergeable section. + if (getContext().isELFGenericMergeableSection(SectionName)) { + auto maybeID = getContext().getELFUniqueIDForEntsize( + SectionName, Flags, EntrySize); + UniqueID = maybeID ? *maybeID : NextUniqueID++; + } + } + } else { + // If two symbols with differing sizes end up in the same mergeable + // section that section can be assigned an incorrect entry size. To avoid + // this we usually put symbols of the same size into distinct mergeable + // sections with the same name. Doing so relies on the ",unique ," + // assembly feature. This feature is not avalible until bintuils + // version 2.35 (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). + Flags &= ~ELF::SHF_MERGE; + EntrySize = 0; + } } MCSectionELF *Section = getContext().getELFSection( SectionName, getELFSectionType(SectionName, Kind), Flags, - getEntrySizeForKind(Kind), Group, UniqueID, AssociatedSymbol); + EntrySize, Group, UniqueID, LinkedToSym); // Make sure that we did not get some other section with incompatible sh_link. // This should not be possible due to UniqueID code above. - assert(Section->getAssociatedSymbol() == AssociatedSymbol && + assert(Section->getLinkedToSymbol() == LinkedToSym && "Associated symbol mismatch between sections"); - return Section; -} -/// 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.isData()) - return ".data"; - assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); - return ".data.rel.ro"; + if (!getContext().getAsmInfo()->useIntegratedAssembler()) { + // If we are not using the integrated assembler then this symbol might have + // been placed in an incompatible mergeable section. Emit an error if this + // is the case to avoid creating broken output. + if ((Section->getFlags() & ELF::SHF_MERGE) && + (Section->getEntrySize() != getEntrySizeForKind(Kind))) + GO->getContext().diagnose(LoweringDiagnosticInfo( + "Symbol '" + GO->getName() + "' from module '" + + (GO->getParent() ? GO->getParent()->getSourceFileName() : "unknown") + + "' required a section with entry-size=" + + Twine(getEntrySizeForKind(Kind)) + " but was placed in section '" + + SectionName + "' with entry-size=" + Twine(Section->getEntrySize()) + + ": Explicit assignment by pragma or attribute of an incompatible " + "symbol to this section?")); + } + + return Section; } static MCSectionELF *selectELFSectionForGlobal( @@ -641,39 +768,19 @@ static MCSectionELF *selectELFSectionForGlobal( // Get the section entry size based on the kind. unsigned EntrySize = getEntrySizeForKind(Kind); - 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 = GO->getParent()->getDataLayout().getPreferredAlignment( - cast<GlobalVariable>(GO)); - - 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 (const auto *F = dyn_cast<Function>(GO)) { - const auto &OptionalPrefix = F->getSectionPrefix(); - if (OptionalPrefix) - Name += *OptionalPrefix; - } - + bool UniqueSectionName = false; unsigned UniqueID = MCContext::GenericSectionID; if (EmitUniqueSection) { if (TM.getUniqueSectionNames()) { - Name.push_back('.'); - TM.getNameWithPrefix(Name, GO, Mang, true /*MayAlwaysUsePrivate*/); + UniqueSectionName = true; } else { UniqueID = *NextUniqueID; (*NextUniqueID)++; } } + SmallString<128> Name = getELFSectionNameForGlobal( + GO, Kind, Mang, TM, EntrySize, UniqueSectionName); + // Use 0 as the unique ID for execute-only text. if (Kind.isExecuteOnly()) UniqueID = 0; @@ -696,16 +803,16 @@ MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( } EmitUniqueSection |= GO->hasComdat(); - const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); - if (AssociatedSymbol) { + const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); + if (LinkedToSym) { EmitUniqueSection = true; Flags |= ELF::SHF_LINK_ORDER; } MCSectionELF *Section = selectELFSectionForGlobal( getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, - &NextUniqueID, AssociatedSymbol); - assert(Section->getAssociatedSymbol() == AssociatedSymbol); + &NextUniqueID, LinkedToSym); + assert(Section->getLinkedToSymbol() == LinkedToSym); return Section; } @@ -735,7 +842,7 @@ bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection( /// information, return a section that it should be placed in. MCSection *TargetLoweringObjectFileELF::getSectionForConstant( const DataLayout &DL, SectionKind Kind, const Constant *C, - unsigned &Align) const { + Align &Alignment) const { if (Kind.isMergeableConst4() && MergeableConst4Section) return MergeableConst4Section; if (Kind.isMergeableConst8() && MergeableConst8Section) @@ -751,6 +858,46 @@ MCSection *TargetLoweringObjectFileELF::getSectionForConstant( return DataRelROSection; } +/// Returns a unique section for the given machine basic block. +MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock( + const Function &F, const MachineBasicBlock &MBB, + const TargetMachine &TM) const { + assert(MBB.isBeginSection() && "Basic block does not start a section!"); + unsigned UniqueID = MCContext::GenericSectionID; + + // For cold sections use the .text.unlikely prefix along with the parent + // function name. All cold blocks for the same function go to the same + // section. Similarly all exception blocks are grouped by symbol name + // under the .text.eh prefix. For regular sections, we either use a unique + // name, or a unique ID for the section. + SmallString<128> Name; + if (MBB.getSectionID() == MBBSectionID::ColdSectionID) { + Name += ".text.unlikely."; + Name += MBB.getParent()->getName(); + } else if (MBB.getSectionID() == MBBSectionID::ExceptionSectionID) { + Name += ".text.eh."; + Name += MBB.getParent()->getName(); + } else { + Name += MBB.getParent()->getSection()->getName(); + if (TM.getUniqueBasicBlockSectionNames()) { + Name += "."; + Name += MBB.getSymbol()->getName(); + } else { + UniqueID = NextUniqueID++; + } + } + + unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; + std::string GroupName = ""; + if (F.hasComdat()) { + Flags |= ELF::SHF_GROUP; + GroupName = F.getComdat()->getName().str(); + } + return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags, + 0 /* Entry Size */, GroupName, UniqueID, + nullptr); +} + static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, bool IsCtor, unsigned Priority, const MCSymbol *KeySym) { @@ -888,8 +1035,8 @@ void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, for (const auto *Option : LinkerOptions->operands()) { SmallVector<std::string, 4> StrOptions; for (const auto &Piece : cast<MDNode>(Option)->operands()) - StrOptions.push_back(cast<MDString>(Piece)->getString()); - Streamer.EmitLinkerOptions(StrOptions); + StrOptions.push_back(std::string(cast<MDString>(Piece)->getString())); + Streamer.emitLinkerOptions(StrOptions); } } @@ -918,10 +1065,10 @@ void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, MCSectionMachO *S = getContext().getMachOSection( Segment, Section, TAA, StubSize, SectionKind::getData()); Streamer.SwitchSection(S); - Streamer.EmitLabel(getContext(). + Streamer.emitLabel(getContext(). getOrCreateSymbol(StringRef("L_OBJC_IMAGE_INFO"))); - Streamer.EmitIntValue(VersionVal, 4); - Streamer.EmitIntValue(ImageInfoFlags, 4); + Streamer.emitInt32(VersionVal); + Streamer.emitInt32(ImageInfoFlags); Streamer.AddBlankLine(); } @@ -998,16 +1145,16 @@ MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( // FIXME: Alignment check should be handled by section classifier. if (Kind.isMergeable1ByteCString() && - GO->getParent()->getDataLayout().getPreferredAlignment( - cast<GlobalVariable>(GO)) < 32) + GO->getParent()->getDataLayout().getPreferredAlign( + cast<GlobalVariable>(GO)) < Align(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() && !GO->hasExternalLinkage() && - GO->getParent()->getDataLayout().getPreferredAlignment( - cast<GlobalVariable>(GO)) < 32) + GO->getParent()->getDataLayout().getPreferredAlign( + cast<GlobalVariable>(GO)) < Align(32)) return UStringSection; // With MachO only variables whose corresponding symbol starts with 'l' or @@ -1047,7 +1194,7 @@ MCSection *TargetLoweringObjectFileMachO::SelectSectionForGlobal( MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( const DataLayout &DL, SectionKind Kind, const Constant *C, - unsigned &Align) const { + Align &Alignment) const { // If this constant requires a relocation, we have to put it in the data // segment, not in the text segment. if (Kind.isData() || Kind.isReadOnlyWithRel()) @@ -1453,8 +1600,8 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, for (const auto &Piece : cast<MDNode>(Option)->operands()) { // Lead with a space for consistency with our dllexport implementation. std::string Directive(" "); - Directive.append(cast<MDString>(Piece)->getString()); - Streamer.EmitBytes(Directive); + Directive.append(std::string(cast<MDString>(Piece)->getString())); + Streamer.emitBytes(Directive); } } } @@ -1472,9 +1619,9 @@ void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, Section, COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, SectionKind::getReadOnly()); Streamer.SwitchSection(S); - Streamer.EmitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); - Streamer.EmitIntValue(Version, 4); - Streamer.EmitIntValue(Flags, 4); + Streamer.emitLabel(C.getOrCreateSymbol(StringRef("OBJC_IMAGE_INFO"))); + Streamer.emitInt32(Version); + Streamer.emitInt32(Flags); Streamer.AddBlankLine(); } @@ -1599,7 +1746,7 @@ const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( static std::string APIntToHexString(const APInt &AI) { unsigned Width = (AI.getBitWidth() / 8) * 2; std::string HexString = AI.toString(16, /*Signed=*/false); - transform(HexString.begin(), HexString.end(), HexString.begin(), tolower); + llvm::transform(HexString, HexString.begin(), tolower); unsigned Size = HexString.size(); assert(Width >= Size && "hex string is too large!"); HexString.insert(HexString.begin(), Width - Size, '0'); @@ -1617,8 +1764,8 @@ static std::string scalarConstantToHexString(const Constant *C) { return APIntToHexString(CI->getValue()); } else { unsigned NumElements; - if (isa<VectorType>(Ty)) - NumElements = Ty->getVectorNumElements(); + if (auto *VTy = dyn_cast<VectorType>(Ty)) + NumElements = cast<FixedVectorType>(VTy)->getNumElements(); else NumElements = Ty->getArrayNumElements(); std::string HexString; @@ -1630,7 +1777,7 @@ static std::string scalarConstantToHexString(const Constant *C) { MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant( const DataLayout &DL, SectionKind Kind, const Constant *C, - unsigned &Align) const { + Align &Alignment) const { if (Kind.isMergeableConst() && C && getContext().getAsmInfo()->hasCOFFComdatConstants()) { // This creates comdat sections with the given symbol name, but unless @@ -1642,25 +1789,25 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant( COFF::IMAGE_SCN_LNK_COMDAT; std::string COMDATSymName; if (Kind.isMergeableConst4()) { - if (Align <= 4) { + if (Alignment <= 4) { COMDATSymName = "__real@" + scalarConstantToHexString(C); - Align = 4; + Alignment = Align(4); } } else if (Kind.isMergeableConst8()) { - if (Align <= 8) { + if (Alignment <= 8) { COMDATSymName = "__real@" + scalarConstantToHexString(C); - Align = 8; + Alignment = Align(8); } } else if (Kind.isMergeableConst16()) { // FIXME: These may not be appropriate for non-x86 architectures. - if (Align <= 16) { + if (Alignment <= 16) { COMDATSymName = "__xmm@" + scalarConstantToHexString(C); - Align = 16; + Alignment = Align(16); } } else if (Kind.isMergeableConst32()) { - if (Align <= 32) { + if (Alignment <= 32) { COMDATSymName = "__ymm@" + scalarConstantToHexString(C); - Align = 32; + Alignment = Align(32); } } @@ -1670,10 +1817,10 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant( COFF::IMAGE_COMDAT_SELECT_ANY); } - return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, Align); + return TargetLoweringObjectFile::getSectionForConstant(DL, Kind, C, + Alignment); } - //===----------------------------------------------------------------------===// // Wasm //===----------------------------------------------------------------------===// @@ -1691,16 +1838,6 @@ static const Comdat *getWasmComdat(const GlobalValue *GV) { return C; } -static SectionKind getWasmKindForNamedSection(StringRef Name, SectionKind K) { - // If we're told we have function data, then use that. - if (K.isText()) - return SectionKind::getText(); - - // Otherwise, ignore whatever section type the generic impl detected and use - // a plain data section. - return SectionKind::getData(); -} - MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { // We don't support explict section names for functions in the wasm object @@ -1711,7 +1848,13 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( StringRef Name = GO->getSection(); - Kind = getWasmKindForNamedSection(Name, Kind); + // Certain data sections we treat as named custom sections rather than + // segments within the data section. + // This could be avoided if all data segements (the wasm sense) were + // represented as their own sections (in the llvm sense). + // TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138 + if (Name == ".llvmcmd" || Name == ".llvmbc") + Kind = SectionKind::getMetadata(); StringRef Group = ""; if (const Comdat *C = getWasmComdat(GO)) { @@ -1827,11 +1970,61 @@ MCSection *TargetLoweringObjectFileWasm::getStaticDtorSection( //===----------------------------------------------------------------------===// // XCOFF //===----------------------------------------------------------------------===// +MCSymbol * +TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV, + const TargetMachine &TM) const { + if (TM.getDataSections()) + report_fatal_error("XCOFF unique data sections not yet implemented"); + + // We always use a qualname symbol for a GV that represents + // a declaration, a function descriptor, or a common symbol. + // It is inherently ambiguous when the GO represents the address of a + // function, as the GO could either represent a function descriptor or a + // function entry point. We choose to always return a function descriptor + // here. + if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) { + if (GO->isDeclarationForLinker()) + return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM)) + ->getQualNameSymbol(); + + SectionKind GOKind = getKindForGlobal(GO, TM); + if (GOKind.isText()) + return cast<MCSectionXCOFF>( + getSectionForFunctionDescriptor(cast<Function>(GO), TM)) + ->getQualNameSymbol(); + if (GOKind.isCommon() || GOKind.isBSSLocal()) + return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM)) + ->getQualNameSymbol(); + } + + // For all other cases, fall back to getSymbol to return the unqualified name. + // This could change for a GV that is a GlobalVariable when we decide to + // support -fdata-sections since we could avoid having label symbols if the + // linkage name is applied to the csect symbol. + return nullptr; +} + MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { report_fatal_error("XCOFF explicit sections not yet implemented."); } +MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference( + const GlobalObject *GO, const TargetMachine &TM) const { + assert(GO->isDeclarationForLinker() && + "Tried to get ER section for a defined global."); + + SmallString<128> Name; + getNameWithPrefix(Name, GO, TM); + XCOFF::StorageClass SC = + TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO); + + // Externals go into a csect of type ER. + return getContext().getXCOFFSection( + Name, isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA, XCOFF::XTY_ER, + SC, SectionKind::getMetadata()); +} + MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { assert(!TM.getFunctionSections() && !TM.getDataSections() && @@ -1850,16 +2043,13 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal( } if (Kind.isMergeableCString()) { - if (!Kind.isMergeable1ByteCString()) - report_fatal_error("Unhandled multi-byte mergeable string kind."); - - unsigned Align = GO->getParent()->getDataLayout().getPreferredAlignment( + Align Alignment = GO->getParent()->getDataLayout().getPreferredAlign( cast<GlobalVariable>(GO)); unsigned EntrySize = getEntrySizeForKind(Kind); std::string SizeSpec = ".rodata.str" + utostr(EntrySize) + "."; SmallString<128> Name; - Name = SizeSpec + utostr(Align); + Name = SizeSpec + utostr(Alignment.value()); return getContext().getXCOFFSection( Name, XCOFF::XMC_RO, XCOFF::XTY_SD, @@ -1906,7 +2096,7 @@ bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection( /// information, return a section that it should be placed in. MCSection *TargetLoweringObjectFileXCOFF::getSectionForConstant( const DataLayout &DL, SectionKind Kind, const Constant *C, - unsigned &Align) const { + Align &Alignment) const { //TODO: Enable emiting constant pool to unique sections when we support it. return ReadOnlySection; } @@ -1943,11 +2133,41 @@ XCOFF::StorageClass TargetLoweringObjectFileXCOFF::getStorageClassForGlobal( return XCOFF::C_HIDEXT; case GlobalValue::ExternalLinkage: case GlobalValue::CommonLinkage: + case GlobalValue::AvailableExternallyLinkage: return XCOFF::C_EXT; case GlobalValue::ExternalWeakLinkage: + case GlobalValue::LinkOnceAnyLinkage: + case GlobalValue::LinkOnceODRLinkage: + case GlobalValue::WeakAnyLinkage: + case GlobalValue::WeakODRLinkage: return XCOFF::C_WEAKEXT; - default: + case GlobalValue::AppendingLinkage: report_fatal_error( - "Unhandled linkage when mapping linkage to StorageClass."); + "There is no mapping that implements AppendingLinkage for XCOFF."); } + llvm_unreachable("Unknown linkage type!"); +} + +MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol( + const Function *F, const TargetMachine &TM) const { + SmallString<128> NameStr; + NameStr.push_back('.'); + getNameWithPrefix(NameStr, F, TM); + return getContext().getOrCreateSymbol(NameStr); +} + +MCSection *TargetLoweringObjectFileXCOFF::getSectionForFunctionDescriptor( + const Function *F, const TargetMachine &TM) const { + SmallString<128> NameStr; + getNameWithPrefix(NameStr, F, TM); + return getContext().getXCOFFSection(NameStr, XCOFF::XMC_DS, XCOFF::XTY_SD, + getStorageClassForGlobal(F), + SectionKind::getData()); +} + +MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry( + const MCSymbol *Sym) const { + return getContext().getXCOFFSection( + cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(), XCOFF::XMC_TC, + XCOFF::XTY_SD, XCOFF::C_HIDEXT, SectionKind::getData()); } |