]> granicus.if.org Git - llvm/commitdiff
[MC] Handle discardable COFF sections in assembly
authorReid Kleckner <rnk@google.com>
Wed, 14 Sep 2016 22:41:50 +0000 (22:41 +0000)
committerReid Kleckner <rnk@google.com>
Wed, 14 Sep 2016 22:41:50 +0000 (22:41 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281554 91177308-0d34-0410-b5e6-96231b3b80d8

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

index c9fd8ea1605de0392280b4eafa09b7a54908cc5c..7d5f9f7f3cde98bbfc925fa384cb5aca1f713692 100644 (file)
@@ -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; }
 };
 
index 653627ad8dca8acb519415df42f417ed5c77ccf1..5bb5d98ccc9b90793942026fce4b9a31418aebe7 100644 (file)
@@ -41,7 +41,8 @@ class COFFAsmParser : public MCAsmParserExtension {
                           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(unsigned Flags) {
   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(StringRef FlagsString, unsigned* Flags) {
       SecFlags &= ~Load;
       break;
 
+    case 'D': // discardable
+      SecFlags |= Discardable;
+      break;
+
     case 'r': // read-only
       ReadOnlyRemoved = false;
       SecFlags |= NoWrite;
@@ -249,6 +256,9 @@ bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) {
     *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(StringRef &SectionName) {
 //   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::ParseDirectiveSection(StringRef, SMLoc) {
     StringRef FlagsStr = getTok().getStringContents();
     Lex();
 
-    if (ParseSectionFlags(FlagsStr, &Flags))
+    if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
       return true;
   }
 
index b8373f40b8bebba18f1479edfd93dbb206602d24..f2dd47d81b7e064a5ae7ab3edf95fef48b2e224e 100644 (file)
@@ -64,6 +64,9 @@ void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
     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 d7547e626eb3301b2b9a7ba17f97b530b80b075e..409c6446cb4688e6b3d7c4529ab5be9caab9a37a 100644 (file)
@@ -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
 // 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
 // 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:      ]