diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 90905f51e37..9a74c57af5f 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -161,13 +161,15 @@ public: class TargetLoweringObjectFileCOFF : public TargetLoweringObjectFile { - mutable void *UniquingMap; + const MCSection *DrectveSection; public: - TargetLoweringObjectFileCOFF() : UniquingMap(0) {} - ~TargetLoweringObjectFileCOFF(); + TargetLoweringObjectFileCOFF() {} + ~TargetLoweringObjectFileCOFF() {} virtual void Initialize(MCContext &Ctx, const TargetMachine &TM); + virtual const MCSection *getDrectveSection() const { return DrectveSection; } + virtual const MCSection * getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; @@ -175,11 +177,6 @@ public: virtual const MCSection * SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; - - /// getCOFFSection - Return the MCSection for the specified COFF section. - /// FIXME: Switch this to a semantic view eventually. - const MCSection *getCOFFSection(StringRef Name, bool isDirective, - SectionKind K) const; }; } // end namespace llvm diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 4434341f529..fcd898b97a7 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -50,7 +50,7 @@ namespace llvm { /// objects. BumpPtrAllocator Allocator; - void *MachOUniquingMap, *ELFUniquingMap; + void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap; public: explicit MCContext(const MCAsmInfo &MAI); ~MCContext(); @@ -97,6 +97,9 @@ namespace llvm { const MCSection *getELFSection(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind, bool IsExplicit = false); + + const MCSection *getCOFFSection(StringRef Section, unsigned Flags, + SectionKind Kind); /// @} diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index e9c19fce20a..1e2ef1e132d 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -48,32 +48,6 @@ namespace llvm { return false; } }; - - class MCSectionCOFF : public MCSection { - // The memory for this string is stored in the same MCContext as *this. - StringRef 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; - - MCSectionCOFF(StringRef name, bool isDirective, SectionKind K) - : MCSection(K), Name(name), IsDirective(isDirective) { - } - public: - - static MCSectionCOFF *Create(StringRef Name, bool IsDirective, - SectionKind K, MCContext &Ctx); - - StringRef getName() const { return Name; } - bool isDirective() const { return IsDirective; } - - virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const; - }; } // end namespace llvm diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h new file mode 100644 index 00000000000..455e1057e90 --- /dev/null +++ b/include/llvm/MC/MCSectionCOFF.h @@ -0,0 +1,83 @@ +//===- MCSectionCOFF.h - COFF 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 MCSectionCOFF class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSECTIONCOFF_H +#define LLVM_MC_MCSECTIONCOFF_H + +#include "llvm/MC/MCSection.h" + +namespace llvm { + +/// MCSectionCOFF - This represents a section on Windows + class MCSectionCOFF : public MCSection { + // The memory for this string is stored in the same MCContext as *this. + StringRef SectionName; + + /// Flags - This is the Characteristics field of a section, drawn + /// from the enums below. + unsigned Flags; + + private: + friend class MCContext; + MCSectionCOFF(StringRef Section, unsigned flags, SectionKind K) + : MCSection(K), SectionName(Section), Flags(flags) { + } + ~MCSectionCOFF(); + + public: + /// ShouldOmitSectionDirective - Decides whether a '.section' directive + /// should be printed before the section name + bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; + + /// Valid section flags. + enum { + IMAGE_SCN_TYPE_NO_PAD = 0x00000008, + IMAGE_SCN_CNT_CODE = 0x00000020, + IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040, + IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080, + IMAGE_SCN_LNK_OTHER = 0x00000100, + IMAGE_SCN_LNK_INFO = 0x00000200, + IMAGE_SCN_LNK_REMOVE = 0x00000800, + IMAGE_SCN_LNK_COMDAT = 0x00001000, + IMAGE_SCN_MEM_FARDATA = 0x00008000, + IMAGE_SCN_MEM_PURGEABLE = 0x00020000, + IMAGE_SCN_MEM_16BIT = 0x00020000, + IMAGE_SCN_MEM_LOCKED = 0x00040000, + IMAGE_SCN_MEM_PRELOAD = 0x00080000, + IMAGE_SCN_ALIGN_1BYTES = 0x00100000, + IMAGE_SCN_ALIGN_2BYTES = 0x00200000, + IMAGE_SCN_ALIGN_4BYTES = 0x00300000, + IMAGE_SCN_ALIGN_8BYTES = 0x00400000, + IMAGE_SCN_ALIGN_16BYTES = 0x00500000, + IMAGE_SCN_ALIGN_32BYTES = 0x00600000, + IMAGE_SCN_ALIGN_64BYTES = 0x00700000, + IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000, + IMAGE_SCN_MEM_DISCARDABLE = 0x02000000, + IMAGE_SCN_MEM_NOT_CACHED = 0x04000000, + IMAGE_SCN_MEM_NOT_PAGED = 0x08000000, + IMAGE_SCN_MEM_SHARED = 0x10000000, + IMAGE_SCN_MEM_EXECUTE = 0x20000000, + IMAGE_SCN_MEM_READ = 0x40000000, + IMAGE_SCN_MEM_WRITE = 0x80000000 + }; + + StringRef getSectionName() const { return SectionName; } + unsigned getFlags() const { return Flags; } + + virtual void PrintSwitchToSection(const MCAsmInfo &MAI, + raw_ostream &OS) const; + }; + +} // end namespace llvm + +#endif diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 9f959932e6d..b74ed567ae4 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -22,6 +22,7 @@ #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" @@ -794,89 +795,147 @@ unsigned TargetLoweringObjectFileMachO::getTTypeEncoding() const { // COFF //===----------------------------------------------------------------------===// -typedef StringMap 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.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) { @@ -900,7 +959,9 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, 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); + return getContext().getCOFFSection(Name.str(), + getCOFFSectionFlags(Kind), + Kind); } if (Kind.isText()) diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index dc757bb0bff..93388c00f87 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -11,6 +11,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSymbol.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" @@ -18,11 +19,13 @@ using namespace llvm; typedef StringMap MachOUniqueMapTy; typedef StringMap ELFUniqueMapTy; +typedef StringMap COFFUniqueMapTy; MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0) { MachOUniquingMap = 0; ELFUniquingMap = 0; + COFFUniquingMap = 0; } MCContext::~MCContext() { @@ -32,6 +35,7 @@ MCContext::~MCContext() { // If we have the MachO uniquing map, free it. delete (MachOUniqueMapTy*)MachOUniquingMap; delete (ELFUniqueMapTy*)ELFUniquingMap; + delete (COFFUniqueMapTy*)COFFUniquingMap; } //===----------------------------------------------------------------------===// @@ -122,4 +126,19 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags, return Result; } - +const MCSection *MCContext:: +getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) { + if (COFFUniquingMap == 0) + COFFUniquingMap = new COFFUniqueMapTy(); + COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap; + + // Do the lookup, if we have a hit, return it. + StringMapEntry &Entry = Map.GetOrCreateValue(Section); + if (Entry.getValue()) return Entry.getValue(); + + MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), Flags, + Kind); + + Entry.setValue(Result); + return Result; +} diff --git a/lib/MC/MCSection.cpp b/lib/MC/MCSection.cpp index f6e96368eb2..a792d563179 100644 --- a/lib/MC/MCSection.cpp +++ b/lib/MC/MCSection.cpp @@ -20,30 +20,3 @@ using namespace llvm; MCSection::~MCSection() { } -//===----------------------------------------------------------------------===// -// MCSectionCOFF -//===----------------------------------------------------------------------===// - -MCSectionCOFF *MCSectionCOFF:: -Create(StringRef Name, bool IsDirective, SectionKind K, MCContext &Ctx) { - char *NameCopy = static_cast( - Ctx.Allocate(Name.size(), /*Alignment=*/1)); - memcpy(NameCopy, Name.data(), Name.size()); - return new (Ctx) MCSectionCOFF(StringRef(NameCopy, Name.size()), - IsDirective, K); -} - -void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const { - - if (isDirective()) { - OS << getName() << '\n'; - return; - } - OS << "\t.section\t" << getName() << ",\""; - if (getKind().isText()) - OS << 'x'; - if (getKind().isWriteable()) - OS << 'w'; - OS << "\"\n"; -} diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp new file mode 100644 index 00000000000..f26768a7641 --- /dev/null +++ b/lib/MC/MCSectionCOFF.cpp @@ -0,0 +1,49 @@ +//===- lib/MC/MCSectionCOFF.cpp - COFF 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/MCSectionCOFF.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +MCSectionCOFF::~MCSectionCOFF() {} // anchor. + +// ShouldOmitSectionDirective - Decides whether a '.section' directive +// should be printed before the section name +bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name, + const MCAsmInfo &MAI) const { + + // FIXME: Does .section .bss/.data/.text work everywhere?? + if (Name == ".text" || Name == ".data" || Name == ".bss") + return true; + + return false; +} + +void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, + raw_ostream &OS) const { + + if (ShouldOmitSectionDirective(SectionName, MAI)) { + OS << '\t' << getSectionName() << '\n'; + return; + } + + OS << "\t.section\t" << getSectionName() << ",\""; + if (getKind().isText()) + OS << 'x'; + if (getKind().isWriteable()) + OS << 'w'; + else + OS << 'r'; + if (getFlags() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE) + OS << 'n'; + OS << "\"\n"; +} diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp index 8b0ed1ce34c..016a8c2515a 100644 --- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp @@ -598,9 +598,7 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { // Output linker support code for dllexported globals on windows. if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) { - OutStreamer.SwitchSection(TLOFCOFF.getCOFFSection(".section .drectve", - true, - SectionKind::getMetadata())); + OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection()); for (unsigned i = 0, e = DLLExportedGlobals.size(); i != e; ++i) OutStreamer.EmitRawText("\t.ascii \" -export:" + Twine(DLLExportedGlobals[i]->getName()) +