#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
return ".gnu.linkonce.d.rel.ro.";
}
+/// getSectionPrefixForGlobal - Return the section prefix name used by options
+/// FunctionsSections and DataSections.
+static const char *getSectionPrefixForGlobal(SectionKind Kind) {
+ if (Kind.isText()) return ".text.";
+ if (Kind.isReadOnly()) return ".rodata.";
+
+ if (Kind.isThreadData()) return ".tdata.";
+ if (Kind.isThreadBSS()) return ".tbss.";
+
+ if (Kind.isDataNoRel()) return ".data.";
+ if (Kind.isDataRelLocal()) return ".data.rel.local.";
+ if (Kind.isDataRel()) return ".data.rel.";
+ if (Kind.isReadOnlyWithRelLocal()) return ".data.rel.ro.local.";
+
+ assert(Kind.isReadOnlyWithRel() && "Unknown section kind");
+ return ".data.rel.ro.";
+}
+
+
const MCSection *TargetLoweringObjectFileELF::
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
+ // If we have -ffunction-section or -fdata-section then we should emit the
+ // global value to a uniqued section specifically for it.
+ bool EmitUniquedSection;
+ if (Kind.isText())
+ EmitUniquedSection = TM.getFunctionSections();
+ else
+ EmitUniquedSection = TM.getDataSections();
// If this global is linkonce/weak and the target handles this by emitting it
// into a 'uniqued' section name, create and return the section now.
- if (GV->isWeakForLinker() && !Kind.isCommon() && !Kind.isBSS()) {
- const char *Prefix = getSectionPrefixForUniqueGlobal(Kind);
+ if ((GV->isWeakForLinker() || EmitUniquedSection) &&
+ !Kind.isCommon() && !Kind.isBSS()) {
+ const char *Prefix;
+ if (GV->isWeakForLinker())
+ Prefix = getSectionPrefixForUniqueGlobal(Kind);
+ else {
+ assert(EmitUniquedSection);
+ Prefix = getSectionPrefixForGlobal(Kind);
+ }
+
SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
MCSymbol *Sym = Mang->getSymbol(GV);
Name.append(Sym->getName().begin(), Sym->getName().end());
= getContext().getMachOSection("__DATA", "__data", 0,
SectionKind::getDataRel());
+ TLSDataSection // .tdata
+ = getContext().getMachOSection("__DATA", "__thread_data",
+ MCSectionMachO::S_THREAD_LOCAL_REGULAR,
+ SectionKind::getDataRel());
+ TLSBSSSection // .tbss
+ = getContext().getMachOSection("__DATA", "__thread_bss",
+ MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
+ SectionKind::getThreadBSS());
+
+ // TODO: Verify datarel below.
+ TLSTLVSection // .tlv
+ = getContext().getMachOSection("__DATA", "__thread_vars",
+ MCSectionMachO::S_THREAD_LOCAL_VARIABLES,
+ SectionKind::getDataRel());
+
+ TLSThreadInitSection
+ = getContext().getMachOSection("__DATA", "__thread_init",
+ MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS,
+ SectionKind::getDataRel());
+
CStringSection // .cstring
= getContext().getMachOSection("__TEXT", "__cstring",
MCSectionMachO::S_CSTRING_LITERALS,
getContext().getMachOSection("__DWARF", "__debug_inlined",
MCSectionMachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
+
+ TLSExtraDataSection = TLSTLVSection;
}
const MCSection *TargetLoweringObjectFileMachO::
const MCSection *TargetLoweringObjectFileMachO::
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
- assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
+
+ // Handle one kind of thread local...
+ if (Kind.isThreadBSS()) return TLSBSSSection;
+ assert(!Kind.isThreadLocal() && "Darwin doesn't support TLS");
+
if (Kind.isText())
return GV->isWeakForLinker() ? TextCoalSection : TextSection;
// COFF
//===----------------------------------------------------------------------===//
-typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy;
-
-TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() {
- delete (COFFUniqueMapTy*)UniquingMap;
-}
-
-
-const MCSection *TargetLoweringObjectFileCOFF::
-getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const {
- // Create the map if it doesn't already exist.
- if (UniquingMap == 0)
- UniquingMap = new COFFUniqueMapTy();
- COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)UniquingMap;
-
- // Do the lookup, if we have a hit, return it.
- const MCSectionCOFF *&Entry = Map[Name];
- if (Entry) return Entry;
-
- return Entry = MCSectionCOFF::Create(Name, isDirective, Kind, getContext());
-}
-
void TargetLoweringObjectFileCOFF::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
- if (UniquingMap != 0)
- ((COFFUniqueMapTy*)UniquingMap)->clear();
TargetLoweringObjectFile::Initialize(Ctx, TM);
- TextSection = getCOFFSection("\t.text", true, SectionKind::getText());
- DataSection = getCOFFSection("\t.data", true, SectionKind::getDataRel());
+ TextSection =
+ getContext().getCOFFSection(".text",
+ MCSectionCOFF::IMAGE_SCN_CNT_CODE |
+ MCSectionCOFF::IMAGE_SCN_MEM_EXECUTE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getText());
+ DataSection =
+ getContext().getCOFFSection(".data",
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ |
+ MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
+ ReadOnlySection =
+ getContext().getCOFFSection(".rdata",
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
StaticCtorSection =
- getCOFFSection(".ctors", false, SectionKind::getDataRel());
+ getContext().getCOFFSection(".ctors",
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ |
+ MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
StaticDtorSection =
- getCOFFSection(".dtors", false, SectionKind::getDataRel());
+ getContext().getCOFFSection(".dtors",
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ |
+ MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
// FIXME: We're emitting LSDA info into a readonly section on COFF, even
// though it contains relocatable pointers. In PIC mode, this is probably a
// big runtime hit for C++ apps. Either the contents of the LSDA need to be
// adjusted or this should be a data section.
LSDASection =
- getCOFFSection(".gcc_except_table", false, SectionKind::getReadOnly());
+ getContext().getCOFFSection(".gcc_except_table",
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getReadOnly());
EHFrameSection =
- getCOFFSection(".eh_frame", false, SectionKind::getDataRel());
+ getContext().getCOFFSection(".eh_frame",
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ |
+ MCSectionCOFF::IMAGE_SCN_MEM_WRITE,
+ SectionKind::getDataRel());
// Debug info.
- // FIXME: Don't use 'directive' mode here.
DwarfAbbrevSection =
- getCOFFSection("\t.section\t.debug_abbrev,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_abbrev",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfInfoSection =
- getCOFFSection("\t.section\t.debug_info,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_info",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfLineSection =
- getCOFFSection("\t.section\t.debug_line,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_line",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfFrameSection =
- getCOFFSection("\t.section\t.debug_frame,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_frame",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfPubNamesSection =
- getCOFFSection("\t.section\t.debug_pubnames,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_pubnames",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
- getCOFFSection("\t.section\t.debug_pubtypes,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_pubtypes",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfStrSection =
- getCOFFSection("\t.section\t.debug_str,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_str",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfLocSection =
- getCOFFSection("\t.section\t.debug_loc,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_loc",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfARangesSection =
- getCOFFSection("\t.section\t.debug_aranges,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_aranges",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfRangesSection =
- getCOFFSection("\t.section\t.debug_ranges,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_ranges",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfMacroInfoSection =
- getCOFFSection("\t.section\t.debug_macinfo,\"dr\"",
- true, SectionKind::getMetadata());
+ getContext().getCOFFSection(".debug_macinfo",
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
+
+ DrectveSection =
+ getContext().getCOFFSection(".drectve",
+ MCSectionCOFF::IMAGE_SCN_LNK_INFO,
+ SectionKind::getMetadata());
+}
+
+static unsigned
+getCOFFSectionFlags(SectionKind K) {
+ unsigned Flags = 0;
+
+ if (!K.isMetadata())
+ Flags |=
+ MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE;
+ else if (K.isText())
+ Flags |=
+ MCSectionCOFF::IMAGE_SCN_MEM_EXECUTE |
+ MCSectionCOFF::IMAGE_SCN_CNT_CODE;
+ else if (K.isBSS ())
+ Flags |=
+ MCSectionCOFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ |
+ MCSectionCOFF::IMAGE_SCN_MEM_WRITE;
+ else if (K.isReadOnly())
+ Flags |=
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ;
+ else if (K.isWriteable())
+ Flags |=
+ MCSectionCOFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ MCSectionCOFF::IMAGE_SCN_MEM_READ |
+ MCSectionCOFF::IMAGE_SCN_MEM_WRITE;
+
+ return Flags;
}
const MCSection *TargetLoweringObjectFileCOFF::
getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
Mangler *Mang, const TargetMachine &TM) const {
- return getCOFFSection(GV->getSection(), false, Kind);
+ return getContext().getCOFFSection(GV->getSection(),
+ getCOFFSectionFlags(Kind),
+ Kind);
}
static const char *getCOFFSectionPrefixForUniqueGlobal(SectionKind Kind) {
if (Kind.isText())
return ".text$linkonce";
+ if (Kind.isBSS ())
+ return ".bss$linkonce";
if (Kind.isWriteable())
return ".data$linkonce";
return ".rdata$linkonce";
SmallString<128> Name(Prefix, Prefix+strlen(Prefix));
MCSymbol *Sym = Mang->getSymbol(GV);
Name.append(Sym->getName().begin(), Sym->getName().end());
- return getCOFFSection(Name.str(), false, Kind);
+
+ unsigned Characteristics = getCOFFSectionFlags(Kind);
+
+ Characteristics |= MCSectionCOFF::IMAGE_SCN_LNK_COMDAT;
+
+ return getContext().getCOFFSection(Name.str(), Characteristics,
+ MCSectionCOFF::IMAGE_COMDAT_SELECT_EXACT_MATCH, Kind);
}
if (Kind.isText())