aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp')
-rw-r--r--llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp127
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