1 //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCParser/MCAsmLexer.h"
16 #include "llvm/MC/MCParser/MCAsmParser.h"
17 #include "llvm/MC/MCSectionMachO.h"
18 #include "llvm/MC/MCStreamer.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include "llvm/Support/SourceMgr.h"
26 /// \brief Implementation of directive handling which is shared across all
28 class DarwinAsmParser
: public MCAsmParserExtension
{
29 template<bool (DarwinAsmParser::*HandlerMethod
)(StringRef
, SMLoc
)>
30 void addDirectiveHandler(StringRef Directive
) {
31 MCAsmParser::ExtensionDirectiveHandler Handler
= std::make_pair(
32 this, HandleDirective
<DarwinAsmParser
, HandlerMethod
>);
33 getParser().addDirectiveHandler(Directive
, Handler
);
36 bool ParseSectionSwitch(const char *Segment
, const char *Section
,
37 unsigned TAA
= 0, unsigned ImplicitAlign
= 0,
38 unsigned StubSize
= 0);
43 virtual void Initialize(MCAsmParser
&Parser
) {
44 // Call the base implementation.
45 this->MCAsmParserExtension::Initialize(Parser
);
47 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveDesc
>(".desc");
48 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveLsym
>(".lsym");
49 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols
>(
50 ".subsections_via_symbols");
51 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveDumpOrLoad
>(".dump");
52 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveDumpOrLoad
>(".load");
53 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveSection
>(".section");
54 addDirectiveHandler
<&DarwinAsmParser::ParseDirectivePushSection
>(
56 addDirectiveHandler
<&DarwinAsmParser::ParseDirectivePopSection
>(
58 addDirectiveHandler
<&DarwinAsmParser::ParseDirectivePrevious
>(".previous");
59 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveSecureLogUnique
>(
60 ".secure_log_unique");
61 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveSecureLogReset
>(
63 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveTBSS
>(".tbss");
64 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveZerofill
>(".zerofill");
66 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveDataRegion
>(
68 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveDataRegionEnd
>(
71 // Special section directives.
72 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveConst
>(".const");
73 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveConstData
>(
75 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveConstructor
>(
77 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveCString
>(
79 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveData
>(".data");
80 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveDestructor
>(
82 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveDyld
>(".dyld");
83 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0
>(
85 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1
>(
88 &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers
>(
89 ".lazy_symbol_pointer");
90 addDirectiveHandler
<&DarwinAsmParser::ParseDirectiveLinkerOption
>(
92 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveLiteral16
>(
94 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveLiteral4
>(
96 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveLiteral8
>(
98 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveModInitFunc
>(
100 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveModTermFunc
>(
103 &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers
>(
104 ".non_lazy_symbol_pointer");
105 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth
>(
106 ".objc_cat_cls_meth");
107 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth
>(
108 ".objc_cat_inst_meth");
109 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCCategory
>(
111 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCClass
>(
113 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames
>(
114 ".objc_class_names");
115 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars
>(
117 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth
>(
119 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs
>(
121 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth
>(
124 &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars
>(
125 ".objc_instance_vars");
126 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs
>(
127 ".objc_message_refs");
128 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass
>(
131 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames
>(
132 ".objc_meth_var_names");
134 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes
>(
135 ".objc_meth_var_types");
136 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo
>(
137 ".objc_module_info");
138 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol
>(
141 &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs
>(
142 ".objc_selector_strs");
144 &DarwinAsmParser::ParseSectionDirectiveObjCStringObject
>(
145 ".objc_string_object");
146 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols
>(
148 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub
>(
150 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveStaticConst
>(
152 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveStaticData
>(
154 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveSymbolStub
>(
156 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveTData
>(".tdata");
157 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveText
>(".text");
158 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc
>(
159 ".thread_init_func");
160 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveTLV
>(".tlv");
162 addDirectiveHandler
<&DarwinAsmParser::ParseSectionDirectiveIdent
>(".ident");
165 bool ParseDirectiveDesc(StringRef
, SMLoc
);
166 bool ParseDirectiveDumpOrLoad(StringRef
, SMLoc
);
167 bool ParseDirectiveLsym(StringRef
, SMLoc
);
168 bool ParseDirectiveLinkerOption(StringRef
, SMLoc
);
169 bool ParseDirectiveSection(StringRef
, SMLoc
);
170 bool ParseDirectivePushSection(StringRef
, SMLoc
);
171 bool ParseDirectivePopSection(StringRef
, SMLoc
);
172 bool ParseDirectivePrevious(StringRef
, SMLoc
);
173 bool ParseDirectiveSecureLogReset(StringRef
, SMLoc
);
174 bool ParseDirectiveSecureLogUnique(StringRef
, SMLoc
);
175 bool ParseDirectiveSubsectionsViaSymbols(StringRef
, SMLoc
);
176 bool ParseDirectiveTBSS(StringRef
, SMLoc
);
177 bool ParseDirectiveZerofill(StringRef
, SMLoc
);
178 bool ParseDirectiveDataRegion(StringRef
, SMLoc
);
179 bool ParseDirectiveDataRegionEnd(StringRef
, SMLoc
);
181 // Named Section Directive
182 bool ParseSectionDirectiveConst(StringRef
, SMLoc
) {
183 return ParseSectionSwitch("__TEXT", "__const");
185 bool ParseSectionDirectiveStaticConst(StringRef
, SMLoc
) {
186 return ParseSectionSwitch("__TEXT", "__static_const");
188 bool ParseSectionDirectiveCString(StringRef
, SMLoc
) {
189 return ParseSectionSwitch("__TEXT","__cstring",
190 MCSectionMachO::S_CSTRING_LITERALS
);
192 bool ParseSectionDirectiveLiteral4(StringRef
, SMLoc
) {
193 return ParseSectionSwitch("__TEXT", "__literal4",
194 MCSectionMachO::S_4BYTE_LITERALS
, 4);
196 bool ParseSectionDirectiveLiteral8(StringRef
, SMLoc
) {
197 return ParseSectionSwitch("__TEXT", "__literal8",
198 MCSectionMachO::S_8BYTE_LITERALS
, 8);
200 bool ParseSectionDirectiveLiteral16(StringRef
, SMLoc
) {
201 return ParseSectionSwitch("__TEXT","__literal16",
202 MCSectionMachO::S_16BYTE_LITERALS
, 16);
204 bool ParseSectionDirectiveConstructor(StringRef
, SMLoc
) {
205 return ParseSectionSwitch("__TEXT","__constructor");
207 bool ParseSectionDirectiveDestructor(StringRef
, SMLoc
) {
208 return ParseSectionSwitch("__TEXT","__destructor");
210 bool ParseSectionDirectiveFVMLibInit0(StringRef
, SMLoc
) {
211 return ParseSectionSwitch("__TEXT","__fvmlib_init0");
213 bool ParseSectionDirectiveFVMLibInit1(StringRef
, SMLoc
) {
214 return ParseSectionSwitch("__TEXT","__fvmlib_init1");
216 bool ParseSectionDirectiveSymbolStub(StringRef
, SMLoc
) {
217 return ParseSectionSwitch("__TEXT","__symbol_stub",
218 MCSectionMachO::S_SYMBOL_STUBS
|
219 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
,
220 // FIXME: Different on PPC and ARM.
223 bool ParseSectionDirectivePICSymbolStub(StringRef
, SMLoc
) {
224 return ParseSectionSwitch("__TEXT","__picsymbol_stub",
225 MCSectionMachO::S_SYMBOL_STUBS
|
226 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
, 0, 26);
228 bool ParseSectionDirectiveData(StringRef
, SMLoc
) {
229 return ParseSectionSwitch("__DATA", "__data");
231 bool ParseSectionDirectiveStaticData(StringRef
, SMLoc
) {
232 return ParseSectionSwitch("__DATA", "__static_data");
234 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef
, SMLoc
) {
235 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
236 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS
, 4);
238 bool ParseSectionDirectiveLazySymbolPointers(StringRef
, SMLoc
) {
239 return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
240 MCSectionMachO::S_LAZY_SYMBOL_POINTERS
, 4);
242 bool ParseSectionDirectiveDyld(StringRef
, SMLoc
) {
243 return ParseSectionSwitch("__DATA", "__dyld");
245 bool ParseSectionDirectiveModInitFunc(StringRef
, SMLoc
) {
246 return ParseSectionSwitch("__DATA", "__mod_init_func",
247 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS
, 4);
249 bool ParseSectionDirectiveModTermFunc(StringRef
, SMLoc
) {
250 return ParseSectionSwitch("__DATA", "__mod_term_func",
251 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS
, 4);
253 bool ParseSectionDirectiveConstData(StringRef
, SMLoc
) {
254 return ParseSectionSwitch("__DATA", "__const");
256 bool ParseSectionDirectiveObjCClass(StringRef
, SMLoc
) {
257 return ParseSectionSwitch("__OBJC", "__class",
258 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
260 bool ParseSectionDirectiveObjCMetaClass(StringRef
, SMLoc
) {
261 return ParseSectionSwitch("__OBJC", "__meta_class",
262 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
264 bool ParseSectionDirectiveObjCCatClsMeth(StringRef
, SMLoc
) {
265 return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
266 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
268 bool ParseSectionDirectiveObjCCatInstMeth(StringRef
, SMLoc
) {
269 return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
270 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
272 bool ParseSectionDirectiveObjCProtocol(StringRef
, SMLoc
) {
273 return ParseSectionSwitch("__OBJC", "__protocol",
274 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
276 bool ParseSectionDirectiveObjCStringObject(StringRef
, SMLoc
) {
277 return ParseSectionSwitch("__OBJC", "__string_object",
278 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
280 bool ParseSectionDirectiveObjCClsMeth(StringRef
, SMLoc
) {
281 return ParseSectionSwitch("__OBJC", "__cls_meth",
282 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
284 bool ParseSectionDirectiveObjCInstMeth(StringRef
, SMLoc
) {
285 return ParseSectionSwitch("__OBJC", "__inst_meth",
286 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
288 bool ParseSectionDirectiveObjCClsRefs(StringRef
, SMLoc
) {
289 return ParseSectionSwitch("__OBJC", "__cls_refs",
290 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
|
291 MCSectionMachO::S_LITERAL_POINTERS
, 4);
293 bool ParseSectionDirectiveObjCMessageRefs(StringRef
, SMLoc
) {
294 return ParseSectionSwitch("__OBJC", "__message_refs",
295 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
|
296 MCSectionMachO::S_LITERAL_POINTERS
, 4);
298 bool ParseSectionDirectiveObjCSymbols(StringRef
, SMLoc
) {
299 return ParseSectionSwitch("__OBJC", "__symbols",
300 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
302 bool ParseSectionDirectiveObjCCategory(StringRef
, SMLoc
) {
303 return ParseSectionSwitch("__OBJC", "__category",
304 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
306 bool ParseSectionDirectiveObjCClassVars(StringRef
, SMLoc
) {
307 return ParseSectionSwitch("__OBJC", "__class_vars",
308 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
310 bool ParseSectionDirectiveObjCInstanceVars(StringRef
, SMLoc
) {
311 return ParseSectionSwitch("__OBJC", "__instance_vars",
312 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
314 bool ParseSectionDirectiveObjCModuleInfo(StringRef
, SMLoc
) {
315 return ParseSectionSwitch("__OBJC", "__module_info",
316 MCSectionMachO::S_ATTR_NO_DEAD_STRIP
);
318 bool ParseSectionDirectiveObjCClassNames(StringRef
, SMLoc
) {
319 return ParseSectionSwitch("__TEXT", "__cstring",
320 MCSectionMachO::S_CSTRING_LITERALS
);
322 bool ParseSectionDirectiveObjCMethVarTypes(StringRef
, SMLoc
) {
323 return ParseSectionSwitch("__TEXT", "__cstring",
324 MCSectionMachO::S_CSTRING_LITERALS
);
326 bool ParseSectionDirectiveObjCMethVarNames(StringRef
, SMLoc
) {
327 return ParseSectionSwitch("__TEXT", "__cstring",
328 MCSectionMachO::S_CSTRING_LITERALS
);
330 bool ParseSectionDirectiveObjCSelectorStrs(StringRef
, SMLoc
) {
331 return ParseSectionSwitch("__OBJC", "__selector_strs",
332 MCSectionMachO::S_CSTRING_LITERALS
);
334 bool ParseSectionDirectiveTData(StringRef
, SMLoc
) {
335 return ParseSectionSwitch("__DATA", "__thread_data",
336 MCSectionMachO::S_THREAD_LOCAL_REGULAR
);
338 bool ParseSectionDirectiveText(StringRef
, SMLoc
) {
339 return ParseSectionSwitch("__TEXT", "__text",
340 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
);
342 bool ParseSectionDirectiveTLV(StringRef
, SMLoc
) {
343 return ParseSectionSwitch("__DATA", "__thread_vars",
344 MCSectionMachO::S_THREAD_LOCAL_VARIABLES
);
346 bool ParseSectionDirectiveIdent(StringRef
, SMLoc
) {
347 // Darwin silently ignores the .ident directive.
348 getParser().eatToEndOfStatement();
351 bool ParseSectionDirectiveThreadInitFunc(StringRef
, SMLoc
) {
352 return ParseSectionSwitch("__DATA", "__thread_init",
353 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
);
358 } // end anonymous namespace
360 bool DarwinAsmParser::ParseSectionSwitch(const char *Segment
,
362 unsigned TAA
, unsigned Align
,
364 if (getLexer().isNot(AsmToken::EndOfStatement
))
365 return TokError("unexpected token in section switching directive");
368 // FIXME: Arch specific.
369 bool isText
= TAA
& MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS
;
370 getStreamer().SwitchSection(getContext().getMachOSection(
371 Segment
, Section
, TAA
, StubSize
,
372 isText
? SectionKind::getText()
373 : SectionKind::getDataRel()));
375 // Set the implicit alignment, if any.
377 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
378 // alignment on the section (e.g., if one manually inserts bytes into the
379 // section, then just issuing the section switch directive will not realign
380 // the section. However, this is arguably more reasonable behavior, and there
381 // is no good reason for someone to intentionally emit incorrectly sized
382 // values into the implicitly aligned sections.
384 getStreamer().EmitValueToAlignment(Align
, 0, 1, 0);
389 /// ParseDirectiveDesc
390 /// ::= .desc identifier , expression
391 bool DarwinAsmParser::ParseDirectiveDesc(StringRef
, SMLoc
) {
393 if (getParser().parseIdentifier(Name
))
394 return TokError("expected identifier in directive");
396 // Handle the identifier as the key symbol.
397 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
399 if (getLexer().isNot(AsmToken::Comma
))
400 return TokError("unexpected token in '.desc' directive");
404 if (getParser().parseAbsoluteExpression(DescValue
))
407 if (getLexer().isNot(AsmToken::EndOfStatement
))
408 return TokError("unexpected token in '.desc' directive");
412 // Set the n_desc field of this Symbol to this DescValue
413 getStreamer().EmitSymbolDesc(Sym
, DescValue
);
418 /// ParseDirectiveDumpOrLoad
419 /// ::= ( .dump | .load ) "filename"
420 bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive
,
422 bool IsDump
= Directive
== ".dump";
423 if (getLexer().isNot(AsmToken::String
))
424 return TokError("expected string in '.dump' or '.load' directive");
428 if (getLexer().isNot(AsmToken::EndOfStatement
))
429 return TokError("unexpected token in '.dump' or '.load' directive");
433 // FIXME: If/when .dump and .load are implemented they will be done in the
434 // the assembly parser and not have any need for an MCStreamer API.
436 return Warning(IDLoc
, "ignoring directive .dump for now");
438 return Warning(IDLoc
, "ignoring directive .load for now");
441 /// ParseDirectiveLinkerOption
442 /// ::= .linker_option "string" ( , "string" )*
443 bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal
, SMLoc
) {
444 SmallVector
<std::string
, 4> Args
;
446 if (getLexer().isNot(AsmToken::String
))
447 return TokError("expected string in '" + Twine(IDVal
) + "' directive");
450 if (getParser().parseEscapedString(Data
))
453 Args
.push_back(Data
);
456 if (getLexer().is(AsmToken::EndOfStatement
))
459 if (getLexer().isNot(AsmToken::Comma
))
460 return TokError("unexpected token in '" + Twine(IDVal
) + "' directive");
464 getStreamer().EmitLinkerOptions(Args
);
468 /// ParseDirectiveLsym
469 /// ::= .lsym identifier , expression
470 bool DarwinAsmParser::ParseDirectiveLsym(StringRef
, SMLoc
) {
472 if (getParser().parseIdentifier(Name
))
473 return TokError("expected identifier in directive");
475 // Handle the identifier as the key symbol.
476 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
478 if (getLexer().isNot(AsmToken::Comma
))
479 return TokError("unexpected token in '.lsym' directive");
483 if (getParser().parseExpression(Value
))
486 if (getLexer().isNot(AsmToken::EndOfStatement
))
487 return TokError("unexpected token in '.lsym' directive");
491 // We don't currently support this directive.
493 // FIXME: Diagnostic location!
495 return TokError("directive '.lsym' is unsupported");
498 /// ParseDirectiveSection:
499 /// ::= .section identifier (',' identifier)*
500 bool DarwinAsmParser::ParseDirectiveSection(StringRef
, SMLoc
) {
501 SMLoc Loc
= getLexer().getLoc();
503 StringRef SectionName
;
504 if (getParser().parseIdentifier(SectionName
))
505 return Error(Loc
, "expected identifier after '.section' directive");
507 // Verify there is a following comma.
508 if (!getLexer().is(AsmToken::Comma
))
509 return TokError("unexpected token in '.section' directive");
511 std::string SectionSpec
= SectionName
;
514 // Add all the tokens until the end of the line, ParseSectionSpecifier will
516 StringRef EOL
= getLexer().LexUntilEndOfStatement();
517 SectionSpec
.append(EOL
.begin(), EOL
.end());
520 if (getLexer().isNot(AsmToken::EndOfStatement
))
521 return TokError("unexpected token in '.section' directive");
525 StringRef Segment
, Section
;
529 std::string ErrorStr
=
530 MCSectionMachO::ParseSectionSpecifier(SectionSpec
, Segment
, Section
,
531 TAA
, TAAParsed
, StubSize
);
533 if (!ErrorStr
.empty())
534 return Error(Loc
, ErrorStr
.c_str());
536 // FIXME: Arch specific.
537 bool isText
= Segment
== "__TEXT"; // FIXME: Hack.
538 getStreamer().SwitchSection(getContext().getMachOSection(
539 Segment
, Section
, TAA
, StubSize
,
540 isText
? SectionKind::getText()
541 : SectionKind::getDataRel()));
545 /// ParseDirectivePushSection:
546 /// ::= .pushsection identifier (',' identifier)*
547 bool DarwinAsmParser::ParseDirectivePushSection(StringRef S
, SMLoc Loc
) {
548 getStreamer().PushSection();
550 if (ParseDirectiveSection(S
, Loc
)) {
551 getStreamer().PopSection();
558 /// ParseDirectivePopSection:
560 bool DarwinAsmParser::ParseDirectivePopSection(StringRef
, SMLoc
) {
561 if (!getStreamer().PopSection())
562 return TokError(".popsection without corresponding .pushsection");
566 /// ParseDirectivePrevious:
568 bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName
, SMLoc
) {
569 const MCSection
*PreviousSection
= getStreamer().getPreviousSection();
570 if (PreviousSection
== NULL
)
571 return TokError(".previous without corresponding .section");
572 getStreamer().SwitchSection(PreviousSection
);
576 /// ParseDirectiveSecureLogUnique
577 /// ::= .secure_log_unique ... message ...
578 bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef
, SMLoc IDLoc
) {
579 StringRef LogMessage
= getParser().parseStringToEndOfStatement();
580 if (getLexer().isNot(AsmToken::EndOfStatement
))
581 return TokError("unexpected token in '.secure_log_unique' directive");
583 if (getContext().getSecureLogUsed() != false)
584 return Error(IDLoc
, ".secure_log_unique specified multiple times");
586 // Get the secure log path.
587 const char *SecureLogFile
= getContext().getSecureLogFile();
588 if (SecureLogFile
== NULL
)
589 return Error(IDLoc
, ".secure_log_unique used but AS_SECURE_LOG_FILE "
590 "environment variable unset.");
592 // Open the secure log file if we haven't already.
593 raw_ostream
*OS
= getContext().getSecureLog();
596 OS
= new raw_fd_ostream(SecureLogFile
, Err
, raw_fd_ostream::F_Append
);
599 return Error(IDLoc
, Twine("can't open secure log file: ") +
600 SecureLogFile
+ " (" + Err
+ ")");
602 getContext().setSecureLog(OS
);
605 // Write the message.
606 int CurBuf
= getSourceManager().FindBufferContainingLoc(IDLoc
);
607 *OS
<< getSourceManager().getBufferInfo(CurBuf
).Buffer
->getBufferIdentifier()
608 << ":" << getSourceManager().FindLineNumber(IDLoc
, CurBuf
) << ":"
609 << LogMessage
+ "\n";
611 getContext().setSecureLogUsed(true);
616 /// ParseDirectiveSecureLogReset
617 /// ::= .secure_log_reset
618 bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef
, SMLoc IDLoc
) {
619 if (getLexer().isNot(AsmToken::EndOfStatement
))
620 return TokError("unexpected token in '.secure_log_reset' directive");
624 getContext().setSecureLogUsed(false);
629 /// ParseDirectiveSubsectionsViaSymbols
630 /// ::= .subsections_via_symbols
631 bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef
, SMLoc
) {
632 if (getLexer().isNot(AsmToken::EndOfStatement
))
633 return TokError("unexpected token in '.subsections_via_symbols' directive");
637 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols
);
642 /// ParseDirectiveTBSS
643 /// ::= .tbss identifier, size, align
644 bool DarwinAsmParser::ParseDirectiveTBSS(StringRef
, SMLoc
) {
645 SMLoc IDLoc
= getLexer().getLoc();
647 if (getParser().parseIdentifier(Name
))
648 return TokError("expected identifier in directive");
650 // Handle the identifier as the key symbol.
651 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(Name
);
653 if (getLexer().isNot(AsmToken::Comma
))
654 return TokError("unexpected token in directive");
658 SMLoc SizeLoc
= getLexer().getLoc();
659 if (getParser().parseAbsoluteExpression(Size
))
662 int64_t Pow2Alignment
= 0;
663 SMLoc Pow2AlignmentLoc
;
664 if (getLexer().is(AsmToken::Comma
)) {
666 Pow2AlignmentLoc
= getLexer().getLoc();
667 if (getParser().parseAbsoluteExpression(Pow2Alignment
))
671 if (getLexer().isNot(AsmToken::EndOfStatement
))
672 return TokError("unexpected token in '.tbss' directive");
677 return Error(SizeLoc
, "invalid '.tbss' directive size, can't be less than"
680 // FIXME: Diagnose overflow.
681 if (Pow2Alignment
< 0)
682 return Error(Pow2AlignmentLoc
, "invalid '.tbss' alignment, can't be less"
685 if (!Sym
->isUndefined())
686 return Error(IDLoc
, "invalid symbol redefinition");
688 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
689 "__DATA", "__thread_bss",
690 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL
,
691 0, SectionKind::getThreadBSS()),
692 Sym
, Size
, 1 << Pow2Alignment
);
697 /// ParseDirectiveZerofill
698 /// ::= .zerofill segname , sectname [, identifier , size_expression [
699 /// , align_expression ]]
700 bool DarwinAsmParser::ParseDirectiveZerofill(StringRef
, SMLoc
) {
702 if (getParser().parseIdentifier(Segment
))
703 return TokError("expected segment name after '.zerofill' directive");
705 if (getLexer().isNot(AsmToken::Comma
))
706 return TokError("unexpected token in directive");
710 if (getParser().parseIdentifier(Section
))
711 return TokError("expected section name after comma in '.zerofill' "
714 // If this is the end of the line all that was wanted was to create the
715 // the section but with no symbol.
716 if (getLexer().is(AsmToken::EndOfStatement
)) {
717 // Create the zerofill section but no symbol
718 getStreamer().EmitZerofill(getContext().getMachOSection(
719 Segment
, Section
, MCSectionMachO::S_ZEROFILL
,
720 0, SectionKind::getBSS()));
724 if (getLexer().isNot(AsmToken::Comma
))
725 return TokError("unexpected token in directive");
728 SMLoc IDLoc
= getLexer().getLoc();
730 if (getParser().parseIdentifier(IDStr
))
731 return TokError("expected identifier in directive");
733 // handle the identifier as the key symbol.
734 MCSymbol
*Sym
= getContext().GetOrCreateSymbol(IDStr
);
736 if (getLexer().isNot(AsmToken::Comma
))
737 return TokError("unexpected token in directive");
741 SMLoc SizeLoc
= getLexer().getLoc();
742 if (getParser().parseAbsoluteExpression(Size
))
745 int64_t Pow2Alignment
= 0;
746 SMLoc Pow2AlignmentLoc
;
747 if (getLexer().is(AsmToken::Comma
)) {
749 Pow2AlignmentLoc
= getLexer().getLoc();
750 if (getParser().parseAbsoluteExpression(Pow2Alignment
))
754 if (getLexer().isNot(AsmToken::EndOfStatement
))
755 return TokError("unexpected token in '.zerofill' directive");
760 return Error(SizeLoc
, "invalid '.zerofill' directive size, can't be less "
763 // NOTE: The alignment in the directive is a power of 2 value, the assembler
764 // may internally end up wanting an alignment in bytes.
765 // FIXME: Diagnose overflow.
766 if (Pow2Alignment
< 0)
767 return Error(Pow2AlignmentLoc
, "invalid '.zerofill' directive alignment, "
768 "can't be less than zero");
770 if (!Sym
->isUndefined())
771 return Error(IDLoc
, "invalid symbol redefinition");
773 // Create the zerofill Symbol with Size and Pow2Alignment
775 // FIXME: Arch specific.
776 getStreamer().EmitZerofill(getContext().getMachOSection(
777 Segment
, Section
, MCSectionMachO::S_ZEROFILL
,
778 0, SectionKind::getBSS()),
779 Sym
, Size
, 1 << Pow2Alignment
);
784 /// ParseDirectiveDataRegion
785 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
786 bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef
, SMLoc
) {
787 if (getLexer().is(AsmToken::EndOfStatement
)) {
789 getStreamer().EmitDataRegion(MCDR_DataRegion
);
792 StringRef RegionType
;
793 SMLoc Loc
= getParser().getTok().getLoc();
794 if (getParser().parseIdentifier(RegionType
))
795 return TokError("expected region type after '.data_region' directive");
796 int Kind
= StringSwitch
<int>(RegionType
)
797 .Case("jt8", MCDR_DataRegionJT8
)
798 .Case("jt16", MCDR_DataRegionJT16
)
799 .Case("jt32", MCDR_DataRegionJT32
)
802 return Error(Loc
, "unknown region type in '.data_region' directive");
805 getStreamer().EmitDataRegion((MCDataRegionType
)Kind
);
809 /// ParseDirectiveDataRegionEnd
810 /// ::= .end_data_region
811 bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef
, SMLoc
) {
812 if (getLexer().isNot(AsmToken::EndOfStatement
))
813 return TokError("unexpected token in '.end_data_region' directive");
816 getStreamer().EmitDataRegion(MCDR_DataRegionEnd
);
822 MCAsmParserExtension
*createDarwinAsmParser() {
823 return new DarwinAsmParser
;
826 } // end llvm namespace