Add .pushsection', .popsection', and `.previous' directives to Darwin ASM.

There are situations where inline ASM may want to change the section -- for
instance, to create a variable in the .data section. However, it cannot do this
without (potentially) restoring to the wrong section. E.g.:

  asm volatile (".section __DATA, __data\n\t"
                ".globl _fnord\n\t"
                "_fnord: .quad 1f\n\t"
                ".text\n\t"
                "1:" :::);

This may be wrong if this is inlined into a function that has a "section"
attribute. The user should use `.pushsection' and `.popsection' here instead.

The addition of `.previous' is added for completeness.
<rdar://problem/12048387>


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161477 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2012-08-08 06:30:30 +00:00
parent d43b5c97cf
commit ef920552d4
3 changed files with 68 additions and 2 deletions

View File

@ -50,6 +50,9 @@ public:
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump"); AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load"); AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section"); AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>( AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
".secure_log_unique"); ".secure_log_unique");
AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>( AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
@ -112,6 +115,9 @@ public:
bool ParseDirectiveDumpOrLoad(StringRef, SMLoc); bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
bool ParseDirectiveLsym(StringRef, SMLoc); bool ParseDirectiveLsym(StringRef, SMLoc);
bool ParseDirectiveSection(StringRef, SMLoc); bool ParseDirectiveSection(StringRef, SMLoc);
bool ParseDirectivePushSection(StringRef, SMLoc);
bool ParseDirectivePopSection(StringRef, SMLoc);
bool ParseDirectivePrevious(StringRef, SMLoc);
bool ParseDirectiveSecureLogReset(StringRef, SMLoc); bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
bool ParseDirectiveSecureLogUnique(StringRef, SMLoc); bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
@ -297,7 +303,7 @@ public:
}; };
} } // end anonymous namespace
bool DarwinAsmParser::ParseSectionSwitch(const char *Segment, bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
const char *Section, const char *Section,
@ -457,6 +463,37 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
return false; return false;
} }
/// ParseDirectivePushSection:
/// ::= .pushsection identifier (',' identifier)*
bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
getStreamer().PushSection();
if (ParseDirectiveSection(S, Loc)) {
getStreamer().PopSection();
return true;
}
return false;
}
/// ParseDirectivePopSection:
/// ::= .popsection
bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
if (!getStreamer().PopSection())
return TokError(".popsection without corresponding .pushsection");
return false;
}
/// ParseDirectivePrevious:
/// ::= .previous
bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
const MCSection *PreviousSection = getStreamer().getPreviousSection();
if (PreviousSection == NULL)
return TokError(".previous without corresponding .section");
getStreamer().SwitchSection(PreviousSection);
return false;
}
/// ParseDirectiveSecureLogUnique /// ParseDirectiveSecureLogUnique
/// ::= .secure_log_unique ... message ... /// ::= .secure_log_unique ... message ...
bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
@ -707,4 +744,4 @@ MCAsmParserExtension *createDarwinAsmParser() {
return new DarwinAsmParser; return new DarwinAsmParser;
} }
} } // end llvm namespace

13
test/MC/MachO/previous.s Normal file
View File

@ -0,0 +1,13 @@
// RUN: llvm-mc -triple i386-apple-darwin9 %s -o - | FileCheck %s
.text
// CHECK: .section __TEXT,__text
.data
// CHECK: .section __DATA,__data
.previous
// CHECK: .section __TEXT,__text
.previous
// CHECK: .section __DATA,__data

View File

@ -0,0 +1,16 @@
// RUN: llvm-mc -triple i386-apple-darwin9 %s -o - | FileCheck %s
.text
// CHECK: .section __TEXT,__text
.pushsection __DATA, __data
// CHECK: .section __DATA,__data
.pushsection __TEXT, initcode
// CHECK: .section __TEXT,initcode
.popsection
// CHECK: .section __DATA,__data
.popsection
// CHECK: .section __TEXT,__text