Skip to content

Commit 63538a0

Browse files
cynecxMaskRay
authored andcommitted
[MC] Add .pushsection/.popsection support to COFFAsmParser
The COFFAsmParser (to my surprise) didn't support the .pushsection and .popsection directives. These directives aren't directly useful, however for frontends that have inline asm support this is really useful. Rust in particular, has support for inline asm, which can be used together with these directives to "emulate" features like static generics. This patch adds support for the two mentioned directives. Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D152085
1 parent 1704c8d commit 63538a0

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed

llvm/lib/MC/MCParser/COFFAsmParser.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ class COFFAsmParser : public MCAsmParserExtension {
5656
addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
5757
addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
5858
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
59+
addDirectiveHandler<&COFFAsmParser::ParseDirectivePushSection>(
60+
".pushsection");
61+
addDirectiveHandler<&COFFAsmParser::ParseDirectivePopSection>(
62+
".popsection");
5963
addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
6064
addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
6165
addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
@@ -115,6 +119,9 @@ class COFFAsmParser : public MCAsmParserExtension {
115119
}
116120

117121
bool ParseDirectiveSection(StringRef, SMLoc);
122+
bool parseSectionArguments(StringRef, SMLoc);
123+
bool ParseDirectivePushSection(StringRef, SMLoc);
124+
bool ParseDirectivePopSection(StringRef, SMLoc);
118125
bool ParseDirectiveDef(StringRef, SMLoc);
119126
bool ParseDirectiveScl(StringRef, SMLoc);
120127
bool ParseDirectiveType(StringRef, SMLoc);
@@ -343,7 +350,12 @@ bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
343350
return false;
344351
}
345352

353+
bool COFFAsmParser::ParseDirectiveSection(StringRef directive, SMLoc loc) {
354+
return parseSectionArguments(directive, loc);
355+
}
356+
346357
// .section name [, "flags"] [, identifier [ identifier ], identifier]
358+
// .pushsection <same as above>
347359
//
348360
// Supported flags:
349361
// a: Ignored.
@@ -358,7 +370,7 @@ bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
358370
// y: Not-readable section (clears 'r')
359371
//
360372
// Subsections are not supported.
361-
bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
373+
bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
362374
StringRef SectionName;
363375

364376
if (ParseSectionName(SectionName))
@@ -417,6 +429,23 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
417429
return false;
418430
}
419431

432+
bool COFFAsmParser::ParseDirectivePushSection(StringRef directive, SMLoc loc) {
433+
getStreamer().pushSection();
434+
435+
if (parseSectionArguments(directive, loc)) {
436+
getStreamer().popSection();
437+
return true;
438+
}
439+
440+
return false;
441+
}
442+
443+
bool COFFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
444+
if (!getStreamer().popSection())
445+
return TokError(".popsection without corresponding .pushsection");
446+
return false;
447+
}
448+
420449
bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
421450
StringRef SymbolName;
422451

llvm/test/MC/COFF/section.s

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: llvm-mc -triple i386-pc-win32 -filetype=obj %s | llvm-readobj -S - | FileCheck %s
22
// RUN: llvm-mc -triple x86_64-pc-win32 -filetype=obj %s | llvm-readobj -S - | FileCheck %s
3+
// RUN: not llvm-mc -triple x86_64-pc-win32 -filetype=obj --defsym ERR=1 %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
34

45
.section .foo$bar; .long 1
56
.section .foo@bar; .long 1
@@ -208,3 +209,74 @@
208209

209210
// CHECK-NOT: Section {
210211
// CHECK: ]
212+
213+
.section data1; .quad 0
214+
215+
.pushsection data2; .quad 0
216+
.popsection
217+
218+
// Back to section data1
219+
.quad 2
220+
221+
// CHECK: Section {
222+
// CHECK-NEXT: Number:
223+
// CHECK-NEXT: Name: data1
224+
// CHECK: RawDataSize: 16
225+
226+
// CHECK: Section {
227+
// CHECK-NEXT: Number:
228+
// CHECK-NEXT: Name: data2
229+
// CHECK: RawDataSize: 8
230+
231+
.section .data3,"dw"; .quad 1
232+
233+
.pushsection .data4,"dw"; .quad 1
234+
.popsection
235+
236+
.pushsection .data5,"dr"; .quad 1
237+
.popsection
238+
239+
// in section .data3
240+
.quad 4
241+
242+
// Notice the different section flags here.
243+
// This shouldn't overwrite the intial section flags.
244+
.pushsection .data4,"dr"; .quad 1
245+
.popsection
246+
247+
// CHECK: Section {
248+
// CHECK-NEXT: Number:
249+
// CHECK-NEXT: Name: .data3
250+
// CHECK: RawDataSize: 16
251+
// CHECK: Characteristics [
252+
// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES
253+
// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
254+
// CHECK-NEXT: IMAGE_SCN_MEM_READ
255+
// CHECK-NEXT: IMAGE_SCN_MEM_WRITE
256+
// CHECK-NEXT: ]
257+
258+
// CHECK: Section {
259+
// CHECK-NEXT: Number:
260+
// CHECK-NEXT: Name: .data4
261+
// CHECK: RawDataSize: 16
262+
// CHECK: Characteristics [
263+
// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES
264+
// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
265+
// CHECK-NEXT: IMAGE_SCN_MEM_READ
266+
// CHECK-NEXT: IMAGE_SCN_MEM_WRITE
267+
// CHECK-NEXT: ]
268+
269+
// CHECK: Section {
270+
// CHECK-NEXT: Number:
271+
// CHECK-NEXT: Name: .data5
272+
// CHECK: RawDataSize: 8
273+
// CHECK: Characteristics [
274+
// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES
275+
// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA
276+
// CHECK-NEXT: IMAGE_SCN_MEM_READ
277+
// CHECK-NEXT: ]
278+
279+
.ifdef ERR
280+
// ERR: :[[#@LINE+1]]:12: error: .popsection without corresponding .pushsection
281+
.popsection
282+
.endif

0 commit comments

Comments
 (0)