aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-29 20:15:26 +0000
commit344a3780b2e33f6ca763666c380202b18aab72a3 (patch)
treef0b203ee6eb71d7fdd792373e3c81eb18d6934dd /llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r--llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp511
1 files changed, 352 insertions, 159 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index fe64b38cf0be..add34eccc1f3 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -21,6 +21,7 @@
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/ELF.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"
@@ -47,6 +48,7 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCSectionXCOFF.h"
@@ -153,7 +155,7 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
((CM == CodeModel::Small || CM == CodeModel::Medium)
- ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4);
+ ? dwarf::DW_EH_PE_sdata4 : dwarf::DW_EH_PE_sdata8);
} else {
PersonalityEncoding =
(CM == CodeModel::Small || CM == CodeModel::Medium)
@@ -293,6 +295,14 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
}
}
+void TargetLoweringObjectFileELF::getModuleMetadata(Module &M) {
+ SmallVector<GlobalValue *, 4> Vec;
+ collectUsedGlobalVariables(M, Vec, false);
+ for (GlobalValue *GV : Vec)
+ if (auto *GO = dyn_cast<GlobalObject>(GV))
+ Used.insert(GO);
+}
+
void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
Module &M) const {
auto &C = getContext();
@@ -315,7 +325,7 @@ void TargetLoweringObjectFileELF::emitModuleMetadata(MCStreamer &Streamer,
if (NamedMDNode *DependentLibraries = M.getNamedMetadata("llvm.dependent-libraries")) {
auto *S = C.getELFSection(".deplibs", ELF::SHT_LLVM_DEPENDENT_LIBRARIES,
- ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
+ ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
Streamer.SwitchSection(S);
@@ -522,8 +532,10 @@ static const Comdat *getELFComdat(const GlobalValue *GV) {
if (!C)
return nullptr;
- if (C->getSelectionKind() != Comdat::Any)
- report_fatal_error("ELF COMDATs only support SelectionKind::Any, '" +
+ if (C->getSelectionKind() != Comdat::Any &&
+ C->getSelectionKind() != Comdat::NoDeduplicate)
+ report_fatal_error("ELF COMDATs only support SelectionKind::Any and "
+ "SelectionKind::NoDeduplicate, '" +
C->getName() + "' cannot be lowered.");
return C;
@@ -624,6 +636,8 @@ getELFSectionNameForGlobal(const GlobalObject *GO, SectionKind Kind,
Name.push_back('.');
TM.getNameWithPrefix(Name, GO, Mang, /*MayAlwaysUsePrivate*/true);
} else if (HasPrefix)
+ // For distinguishing between .text.${text-section-prefix}. (with trailing
+ // dot) and .text.${function-name}
Name.push_back('.');
return Name;
}
@@ -640,8 +654,85 @@ public:
};
}
-MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
- const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
+/// Calculate an appropriate unique ID for a section, and update Flags,
+/// EntrySize and NextUniqueID where appropriate.
+static unsigned
+calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName,
+ SectionKind Kind, const TargetMachine &TM,
+ MCContext &Ctx, Mangler &Mang, unsigned &Flags,
+ unsigned &EntrySize, unsigned &NextUniqueID,
+ const bool Retain, const bool ForceUnique) {
+ // Increment uniqueID if we are forced to emit a unique section.
+ // This works perfectly fine with section attribute or pragma section as the
+ // sections with the same name are grouped together by the assembler.
+ if (ForceUnique)
+ return NextUniqueID++;
+
+ // A section can have at most one associated section. Put each global with
+ // MD_associated in a unique section.
+ const bool Associated = GO->getMetadata(LLVMContext::MD_associated);
+ if (Associated) {
+ Flags |= ELF::SHF_LINK_ORDER;
+ return NextUniqueID++;
+ }
+
+ if (Retain) {
+ if (Ctx.getAsmInfo()->useIntegratedAssembler() ||
+ Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))
+ Flags |= ELF::SHF_GNU_RETAIN;
+ return NextUniqueID++;
+ }
+
+ // 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).
+ const bool SupportsUnique = Ctx.getAsmInfo()->useIntegratedAssembler() ||
+ Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35);
+ if (!SupportsUnique) {
+ Flags &= ~ELF::SHF_MERGE;
+ EntrySize = 0;
+ return MCContext::GenericSectionID;
+ }
+
+ 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
+ // generic section
+ if (!SymbolMergeable && !SeenSectionNameBefore)
+ return MCContext::GenericSectionID;
+
+ // Symbols must be placed into sections with compatible entry sizes. Generate
+ // unique sections for symbols that have not been assigned to compatible
+ // sections.
+ const auto PreviousID =
+ Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize);
+ if (PreviousID)
+ 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);
+ if (SymbolMergeable &&
+ Ctx.isELFImplicitMergeableSectionNamePrefix(SectionName) &&
+ SectionName.startswith(ImplicitSectionNameStem))
+ return MCContext::GenericSectionID;
+
+ // We have seen this section name before, but with different flags or entity
+ // size. Create a new unique ID.
+ return NextUniqueID++;
+}
+
+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();
// Check if '#pragma clang section' name is applicable.
@@ -669,76 +760,30 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
Kind = getELFKindForNamedSection(SectionName, Kind);
StringRef Group = "";
+ bool IsComdat = false;
unsigned Flags = getELFSectionFlags(Kind);
if (const Comdat *C = getELFComdat(GO)) {
Group = C->getName();
+ IsComdat = C->getSelectionKind() == Comdat::Any;
Flags |= ELF::SHF_GROUP;
}
unsigned EntrySize = getEntrySizeForKind(Kind);
+ const unsigned UniqueID = calcUniqueIDUpdateFlagsAndSize(
+ GO, SectionName, Kind, TM, Ctx, Mang, Flags, EntrySize, NextUniqueID,
+ Retain, ForceUnique);
- // 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 *LinkedToSym = getLinkedToSymbol(GO, TM);
- if (GO->getMetadata(LLVMContext::MD_associated)) {
- UniqueID = NextUniqueID++;
- Flags |= ELF::SHF_LINK_ORDER;
- } else {
- if (getContext().getAsmInfo()->useIntegratedAssembler() ||
- getContext().getAsmInfo()->binutilsIsAtLeast(2, 35)) {
- // 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,
- EntrySize, Group, UniqueID, LinkedToSym);
+ MCSectionELF *Section = Ctx.getELFSection(
+ SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize,
+ Group, IsComdat, 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->getLinkedToSymbol() == LinkedToSym &&
"Associated symbol mismatch between sections");
- if (!(getContext().getAsmInfo()->useIntegratedAssembler() ||
- getContext().getAsmInfo()->binutilsIsAtLeast(2, 35))) {
+ if (!(Ctx.getAsmInfo()->useIntegratedAssembler() ||
+ Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35))) {
// If we are using GNU as before 2.35, 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.
@@ -757,15 +802,24 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
return Section;
}
+MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
+ const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
+ return selectExplicitSectionGlobal(GO, Kind, TM, getContext(), getMangler(),
+ NextUniqueID, Used.count(GO),
+ /* ForceUnique = */false);
+}
+
static MCSectionELF *selectELFSectionForGlobal(
MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags,
unsigned *NextUniqueID, const MCSymbolELF *AssociatedSymbol) {
StringRef Group = "";
+ bool IsComdat = false;
if (const Comdat *C = getELFComdat(GO)) {
Flags |= ELF::SHF_GROUP;
Group = C->getName();
+ IsComdat = C->getSelectionKind() == Comdat::Any;
}
// Get the section entry size based on the kind.
@@ -788,7 +842,30 @@ static MCSectionELF *selectELFSectionForGlobal(
if (Kind.isExecuteOnly())
UniqueID = 0;
return Ctx.getELFSection(Name, getELFSectionType(Name, Kind), Flags,
- EntrySize, Group, UniqueID, AssociatedSymbol);
+ EntrySize, Group, IsComdat, UniqueID,
+ AssociatedSymbol);
+}
+
+static MCSection *selectELFSectionForGlobal(
+ MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
+ const TargetMachine &TM, bool Retain, bool EmitUniqueSection,
+ unsigned Flags, unsigned *NextUniqueID) {
+ const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM);
+ if (LinkedToSym) {
+ EmitUniqueSection = true;
+ Flags |= ELF::SHF_LINK_ORDER;
+ }
+ if (Retain && (Ctx.getAsmInfo()->useIntegratedAssembler() ||
+ Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))) {
+ EmitUniqueSection = true;
+ Flags |= ELF::SHF_GNU_RETAIN;
+ }
+
+ MCSectionELF *Section = selectELFSectionForGlobal(
+ Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags,
+ NextUniqueID, LinkedToSym);
+ assert(Section->getLinkedToSymbol() == LinkedToSym);
+ return Section;
}
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
@@ -805,18 +882,25 @@ MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
EmitUniqueSection = TM.getDataSections();
}
EmitUniqueSection |= GO->hasComdat();
+ return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM,
+ Used.count(GO), EmitUniqueSection, Flags,
+ &NextUniqueID);
+}
- 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, LinkedToSym);
- assert(Section->getLinkedToSymbol() == LinkedToSym);
- return Section;
+MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction(
+ const Function &F, const TargetMachine &TM) const {
+ SectionKind Kind = SectionKind::getText();
+ unsigned Flags = getELFSectionFlags(Kind);
+ // If the function's section names is pre-determined via pragma or a
+ // section attribute, call selectExplicitSectionGlobal.
+ if (F.hasSection() || F.hasFnAttribute("implicit-section-name"))
+ 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);
}
MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
@@ -834,9 +918,8 @@ MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable(
/* AssociatedSymbol */ nullptr);
}
-MCSection *
-TargetLoweringObjectFileELF::getSectionForLSDA(const Function &F,
- const TargetMachine &TM) const {
+MCSection *TargetLoweringObjectFileELF::getSectionForLSDA(
+ const Function &F, const MCSymbol &FnSym, const TargetMachine &TM) const {
// If neither COMDAT nor function sections, use the monolithic LSDA section.
// Re-use this path if LSDASection is null as in the Arm EHABI.
if (!LSDASection || (!F.hasComdat() && !TM.getFunctionSections()))
@@ -844,31 +927,30 @@ TargetLoweringObjectFileELF::getSectionForLSDA(const Function &F,
const auto *LSDA = cast<MCSectionELF>(LSDASection);
unsigned Flags = LSDA->getFlags();
+ const MCSymbolELF *LinkedToSym = nullptr;
StringRef Group;
- if (F.hasComdat()) {
- Group = F.getComdat()->getName();
+ bool IsComdat = false;
+ if (const Comdat *C = getELFComdat(&F)) {
Flags |= ELF::SHF_GROUP;
+ Group = C->getName();
+ IsComdat = C->getSelectionKind() == Comdat::Any;
+ }
+ // Use SHF_LINK_ORDER to facilitate --gc-sections if we can use GNU ld>=2.36
+ // or LLD, which support mixed SHF_LINK_ORDER & non-SHF_LINK_ORDER.
+ if (TM.getFunctionSections() &&
+ (getContext().getAsmInfo()->useIntegratedAssembler() &&
+ getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) {
+ Flags |= ELF::SHF_LINK_ORDER;
+ LinkedToSym = cast<MCSymbolELF>(&FnSym);
}
// Append the function name as the suffix like GCC, assuming
// -funique-section-names applies to .gcc_except_table sections.
- if (TM.getUniqueSectionNames())
- return getContext().getELFSection(LSDA->getName() + "." + F.getName(),
- LSDA->getType(), Flags, 0, Group,
- MCSection::NonUniqueID, nullptr);
-
- // Allocate a unique ID if function sections && (integrated assembler or GNU
- // as>=2.35). Note we could use SHF_LINK_ORDER to facilitate --gc-sections but
- // that would require that we know the linker is a modern LLD (12.0 or later).
- // GNU ld as of 2.35 does not support mixed SHF_LINK_ORDER &
- // non-SHF_LINK_ORDER components in an output section
- // https://sourceware.org/bugzilla/show_bug.cgi?id=26256
- unsigned ID = TM.getFunctionSections() &&
- getContext().getAsmInfo()->useIntegratedAssembler()
- ? NextUniqueID++
- : MCSection::NonUniqueID;
- return getContext().getELFSection(LSDA->getName(), LSDA->getType(), Flags, 0,
- Group, ID, nullptr);
+ return getContext().getELFSection(
+ (TM.getUniqueSectionNames() ? LSDA->getName() + "." + F.getName()
+ : LSDA->getName()),
+ LSDA->getType(), Flags, 0, Group, IsComdat, MCSection::NonUniqueID,
+ LinkedToSym);
}
bool TargetLoweringObjectFileELF::shouldPutJumpTableInFunctionSection(
@@ -920,7 +1002,8 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
} else {
Name += MBB.getParent()->getSection()->getName();
if (TM.getUniqueBasicBlockSectionNames()) {
- Name += ".";
+ if (!Name.endswith("."))
+ Name += ".";
Name += MBB.getSymbol()->getName();
} else {
UniqueID = NextUniqueID++;
@@ -934,8 +1017,8 @@ MCSection *TargetLoweringObjectFileELF::getSectionForMachineBasicBlock(
GroupName = F.getComdat()->getName().str();
}
return getContext().getELFSection(Name, ELF::SHT_PROGBITS, Flags,
- 0 /* Entry Size */, GroupName, UniqueID,
- nullptr);
+ 0 /* Entry Size */, GroupName,
+ F.hasComdat(), UniqueID, nullptr);
}
static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
@@ -944,7 +1027,7 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
std::string Name;
unsigned Type;
unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE;
- StringRef COMDAT = KeySym ? KeySym->getName() : "";
+ StringRef Comdat = KeySym ? KeySym->getName() : "";
if (KeySym)
Flags |= ELF::SHF_GROUP;
@@ -973,7 +1056,7 @@ static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray,
Type = ELF::SHT_PROGBITS;
}
- return Ctx.getELFSection(Name, Type, Flags, 0, COMDAT);
+ return Ctx.getELFSection(Name, Type, Flags, 0, Comdat, /*IsComdat=*/true);
}
MCSection *TargetLoweringObjectFileELF::getStaticCtorSection(
@@ -1027,7 +1110,7 @@ MCSection *TargetLoweringObjectFileELF::getSectionForCommandLines() const {
// -frecord-gcc-switches which in turn attempts to mimic GCC's switch of the
// same name.
return getContext().getELFSection(".GCC.command.line", ELF::SHT_PROGBITS,
- ELF::SHF_MERGE | ELF::SHF_STRINGS, 1, "");
+ ELF::SHF_MERGE | ELF::SHF_STRINGS, 1);
}
void
@@ -1107,13 +1190,12 @@ void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer,
StringRef Segment, Section;
unsigned TAA = 0, StubSize = 0;
bool TAAParsed;
- std::string ErrorCode =
- MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section,
- TAA, TAAParsed, StubSize);
- if (!ErrorCode.empty())
+ if (Error E = MCSectionMachO::ParseSectionSpecifier(
+ SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) {
// If invalid, report the error with report_fatal_error.
- report_fatal_error("Invalid section specifier '" + Section + "': " +
- ErrorCode + ".");
+ report_fatal_error("Invalid section specifier '" + Section +
+ "': " + toString(std::move(E)) + ".");
+ }
// Get the section.
MCSectionMachO *S = getContext().getMachOSection(
@@ -1137,6 +1219,14 @@ static void checkMachOComdat(const GlobalValue *GV) {
MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
+
+ StringRef SectionName = GO->getSection();
+
+ const Function *F = dyn_cast<Function>(GO);
+ if (F && F->hasFnAttribute("implicit-section-name")) {
+ SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
+ }
+
// Parse the section specifier and create it if valid.
StringRef Segment, Section;
unsigned TAA = 0, StubSize = 0;
@@ -1144,14 +1234,12 @@ MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
checkMachOComdat(GO);
- std::string ErrorCode =
- MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section,
- TAA, TAAParsed, StubSize);
- if (!ErrorCode.empty()) {
+ if (Error E = MCSectionMachO::ParseSectionSpecifier(
+ SectionName, Segment, Section, TAA, TAAParsed, StubSize)) {
// If invalid, report the error with report_fatal_error.
report_fatal_error("Global variable '" + GO->getName() +
"' has an invalid section specifier '" +
- GO->getSection() + "': " + ErrorCode + ".");
+ GO->getSection() + "': " + toString(std::move(E)) + ".");
}
// Get the section.
@@ -1393,11 +1481,10 @@ static bool canUsePrivateLabel(const MCAsmInfo &AsmInfo,
if (!AsmInfo.isSectionAtomizableBySymbols(Section))
return true;
- // If it is not dead stripped, it is safe to use private labels.
- const MCSectionMachO &SMO = cast<MCSectionMachO>(Section);
- if (SMO.hasAttribute(MachO::S_ATTR_NO_DEAD_STRIP))
- return true;
-
+ // FIXME: we should be able to use private labels for sections that can't be
+ // dead-stripped (there's no issue with blocking atomization there), but `ld
+ // -r` sometimes drops the no_dead_strip attribute from sections so for safety
+ // we don't allow it.
return false;
}
@@ -1485,7 +1572,7 @@ static int getSelectionForCOFF(const GlobalValue *GV) {
return COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH;
case Comdat::Largest:
return COFF::IMAGE_COMDAT_SELECT_LARGEST;
- case Comdat::NoDuplicates:
+ case Comdat::NoDeduplicate:
return COFF::IMAGE_COMDAT_SELECT_NODUPLICATES;
case Comdat::SameSize:
return COFF::IMAGE_COMDAT_SELECT_SAME_SIZE;
@@ -1576,7 +1663,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 (getTargetTriple().isWindowsGNUEnvironment())
+ if (getContext().getTargetTriple().isWindowsGNUEnvironment())
raw_svector_ostream(Name) << '$' << ComdatGV->getName();
return getContext().getCOFFSection(Name, Characteristics, Kind,
@@ -1693,7 +1780,8 @@ void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
std::string Flags;
for (const GlobalValue &GV : M.global_values()) {
raw_string_ostream OS(Flags);
- emitLinkerFlagsForGlobalCOFF(OS, &GV, getTargetTriple(), getMangler());
+ emitLinkerFlagsForGlobalCOFF(OS, &GV, getContext().getTargetTriple(),
+ getMangler());
OS.flush();
if (!Flags.empty()) {
Streamer.SwitchSection(getDrectveSection());
@@ -1717,7 +1805,8 @@ void TargetLoweringObjectFileCOFF::emitLinkerDirectives(
continue;
raw_string_ostream OS(Flags);
- emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
+ emitLinkerFlagsForUsedCOFF(OS, GV, getContext().getTargetTriple(),
+ getMangler());
OS.flush();
if (!Flags.empty()) {
@@ -1796,16 +1885,16 @@ static MCSectionCOFF *getCOFFStaticStructorSection(MCContext &Ctx,
MCSection *TargetLoweringObjectFileCOFF::getStaticCtorSection(
unsigned Priority, const MCSymbol *KeySym) const {
- return getCOFFStaticStructorSection(getContext(), getTargetTriple(), true,
- Priority, KeySym,
- cast<MCSectionCOFF>(StaticCtorSection));
+ return getCOFFStaticStructorSection(
+ getContext(), getContext().getTargetTriple(), true, Priority, KeySym,
+ cast<MCSectionCOFF>(StaticCtorSection));
}
MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
unsigned Priority, const MCSymbol *KeySym) const {
- return getCOFFStaticStructorSection(getContext(), getTargetTriple(), false,
- Priority, KeySym,
- cast<MCSectionCOFF>(StaticDtorSection));
+ return getCOFFStaticStructorSection(
+ getContext(), getContext().getTargetTriple(), false, Priority, KeySym,
+ cast<MCSectionCOFF>(StaticDtorSection));
}
const MCExpr *TargetLoweringObjectFileCOFF::lowerRelativeReference(
@@ -1841,7 +1930,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);
+ std::string HexString = toString(AI, 16, /*Signed=*/false);
llvm::transform(HexString, HexString.begin(), tolower);
unsigned Size = HexString.size();
assert(Width >= Size && "hex string is too large!");
@@ -1934,6 +2023,20 @@ static const Comdat *getWasmComdat(const GlobalValue *GV) {
return C;
}
+static unsigned getWasmSectionFlags(SectionKind K) {
+ unsigned Flags = 0;
+
+ if (K.isThreadLocal())
+ Flags |= wasm::WASM_SEG_FLAG_TLS;
+
+ if (K.isMergeableCString())
+ Flags |= wasm::WASM_SEG_FLAG_STRINGS;
+
+ // TODO(sbc): Add suport for K.isMergeableConst()
+
+ return Flags;
+}
+
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
@@ -1957,9 +2060,9 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
Group = C->getName();
}
- MCSectionWasm* Section =
- getContext().getWasmSection(Name, Kind, Group,
- MCContext::GenericSectionID);
+ unsigned Flags = getWasmSectionFlags(Kind);
+ MCSectionWasm *Section = getContext().getWasmSection(
+ Name, Kind, Flags, Group, MCContext::GenericSectionID);
return Section;
}
@@ -1991,7 +2094,8 @@ static MCSectionWasm *selectWasmSectionForGlobal(
(*NextUniqueID)++;
}
- return Ctx.getWasmSection(Name, Kind, Group, UniqueID);
+ unsigned Flags = getWasmSectionFlags(Kind);
+ return Ctx.getWasmSection(Name, Kind, Flags, Group, UniqueID);
}
MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal(
@@ -2075,14 +2179,26 @@ bool TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(
if (!F.hasPersonalityFn() || !F.needsUnwindTableEntry())
return false;
- const Function *Per =
- dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
+ const GlobalValue *Per =
+ dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
+ assert(Per && "Personality routine is not a GlobalValue type.");
if (isNoOpWithoutInvoke(classifyEHPersonality(Per)))
return false;
return true;
}
+bool TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB(
+ const MachineFunction *MF) {
+ const Function &F = MF->getFunction();
+ if (!F.hasStackProtectorFnAttr())
+ return false;
+ // FIXME: check presence of canary word
+ // There are cases that the stack protectors are not really inserted even if
+ // the attributes are on.
+ return true;
+}
+
MCSymbol *
TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(const MachineFunction *MF) {
return MF->getMMI().getContext().getOrCreateSymbol(
@@ -2101,6 +2217,12 @@ TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
// function entry point. We choose to always return a function descriptor
// here.
if (const GlobalObject *GO = dyn_cast<GlobalObject>(GV)) {
+ if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
+ if (GVar->hasAttribute("toc-data"))
+ return cast<MCSectionXCOFF>(
+ SectionForGlobal(GVar, SectionKind::getData(), TM))
+ ->getQualNameSymbol();
+
if (GO->isDeclarationForLinker())
return cast<MCSectionXCOFF>(getSectionForExternalReference(GO, TM))
->getQualNameSymbol();
@@ -2110,8 +2232,8 @@ TargetLoweringObjectFileXCOFF::getTargetSymbol(const GlobalValue *GV,
return cast<MCSectionXCOFF>(
getSectionForFunctionDescriptor(cast<Function>(GO), TM))
->getQualNameSymbol();
- if ((TM.getDataSections() && !GO->hasSection()) || GOKind.isCommon() ||
- GOKind.isBSSLocal())
+ if ((TM.getDataSections() && !GO->hasSection()) || GO->hasCommonLinkage() ||
+ GOKind.isBSSLocal() || GOKind.isThreadBSSLocal())
return cast<MCSectionXCOFF>(SectionForGlobal(GO, GOKind, TM))
->getQualNameSymbol();
}
@@ -2126,6 +2248,15 @@ MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
report_fatal_error("#pragma clang section is not yet supported");
StringRef SectionName = GO->getSection();
+
+ // Handle the XCOFF::TD case first, then deal with the rest.
+ if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
+ if (GVar->hasAttribute("toc-data"))
+ return getContext().getXCOFFSection(
+ SectionName, Kind,
+ XCOFF::CsectProperties(/*MappingClass*/ XCOFF::XMC_TD, XCOFF::XTY_SD),
+ /* MultiSymbolsAllowed*/ true);
+
XCOFF::StorageMappingClass MappingClass;
if (Kind.isText())
MappingClass = XCOFF::XMC_PR;
@@ -2136,8 +2267,9 @@ MCSection *TargetLoweringObjectFileXCOFF::getExplicitSectionGlobal(
else
report_fatal_error("XCOFF other section types not yet implemented.");
- return getContext().getXCOFFSection(SectionName, MappingClass, XCOFF::XTY_SD,
- Kind, /* MultiSymbolsAllowed*/ true);
+ return getContext().getXCOFFSection(
+ SectionName, Kind, XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD),
+ /* MultiSymbolsAllowed*/ true);
}
MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
@@ -2148,22 +2280,41 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForExternalReference(
SmallString<128> Name;
getNameWithPrefix(Name, GO, TM);
+ XCOFF::StorageMappingClass SMC =
+ isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA;
+ if (GO->isThreadLocal())
+ SMC = XCOFF::XMC_UL;
+
// Externals go into a csect of type ER.
return getContext().getXCOFFSection(
- Name, isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA, XCOFF::XTY_ER,
- SectionKind::getMetadata());
+ Name, SectionKind::getMetadata(),
+ XCOFF::CsectProperties(SMC, XCOFF::XTY_ER));
}
MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
+ // Handle the XCOFF::TD case first, then deal with the rest.
+ if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GO))
+ if (GVar->hasAttribute("toc-data")) {
+ SmallString<128> Name;
+ getNameWithPrefix(Name, GO, TM);
+ return getContext().getXCOFFSection(
+ Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TD, XCOFF::XTY_SD),
+ /* MultiSymbolsAllowed*/ true);
+ }
+
// Common symbols go into a csect with matching name which will get mapped
// into the .bss section.
- if (Kind.isBSSLocal() || Kind.isCommon()) {
+ // Zero-initialized local TLS symbols go into a csect with matching name which
+ // will get mapped into the .tbss section.
+ if (Kind.isBSSLocal() || GO->hasCommonLinkage() || Kind.isThreadBSSLocal()) {
SmallString<128> Name;
getNameWithPrefix(Name, GO, TM);
+ XCOFF::StorageMappingClass SMC = Kind.isBSSLocal() ? XCOFF::XMC_BS
+ : Kind.isCommon() ? XCOFF::XMC_RW
+ : XCOFF::XMC_UL;
return getContext().getXCOFFSection(
- Name, Kind.isBSSLocal() ? XCOFF::XMC_BS : XCOFF::XMC_RW, XCOFF::XTY_CM,
- Kind);
+ Name, Kind, XCOFF::CsectProperties(SMC, XCOFF::XTY_CM));
}
if (Kind.isMergeableCString()) {
@@ -2179,7 +2330,7 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
getNameWithPrefix(Name, GO, TM);
return getContext().getXCOFFSection(
- Name, XCOFF::XMC_RO, XCOFF::XTY_SD, Kind,
+ Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD),
/* MultiSymbolsAllowed*/ !TM.getDataSections());
}
@@ -2202,8 +2353,9 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
if (TM.getDataSections()) {
SmallString<128> Name;
getNameWithPrefix(Name, GO, TM);
- return getContext().getXCOFFSection(Name, XCOFF::XMC_RW, XCOFF::XTY_SD,
- SectionKind::getData());
+ return getContext().getXCOFFSection(
+ Name, SectionKind::getData(),
+ XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD));
}
return DataSection;
}
@@ -2212,12 +2364,27 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
if (TM.getDataSections()) {
SmallString<128> Name;
getNameWithPrefix(Name, GO, TM);
- return getContext().getXCOFFSection(Name, XCOFF::XMC_RO, XCOFF::XTY_SD,
- SectionKind::getReadOnly());
+ return getContext().getXCOFFSection(
+ Name, SectionKind::getReadOnly(),
+ XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));
}
return ReadOnlySection;
}
+ // External/weak TLS data and initialized local TLS data are not eligible
+ // to be put into common csect. If data sections are enabled, thread
+ // data are emitted into separate sections. Otherwise, thread data
+ // are emitted into the .tdata section.
+ if (Kind.isThreadLocal()) {
+ if (TM.getDataSections()) {
+ SmallString<128> Name;
+ getNameWithPrefix(Name, GO, TM);
+ return getContext().getXCOFFSection(
+ Name, Kind, XCOFF::CsectProperties(XCOFF::XMC_TL, XCOFF::XTY_SD));
+ }
+ return TLSDataSection;
+ }
+
report_fatal_error("XCOFF other section types not yet implemented.");
}
@@ -2232,8 +2399,9 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForJumpTable(
// the table doesn't prevent the removal.
SmallString<128> NameStr(".rodata.jmp..");
getNameWithPrefix(NameStr, &F, TM);
- return getContext().getXCOFFSection(NameStr, XCOFF::XMC_RO, XCOFF::XTY_SD,
- SectionKind::getReadOnly());
+ return getContext().getXCOFFSection(
+ NameStr, SectionKind::getReadOnly(),
+ XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD));
}
bool TargetLoweringObjectFileXCOFF::shouldPutJumpTableInFunctionSection(
@@ -2324,9 +2492,11 @@ MCSymbol *TargetLoweringObjectFileXCOFF::getFunctionEntryPointSymbol(
Func->isDeclaration()) &&
isa<Function>(Func)) {
return getContext()
- .getXCOFFSection(NameStr, XCOFF::XMC_PR,
- Func->isDeclaration() ? XCOFF::XTY_ER : XCOFF::XTY_SD,
- SectionKind::getText())
+ .getXCOFFSection(
+ NameStr, SectionKind::getText(),
+ XCOFF::CsectProperties(XCOFF::XMC_PR, Func->isDeclaration()
+ ? XCOFF::XTY_ER
+ : XCOFF::XTY_SD))
->getQualNameSymbol();
}
@@ -2337,8 +2507,9 @@ 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,
- SectionKind::getData());
+ return getContext().getXCOFFSection(
+ NameStr, SectionKind::getData(),
+ XCOFF::CsectProperties(XCOFF::XMC_DS, XCOFF::XTY_SD));
}
MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
@@ -2346,7 +2517,29 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
// Use TE storage-mapping class when large code model is enabled so that
// the chance of needing -bbigtoc is decreased.
return getContext().getXCOFFSection(
- cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(),
- TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
- XCOFF::XTY_SD, SectionKind::getData());
+ cast<MCSymbolXCOFF>(Sym)->getSymbolTableName(), SectionKind::getData(),
+ XCOFF::CsectProperties(
+ TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
+ XCOFF::XTY_SD));
+}
+
+//===----------------------------------------------------------------------===//
+// GOFF
+//===----------------------------------------------------------------------===//
+TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF()
+ : TargetLoweringObjectFile() {}
+
+MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
+ const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
+ return SelectSectionForGlobal(GO, Kind, TM);
+}
+
+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());
+
+ return getContext().getObjectFileInfo()->getTextSection();
}