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::*Handler)(StringRef, SMLoc)>
30 void AddDirectiveHandler(StringRef Directive) {
31 getParser().AddDirectiveHandler(this, Directive,
32 HandleDirective<DarwinAsmParser, Handler>);
35 bool ParseSectionSwitch(const char *Segment, const char *Section,
36 unsigned TAA = 0, unsigned ImplicitAlign = 0,
37 unsigned StubSize = 0);
42 virtual void Initialize(MCAsmParser &Parser) {
43 // Call the base implementation.
44 this->MCAsmParserExtension::Initialize(Parser);
46 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
47 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
48 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
49 ".subsections_via_symbols");
50 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
51 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
52 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
53 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection");
54 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
55 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
56 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
57 ".secure_log_unique");
58 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
60 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
61 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
63 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(".data_region");
64 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(".end_data_region");
66 // Special section directives.
67 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
68 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data");
69 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(".constructor");
70 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(".cstring");
71 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
72 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(".destructor");
73 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
74 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(".fvmlib_init0");
75 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(".fvmlib_init1");
76 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(".lazy_symbol_pointer");
77 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(".literal16");
78 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(".literal4");
79 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(".literal8");
80 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(".mod_init_func");
81 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(".mod_term_func");
82 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(".non_lazy_symbol_pointer");
83 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(".objc_cat_cls_meth");
84 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(".objc_cat_inst_meth");
85 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(".objc_category");
86 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(".objc_class");
87 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(".objc_class_names");
88 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(".objc_class_vars");
89 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(".objc_cls_meth");
90 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(".objc_cls_refs");
91 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(".objc_inst_meth");
92 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(".objc_instance_vars");
93 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(".objc_message_refs");
94 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(".objc_meta_class");
95 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(".objc_meth_var_names");
96 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(".objc_meth_var_types");
97 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(".objc_module_info");
98 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(".objc_protocol");
99 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(".objc_selector_strs");
100 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(".objc_string_object");
101 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(".objc_symbols");
102 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(".picsymbol_stub");
103 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(".static_const");
104 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(".static_data");
105 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(".symbol_stub");
106 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
107 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
108 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(".thread_init_func");
109 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
111 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
114 bool ParseDirectiveDesc(StringRef, SMLoc);
115 bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
116 bool ParseDirectiveLsym(StringRef, SMLoc);
117 bool ParseDirectiveSection(StringRef, SMLoc);
118 bool ParseDirectivePushSection(StringRef, SMLoc);
119 bool ParseDirectivePopSection(StringRef, SMLoc);
120 bool ParseDirectivePrevious(StringRef, SMLoc);
121 bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
122 bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
123 bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
124 bool ParseDirectiveTBSS(StringRef, SMLoc);
125 bool ParseDirectiveZerofill(StringRef, SMLoc);
126 bool ParseDirectiveDataRegion(StringRef, SMLoc);
127 bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
129 // Named Section Directive
130 bool ParseSectionDirectiveConst(StringRef, SMLoc) {
131 return ParseSectionSwitch("__TEXT", "__const");
133 bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
134 return ParseSectionSwitch("__TEXT", "__static_const");
136 bool ParseSectionDirectiveCString(StringRef, SMLoc) {
137 return ParseSectionSwitch("__TEXT","__cstring",
138 MCSectionMachO::S_CSTRING_LITERALS);
140 bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
141 return ParseSectionSwitch("__TEXT", "__literal4",
142 MCSectionMachO::S_4BYTE_LITERALS, 4);
144 bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
145 return ParseSectionSwitch("__TEXT", "__literal8",
146 MCSectionMachO::S_8BYTE_LITERALS, 8);
148 bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
149 return ParseSectionSwitch("__TEXT","__literal16",
150 MCSectionMachO::S_16BYTE_LITERALS, 16);
152 bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
153 return ParseSectionSwitch("__TEXT","__constructor");
155 bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
156 return ParseSectionSwitch("__TEXT","__destructor");
158 bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
159 return ParseSectionSwitch("__TEXT","__fvmlib_init0");
161 bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
162 return ParseSectionSwitch("__TEXT","__fvmlib_init1");
164 bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
165 return ParseSectionSwitch("__TEXT","__symbol_stub",
166 MCSectionMachO::S_SYMBOL_STUBS |
167 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
168 // FIXME: Different on PPC and ARM.
171 bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
172 return ParseSectionSwitch("__TEXT","__picsymbol_stub",
173 MCSectionMachO::S_SYMBOL_STUBS |
174 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
176 bool ParseSectionDirectiveData(StringRef, SMLoc) {
177 return ParseSectionSwitch("__DATA", "__data");
179 bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
180 return ParseSectionSwitch("__DATA", "__static_data");
182 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
183 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
184 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
186 bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
187 return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
188 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
190 bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
191 return ParseSectionSwitch("__DATA", "__dyld");
193 bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
194 return ParseSectionSwitch("__DATA", "__mod_init_func",
195 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
197 bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
198 return ParseSectionSwitch("__DATA", "__mod_term_func",
199 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
201 bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
202 return ParseSectionSwitch("__DATA", "__const");
204 bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
205 return ParseSectionSwitch("__OBJC", "__class",
206 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
208 bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
209 return ParseSectionSwitch("__OBJC", "__meta_class",
210 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
212 bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
213 return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
214 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
216 bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
217 return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
218 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
220 bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
221 return ParseSectionSwitch("__OBJC", "__protocol",
222 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
224 bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
225 return ParseSectionSwitch("__OBJC", "__string_object",
226 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
228 bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
229 return ParseSectionSwitch("__OBJC", "__cls_meth",
230 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
232 bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
233 return ParseSectionSwitch("__OBJC", "__inst_meth",
234 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
236 bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
237 return ParseSectionSwitch("__OBJC", "__cls_refs",
238 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
239 MCSectionMachO::S_LITERAL_POINTERS, 4);
241 bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
242 return ParseSectionSwitch("__OBJC", "__message_refs",
243 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
244 MCSectionMachO::S_LITERAL_POINTERS, 4);
246 bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
247 return ParseSectionSwitch("__OBJC", "__symbols",
248 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
250 bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
251 return ParseSectionSwitch("__OBJC", "__category",
252 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
254 bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
255 return ParseSectionSwitch("__OBJC", "__class_vars",
256 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
258 bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
259 return ParseSectionSwitch("__OBJC", "__instance_vars",
260 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
262 bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
263 return ParseSectionSwitch("__OBJC", "__module_info",
264 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
266 bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
267 return ParseSectionSwitch("__TEXT", "__cstring",
268 MCSectionMachO::S_CSTRING_LITERALS);
270 bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
271 return ParseSectionSwitch("__TEXT", "__cstring",
272 MCSectionMachO::S_CSTRING_LITERALS);
274 bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
275 return ParseSectionSwitch("__TEXT", "__cstring",
276 MCSectionMachO::S_CSTRING_LITERALS);
278 bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
279 return ParseSectionSwitch("__OBJC", "__selector_strs",
280 MCSectionMachO::S_CSTRING_LITERALS);
282 bool ParseSectionDirectiveTData(StringRef, SMLoc) {
283 return ParseSectionSwitch("__DATA", "__thread_data",
284 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
286 bool ParseSectionDirectiveText(StringRef, SMLoc) {
287 return ParseSectionSwitch("__TEXT", "__text",
288 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
290 bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
291 return ParseSectionSwitch("__DATA", "__thread_vars",
292 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
294 bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
295 // Darwin silently ignores the .ident directive.
296 getParser().EatToEndOfStatement();
299 bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
300 return ParseSectionSwitch("__DATA", "__thread_init",
301 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
306 } // end anonymous namespace
308 bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
310 unsigned TAA, unsigned Align,
312 if (getLexer().isNot(AsmToken::EndOfStatement))
313 return TokError("unexpected token in section switching directive");
316 // FIXME: Arch specific.
317 bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
318 getStreamer().SwitchSection(getContext().getMachOSection(
319 Segment, Section, TAA, StubSize,
320 isText ? SectionKind::getText()
321 : SectionKind::getDataRel()));
323 // Set the implicit alignment, if any.
325 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
326 // alignment on the section (e.g., if one manually inserts bytes into the
327 // section, then just issuing the section switch directive will not realign
328 // the section. However, this is arguably more reasonable behavior, and there
329 // is no good reason for someone to intentionally emit incorrectly sized
330 // values into the implicitly aligned sections.
332 getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
337 /// ParseDirectiveDesc
338 /// ::= .desc identifier , expression
339 bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
341 if (getParser().ParseIdentifier(Name))
342 return TokError("expected identifier in directive");
344 // Handle the identifier as the key symbol.
345 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
347 if (getLexer().isNot(AsmToken::Comma))
348 return TokError("unexpected token in '.desc' directive");
352 if (getParser().ParseAbsoluteExpression(DescValue))
355 if (getLexer().isNot(AsmToken::EndOfStatement))
356 return TokError("unexpected token in '.desc' directive");
360 // Set the n_desc field of this Symbol to this DescValue
361 getStreamer().EmitSymbolDesc(Sym, DescValue);
366 /// ParseDirectiveDumpOrLoad
367 /// ::= ( .dump | .load ) "filename"
368 bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
370 bool IsDump = Directive == ".dump";
371 if (getLexer().isNot(AsmToken::String))
372 return TokError("expected string in '.dump' or '.load' directive");
376 if (getLexer().isNot(AsmToken::EndOfStatement))
377 return TokError("unexpected token in '.dump' or '.load' directive");
381 // FIXME: If/when .dump and .load are implemented they will be done in the
382 // the assembly parser and not have any need for an MCStreamer API.
384 return Warning(IDLoc, "ignoring directive .dump for now");
386 return Warning(IDLoc, "ignoring directive .load for now");
389 /// ParseDirectiveLsym
390 /// ::= .lsym identifier , expression
391 bool DarwinAsmParser::ParseDirectiveLsym(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 '.lsym' directive");
404 if (getParser().ParseExpression(Value))
407 if (getLexer().isNot(AsmToken::EndOfStatement))
408 return TokError("unexpected token in '.lsym' directive");
412 // We don't currently support this directive.
414 // FIXME: Diagnostic location!
416 return TokError("directive '.lsym' is unsupported");
419 /// ParseDirectiveSection:
420 /// ::= .section identifier (',' identifier)*
421 bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
422 SMLoc Loc = getLexer().getLoc();
424 StringRef SectionName;
425 if (getParser().ParseIdentifier(SectionName))
426 return Error(Loc, "expected identifier after '.section' directive");
428 // Verify there is a following comma.
429 if (!getLexer().is(AsmToken::Comma))
430 return TokError("unexpected token in '.section' directive");
432 std::string SectionSpec = SectionName;
435 // Add all the tokens until the end of the line, ParseSectionSpecifier will
437 StringRef EOL = getLexer().LexUntilEndOfStatement();
438 SectionSpec.append(EOL.begin(), EOL.end());
441 if (getLexer().isNot(AsmToken::EndOfStatement))
442 return TokError("unexpected token in '.section' directive");
446 StringRef Segment, Section;
450 std::string ErrorStr =
451 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
452 TAA, TAAParsed, StubSize);
454 if (!ErrorStr.empty())
455 return Error(Loc, ErrorStr.c_str());
457 // FIXME: Arch specific.
458 bool isText = Segment == "__TEXT"; // FIXME: Hack.
459 getStreamer().SwitchSection(getContext().getMachOSection(
460 Segment, Section, TAA, StubSize,
461 isText ? SectionKind::getText()
462 : SectionKind::getDataRel()));
466 /// ParseDirectivePushSection:
467 /// ::= .pushsection identifier (',' identifier)*
468 bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
469 getStreamer().PushSection();
471 if (ParseDirectiveSection(S, Loc)) {
472 getStreamer().PopSection();
479 /// ParseDirectivePopSection:
481 bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
482 if (!getStreamer().PopSection())
483 return TokError(".popsection without corresponding .pushsection");
487 /// ParseDirectivePrevious:
489 bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
490 const MCSection *PreviousSection = getStreamer().getPreviousSection();
491 if (PreviousSection == NULL)
492 return TokError(".previous without corresponding .section");
493 getStreamer().SwitchSection(PreviousSection);
497 /// ParseDirectiveSecureLogUnique
498 /// ::= .secure_log_unique ... message ...
499 bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
500 StringRef LogMessage = getParser().ParseStringToEndOfStatement();
501 if (getLexer().isNot(AsmToken::EndOfStatement))
502 return TokError("unexpected token in '.secure_log_unique' directive");
504 if (getContext().getSecureLogUsed() != false)
505 return Error(IDLoc, ".secure_log_unique specified multiple times");
507 // Get the secure log path.
508 const char *SecureLogFile = getContext().getSecureLogFile();
509 if (SecureLogFile == NULL)
510 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
511 "environment variable unset.");
513 // Open the secure log file if we haven't already.
514 raw_ostream *OS = getContext().getSecureLog();
517 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
520 return Error(IDLoc, Twine("can't open secure log file: ") +
521 SecureLogFile + " (" + Err + ")");
523 getContext().setSecureLog(OS);
526 // Write the message.
527 int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
528 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
529 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
530 << LogMessage + "\n";
532 getContext().setSecureLogUsed(true);
537 /// ParseDirectiveSecureLogReset
538 /// ::= .secure_log_reset
539 bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
540 if (getLexer().isNot(AsmToken::EndOfStatement))
541 return TokError("unexpected token in '.secure_log_reset' directive");
545 getContext().setSecureLogUsed(false);
550 /// ParseDirectiveSubsectionsViaSymbols
551 /// ::= .subsections_via_symbols
552 bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
553 if (getLexer().isNot(AsmToken::EndOfStatement))
554 return TokError("unexpected token in '.subsections_via_symbols' directive");
558 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
563 /// ParseDirectiveTBSS
564 /// ::= .tbss identifier, size, align
565 bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
566 SMLoc IDLoc = getLexer().getLoc();
568 if (getParser().ParseIdentifier(Name))
569 return TokError("expected identifier in directive");
571 // Handle the identifier as the key symbol.
572 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
574 if (getLexer().isNot(AsmToken::Comma))
575 return TokError("unexpected token in directive");
579 SMLoc SizeLoc = getLexer().getLoc();
580 if (getParser().ParseAbsoluteExpression(Size))
583 int64_t Pow2Alignment = 0;
584 SMLoc Pow2AlignmentLoc;
585 if (getLexer().is(AsmToken::Comma)) {
587 Pow2AlignmentLoc = getLexer().getLoc();
588 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
592 if (getLexer().isNot(AsmToken::EndOfStatement))
593 return TokError("unexpected token in '.tbss' directive");
598 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
601 // FIXME: Diagnose overflow.
602 if (Pow2Alignment < 0)
603 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
606 if (!Sym->isUndefined())
607 return Error(IDLoc, "invalid symbol redefinition");
609 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
610 "__DATA", "__thread_bss",
611 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
612 0, SectionKind::getThreadBSS()),
613 Sym, Size, 1 << Pow2Alignment);
618 /// ParseDirectiveZerofill
619 /// ::= .zerofill segname , sectname [, identifier , size_expression [
620 /// , align_expression ]]
621 bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
623 if (getParser().ParseIdentifier(Segment))
624 return TokError("expected segment name after '.zerofill' directive");
626 if (getLexer().isNot(AsmToken::Comma))
627 return TokError("unexpected token in directive");
631 if (getParser().ParseIdentifier(Section))
632 return TokError("expected section name after comma in '.zerofill' "
635 // If this is the end of the line all that was wanted was to create the
636 // the section but with no symbol.
637 if (getLexer().is(AsmToken::EndOfStatement)) {
638 // Create the zerofill section but no symbol
639 getStreamer().EmitZerofill(getContext().getMachOSection(
640 Segment, Section, MCSectionMachO::S_ZEROFILL,
641 0, SectionKind::getBSS()));
645 if (getLexer().isNot(AsmToken::Comma))
646 return TokError("unexpected token in directive");
649 SMLoc IDLoc = getLexer().getLoc();
651 if (getParser().ParseIdentifier(IDStr))
652 return TokError("expected identifier in directive");
654 // handle the identifier as the key symbol.
655 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
657 if (getLexer().isNot(AsmToken::Comma))
658 return TokError("unexpected token in directive");
662 SMLoc SizeLoc = getLexer().getLoc();
663 if (getParser().ParseAbsoluteExpression(Size))
666 int64_t Pow2Alignment = 0;
667 SMLoc Pow2AlignmentLoc;
668 if (getLexer().is(AsmToken::Comma)) {
670 Pow2AlignmentLoc = getLexer().getLoc();
671 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
675 if (getLexer().isNot(AsmToken::EndOfStatement))
676 return TokError("unexpected token in '.zerofill' directive");
681 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
684 // NOTE: The alignment in the directive is a power of 2 value, the assembler
685 // may internally end up wanting an alignment in bytes.
686 // FIXME: Diagnose overflow.
687 if (Pow2Alignment < 0)
688 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
689 "can't be less than zero");
691 if (!Sym->isUndefined())
692 return Error(IDLoc, "invalid symbol redefinition");
694 // Create the zerofill Symbol with Size and Pow2Alignment
696 // FIXME: Arch specific.
697 getStreamer().EmitZerofill(getContext().getMachOSection(
698 Segment, Section, MCSectionMachO::S_ZEROFILL,
699 0, SectionKind::getBSS()),
700 Sym, Size, 1 << Pow2Alignment);
705 /// ParseDirectiveDataRegion
706 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
707 bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
708 if (getLexer().is(AsmToken::EndOfStatement)) {
710 getStreamer().EmitDataRegion(MCDR_DataRegion);
713 StringRef RegionType;
714 SMLoc Loc = getParser().getTok().getLoc();
715 if (getParser().ParseIdentifier(RegionType))
716 return TokError("expected region type after '.data_region' directive");
717 int Kind = StringSwitch<int>(RegionType)
718 .Case("jt8", MCDR_DataRegionJT8)
719 .Case("jt16", MCDR_DataRegionJT16)
720 .Case("jt32", MCDR_DataRegionJT32)
723 return Error(Loc, "unknown region type in '.data_region' directive");
726 getStreamer().EmitDataRegion((MCDataRegionType)Kind);
730 /// ParseDirectiveDataRegionEnd
731 /// ::= .end_data_region
732 bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
733 if (getLexer().isNot(AsmToken::EndOfStatement))
734 return TokError("unexpected token in '.end_data_region' directive");
737 getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
743 MCAsmParserExtension *createDarwinAsmParser() {
744 return new DarwinAsmParser;
747 } // end llvm namespace