diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -235,6 +235,8 @@ /// Set the code model. void setCodeModel(CodeModel::Model CM) { CMModel = CM; } + bool isLargeData() const; + bool isPositionIndependent() const; bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -614,21 +614,21 @@ /// 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"); } @@ -650,7 +650,10 @@ Name = ".rodata.cst"; Name += utostr(EntrySize); } else { - Name = getSectionPrefixForGlobal(Kind); + bool IsLarge = false; + if (isa(GO)) + IsLarge = TM.isLargeData(); + Name = getSectionPrefixForGlobal(Kind, IsLarge); } bool HasPrefix = false; @@ -852,6 +855,12 @@ Group = C->getName(); IsComdat = C->getSelectionKind() == Comdat::Any; } + if (isa(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); @@ -2165,7 +2174,7 @@ } bool UniqueSectionNames = TM.getUniqueSectionNames(); - SmallString<128> Name = getSectionPrefixForGlobal(Kind); + SmallString<128> Name = getSectionPrefixForGlobal(Kind, /*IsLarge=*/false); if (const auto *F = dyn_cast(GO)) { const auto &OptionalPrefix = F->getSectionPrefix(); diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -21,6 +21,7 @@ #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/CodeGen.h" #include "llvm/Target/TargetLoweringObjectFile.h" using namespace llvm; @@ -38,6 +39,16 @@ TargetMachine::~TargetMachine() = default; +bool TargetMachine::isLargeData() const { + if (getTargetTriple().getArch() != Triple::x86_64) + return false; + // Large data under the large code model still needs to be thought about, so + // restrict this to medium. + if (getCodeModel() != CodeModel::Medium) + return false; + return true; +} + bool TargetMachine::isPositionIndependent() const { return getRelocationModel() == Reloc::PIC_; } diff --git a/llvm/test/CodeGen/X86/code-model-elf-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-sections.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/code-model-elf-sections.ll @@ -0,0 +1,43 @@ +; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=small -o %t +; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL +; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -o %t +; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE +; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=large -o %t +; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL + +; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=small -data-sections -o %t +; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL-DS +; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=medium -data-sections -o %t +; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=LARGE-DS +; RUN: llc < %s -relocation-model=pic -filetype=obj -code-model=large -data-sections -o %t +; RUN: llvm-readelf -S %t | FileCheck %s --check-prefix=SMALL-DS + +; SMALL: .data {{.*}} WA {{.*}} +; SMALL: .bss {{.*}} WA {{.*}} +; SMALL: .rodata {{.*}} A {{.*}} +; SMALL: .data.rel.ro {{.*}} WA {{.*}} + +; SMALL-DS: .data.data {{.*}} WA {{.*}} +; SMALL-DS: .bss.bss {{.*}} WA {{.*}} +; SMALL-DS: .rodata.rodata {{.*}} A {{.*}} +; SMALL-DS: .data.rel.ro.relro {{.*}} WA {{.*}} + +; LARGE: .ldata {{.*}} WAl {{.*}} +; LARGE: .lbss {{.*}} WAl {{.*}} +; LARGE: .lrodata {{.*}} Al {{.*}} +; LARGE: .ldata.rel.ro {{.*}} WAl {{.*}} + +; LARGE-DS: .ldata.data {{.*}} WAl {{.*}} +; LARGE-DS: .lbss.bss {{.*}} WAl {{.*}} +; LARGE-DS: .lrodata.rodata {{.*}} Al {{.*}} +; LARGE-DS: .ldata.rel.ro.relro {{.*}} WAl {{.*}} + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64--linux" + +@data = internal global [10 x i64] [i64 1, i64 2, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0] +@bss = internal global [10 x i64] zeroinitializer +@rodata = internal constant [10 x i64] zeroinitializer +@relro = internal constant [10 x ptr] [ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func, ptr @func] + +declare void @func()