diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 472 |
1 files changed, 288 insertions, 184 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 0d3e4ba5662e..7e501a9e2aa4 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -19,11 +19,13 @@ #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/BinaryFormat/GOFF.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/BinaryFormat/Wasm.h" #include "llvm/CodeGen/BasicBlockSectionUtils.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/IR/Comdat.h" @@ -46,6 +48,7 @@ #include "llvm/MC/MCAsmInfoDarwin.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCGOFFAttributes.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionGOFF.h" @@ -55,6 +58,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCSymbolGOFF.h" #include "llvm/MC/MCValue.h" #include "llvm/MC/SectionKind.h" #include "llvm/ProfileData/InstrProf.h" @@ -63,6 +67,7 @@ #include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/Triple.h" @@ -114,10 +119,6 @@ static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, // ELF //===----------------------------------------------------------------------===// -TargetLoweringObjectFileELF::TargetLoweringObjectFileELF() { - SupportDSOLocalEquivalentLowering = true; -} - void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, const TargetMachine &TgtM) { TargetLoweringObjectFile::Initialize(Ctx, TgtM); @@ -306,21 +307,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { auto &C = getContext(); - if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { - auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS, - ELF::SHF_EXCLUDE); - - Streamer.switchSection(S); - - for (const auto *Operand : LinkerOptions->operands()) { - 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.emitInt8(0); - } - } - } + emitLinkerDirectives(Streamer, M); if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) { auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES, @@ -335,28 +322,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, } } - if (NamedMDNode *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName)) { - // Emit a descriptor for every function including functions that have an - // available external linkage. We may not want this for imported functions - // that has code in another thinLTO module but we don't have a good way to - // tell them apart from inline functions defined in header files. Therefore - // we put each descriptor in a separate comdat section and rely on the - // linker to deduplicate. - for (const auto *Operand : FuncInfo->operands()) { - const auto *MD = cast<MDNode>(Operand); - auto *GUID = mdconst::dyn_extract<ConstantInt>(MD->getOperand(0)); - auto *Hash = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1)); - auto *Name = cast<MDString>(MD->getOperand(2)); - auto *S = C.getObjectFileInfo()->getPseudoProbeDescSection( - TM->getFunctionSections() ? Name->getString() : StringRef()); - - Streamer.switchSection(S); - Streamer.emitInt64(GUID->getZExtValue()); - Streamer.emitInt64(Hash->getZExtValue()); - Streamer.emitULEB128IntValue(Name->getString().size()); - Streamer.emitBytes(Name->getString()); - } - } + emitPseudoProbeDescMetadata(Streamer, M); if (NamedMDNode *LLVMStats = M.getNamedMetadata("llvm.stats")) { // Emit the metadata for llvm statistics into .llvm_stats section, which is @@ -400,6 +366,26 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer, emitCGProfileMetadata(Streamer, M); } +void TargetLoweringObjectFileELF::emitLinkerDirectives(MCStreamer &Streamer, + Module &M) const { + auto &C = getContext(); + if (NamedMDNode *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { + auto *S = C.getELFSection(".linker-options", ELF::SHT_LLVM_LINKER_OPTIONS, + ELF::SHF_EXCLUDE); + + Streamer.switchSection(S); + + for (const auto *Operand : LinkerOptions->operands()) { + 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.emitInt8(0); + } + } + } +} + MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const { @@ -413,7 +399,8 @@ MCSymbol *TargetLoweringObjectFileELF::getCFIPersonalitySymbol( } void TargetLoweringObjectFileELF::emitPersonalityValue( - MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { + MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym, + const MachineModuleInfo *MMI) const { SmallString<64> NameData("DW.ref."); NameData += Sym->getName(); MCSymbolELF *Label = @@ -431,7 +418,13 @@ void TargetLoweringObjectFileELF::emitPersonalityValue( Streamer.emitELFSize(Label, E); Streamer.emitLabel(Label); - Streamer.emitSymbolValue(Sym, Size); + emitPersonalityValueImpl(Streamer, DL, Sym, MMI); +} + +void TargetLoweringObjectFileELF::emitPersonalityValueImpl( + MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym, + const MachineModuleInfo *MMI) const { + Streamer.emitSymbolValue(Sym, DL.getPointerSize()); } const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( @@ -533,7 +526,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) { return ELF::SHT_PROGBITS; } -static unsigned getELFSectionFlags(SectionKind K) { +static unsigned getELFSectionFlags(SectionKind K, const Triple &T) { unsigned Flags = 0; if (!K.isMetadata() && !K.isExclude()) @@ -545,8 +538,12 @@ static unsigned getELFSectionFlags(SectionKind K) { if (K.isText()) Flags |= ELF::SHF_EXECINSTR; - if (K.isExecuteOnly()) - Flags |= ELF::SHF_ARM_PURECODE; + if (K.isExecuteOnly()) { + if (T.isAArch64()) + Flags |= ELF::SHF_AARCH64_PURECODE; + else if (T.isARM() || T.isThumb()) + Flags |= ELF::SHF_ARM_PURECODE; + } if (K.isWriteable()) Flags |= ELF::SHF_WRITE; @@ -635,7 +632,8 @@ static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) { static SmallString<128> getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind, Mangler &Mang, const TargetMachine &TM, - unsigned EntrySize, bool UniqueSectionName) { + unsigned EntrySize, bool UniqueSectionName, + const MachineJumpTableEntry *JTE) { SmallString<128> Name = getSectionPrefixForGlobal(Kind, TM.isLargeGlobalValue(GO)); if (Kind.isMergeableCString()) { @@ -656,7 +654,24 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind, bool HasPrefix = false; if (const auto *F = dyn_cast<Function>(GO)) { - if (std::optional<StringRef> Prefix = F->getSectionPrefix()) { + // Jump table hotness takes precedence over its enclosing function's hotness + // if it's known. The function's section prefix is used if jump table entry + // hotness is unknown. + if (JTE && JTE->Hotness != MachineFunctionDataHotness::Unknown) { + if (JTE->Hotness == MachineFunctionDataHotness::Hot) { + raw_svector_ostream(Name) << ".hot"; + } else { + assert(JTE->Hotness == MachineFunctionDataHotness::Cold && + "Hotness must be cold"); + raw_svector_ostream(Name) << ".unlikely"; + } + HasPrefix = true; + } else if (std::optional<StringRef> Prefix = F->getSectionPrefix()) { + raw_svector_ostream(Name) << '.' << *Prefix; + HasPrefix = true; + } + } else if (const auto *GV = dyn_cast<GlobalVariable>(GO)) { + if (std::optional<StringRef> Prefix = GV->getSectionPrefix()) { raw_svector_ostream(Name) << '.' << *Prefix; HasPrefix = true; } @@ -677,7 +692,7 @@ class LoweringDiagnosticInfo : public DiagnosticInfo { const Twine &Msg; public: - LoweringDiagnosticInfo(const Twine &DiagMsg, + LoweringDiagnosticInfo(const Twine &DiagMsg LLVM_LIFETIME_BOUND, DiagnosticSeverity Severity = DS_Error) : DiagnosticInfo(DK_Lowering, Severity), Msg(DiagMsg) {} void print(DiagnosticPrinter &DP) const override { DP << Msg; } @@ -719,26 +734,26 @@ calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName, // 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 + // feature is not available until binutils version 2.35 // (https://sourceware.org/bugzilla/show_bug.cgi?id=25380). const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() || Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35); if (!SupportsUnique) { Flags &= ~ELF::SHF_MERGE; EntrySize = 0; - return MCContext::GenericSectionID; + return MCSection::NonUniqueID; } const bool SymbolMergeable = Flags & ELF::SHF_MERGE; const bool SeenSectionNameBefore = Ctx.isELFGenericMergeableSection(SectionName); - // If this is the first ocurrence of this section name, treat it as the + // If this is the first occurrence of this section name, treat it as the // generic section if (!SymbolMergeable && !SeenSectionNameBefore) { if (TM.getSeparateNamedSections()) return NextUniqueID++; else - return MCContext::GenericSectionID; + return MCSection::NonUniqueID; } // Symbols must be placed into sections with compatible entry sizes. Generate @@ -746,20 +761,20 @@ calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName, // sections. const auto PreviousID = Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize); - if (PreviousID && (!TM.getSeparateNamedSections() || - *PreviousID == MCContext::GenericSectionID)) + if (PreviousID && + (!TM.getSeparateNamedSections() || *PreviousID == MCSection::NonUniqueID)) return *PreviousID; // 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, Mang, TM, EntrySize, false); + SmallString<128> ImplicitSectionNameStem = getELFSectionNameForGlobal( + GO, Kind, Mang, TM, EntrySize, false, /*MJTE=*/nullptr); if (SymbolMergeable && Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) && SectionName.starts_with(ImplicitSectionNameStem)) - return MCContext::GenericSectionID; + return MCSection::NonUniqueID; // We have seen this section name before, but with different flags or entity // size. Create a new unique ID. @@ -781,33 +796,39 @@ getGlobalObjectInfo(const GlobalObject *GO, const TargetMachine &TM) { return {Group, IsComdat, Flags}; } -static MCSection *selectExplicitSectionGlobal( - const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM, - MCContext &Ctx, Mangler &Mang, unsigned &NextUniqueID, - bool Retain, bool ForceUnique) { - StringRef SectionName = GO->getSection(); - +static StringRef handlePragmaClangSection(const GlobalObject *GO, + SectionKind Kind) { // Check if '#pragma clang section' name is applicable. // Note that pragma directive overrides -ffunction-section, -fdata-section // and so section name is exactly as user specified and not uniqued. const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); if (GV && GV->hasImplicitSection()) { auto Attrs = GV->getAttributes(); - if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { - SectionName = Attrs.getAttribute("bss-section").getValueAsString(); - } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { - SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); - } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) { - SectionName = Attrs.getAttribute("relro-section").getValueAsString(); - } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { - SectionName = Attrs.getAttribute("data-section").getValueAsString(); - } + if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) + return Attrs.getAttribute("bss-section").getValueAsString(); + else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) + return Attrs.getAttribute("rodata-section").getValueAsString(); + else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) + return Attrs.getAttribute("relro-section").getValueAsString(); + else if (Attrs.hasAttribute("data-section") && Kind.isData()) + return Attrs.getAttribute("data-section").getValueAsString(); } + return GO->getSection(); +} + +static MCSection *selectExplicitSectionGlobal(const GlobalObject *GO, + SectionKind Kind, + const TargetMachine &TM, + MCContext &Ctx, Mangler &Mang, + unsigned &NextUniqueID, + bool Retain, bool ForceUnique) { + StringRef SectionName = handlePragmaClangSection(GO, Kind); + // Infer section flags from the section name if we can. Kind = getELFKindForNamedSection(SectionName, Kind); - unsigned Flags = getELFSectionFlags(Kind); + unsigned Flags = getELFSectionFlags(Kind, TM.getTargetTriple()); auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM); Flags |= ExtraFlags; @@ -855,7 +876,8 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( static MCSectionELF *selectELFSectionForGlobal( MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, - unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) { + unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol, + const MachineJumpTableEntry *MJTE = nullptr) { auto [Group, IsComdat, ExtraFlags] = getGlobalObjectInfo(GO, TM); Flags |= ExtraFlags; @@ -864,7 +886,7 @@ static MCSectionELF *selectELFSectionForGlobal( unsigned EntrySize = getEntrySizeForKind(Kind); bool UniqueSectionName = false; - unsigned UniqueID = MCContext::GenericSectionID; + unsigned UniqueID = MCSection::NonUniqueID; if (EmitUniqueSection) { if (TM.getUniqueSectionNames()) { UniqueSectionName = true; @@ -874,7 +896,7 @@ static MCSectionELF *selectELFSectionForGlobal( } } SmallString<128> Name = getELFSectionNameForGlobal( - GO, Kind, Mang, TM, EntrySize, UniqueSectionName); + GO, Kind, Mang, TM, EntrySize, UniqueSectionName, MJTE); // Use 0 as the unique ID for execute-only text. if (Kind.isExecuteOnly()) @@ -913,7 +935,7 @@ static MCSection *selectELFSectionForGlobal( MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { - unsigned Flags = getELFSectionFlags(Kind); + unsigned Flags = getELFSectionFlags(Kind, TM.getTargetTriple()); // If we have -ffunction-section or -fdata-section then we should emit the // global value to a uniqued section specifically for it. @@ -933,32 +955,38 @@ MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction( const Function &F, const TargetMachine &TM) const { SectionKind Kind = SectionKind::getText(); - unsigned Flags = getELFSectionFlags(Kind); + unsigned Flags = getELFSectionFlags(Kind, TM.getTargetTriple()); // If the function's section names is pre-determined via pragma or a // section attribute, call selectExplicitSectionGlobal. if (F.hasSection()) return selectExplicitSectionGlobal( &F, Kind, TM, getContext(), getMangler(), NextUniqueID, Used.count(&F), /* ForceUnique = */true); - else - return selectELFSectionForGlobal( - getContext(), &F, Kind, getMangler(), TM, Used.count(&F), - /*EmitUniqueSection=*/true, Flags, &NextUniqueID); + + return selectELFSectionForGlobal( + getContext(), &F, Kind, getMangler(), TM, Used.count(&F), + /*EmitUniqueSection=*/true, Flags, &NextUniqueID); } MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( const Function &F, const TargetMachine &TM) const { + return getSectionForJumpTable(F, TM, /*JTE=*/nullptr); +} + +MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( + const Function &F, const TargetMachine &TM, + const MachineJumpTableEntry *JTE) 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) + if (!EmitUniqueSection && !TM.getEnableStaticDataPartitioning()) return ReadOnlySection; return selectELFSectionForGlobal(getContext(), &F, SectionKind::getReadOnly(), getMangler(), TM, EmitUniqueSection, ELF::SHF_ALLOC, &NextUniqueID, - /* AssociatedSymbol */ nullptr); + /* AssociatedSymbol */ nullptr, JTE); } MCSection *TargetLoweringObjectFileELF::getSectionForLSDA( @@ -1023,12 +1051,47 @@ MCSection *TargetLoweringObjectFileELF::getSectionForConstant( return DataRelROSection; } +MCSection *TargetLoweringObjectFileELF::getSectionForConstant( + const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment, + StringRef SectionSuffix) const { + // TODO: Share code between this function and + // MCObjectInfo::initELFMCObjectFileInfo. + if (SectionSuffix.empty()) + return getSectionForConstant(DL, Kind, C, Alignment); + + auto &Context = getContext(); + if (Kind.isMergeableConst4() && MergeableConst4Section) + return Context.getELFSection(".rodata.cst4." + SectionSuffix, + ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE, 4); + if (Kind.isMergeableConst8() && MergeableConst8Section) + return Context.getELFSection(".rodata.cst8." + SectionSuffix, + ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE, 8); + if (Kind.isMergeableConst16() && MergeableConst16Section) + return Context.getELFSection(".rodata.cst16." + SectionSuffix, + ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE, 16); + if (Kind.isMergeableConst32() && MergeableConst32Section) + return Context.getELFSection(".rodata.cst32." + SectionSuffix, + ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE, 32); + if (Kind.isReadOnly()) + return Context.getELFSection(".rodata." + SectionSuffix, ELF::SHT_PROGBITS, + ELF::SHF_ALLOC); + + assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); + return Context.getELFSection(".data.rel.ro." + SectionSuffix, + ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE); +} + /// 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; + unsigned UniqueID = MCSection::NonUniqueID; // For cold sections use the .text.split. prefix along with the parent // function name. All cold blocks for the same function go to the same @@ -1125,38 +1188,46 @@ MCSection *TargetLoweringObjectFileELF::getStaticDtorSection( KeySym); } -const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( - const GlobalValue *LHS, const GlobalValue *RHS, - const TargetMachine &TM) const { - // We may only use a PLT-relative relocation to refer to unnamed_addr - // functions. - if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) - return nullptr; +const MCExpr *TargetLoweringObjectFileELF::lowerSymbolDifference( + const MCSymbol *LHS, const MCSymbol *RHS, int64_t Addend, + std::optional<int64_t> PCRelativeOffset) const { + auto &Ctx = getContext(); + const MCExpr *Res; + // Return a relocatable expression with the PLT specifier, %plt(GV) or + // %plt(GV-RHS). + if (PCRelativeOffset && PLTPCRelativeSpecifier) { + Res = MCSymbolRefExpr::create(LHS, Ctx); + // The current location is RHS plus *PCRelativeOffset. Compensate for it. + Addend += *PCRelativeOffset; + if (Addend) + Res = MCBinaryExpr::createAdd(Res, MCConstantExpr::create(Addend, Ctx), + Ctx); + return MCSpecifierExpr::create(Res, PLTPCRelativeSpecifier, getContext()); + } - // Basic correctness checks. - if (LHS->getType()->getPointerAddressSpace() != 0 || - RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || - RHS->isThreadLocal()) + if (!PLTRelativeSpecifier) return nullptr; - - return MCBinaryExpr::createSub( - MCSymbolRefExpr::create(TM.getSymbol(LHS), PLTRelativeVariantKind, - getContext()), - MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); + Res = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(LHS, PLTRelativeSpecifier, Ctx), + MCSymbolRefExpr::create(RHS, Ctx), Ctx); + if (Addend) + Res = + MCBinaryExpr::createAdd(Res, MCConstantExpr::create(Addend, Ctx), Ctx); + return Res; } +// Reference the PLT entry of a function, optionally with a subtrahend (`RHS`). const MCExpr *TargetLoweringObjectFileELF::lowerDSOLocalEquivalent( - const DSOLocalEquivalent *Equiv, const TargetMachine &TM) const { - assert(supportDSOLocalEquivalentLowering()); - - const auto *GV = Equiv->getGlobalValue(); + const MCSymbol *LHS, const MCSymbol *RHS, int64_t Addend, + std::optional<int64_t> PCRelativeOffset, const TargetMachine &TM) const { + if (RHS) + return lowerSymbolDifference(LHS, RHS, Addend, PCRelativeOffset); - // A PLT entry is not needed for dso_local globals. - if (GV->isDSOLocal() || GV->isImplicitDSOLocal()) - return MCSymbolRefExpr::create(TM.getSymbol(GV), getContext()); - - return MCSymbolRefExpr::create(TM.getSymbol(GV), PLTRelativeVariantKind, - getContext()); + // Only the legacy MCSymbolRefExpr::VariantKind approach is implemented. + // Reference LHS@plt or LHS@plt - RHS. + if (PLTRelativeSpecifier) + return MCSymbolRefExpr::create(LHS, PLTRelativeSpecifier, getContext()); + return nullptr; } MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const { @@ -1231,14 +1302,7 @@ MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection( void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { // Emit the linker options if present. - if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { - for (const auto *Option : LinkerOptions->operands()) { - SmallVector<std::string, 4> StrOptions; - for (const auto &Piece : cast<MDNode>(Option)->operands()) - StrOptions.push_back(std::string(cast<MDString>(Piece)->getString())); - Streamer.emitLinkerOptions(StrOptions); - } - } + emitLinkerDirectives(Streamer, M); unsigned VersionVal = 0; unsigned ImageInfoFlags = 0; @@ -1272,6 +1336,18 @@ void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, Streamer.addBlankLine(); } +void TargetLoweringObjectFileMachO::emitLinkerDirectives(MCStreamer &Streamer, + Module &M) const { + if (auto *LinkerOptions = M.getNamedMetadata("llvm.linker.options")) { + for (const auto *Option : LinkerOptions->operands()) { + SmallVector<std::string, 4> StrOptions; + for (const auto &Piece : cast<MDNode>(Option)->operands()) + StrOptions.push_back(std::string(cast<MDString>(Piece)->getString())); + Streamer.emitLinkerOptions(StrOptions); + } + } +} + static void checkMachOComdat(const GlobalValue *GV) { const Comdat *C = GV->getComdat(); if (!C) @@ -1284,21 +1360,7 @@ static void checkMachOComdat(const GlobalValue *GV) { MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { - StringRef SectionName = GO->getSection(); - - const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); - if (GV && GV->hasImplicitSection()) { - auto Attrs = GV->getAttributes(); - if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { - SectionName = Attrs.getAttribute("bss-section").getValueAsString(); - } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { - SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); - } else if (Attrs.hasAttribute("relro-section") && Kind.isReadOnlyWithRel()) { - SectionName = Attrs.getAttribute("relro-section").getValueAsString(); - } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { - SectionName = Attrs.getAttribute("data-section").getValueAsString(); - } - } + StringRef SectionName = handlePragmaClangSection(GO, Kind); // Parse the section specifier and create it if valid. StringRef Segment, Section; @@ -1524,7 +1586,7 @@ const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( // 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(); + const MCSymbol *BaseSym = MV.getSubSym(); // Access the final symbol via sym$non_lazy_ptr and generate the appropriated // non_lazy_ptr stubs. @@ -1541,10 +1603,8 @@ const MCExpr *TargetLoweringObjectFileMachO::getIndirectSymViaGOTPCRel( StubSym = MachineModuleInfoImpl::StubValueTy(const_cast<MCSymbol *>(Sym), !GV->hasLocalLinkage()); - const MCExpr *BSymExpr = - MCSymbolRefExpr::create(BaseSym, MCSymbolRefExpr::VK_None, Ctx); - const MCExpr *LHS = - MCSymbolRefExpr::create(Stub, MCSymbolRefExpr::VK_None, Ctx); + const MCExpr *BSymExpr = MCSymbolRefExpr::create(BaseSym, Ctx); + const MCExpr *LHS = MCSymbolRefExpr::create(Stub, Ctx); if (!Offset) return MCBinaryExpr::createSub(LHS, BSymExpr, Ctx); @@ -1667,7 +1727,7 @@ static int getSelectionForCOFF(const GlobalValue *GV) { MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { - StringRef Name = GO->getSection(); + StringRef Name = handlePragmaClangSection(GO, Kind); if (Name == getInstrProfSectionName(IPSK_covmap, Triple::COFF, /*AddSegmentInfo=*/false) || Name == getInstrProfSectionName(IPSK_covfun, Triple::COFF, @@ -1738,7 +1798,7 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( else ComdatGV = GO; - unsigned UniqueID = MCContext::GenericSectionID; + unsigned UniqueID = MCSection::NonUniqueID; if (EmitUniquedSection) UniqueID = NextUniqueID++; @@ -1753,7 +1813,7 @@ MCSection *TargetLoweringObjectFileCOFF::SelectSectionForGlobal( // Append "$symbol" to the section name *before* IR-level mangling is // applied when targetting mingw. This is what GCC does, and the ld.bfd // COFF linker will not properly handle comdats otherwise. - if (getContext().getTargetTriple().isWindowsGNUEnvironment()) + if (getContext().getTargetTriple().isOSCygMing()) raw_svector_ostream(Name) << '$' << ComdatGV->getName(); return getContext().getCOFFSection(Name, Characteristics, COMDATSymName, @@ -2006,8 +2066,8 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection( } const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( - const GlobalValue *LHS, const GlobalValue *RHS, - const TargetMachine &TM) const { + const GlobalValue *LHS, const GlobalValue *RHS, int64_t Addend, + std::optional<int64_t> PCRelativeOffset, const TargetMachine &TM) const { const Triple &T = TM.getTargetTriple(); if (T.isOSCygMing()) return nullptr; @@ -2031,9 +2091,12 @@ const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference( cast<GlobalVariable>(RHS)->hasInitializer() || RHS->hasSection()) return nullptr; - return MCSymbolRefExpr::create(TM.getSymbol(LHS), - MCSymbolRefExpr::VK_COFF_IMGREL32, - getContext()); + const MCExpr *Res = MCSymbolRefExpr::create( + TM.getSymbol(LHS), MCSymbolRefExpr::VK_COFF_IMGREL32, getContext()); + if (Addend != 0) + Res = MCBinaryExpr::createAdd( + Res, MCConstantExpr::create(Addend, getContext()), getContext()); + return Res; } static std::string APIntToHexString(const APInt &AI) { @@ -2171,7 +2234,11 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( // 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") + if (Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm, + /*AddSegmentInfo=*/false) || + Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm, + /*AddSegmentInfo=*/false) || + Name == ".llvmbc" || Name == ".llvmcmd") Kind = SectionKind::getMetadata(); StringRef Group = ""; @@ -2180,8 +2247,8 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( } unsigned Flags = getWasmSectionFlags(Kind, Used.count(GO)); - MCSectionWasm *Section = getContext().getWasmSection( - Name, Kind, Flags, Group, MCContext::GenericSectionID); + MCSectionWasm *Section = getContext().getWasmSection(Name, Kind, Flags, Group, + MCSection::NonUniqueID); return Section; } @@ -2209,7 +2276,7 @@ selectWasmSectionForGlobal(MCContext &Ctx, const GlobalObject *GO, Name.push_back('.'); TM.getNameWithPrefix(Name, GO, Mang, true); } - unsigned UniqueID = MCContext::GenericSectionID; + unsigned UniqueID = MCSection::NonUniqueID; if (EmitUniqueSection && !UniqueSectionNames) { UniqueID = *NextUniqueID; (*NextUniqueID)++; @@ -2247,26 +2314,6 @@ bool TargetLoweringObjectFileWasm::shouldPutJumpTableInFunctionSection( return false; } -const MCExpr *TargetLoweringObjectFileWasm::lowerRelativeReference( - const GlobalValue *LHS, const GlobalValue *RHS, - const TargetMachine &TM) const { - // We may only use a PLT-relative relocation to refer to unnamed_addr - // functions. - if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) - return nullptr; - - // Basic correctness checks. - if (LHS->getType()->getPointerAddressSpace() != 0 || - RHS->getType()->getPointerAddressSpace() != 0 || LHS->isThreadLocal() || - RHS->isThreadLocal()) - return nullptr; - - return MCBinaryExpr::createSub( - MCSymbolRefExpr::create(TM.getSymbol(LHS), MCSymbolRefExpr::VK_None, - getContext()), - MCSymbolRefExpr::create(TM.getSymbol(RHS), getContext()), getContext()); -} - void TargetLoweringObjectFileWasm::InitializeWasm() { StaticCtorSection = getContext().getWasmSection(".init_array", SectionKind::getData()); @@ -2594,13 +2641,6 @@ MCSection *TargetLoweringObjectFileXCOFF::getStaticDtorSection( report_fatal_error("no static destructor section on AIX"); } -const MCExpr *TargetLoweringObjectFileXCOFF::lowerRelativeReference( - const GlobalValue *LHS, const GlobalValue *RHS, - const TargetMachine &TM) const { - /* Not implemented yet, but don't crash, return nullptr. */ - return nullptr; -} - XCOFF::StorageClass TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(const GlobalValue *GV) { assert(!isa<GlobalIFunc>(GV) && "GlobalIFunc is not supported on AIX."); @@ -2718,6 +2758,29 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForLSDA( //===----------------------------------------------------------------------===// TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default; +void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) { + // Construct the default names for the root SD and the ADA PR symbol. + StringRef FileName = sys::path::stem(M.getSourceFileName()); + if (FileName.size() > 1 && FileName.starts_with('<') && + FileName.ends_with('>')) + FileName = FileName.substr(1, FileName.size() - 2); + DefaultRootSDName = Twine(FileName).concat("#C").str(); + DefaultADAPRName = Twine(FileName).concat("#S").str(); + MCSectionGOFF *RootSD = + static_cast<MCSectionGOFF *>(TextSection)->getParent(); + MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection); + RootSD->setName(DefaultRootSDName); + ADAPR->setName(DefaultADAPRName); + // Initialize the label for the text section. + MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>( + getContext().getOrCreateSymbol(RootSD->getName())); + TextLD->setLDAttributes(GOFF::LDAttr{ + false, GOFF::ESD_EXE_CODE, GOFF::ESD_BST_Strong, GOFF::ESD_LT_XPLink, + GOFF::ESD_AMODE_64, GOFF::ESD_BSC_Section}); + TextLD->setADA(ADAPR); + TextSection->setBeginSymbol(TextLD); +} + MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { return SelectSectionForGlobal(GO, Kind, TM); @@ -2726,15 +2789,56 @@ MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal( MCSection *TargetLoweringObjectFileGOFF::getSectionForLSDA( const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const { std::string Name = ".gcc_exception_table." + F.getName().str(); - return getContext().getGOFFSection(Name, SectionKind::getData(), nullptr, 0); + + MCSectionGOFF *WSA = getContext().getGOFFSection( + SectionKind::getMetadata(), GOFF::CLASS_WSA, + GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Initial, GOFF::ESD_RQ_0, + GOFF::ESD_ALIGN_Fullword, 0}, + static_cast<MCSectionGOFF *>(TextSection)->getParent()); + return getContext().getGOFFSection(SectionKind::getData(), Name, + GOFF::PRAttr{true, GOFF::ESD_EXE_DATA, + GOFF::ESD_LT_XPLink, + GOFF::ESD_BSC_Section, 0}, + WSA); } MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { auto *Symbol = TM.getSymbol(GO); - if (Kind.isBSS()) - return getContext().getGOFFSection(Symbol->getName(), SectionKind::getBSS(), - nullptr, 0); - return getContext().getObjectFileInfo()->getTextSection(); + if (Kind.isBSS() || Kind.isData()) { + GOFF::ESDBindingScope PRBindingScope = + GO->hasExternalLinkage() + ? (GO->hasDefaultVisibility() ? GOFF::ESD_BSC_ImportExport + : GOFF::ESD_BSC_Library) + : GOFF::ESD_BSC_Section; + GOFF::ESDBindingScope SDBindingScope = + PRBindingScope == GOFF::ESD_BSC_Section ? GOFF::ESD_BSC_Section + : GOFF::ESD_BSC_Unspecified; + MaybeAlign Alignment; + if (auto *F = dyn_cast<Function>(GO)) + Alignment = F->getAlign(); + else if (auto *V = dyn_cast<GlobalVariable>(GO)) + Alignment = V->getAlign(); + GOFF::ESDAlignment Align = + Alignment ? static_cast<GOFF::ESDAlignment>(Log2(*Alignment)) + : GOFF::ESD_ALIGN_Doubleword; + MCSectionGOFF *SD = getContext().getGOFFSection( + SectionKind::getMetadata(), Symbol->getName(), + GOFF::SDAttr{GOFF::ESD_TA_Unspecified, SDBindingScope}); + MCSectionGOFF *ED = getContext().getGOFFSection( + SectionKind::getMetadata(), GOFF::CLASS_WSA, + GOFF::EDAttr{false, GOFF::ESD_RMODE_64, GOFF::ESD_NS_Parts, + GOFF::ESD_TS_ByteOriented, GOFF::ESD_BA_Merge, + GOFF::ESD_LB_Deferred, GOFF::ESD_RQ_0, Align, 0}, + SD); + return getContext().getGOFFSection(Kind, Symbol->getName(), + GOFF::PRAttr{false, GOFF::ESD_EXE_DATA, + GOFF::ESD_LT_XPLink, + PRBindingScope, 0}, + ED); + } + return TextSection; } |
