From 6e5ce287b0e53c264af0ba37169ad964e19b5bb7 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 7 May 2010 21:49:09 +0000 Subject: [PATCH] add COFF support for COMDAT sections, patch by Nathan Jeffords! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103304 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCContext.h | 10 ++++- include/llvm/MC/MCSectionCOFF.h | 39 +++++++++++++++++--- lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 20 ++++++++-- lib/MC/MCContext.cpp | 11 ++++-- lib/MC/MCSectionCOFF.cpp | 2 +- 5 files changed, 65 insertions(+), 17 deletions(-) diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index fcd898b97a7..50ae9cc7df9 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -98,8 +98,14 @@ namespace llvm { unsigned Flags, SectionKind Kind, bool IsExplicit = false); - const MCSection *getCOFFSection(StringRef Section, unsigned Flags, - SectionKind Kind); + const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics, + int Selection, SectionKind Kind); + + const MCSection *getCOFFSection(StringRef Section, unsigned Characteristics, + SectionKind Kind) { + return getCOFFSection (Section, Characteristics, 0, Kind); + } + /// @} diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 455e1057e90..f91f0d5a872 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -23,14 +23,22 @@ namespace llvm { // 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; + /// Characteristics - This is the Characteristics field of a section, + // drawn from the enums below. + unsigned Characteristics; + + /// Selection - This is the Selection field for the section symbol, if + /// it is a COMDAT section (Characteristics & IMAGE_SCN_LNK_COMDAT) != 0 + int Selection; private: friend class MCContext; - MCSectionCOFF(StringRef Section, unsigned flags, SectionKind K) - : MCSection(K), SectionName(Section), Flags(flags) { + MCSectionCOFF(StringRef Section, unsigned Characteristics, + int Selection, SectionKind K) + : MCSection(K), SectionName(Section), Characteristics(Characteristics), + Selection (Selection) { + assert ((Characteristics & 0x00F00000) == 0 && + "alignment must not be set upon section creation"); } ~MCSectionCOFF(); @@ -39,6 +47,13 @@ namespace llvm { /// should be printed before the section name bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const; + //FIXME: all COFF enumerations/flags should be standardized into one place... + // Target/X86COFF.h doesn't seem right as COFF can be used for other targets, + // MC/WinCOFF.h maybe right as it isn't target or entity specific, and it is + // pretty low on the dependancy graph (is there any need to support non + // windows COFF?) + // here is good for section stuff, but others should go elsewhere + /// Valid section flags. enum { IMAGE_SCN_TYPE_NO_PAD = 0x00000008, @@ -54,6 +69,7 @@ namespace llvm { IMAGE_SCN_MEM_16BIT = 0x00020000, IMAGE_SCN_MEM_LOCKED = 0x00040000, IMAGE_SCN_MEM_PRELOAD = 0x00080000, + /* these are handled elsewhere IMAGE_SCN_ALIGN_1BYTES = 0x00100000, IMAGE_SCN_ALIGN_2BYTES = 0x00200000, IMAGE_SCN_ALIGN_4BYTES = 0x00300000, @@ -61,6 +77,7 @@ namespace llvm { 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, @@ -71,8 +88,18 @@ namespace llvm { IMAGE_SCN_MEM_WRITE = 0x80000000 }; + enum { + IMAGE_COMDAT_SELECT_NODUPLICATES = 1, + IMAGE_COMDAT_SELECT_ANY, + IMAGE_COMDAT_SELECT_SAME_SIZE, + IMAGE_COMDAT_SELECT_EXACT_MATCH, + IMAGE_COMDAT_SELECT_ASSOCIATIVE, + IMAGE_COMDAT_SELECT_LARGEST + }; + StringRef getSectionName() const { return SectionName; } - unsigned getFlags() const { return Flags; } + unsigned getCharacteristics() const { return Characteristics; } + int getSelection () const { return Selection; } virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS) const; diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index b74ed567ae4..00e1e83cf18 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -912,11 +912,17 @@ getCOFFSectionFlags(SectionKind K) { unsigned Flags = 0; if (!K.isMetadata()) - Flags |= MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE; + 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 | @@ -941,6 +947,8 @@ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind 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"; @@ -959,9 +967,13 @@ 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 getContext().getCOFFSection(Name.str(), - getCOFFSectionFlags(Kind), - 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()) diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 93388c00f87..5a65b8ae380 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -126,8 +126,10 @@ getELFSection(StringRef Section, unsigned Type, unsigned Flags, return Result; } -const MCSection *MCContext:: -getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) { +const MCSection *MCContext::getCOFFSection(StringRef Section, + unsigned Characteristics, + int Selection, + SectionKind Kind) { if (COFFUniquingMap == 0) COFFUniquingMap = new COFFUniqueMapTy(); COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap; @@ -136,8 +138,9 @@ getCOFFSection(StringRef Section, unsigned Flags, SectionKind Kind) { StringMapEntry &Entry = Map.GetOrCreateValue(Section); if (Entry.getValue()) return Entry.getValue(); - MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), Flags, - Kind); + MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), + Characteristics, + Selection, Kind); Entry.setValue(Result); return Result; diff --git a/lib/MC/MCSectionCOFF.cpp b/lib/MC/MCSectionCOFF.cpp index f26768a7641..d15146654eb 100644 --- a/lib/MC/MCSectionCOFF.cpp +++ b/lib/MC/MCSectionCOFF.cpp @@ -43,7 +43,7 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, OS << 'w'; else OS << 'r'; - if (getFlags() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE) + if (getCharacteristics() & MCSectionCOFF::IMAGE_SCN_MEM_DISCARDABLE) OS << 'n'; OS << "\"\n"; } -- 2.34.1