diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:03:47 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:04:23 +0000 |
commit | 7fa27ce4a07f19b07799a767fc29416f3b625afb (patch) | |
tree | 27825c83636c4de341eb09a74f49f5d38a15d165 /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | |
parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) |
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 127 |
1 files changed, 83 insertions, 44 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index e760564779c2..3994552884c4 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -16,7 +16,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/BinaryFormat/ELF.h" @@ -65,12 +64,17 @@ #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/TargetParser/Triple.h" #include <cassert> #include <string> using namespace llvm; using namespace dwarf; +static cl::opt<bool> JumpTableInFunctionSection( + "jumptable-in-function-section", cl::Hidden, cl::init(false), + cl::desc("Putting Jump Table in function section")); + static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, StringRef &Section) { SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags; @@ -182,26 +186,14 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx, // The small model guarantees static code/data size < 4GB, but not where it // will be in memory. Most of these could end up >2GB away so even a signed // pc-relative 32-bit address is insufficient, theoretically. - if (isPositionIndependent()) { - // ILP32 uses sdata4 instead of sdata8 - if (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32) { - PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata4; - LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata4; - } else { - PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata8; - LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8; - TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | - dwarf::DW_EH_PE_sdata8; - } - } else { - PersonalityEncoding = dwarf::DW_EH_PE_absptr; - LSDAEncoding = dwarf::DW_EH_PE_absptr; - TTypeEncoding = dwarf::DW_EH_PE_absptr; - } + // + // Use DW_EH_PE_indirect even for -fno-pic to avoid copy relocations. + LSDAEncoding = dwarf::DW_EH_PE_pcrel | + (TgtM.getTargetTriple().getEnvironment() == Triple::GNUILP32 + ? dwarf::DW_EH_PE_sdata4 + : dwarf::DW_EH_PE_sdata8); + PersonalityEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect; + TTypeEncoding = LSDAEncoding | dwarf::DW_EH_PE_indirect; break; case Triple::lanai: LSDAEncoding = dwarf::DW_EH_PE_absptr; @@ -591,14 +583,7 @@ static const MCSymbolELF *getLinkedToSymbol(const GlobalObject *GO, if (!MD) return nullptr; - const MDOperand &Op = MD->getOperand(0); - if (!Op.get()) - return nullptr; - - auto *VM = dyn_cast<ValueAsMetadata>(Op); - if (!VM) - report_fatal_error("MD_associated operand is not ValueAsMetadata"); - + auto *VM = cast<ValueAsMetadata>(MD->getOperand(0).get()); auto *OtherGV = dyn_cast<GlobalValue>(VM->getValue()); return OtherGV ? dyn_cast<MCSymbolELF>(TM.getSymbol(OtherGV)) : nullptr; } @@ -629,21 +614,21 @@ static unsigned getEntrySizeForKind(SectionKind Kind) { /// Return the section prefix name used by options FunctionsSections and /// DataSections. -static StringRef getSectionPrefixForGlobal(SectionKind Kind) { +static StringRef getSectionPrefixForGlobal(SectionKind Kind, bool IsLarge) { if (Kind.isText()) return ".text"; if (Kind.isReadOnly()) - return ".rodata"; + return IsLarge ? ".lrodata" : ".rodata"; if (Kind.isBSS()) - return ".bss"; + return IsLarge ? ".lbss" : ".bss"; if (Kind.isThreadData()) return ".tdata"; if (Kind.isThreadBSS()) return ".tbss"; if (Kind.isData()) - return ".data"; + return IsLarge ? ".ldata" : ".data"; if (Kind.isReadOnlyWithRel()) - return ".data.rel.ro"; + return IsLarge ? ".ldata.rel.ro" : ".data.rel.ro"; llvm_unreachable("Unknown section kind"); } @@ -665,7 +650,10 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind, Name = ".rodata.cst"; Name += utostr(EntrySize); } else { - Name = getSectionPrefixForGlobal(Kind); + bool IsLarge = false; + if (isa<GlobalVariable>(GO)) + IsLarge = TM.isLargeData(); + Name = getSectionPrefixForGlobal(Kind, IsLarge); } bool HasPrefix = false; @@ -867,6 +855,12 @@ static MCSectionELF *selectELFSectionForGlobal( Group = C->getName(); IsComdat = C->getSelectionKind() == Comdat::Any; } + if (isa<GlobalVariable>(GO)) { + if (TM.isLargeData()) { + assert(TM.getTargetTriple().getArch() == Triple::x86_64); + Flags |= ELF::SHF_X86_64_LARGE; + } + } // Get the section entry size based on the kind. unsigned EntrySize = getEntrySizeForKind(Kind); @@ -1217,11 +1211,12 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection( unsigned Priority, const MCSymbol *KeySym) const { - // TODO(yln): Remove -lower-global-dtors-via-cxa-atexit fallback flag - // (LowerGlobalDtorsViaCxaAtExit) and always issue a fatal error here. - if (TM->Options.LowerGlobalDtorsViaCxaAtExit) - report_fatal_error("@llvm.global_dtors should have been lowered already"); return StaticDtorSection; + // In userspace, we lower global destructors via atexit(), but kernel/kext + // environments do not provide this function so we still need to support the + // legacy way here. + // See the -disable-atexit-based-global-dtor-lowering CodeGen flag for more + // context. } void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, @@ -1282,6 +1277,20 @@ MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( 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(); + } + } + const Function *F = dyn_cast<Function>(GO); if (F && F->hasFnAttribute("implicit-section-name")) { SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); @@ -1411,6 +1420,11 @@ MCSection *TargetLoweringObjectFileMachO::getSectionForConstant( return ReadOnlySection; // .const } +MCSection *TargetLoweringObjectFileMachO::getSectionForCommandLines() const { + return getContext().getMachOSection("__TEXT", "__command_line", 0, + SectionKind::getReadOnly()); +} + const MCExpr *TargetLoweringObjectFileMachO::getTTypeGlobalReference( const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, MachineModuleInfo *MMI, MCStreamer &Streamer) const { @@ -1796,6 +1810,19 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); } +bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection( + bool UsesLabelDifference, const Function &F) const { + if (TM->getTargetTriple().getArch() == Triple::x86_64) { + if (!JumpTableInFunctionSection) { + // We can always create relative relocations, so use another section + // that can be marked non-executable. + return false; + } + } + return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( + UsesLabelDifference, F); +} + void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { emitLinkerDirectives(Streamer, M); @@ -2152,7 +2179,7 @@ static MCSectionWasm *selectWasmSectionForGlobal( } bool UniqueSectionNames = TM.getUniqueSectionNames(); - SmallString<128> Name = getSectionPrefixForGlobal(Kind); + SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false); if (const auto *F = dyn_cast<Function>(GO)) { const auto &OptionalPrefix = F->getSectionPrefix(); @@ -2335,8 +2362,11 @@ MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal( XCOFF::StorageMappingClass MappingClass; if (Kind.isText()) MappingClass = XCOFF::XMC_PR; - else if (Kind.isData() || Kind.isReadOnlyWithRel() || Kind.isBSS()) + else if (Kind.isData() || Kind.isBSS()) MappingClass = XCOFF::XMC_RW; + else if (Kind.isReadOnlyWithRel()) + MappingClass = + TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW; else if (Kind.isReadOnly()) MappingClass = XCOFF::XMC_RO; else @@ -2421,9 +2451,18 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal( return TextSection; } - // TODO: We may put Kind.isReadOnlyWithRel() under option control, because - // user may want to have read-only data with relocations placed into a - // read-only section by the compiler. + if (TM.Options.XCOFFReadOnlyPointers && Kind.isReadOnlyWithRel()) { + if (!TM.getDataSections()) + report_fatal_error( + "ReadOnlyPointers is supported only if data sections is turned on"); + + SmallString<128> Name; + getNameWithPrefix(Name, GO, TM); + return getContext().getXCOFFSection( + Name, SectionKind::getReadOnly(), + XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD)); + } + // For BSS kind, zero initialized data must be emitted to the .data section // because external linkage control sections that get mapped to the .bss // section will be linked as tentative defintions, which is only appropriate |