summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-09-14 22:41:50 +0000
committerReid Kleckner <rnk@google.com>2016-09-14 22:41:50 +0000
commit31263731da2214579540198ae96c0990b315d0ed (patch)
treee0f6d7d1549ec18d81694256654b6ad24dace85b
parent446b5d88116b51a883ce9bfb271de09c232ea86f (diff)
downloadbcm5719-llvm-31263731da2214579540198ae96c0990b315d0ed.tar.gz
bcm5719-llvm-31263731da2214579540198ae96c0990b315d0ed.zip
[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 llvm-svn: 281554
-rw-r--r--llvm/include/llvm/MC/MCSectionCOFF.h4
-rw-r--r--llvm/lib/MC/MCParser/COFFAsmParser.cpp37
-rw-r--r--llvm/lib/MC/MCSectionCOFF.cpp3
-rw-r--r--llvm/test/MC/COFF/section.s24
4 files changed, 55 insertions, 13 deletions
diff --git a/llvm/include/llvm/MC/MCSectionCOFF.h b/llvm/include/llvm/MC/MCSectionCOFF.h
index c9fd8ea1605..7d5f9f7f3cd 100644
--- a/llvm/include/llvm/MC/MCSectionCOFF.h
+++ b/llvm/include/llvm/MC/MCSectionCOFF.h
@@ -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; }
};
diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
index 653627ad8dc..5bb5d98ccc9 100644
--- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp
@@ -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;
}
diff --git a/llvm/lib/MC/MCSectionCOFF.cpp b/llvm/lib/MC/MCSectionCOFF.cpp
index b8373f40b8b..f2dd47d81b7 100644
--- a/llvm/lib/MC/MCSectionCOFF.cpp
+++ b/llvm/lib/MC/MCSectionCOFF.cpp
@@ -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) {
diff --git a/llvm/test/MC/COFF/section.s b/llvm/test/MC/COFF/section.s
index d7547e626eb..409c6446cb4 100644
--- a/llvm/test/MC/COFF/section.s
+++ b/llvm/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: ]
OpenPOWER on IntegriCloud