Index: llvm/trunk/include/llvm/MC/MCSectionCOFF.h =================================================================== --- llvm/trunk/include/llvm/MC/MCSectionCOFF.h +++ llvm/trunk/include/llvm/MC/MCSectionCOFF.h @@ -84,6 +84,10 @@ return WinCFISectionID; } + static bool isImplicitlyDiscardable(StringRef Name) { + return Name.startswith(".debug"); + } + static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; } }; Index: llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp =================================================================== --- llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp +++ llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp @@ -41,7 +41,8 @@ COFF::COMDATType Type); bool ParseSectionName(StringRef &SectionName); - bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags); + bool ParseSectionFlags(StringRef SectionName, StringRef FlagsString, + unsigned *Flags); void Initialize(MCAsmParser &Parser) override { // Call the base implementation. @@ -155,17 +156,19 @@ return SectionKind::getData(); } -bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) { +bool COFFAsmParser::ParseSectionFlags(StringRef SectionName, + StringRef FlagsString, unsigned *Flags) { enum { - None = 0, - Alloc = 1 << 0, - Code = 1 << 1, - Load = 1 << 2, - InitData = 1 << 3, - Shared = 1 << 4, - NoLoad = 1 << 5, - NoRead = 1 << 6, - NoWrite = 1 << 7 + None = 0, + Alloc = 1 << 0, + Code = 1 << 1, + Load = 1 << 2, + InitData = 1 << 3, + Shared = 1 << 4, + NoLoad = 1 << 5, + NoRead = 1 << 6, + NoWrite = 1 << 7, + Discardable = 1 << 8, }; bool ReadOnlyRemoved = false; @@ -198,6 +201,10 @@ SecFlags &= ~Load; break; + case 'D': // discardable + SecFlags |= Discardable; + break; + case 'r': // read-only ReadOnlyRemoved = false; SecFlags |= NoWrite; @@ -249,6 +256,9 @@ *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; if (SecFlags & NoLoad) *Flags |= COFF::IMAGE_SCN_LNK_REMOVE; + if ((SecFlags & Discardable) || + MCSectionCOFF::isImplicitlyDiscardable(SectionName)) + *Flags |= COFF::IMAGE_SCN_MEM_DISCARDABLE; if ((SecFlags & NoRead) == 0) *Flags |= COFF::IMAGE_SCN_MEM_READ; if ((SecFlags & NoWrite) == 0) @@ -326,7 +336,8 @@ // a: Ignored. // b: BSS section (uninitialized data) // d: data section (initialized data) -// n: Discardable section +// n: "noload" section (removed by linker) +// D: Discardable section // r: Readable section // s: Shared section // w: Writable section @@ -353,7 +364,7 @@ StringRef FlagsStr = getTok().getStringContents(); Lex(); - if (ParseSectionFlags(FlagsStr, &Flags)) + if (ParseSectionFlags(SectionName, FlagsStr, &Flags)) return true; } Index: llvm/trunk/lib/MC/MCSectionCOFF.cpp =================================================================== --- llvm/trunk/lib/MC/MCSectionCOFF.cpp +++ llvm/trunk/lib/MC/MCSectionCOFF.cpp @@ -64,6 +64,9 @@ OS << 'n'; if (getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED) OS << 's'; + if ((getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE) && + !isImplicitlyDiscardable(SectionName)) + OS << 'D'; OS << '"'; if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { Index: llvm/trunk/test/MC/COFF/section.s =================================================================== --- llvm/trunk/test/MC/COFF/section.s +++ llvm/trunk/test/MC/COFF/section.s @@ -30,6 +30,7 @@ .section s_a,"a"; .long 1 .section s_b,"b"; .long 1 .section s_d,"d"; .long 1 +.section s_D,"D"; .long 1 .section s_n,"n"; .long 1 .section s_r,"r"; .long 1 .section s_s,"s"; .long 1 @@ -83,6 +84,15 @@ // CHECK-NEXT: ] // CHECK: } // CHECK: Section { +// CHECK: Name: s_D +// CHECK: Characteristics [ +// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES +// CHECK-NEXT: IMAGE_SCN_MEM_DISCARDABLE +// CHECK-NEXT: IMAGE_SCN_MEM_READ +// CHECK-NEXT: IMAGE_SCN_MEM_WRITE +// CHECK-NEXT: ] +// CHECK: } +// CHECK: Section { // CHECK: Name: s_n // CHECK: Characteristics [ // CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES @@ -167,4 +177,18 @@ // CHECK-NEXT: ] // CHECK: } +// Sections starting with ".debug" are implicitly discardable. This is +// compatible with gas. +.section .debug_asdf,"dr"; .long 1 +// CHECK: Section { +// CHECK: Name: .debug_asdf +// CHECK: Characteristics [ +// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES +// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +// CHECK-NEXT: IMAGE_SCN_MEM_DISCARDABLE +// CHECK-NEXT: IMAGE_SCN_MEM_READ +// CHECK-NEXT: ] +// CHECK: } + + // CHECK: ]