aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-08-13 05:07:35 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2009-08-13 05:07:35 +0000
commitb808588a3a5febe931896b3779d159ba90d836f7 (patch)
treee07ae309748105f8a462ce435a66f3412dce5ba6
parent62728dc14d05e9a677664b784c4f5c6e188aa11a (diff)
downloadexternal_llvm-b808588a3a5febe931896b3779d159ba90d836f7.zip
external_llvm-b808588a3a5febe931896b3779d159ba90d836f7.tar.gz
external_llvm-b808588a3a5febe931896b3779d159ba90d836f7.tar.bz2
Change MCSectionELF to represent a section semantically instead of
syntactically as a string, very similiar to what Chris did with MachO. The parsing support and validation is not introduced yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78890 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/MC/MCSection.h27
-rw-r--r--include/llvm/MC/MCSectionELF.h168
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h5
-rw-r--r--lib/CodeGen/ELFWriter.cpp36
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/MCSection.cpp85
-rw-r--r--lib/MC/MCSectionELF.cpp123
-rw-r--r--lib/Target/ARM/ARMTargetObjectFile.h9
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp220
-rw-r--r--lib/Target/XCore/XCoreTargetObjectFile.cpp21
-rw-r--r--test/CodeGen/X86/attribute-sections.ll18
11 files changed, 514 insertions, 199 deletions
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index b33e8c9..6a1f9d7 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -41,33 +41,6 @@ namespace llvm {
raw_ostream &OS) const = 0;
};
-
- class MCSectionELF : public MCSection {
- std::string Name;
-
- /// IsDirective - This is true if the section name is a directive, not
- /// something that should be printed with ".section".
- ///
- /// FIXME: This is a hack. Switch to a semantic view of the section instead
- /// of a syntactic one.
- bool IsDirective;
-
- MCSectionELF(const StringRef &name, bool isDirective, SectionKind K)
- : MCSection(K), Name(name), IsDirective(isDirective) {
- }
- public:
-
- static MCSectionELF *Create(const StringRef &Name, bool IsDirective,
- SectionKind K, MCContext &Ctx);
-
- const std::string &getName() const { return Name; }
- bool isDirective() const { return IsDirective; }
-
-
- virtual void PrintSwitchToSection(const TargetAsmInfo &TAI,
- raw_ostream &OS) const;
- };
-
class MCSectionCOFF : public MCSection {
std::string Name;
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
new file mode 100644
index 0000000..00369f7
--- /dev/null
+++ b/include/llvm/MC/MCSectionELF.h
@@ -0,0 +1,168 @@
+//===- MCSectionELF.h - ELF Machine Code Sections ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the MCSectionELF class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCSECTIONELF_H
+#define LLVM_MC_MCSECTIONELF_H
+
+#include "llvm/MC/MCSection.h"
+
+namespace llvm {
+
+/// MCSectionELF - This represents a section on linux, lots of unix variants
+/// and some bare metal systems.
+class MCSectionELF : public MCSection {
+ std::string SectionName;
+
+ /// Type - This is the sh_type field of a section, drawn from the enums below.
+ unsigned Type;
+
+ /// Flags - This is the sh_flags field of a section, drawn from the enums.
+ /// below.
+ unsigned Flags;
+
+ /// HasCrazyBSS - PPC/Linux doesn't support the .bss directive, it
+ /// needs .section .bss. TODO: replace this with a TAI method.
+ bool HasCrazyBSS;
+
+ /// IsExplicit - Indicates that this section comes from globals with an
+ /// explicit section specfied.
+ bool IsExplicit;
+
+ MCSectionELF(const StringRef &Section, unsigned T, unsigned F,
+ SectionKind K, bool hasCrazyBSS, bool isExplicit)
+ : MCSection(K), SectionName(Section.str()), Type(T), Flags(F),
+ HasCrazyBSS(hasCrazyBSS), IsExplicit(isExplicit) {}
+public:
+
+ static MCSectionELF *Create(const StringRef &Section, unsigned Type,
+ unsigned Flags, SectionKind K,
+ bool hasCrazyBSS, bool isExplicit,
+ MCContext &Ctx);
+
+ /// ShouldOmitSectionDirective - Decides whether a '.section' directive
+ /// should be printed before the section name
+ bool ShouldOmitSectionDirective(const char *Name) const;
+
+ /// ShouldPrintSectionType - Only prints the section type if supported
+ bool ShouldPrintSectionType(unsigned Ty) const;
+
+ /// These are the section type and flags fields. An ELF section can have
+ /// only one Type, but can have more than one of the flags specified.
+ ///
+ /// Valid section types.
+ enum {
+ // This value marks the section header as inactive.
+ SHT_NULL = 0x00U,
+
+ // Holds information defined by the program, with custom format and meaning.
+ SHT_PROGBITS = 0x01U,
+
+ // This section holds a symbol table.
+ SHT_SYMTAB = 0x02U,
+
+ // The section holds a string table.
+ SHT_STRTAB = 0x03U,
+
+ // The section holds relocation entries with explicit addends.
+ SHT_RELA = 0x04U,
+
+ // The section holds a symbol hash table.
+ SHT_HASH = 0x05U,
+
+ // Information for dynamic linking.
+ SHT_DYNAMIC = 0x06U,
+
+ // The section holds information that marks the file in some way.
+ SHT_NOTE = 0x07U,
+
+ // A section of this type occupies no space in the file.
+ SHT_NOBITS = 0x08U,
+
+ // The section holds relocation entries without explicit addends.
+ SHT_REL = 0x09U,
+
+ // This section type is reserved but has unspecified semantics.
+ SHT_SHLIB = 0x0aU,
+
+ // This section holds a symbol table.
+ SHT_DYNSYM = 0x0bU,
+
+ // This section contains an array of pointers to initialization functions.
+ SHT_INIT_ARRAY = 0x0eU,
+
+ // This section contains an array of pointers to termination functions.
+ SHT_FINI_ARRAY = 0x0fU,
+
+ // This section contains an array of pointers to functions that are invoked
+ // before all other initialization functions.
+ SHT_PREINIT_ARRAY = 0x10U,
+
+ // A section group is a set of sections that are related and that must be
+ // treated specially by the linker.
+ SHT_GROUP = 0x11U,
+
+ // This section is associated with a section of type SHT_SYMTAB, when the
+ // referenced symbol table contain the escape value SHN_XINDEX
+ SHT_SYMTAB_SHNDX = 0x12U,
+
+ LAST_KNOWN_SECTION_TYPE = SHT_SYMTAB_SHNDX
+ };
+
+ /// Valid section flags.
+ enum {
+ // The section contains data that should be writable.
+ SHF_WRITE = 0x1U,
+
+ // The section occupies memory during execution.
+ SHF_ALLOC = 0x2U,
+
+ // The section contains executable machine instructions.
+ SHF_EXECINSTR = 0x4U,
+
+ // The data in the section may be merged to eliminate duplication.
+ SHF_MERGE = 0x10U,
+
+ // Elements in the section consist of null-terminated character strings.
+ SHF_STRINGS = 0x20U,
+
+ // A field in this section holds a section header table index.
+ SHF_INFO_LINK = 0x40U,
+
+ // Adds special ordering requirements for link editors.
+ SHF_LINK_ORDER = 0x80U,
+
+ // This section requires special OS-specific processing to avoid incorrect
+ // behavior.
+ SHF_OS_NONCONFORMING = 0x100U,
+
+ // This section is a member of a section group.
+ SHF_GROUP = 0x200U,
+
+ // This section holds Thread-Local Storage.
+ SHF_TLS = 0x400U
+ };
+
+ StringRef getSectionName() const {
+ return StringRef(SectionName);
+ }
+
+ unsigned getType() const { return Type; }
+ unsigned getFlags() const { return Flags; }
+
+ virtual void PrintSwitchToSection(const TargetAsmInfo &TAI,
+ raw_ostream &OS) const;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 102928b..19bb02c 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -204,8 +204,9 @@ protected:
const MCSection *MergeableConst16Section;
protected:
- const MCSection *getELFSection(const char *Name, bool isDirective,
- SectionKind Kind) const;
+ const MCSection *getELFSection(StringRef Section, unsigned Type,
+ unsigned Flags, SectionKind Kind,
+ bool IsExplicit = false) const;
public:
TargetLoweringObjectFileELF(// FIXME: REMOVE AFTER UNIQUING IS FIXED.
bool hasCrazyBSS = false)
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index ff41338..4ad2f8b 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -43,7 +43,7 @@
#include "llvm/CodeGen/MachineCodeEmitter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetELFWriterInfo.h"
@@ -178,30 +178,32 @@ void ELFWriter::addExternalSymbol(const char *External) {
// getCtorSection - Get the static constructor section
ELFSection &ELFWriter::getCtorSection() {
- const MCSection *Ctor = TLOF.getStaticCtorSection();
- return getSection(((MCSectionELF*)Ctor)->getName(), ELFSection::SHT_PROGBITS,
+ const MCSectionELF *Ctor = (const MCSectionELF *)TLOF.getStaticCtorSection();
+ return getSection(Ctor->getSectionName(), ELFSection::SHT_PROGBITS,
getElfSectionFlags(Ctor->getKind()));
}
// getDtorSection - Get the static destructor section
ELFSection &ELFWriter::getDtorSection() {
- const MCSection *Dtor = TLOF.getStaticDtorSection();
- return getSection(((MCSectionELF*)Dtor)->getName(), ELFSection::SHT_PROGBITS,
+ const MCSectionELF *Dtor = (const MCSectionELF *)TLOF.getStaticDtorSection();
+ return getSection(Dtor->getSectionName(), ELFSection::SHT_PROGBITS,
getElfSectionFlags(Dtor->getKind()));
}
// getTextSection - Get the text section for the specified function
ELFSection &ELFWriter::getTextSection(Function *F) {
- const MCSection *Text = TLOF.SectionForGlobal(F, Mang, TM);
- return getSection(((MCSectionELF*)Text)->getName(), ELFSection::SHT_PROGBITS,
+ const MCSectionELF *Text =
+ (const MCSectionELF *)TLOF.SectionForGlobal(F, Mang, TM);
+ return getSection(Text->getSectionName(), ELFSection::SHT_PROGBITS,
getElfSectionFlags(Text->getKind()));
}
// getJumpTableSection - Get a read only section for constants when
// emitting jump tables. TODO: add PIC support
ELFSection &ELFWriter::getJumpTableSection() {
- const MCSection *JT = TLOF.getSectionForConstant(SectionKind::getReadOnly());
- return getSection(((MCSectionELF*)JT)->getName(),
+ const MCSectionELF *JT =
+ (const MCSectionELF *)TLOF.getSectionForConstant(SectionKind::getReadOnly());
+ return getSection(JT->getSectionName(),
ELFSection::SHT_PROGBITS,
getElfSectionFlags(JT->getKind()),
TM.getTargetData()->getPointerABIAlignment());
@@ -226,8 +228,9 @@ ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) {
}
}
- const MCSection *CPSect = TLOF.getSectionForConstant(Kind);
- return getSection(((MCSectionELF*)CPSect)->getName(),
+ const MCSectionELF *CPSect =
+ (const MCSectionELF *)TLOF.getSectionForConstant(Kind);
+ return getSection(CPSect->getSectionName(),
ELFSection::SHT_PROGBITS,
getElfSectionFlags(Kind),
CPE.getAlignment());
@@ -358,8 +361,9 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
return;
// Get the ELF section where this global belongs from TLOF
- const MCSection *S = TLOF.SectionForGlobal(GV, Mang, TM);
- SectionKind Kind = ((MCSectionELF*)S)->getKind();
+ const MCSectionELF *S =
+ (const MCSectionELF *)TLOF.SectionForGlobal(GV, Mang, TM);
+ SectionKind Kind = S->getKind();
unsigned SectionFlags = getElfSectionFlags(Kind);
// The symbol align should update the section alignment if needed
@@ -370,7 +374,7 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
if (isELFCommonSym(GVar)) {
GblSym->SectionIdx = ELFSection::SHN_COMMON;
- getSection(((MCSectionELF*)S)->getName(),
+ getSection(S->getSectionName(),
ELFSection::SHT_NOBITS, SectionFlags, 1);
// A new linkonce section is created for each global in the
@@ -380,7 +384,7 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
} else if (isELFBssSym(GVar, Kind)) {
ELFSection &ES =
- getSection(((MCSectionELF*)S)->getName(), ELFSection::SHT_NOBITS,
+ getSection(S->getSectionName(), ELFSection::SHT_NOBITS,
SectionFlags);
GblSym->SectionIdx = ES.SectionIdx;
@@ -396,7 +400,7 @@ void ELFWriter::EmitGlobal(const GlobalValue *GV) {
} else { // The symbol must go to some kind of data section
ELFSection &ES =
- getSection(((MCSectionELF*)S)->getName(), ELFSection::SHT_PROGBITS,
+ getSection(S->getSectionName(), ELFSection::SHT_PROGBITS,
SectionFlags);
GblSym->SectionIdx = ES.SectionIdx;
diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt
index e3cc536..ec76320 100644
--- a/lib/MC/CMakeLists.txt
+++ b/lib/MC/CMakeLists.txt
@@ -4,6 +4,7 @@ add_llvm_library(LLVMMC
MCAsmStreamer.cpp
MCContext.cpp
MCSection.cpp
+ MCSectionELF.cpp
MCSectionMachO.cpp
MCStreamer.cpp
TargetAsmParser.cpp
diff --git a/lib/MC/MCSection.cpp b/lib/MC/MCSection.cpp
index 8b7fcd2..3e83763 100644
--- a/lib/MC/MCSection.cpp
+++ b/lib/MC/MCSection.cpp
@@ -20,91 +20,6 @@ using namespace llvm;
MCSection::~MCSection() {
}
-
-//===----------------------------------------------------------------------===//
-// MCSectionELF
-//===----------------------------------------------------------------------===//
-
-MCSectionELF *MCSectionELF::
-Create(const StringRef &Name, bool IsDirective, SectionKind K, MCContext &Ctx) {
- return new (Ctx) MCSectionELF(Name, IsDirective, K);
-}
-
-void MCSectionELF::PrintSwitchToSection(const TargetAsmInfo &TAI,
- raw_ostream &OS) const {
- if (isDirective()) {
- OS << getName() << '\n';
- return;
- }
-
- OS << "\t.section\t" << getName();
-
- // Handle the weird solaris syntax if desired.
- if (TAI.usesSunStyleELFSectionSwitchSyntax() &&
- !getKind().isMergeableConst() && !getKind().isMergeableCString()) {
- if (!getKind().isMetadata())
- OS << ",#alloc";
- if (getKind().isText())
- OS << ",#execinstr";
- if (getKind().isWriteable())
- OS << ",#write";
- if (getKind().isThreadLocal())
- OS << ",#tls";
- } else {
- OS << ",\"";
-
- if (!getKind().isMetadata())
- OS << 'a';
- if (getKind().isText())
- OS << 'x';
- if (getKind().isWriteable())
- OS << 'w';
- if (getKind().isMergeable1ByteCString() ||
- getKind().isMergeable2ByteCString() ||
- getKind().isMergeable4ByteCString() ||
- getKind().isMergeableConst4() ||
- getKind().isMergeableConst8() ||
- getKind().isMergeableConst16())
- OS << 'M';
- if (getKind().isMergeable1ByteCString() ||
- getKind().isMergeable2ByteCString() ||
- getKind().isMergeable4ByteCString())
- OS << 'S';
- if (getKind().isThreadLocal())
- OS << 'T';
-
- OS << "\",";
-
- // If comment string is '@', e.g. as on ARM - use '%' instead
- if (TAI.getCommentString()[0] == '@')
- OS << '%';
- else
- OS << '@';
-
- if (getKind().isBSS() || getKind().isThreadBSS())
- OS << "nobits";
- else
- OS << "progbits";
-
- if (getKind().isMergeable1ByteCString()) {
- OS << ",1";
- } else if (getKind().isMergeable2ByteCString()) {
- OS << ",2";
- } else if (getKind().isMergeable4ByteCString()) {
- OS << ",4";
- } else if (getKind().isMergeableConst4()) {
- OS << ",4";
- } else if (getKind().isMergeableConst8()) {
- OS << ",8";
- } else if (getKind().isMergeableConst16()) {
- OS << ",16";
- }
- }
-
- OS << '\n';
-}
-
-
//===----------------------------------------------------------------------===//
// MCSectionCOFF
//===----------------------------------------------------------------------===//
diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp
new file mode 100644
index 0000000..d172a9c
--- /dev/null
+++ b/lib/MC/MCSectionELF.cpp
@@ -0,0 +1,123 @@
+//===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetAsmInfo.h"
+
+using namespace llvm;
+
+MCSectionELF *MCSectionELF::
+Create(const StringRef &Section, unsigned Type, unsigned Flags,
+ SectionKind K, bool hasCrazyBSS, bool isExplicit, MCContext &Ctx) {
+ return new
+ (Ctx) MCSectionELF(Section, Type, Flags, K, hasCrazyBSS, isExplicit);
+}
+
+// ShouldOmitSectionDirective - Decides whether a '.section' directive
+// should be printed before the section name
+bool MCSectionELF::ShouldOmitSectionDirective(const char *Name) const {
+
+ // PPC/Linux doesn't support the .bss directive, it needs .section .bss.
+ // FIXME: Does .section .bss/.data/.text work everywhere??
+ if ((!HasCrazyBSS && strncmp(Name, ".bss", 4) == 0) ||
+ strncmp(Name, ".text", 5) == 0 ||
+ strncmp(Name, ".data", 5) == 0)
+ return true;
+
+ return false;
+}
+
+// ShouldPrintSectionType - Only prints the section type if supported
+bool MCSectionELF::ShouldPrintSectionType(unsigned Ty) const {
+
+ if (IsExplicit && !(Ty == SHT_NOBITS || Ty == SHT_PROGBITS))
+ return false;
+
+ return true;
+}
+
+void MCSectionELF::PrintSwitchToSection(const TargetAsmInfo &TAI,
+ raw_ostream &OS) const {
+
+ if (ShouldOmitSectionDirective(SectionName.c_str())) {
+ OS << '\t' << getSectionName() << '\n';
+ return;
+ }
+
+ OS << "\t.section\t" << getSectionName();
+
+ // Handle the weird solaris syntax if desired.
+ if (TAI.usesSunStyleELFSectionSwitchSyntax() &&
+ !(Flags & MCSectionELF::SHF_MERGE)) {
+ if (Flags & MCSectionELF::SHF_ALLOC)
+ OS << ",#alloc";
+ if (Flags & MCSectionELF::SHF_EXECINSTR)
+ OS << ",#execinstr";
+ if (Flags & MCSectionELF::SHF_WRITE)
+ OS << ",#write";
+ if (Flags & MCSectionELF::SHF_TLS)
+ OS << ",#tls";
+ } else {
+ OS << ",\"";
+
+ if (Flags & MCSectionELF::SHF_ALLOC)
+ OS << 'a';
+ if (Flags & MCSectionELF::SHF_EXECINSTR)
+ OS << 'x';
+ if (Flags & MCSectionELF::SHF_WRITE)
+ OS << 'w';
+ if (Flags & MCSectionELF::SHF_MERGE)
+ OS << 'M';
+ if (Flags & MCSectionELF::SHF_STRINGS)
+ OS << 'S';
+ if (Flags & MCSectionELF::SHF_TLS)
+ OS << 'T';
+
+ OS << '"';
+
+ if (ShouldPrintSectionType(Type)) {
+ OS << ',';
+
+ // If comment string is '@', e.g. as on ARM - use '%' instead
+ if (TAI.getCommentString()[0] == '@')
+ OS << '%';
+ else
+ OS << '@';
+
+ if (Type == MCSectionELF::SHT_INIT_ARRAY)
+ OS << "init_array";
+ else if (Type == MCSectionELF::SHT_FINI_ARRAY)
+ OS << "fini_array";
+ else if (Type == MCSectionELF::SHT_PREINIT_ARRAY)
+ OS << "preinit_array";
+ else if (Type == MCSectionELF::SHT_NOBITS)
+ OS << "nobits";
+ else if (Type == MCSectionELF::SHT_PROGBITS)
+ OS << "progbits";
+
+ if (getKind().isMergeable1ByteCString()) {
+ OS << ",1";
+ } else if (getKind().isMergeable2ByteCString()) {
+ OS << ",2";
+ } else if (getKind().isMergeable4ByteCString() ||
+ getKind().isMergeableConst4()) {
+ OS << ",4";
+ } else if (getKind().isMergeableConst8()) {
+ OS << ",8";
+ } else if (getKind().isMergeableConst16()) {
+ OS << ",16";
+ }
+ }
+ }
+
+ OS << '\n';
+}
+
diff --git a/lib/Target/ARM/ARMTargetObjectFile.h b/lib/Target/ARM/ARMTargetObjectFile.h
index 13fa7e2..9703403 100644
--- a/lib/Target/ARM/ARMTargetObjectFile.h
+++ b/lib/Target/ARM/ARMTargetObjectFile.h
@@ -11,6 +11,7 @@
#define LLVM_TARGET_ARM_TARGETOBJECTFILE_H
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/MC/MCSectionELF.h"
namespace llvm {
@@ -21,14 +22,14 @@ namespace llvm {
void Initialize(MCContext &Ctx, const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
- // FIXME: Add new attribute/flag to MCSection for init_array/fini_array.
- // That will allow not treating these as "directives".
if (TM.getSubtarget<ARMSubtarget>().isAAPCS_ABI()) {
StaticCtorSection =
- getELFSection("\t.section .init_array,\"aw\",%init_array", true,
+ getELFSection(".init_array", MCSectionELF::SHT_INIT_ARRAY,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
StaticDtorSection =
- getELFSection("\t.section .fini_array,\"aw\",%fini_array", true,
+ getELFSection(".fini_array", MCSectionELF::SHT_FINI_ARRAY,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
SectionKind::getDataRel());
}
}
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 00f4ffe..edc9ed3 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/lib/Target/TargetLoweringObjectFile.cpp
@@ -19,7 +19,7 @@
#include "llvm/GlobalVariable.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionMachO.h"
-#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
@@ -288,64 +288,98 @@ TargetLoweringObjectFileELF::~TargetLoweringObjectFileELF() {
}
const MCSection *TargetLoweringObjectFileELF::
-getELFSection(const char *Name, bool isDirective, SectionKind Kind) const {
- // Create the map if it doesn't already exist.
+getELFSection(StringRef Section, unsigned Type, unsigned Flags,
+ SectionKind Kind, bool IsExplicit) const {
if (UniquingMap == 0)
UniquingMap = new ELFUniqueMapTy();
ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)UniquingMap;
// Do the lookup, if we have a hit, return it.
- const MCSectionELF *&Entry = Map[Name];
+ const MCSectionELF *&Entry = Map[Section];
if (Entry) return Entry;
- return Entry = MCSectionELF::Create(Name, isDirective, Kind, getContext());
+ return Entry = MCSectionELF::Create(Section, Type, Flags, Kind, HasCrazyBSS,
+ IsExplicit, getContext());
}
void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFile::Initialize(Ctx, TM);
- if (!HasCrazyBSS)
- BSSSection = getELFSection("\t.bss", true, SectionKind::getBSS());
- else
- // PPC/Linux doesn't support the .bss directive, it needs .section .bss.
- // FIXME: Does .section .bss work everywhere??
- // FIXME2: this should just be handle by the section printer. We should get
- // away from syntactic view of the sections and MCSection should just be a
- // semantic view.
- BSSSection = getELFSection("\t.bss", false, SectionKind::getBSS());
+ BSSSection =
+ getELFSection(".bss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getBSS());
- TextSection = getELFSection("\t.text", true, SectionKind::getText());
- DataSection = getELFSection("\t.data", true, SectionKind::getDataRel());
- ReadOnlySection =
- getELFSection("\t.rodata", false, SectionKind::getReadOnly());
- TLSDataSection =
- getELFSection("\t.tdata", false, SectionKind::getThreadData());
-
- TLSBSSSection = getELFSection("\t.tbss", false,
- SectionKind::getThreadBSS());
-
- DataRelSection = getELFSection("\t.data.rel", false,
- SectionKind::getDataRel());
- DataRelLocalSection = getELFSection("\t.data.rel.local", false,
- SectionKind::getDataRelLocal());
- DataRelROSection = getELFSection("\t.data.rel.ro", false,
- SectionKind::getReadOnlyWithRel());
- DataRelROLocalSection =
- getELFSection("\t.data.rel.ro.local", false,
- SectionKind::getReadOnlyWithRelLocal());
+ TextSection =
+ getELFSection(".text", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC,
+ SectionKind::getText());
+
+ DataSection =
+ getELFSection(".data", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC,
+ SectionKind::getDataRel());
+
+ ReadOnlySection =
+ getELFSection(".rodata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC,
+ SectionKind::getReadOnly());
+
+ TLSDataSection =
+ getELFSection(".tdata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
+ MCSectionELF::SHF_WRITE, SectionKind::getThreadData());
+
+ TLSBSSSection =
+ getELFSection(".tbss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_TLS |
+ MCSectionELF::SHF_WRITE, SectionKind::getThreadBSS());
+
+ DataRelSection =
+ getELFSection(".data.rel", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
+ DataRelLocalSection =
+ getELFSection(".data.rel.local", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRelLocal());
+
+ DataRelROSection =
+ getELFSection(".data.rel.ro", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getReadOnlyWithRel());
+
+ DataRelROLocalSection =
+ getELFSection(".data.rel.ro.local", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getReadOnlyWithRelLocal());
- MergeableConst4Section = getELFSection(".rodata.cst4", false,
- SectionKind::getMergeableConst4());
- MergeableConst8Section = getELFSection(".rodata.cst8", false,
- SectionKind::getMergeableConst8());
- MergeableConst16Section = getELFSection(".rodata.cst16", false,
- SectionKind::getMergeableConst16());
+ MergeableConst4Section =
+ getELFSection(".rodata.cst4", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst4());
+
+ MergeableConst8Section =
+ getELFSection(".rodata.cst8", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst8());
+
+ MergeableConst16Section =
+ getELFSection(".rodata.cst16", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE,
+ SectionKind::getMergeableConst16());
StaticCtorSection =
- getELFSection(".ctors", false, SectionKind::getDataRel());
+ getELFSection(".ctors", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+
StaticDtorSection =
- getELFSection(".dtors", false, SectionKind::getDataRel());
+ getELFSection(".dtors", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
// Exception Handling Sections.
@@ -354,33 +388,46 @@ void TargetLoweringObjectFileELF::Initialize(MCContext &Ctx,
// runtime hit for C++ apps. Either the contents of the LSDA need to be
// adjusted or this should be a data section.
LSDASection =
- getELFSection(".gcc_except_table", false, SectionKind::getReadOnly());
+ getELFSection(".gcc_except_table", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
EHFrameSection =
- getELFSection(".eh_frame", false, SectionKind::getDataRel());
+ getELFSection(".eh_frame", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC, SectionKind::getDataRel());
// Debug Info Sections.
DwarfAbbrevSection =
- getELFSection(".debug_abbrev", false, SectionKind::getMetadata());
+ getELFSection(".debug_abbrev", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfInfoSection =
- getELFSection(".debug_info", false, SectionKind::getMetadata());
+ getELFSection(".debug_info", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfLineSection =
- getELFSection(".debug_line", false, SectionKind::getMetadata());
+ getELFSection(".debug_line", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfFrameSection =
- getELFSection(".debug_frame", false, SectionKind::getMetadata());
+ getELFSection(".debug_frame", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfPubNamesSection =
- getELFSection(".debug_pubnames", false, SectionKind::getMetadata());
+ getELFSection(".debug_pubnames", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
- getELFSection(".debug_pubtypes", false, SectionKind::getMetadata());
+ getELFSection(".debug_pubtypes", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfStrSection =
- getELFSection(".debug_str", false, SectionKind::getMetadata());
+ getELFSection(".debug_str", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfLocSection =
- getELFSection(".debug_loc", false, SectionKind::getMetadata());
+ getELFSection(".debug_loc", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfARangesSection =
- getELFSection(".debug_aranges", false, SectionKind::getMetadata());
+ getELFSection(".debug_aranges", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfRangesSection =
- getELFSection(".debug_ranges", false, SectionKind::getMetadata());
+ getELFSection(".debug_ranges", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfMacroInfoSection =
- getELFSection(".debug_macinfo", false, SectionKind::getMetadata());
+ getELFSection(".debug_macinfo", MCSectionELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
}
@@ -410,13 +457,62 @@ getELFKindForNamedSection(const char *Name, SectionKind K) {
return K;
}
+
+static unsigned
+getELFSectionType(const char *Name, SectionKind K) {
+
+ if (strncmp(Name, ".init_array", 11) == 0)
+ return MCSectionELF::SHT_INIT_ARRAY;
+
+ if (strncmp(Name, ".fini_array", 11) == 0)
+ return MCSectionELF::SHT_FINI_ARRAY;
+
+ if (strncmp(Name, ".preinit_array", 14) == 0)
+ return MCSectionELF::SHT_PREINIT_ARRAY;
+
+ if (K.isBSS() || K.isThreadBSS())
+ return MCSectionELF::SHT_NOBITS;
+
+ return MCSectionELF::SHT_PROGBITS;
+}
+
+
+static unsigned
+getELFSectionFlags(SectionKind K) {
+ unsigned Flags = 0;
+
+ if (!K.isMetadata())
+ Flags |= MCSectionELF::SHF_ALLOC;
+
+ if (K.isWriteable())
+ Flags |= MCSectionELF::SHF_WRITE;
+
+ if (K.isThreadLocal())
+ Flags |= MCSectionELF::SHF_TLS;
+
+ // K.isMergeableConst() is left out to honour PR4650
+ if (K.isMergeableCString() || K.isMergeableConst4() ||
+ K.isMergeableConst8() || K.isMergeableConst16())
+ Flags |= MCSectionELF::SHF_MERGE;
+
+ if (K.isMergeableCString())
+ Flags |= MCSectionELF::SHF_STRINGS;
+
+ return Flags;
+}
+
+
const MCSection *TargetLoweringObjectFileELF::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
+ const char *SectionName = GV->getSection().c_str();
+
// Infer section flags from the section name if we can.
- Kind = getELFKindForNamedSection(GV->getSection().c_str(), Kind);
+ Kind = getELFKindForNamedSection(SectionName, Kind);
- return getELFSection(GV->getSection().c_str(), false, Kind);
+ return getELFSection(SectionName,
+ getELFSectionType(SectionName, Kind),
+ getELFSectionFlags(Kind), Kind, true);
}
static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) {
@@ -445,7 +541,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
if (GV->isWeakForLinker()) {
const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
std::string Name = Mang->makeNameProper(GV->getNameStr());
- return getELFSection((Prefix+Name).c_str(), false, Kind);
+
+ return getELFSection((Prefix+Name).c_str(),
+ getELFSectionType((Prefix+Name).c_str(), Kind),
+ getELFSectionFlags(Kind),
+ Kind);
}
if (Kind.isText()) return TextSection;
@@ -470,7 +570,11 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
std::string Name = SizeSpec + utostr(Align);
- return getELFSection(Name.c_str(), false, Kind);
+ return getELFSection(Name.c_str(), MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC |
+ MCSectionELF::SHF_MERGE |
+ MCSectionELF::SHF_STRINGS,
+ Kind);
}
if (Kind.isMergeableConst()) {
diff --git a/lib/Target/XCore/XCoreTargetObjectFile.cpp b/lib/Target/XCore/XCoreTargetObjectFile.cpp
index 4e2dca1..9415f51 100644
--- a/lib/Target/XCore/XCoreTargetObjectFile.cpp
+++ b/lib/Target/XCore/XCoreTargetObjectFile.cpp
@@ -9,6 +9,7 @@
#include "XCoreTargetObjectFile.h"
#include "XCoreSubtarget.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
@@ -16,9 +17,12 @@ using namespace llvm;
void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
- TextSection = getELFSection("\t.text", true, SectionKind::getText());
- DataSection = getELFSection("\t.dp.data", false, SectionKind::getDataRel());
- BSSSection = getELFSection("\t.dp.bss", false, SectionKind::getBSS());
+ DataSection = getELFSection(".dp.data", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
+ BSSSection = getELFSection(".dp.bss", MCSectionELF::SHT_NOBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getBSS());
// TLS globals are lowered in the backend to arrays indexed by the current
// thread id. After lowering they require no special handling by the linker
@@ -28,9 +32,12 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
if (TM.getSubtarget<XCoreSubtarget>().isXS1A())
// FIXME: Why is this writable ("datarel")???
- ReadOnlySection = getELFSection("\t.dp.rodata", false,
- SectionKind::getDataRel());
+ ReadOnlySection =
+ getELFSection(".dp.rodata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE,
+ SectionKind::getDataRel());
else
- ReadOnlySection = getELFSection("\t.cp.rodata", false,
- SectionKind::getReadOnly());
+ ReadOnlySection =
+ getELFSection(".cp.rodata", MCSectionELF::SHT_PROGBITS,
+ MCSectionELF::SHF_ALLOC, SectionKind::getReadOnly());
}
diff --git a/test/CodeGen/X86/attribute-sections.ll b/test/CodeGen/X86/attribute-sections.ll
new file mode 100644
index 0000000..0dba6e6
--- /dev/null
+++ b/test/CodeGen/X86/attribute-sections.ll
@@ -0,0 +1,18 @@
+; RUN: llvm-as < %s | llc -mtriple=i386-unknown-linux-gnu | FileCheck %s -check-prefix=LINUX
+
+declare i32 @foo()
+@G0 = global i32 ()* @foo, section ".init_array"
+
+; LINUX: .section .init_array,"aw"
+; LINUX: .globl G0
+
+@G1 = global i32 ()* @foo, section ".fini_array"
+
+; LINUX: .section .fini_array,"aw"
+; LINUX: .globl G1
+
+@G2 = global i32 ()* @foo, section ".preinit_array"
+
+; LINUX: .section .preinit_array,"aw"
+; LINUX: .globl G2
+