[llvm] r281554 - [MC] Handle discardable COFF sections in assembly

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 14 15:41:50 PDT 2016


Author: rnk
Date: Wed Sep 14 17:41:50 2016
New Revision: 281554

URL: http://llvm.org/viewvc/llvm-project?rev=281554&view=rev
Log:
[MC] Handle discardable COFF sections in assembly

Summary:
This fixes a dumpbin warning on objects produced by the MC assembler
when starting from text. All .debug$S sections are supposed to be marked
IMAGE_SCN_MEM_DISCARDABLE. The main, non-COMDAT .debug$S section had
this set, but any comdat ones were not being marked discardable because
there was no .section flag for it.

This change does two things:

- If the section name starts with .debug, implicitly mark the section as
  discardable. This means we do the same thing as gas on .s files with
  DWARF from GCC, which is important.

- Adds the 'D' flag to the .section directive on COFF to explicitly say
  a section is discardable. We only emit this flag if the section name
  does not start with .debug. This allows the user to explicitly tweak
  their section flags without worrying about magic section names.

The only thing you can't do in this scheme is to create a
non-discardable section with a name starting with ".debug", but
hopefully users don't need that.

Reviewers: majnemer, rafael

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D24582

Modified:
    llvm/trunk/include/llvm/MC/MCSectionCOFF.h
    llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
    llvm/trunk/lib/MC/MCSectionCOFF.cpp
    llvm/trunk/test/MC/COFF/section.s

Modified: llvm/trunk/include/llvm/MC/MCSectionCOFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSectionCOFF.h?rev=281554&r1=281553&r2=281554&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSectionCOFF.h (original)
+++ llvm/trunk/include/llvm/MC/MCSectionCOFF.h Wed Sep 14 17:41:50 2016
@@ -84,6 +84,10 @@ public:
     return WinCFISectionID;
   }
 
+  static bool isImplicitlyDiscardable(StringRef Name) {
+    return Name.startswith(".debug");
+  }
+
   static bool classof(const MCSection *S) { return S->getVariant() == SV_COFF; }
 };
 

Modified: llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp?rev=281554&r1=281553&r2=281554&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/COFFAsmParser.cpp Wed Sep 14 17:41:50 2016
@@ -41,7 +41,8 @@ class COFFAsmParser : public MCAsmParser
                           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 @@ static SectionKind computeSectionKind(un
   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 @@ bool COFFAsmParser::ParseSectionFlags(St
       SecFlags &= ~Load;
       break;
 
+    case 'D': // discardable
+      SecFlags |= Discardable;
+      break;
+
     case 'r': // read-only
       ReadOnlyRemoved = false;
       SecFlags |= NoWrite;
@@ -249,6 +256,9 @@ bool COFFAsmParser::ParseSectionFlags(St
     *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 @@ bool COFFAsmParser::ParseSectionName(Str
 //   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 @@ bool COFFAsmParser::ParseDirectiveSectio
     StringRef FlagsStr = getTok().getStringContents();
     Lex();
 
-    if (ParseSectionFlags(FlagsStr, &Flags))
+    if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
       return true;
   }
 

Modified: llvm/trunk/lib/MC/MCSectionCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSectionCOFF.cpp?rev=281554&r1=281553&r2=281554&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSectionCOFF.cpp (original)
+++ llvm/trunk/lib/MC/MCSectionCOFF.cpp Wed Sep 14 17:41:50 2016
@@ -64,6 +64,9 @@ void MCSectionCOFF::PrintSwitchToSection
     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) {

Modified: llvm/trunk/test/MC/COFF/section.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/COFF/section.s?rev=281554&r1=281553&r2=281554&view=diff
==============================================================================
--- llvm/trunk/test/MC/COFF/section.s (original)
+++ llvm/trunk/test/MC/COFF/section.s Wed Sep 14 17:41:50 2016
@@ -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:      ]




More information about the llvm-commits mailing list