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>(".pushsection");
55 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
56 AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
57 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
58 ".secure_log_unique");
59 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
61 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
62 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
64 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(".data_region");
65 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(".end_data_region");
67 // Special section directives.
68 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
69 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data");
70 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(".constructor");
71 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(".cstring");
72 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
73 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(".destructor");
74 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
75 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(".fvmlib_init0");
76 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(".fvmlib_init1");
77 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(".lazy_symbol_pointer");
78 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(".literal16");
79 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(".literal4");
80 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(".literal8");
81 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(".mod_init_func");
82 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(".mod_term_func");
83 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(".non_lazy_symbol_pointer");
84 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(".objc_cat_cls_meth");
85 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(".objc_cat_inst_meth");
86 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(".objc_category");
87 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(".objc_class");
88 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(".objc_class_names");
89 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(".objc_class_vars");
90 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(".objc_cls_meth");
91 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(".objc_cls_refs");
92 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(".objc_inst_meth");
93 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(".objc_instance_vars");
94 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(".objc_message_refs");
95 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(".objc_meta_class");
96 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(".objc_meth_var_names");
97 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(".objc_meth_var_types");
98 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(".objc_module_info");
99 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(".objc_protocol");
100 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(".objc_selector_strs");
101 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(".objc_string_object");
102 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(".objc_symbols");
103 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(".picsymbol_stub");
104 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(".static_const");
105 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(".static_data");
106 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(".symbol_stub");
107 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
108 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
109 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(".thread_init_func");
110 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
112 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
115 bool ParseDirectiveDesc(StringRef, SMLoc);
116 bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
117 bool ParseDirectiveLsym(StringRef, SMLoc);
118 bool ParseDirectiveSection(StringRef, SMLoc);
119 bool ParseDirectivePushSection(StringRef, SMLoc);
120 bool ParseDirectivePopSection(StringRef, SMLoc);
121 bool ParseDirectivePrevious(StringRef, SMLoc);
122 bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
123 bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
124 bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
125 bool ParseDirectiveTBSS(StringRef, SMLoc);
126 bool ParseDirectiveZerofill(StringRef, SMLoc);
127 bool ParseDirectiveDataRegion(StringRef, SMLoc);
128 bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
130 // Named Section Directive
131 bool ParseSectionDirectiveConst(StringRef, SMLoc) {
132 return ParseSectionSwitch("__TEXT", "__const");
134 bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
135 return ParseSectionSwitch("__TEXT", "__static_const");
137 bool ParseSectionDirectiveCString(StringRef, SMLoc) {
138 return ParseSectionSwitch("__TEXT","__cstring",
139 MCSectionMachO::S_CSTRING_LITERALS);
141 bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
142 return ParseSectionSwitch("__TEXT", "__literal4",
143 MCSectionMachO::S_4BYTE_LITERALS, 4);
145 bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
146 return ParseSectionSwitch("__TEXT", "__literal8",
147 MCSectionMachO::S_8BYTE_LITERALS, 8);
149 bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
150 return ParseSectionSwitch("__TEXT","__literal16",
151 MCSectionMachO::S_16BYTE_LITERALS, 16);
153 bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
154 return ParseSectionSwitch("__TEXT","__constructor");
156 bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
157 return ParseSectionSwitch("__TEXT","__destructor");
159 bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
160 return ParseSectionSwitch("__TEXT","__fvmlib_init0");
162 bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
163 return ParseSectionSwitch("__TEXT","__fvmlib_init1");
165 bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
166 return ParseSectionSwitch("__TEXT","__symbol_stub",
167 MCSectionMachO::S_SYMBOL_STUBS |
168 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
169 // FIXME: Different on PPC and ARM.
172 bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
173 return ParseSectionSwitch("__TEXT","__picsymbol_stub",
174 MCSectionMachO::S_SYMBOL_STUBS |
175 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
177 bool ParseSectionDirectiveData(StringRef, SMLoc) {
178 return ParseSectionSwitch("__DATA", "__data");
180 bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
181 return ParseSectionSwitch("__DATA", "__static_data");
183 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
184 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
185 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
187 bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
188 return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
189 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
191 bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
192 return ParseSectionSwitch("__DATA", "__dyld");
194 bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
195 return ParseSectionSwitch("__DATA", "__mod_init_func",
196 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
198 bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
199 return ParseSectionSwitch("__DATA", "__mod_term_func",
200 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
202 bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
203 return ParseSectionSwitch("__DATA", "__const");
205 bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
206 return ParseSectionSwitch("__OBJC", "__class",
207 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
209 bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
210 return ParseSectionSwitch("__OBJC", "__meta_class",
211 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
213 bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
214 return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
215 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
217 bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
218 return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
219 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
221 bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
222 return ParseSectionSwitch("__OBJC", "__protocol",
223 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
225 bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
226 return ParseSectionSwitch("__OBJC", "__string_object",
227 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
229 bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
230 return ParseSectionSwitch("__OBJC", "__cls_meth",
231 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
233 bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
234 return ParseSectionSwitch("__OBJC", "__inst_meth",
235 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
237 bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
238 return ParseSectionSwitch("__OBJC", "__cls_refs",
239 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
240 MCSectionMachO::S_LITERAL_POINTERS, 4);
242 bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
243 return ParseSectionSwitch("__OBJC", "__message_refs",
244 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
245 MCSectionMachO::S_LITERAL_POINTERS, 4);
247 bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
248 return ParseSectionSwitch("__OBJC", "__symbols",
249 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
251 bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
252 return ParseSectionSwitch("__OBJC", "__category",
253 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
255 bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
256 return ParseSectionSwitch("__OBJC", "__class_vars",
257 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
259 bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
260 return ParseSectionSwitch("__OBJC", "__instance_vars",
261 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
263 bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
264 return ParseSectionSwitch("__OBJC", "__module_info",
265 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
267 bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
268 return ParseSectionSwitch("__TEXT", "__cstring",
269 MCSectionMachO::S_CSTRING_LITERALS);
271 bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
272 return ParseSectionSwitch("__TEXT", "__cstring",
273 MCSectionMachO::S_CSTRING_LITERALS);
275 bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
276 return ParseSectionSwitch("__TEXT", "__cstring",
277 MCSectionMachO::S_CSTRING_LITERALS);
279 bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
280 return ParseSectionSwitch("__OBJC", "__selector_strs",
281 MCSectionMachO::S_CSTRING_LITERALS);
283 bool ParseSectionDirectiveTData(StringRef, SMLoc) {
284 return ParseSectionSwitch("__DATA", "__thread_data",
285 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
287 bool ParseSectionDirectiveText(StringRef, SMLoc) {
288 return ParseSectionSwitch("__TEXT", "__text",
289 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
291 bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
292 return ParseSectionSwitch("__DATA", "__thread_vars",
293 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
295 bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
296 // Darwin silently ignores the .ident directive.
297 getParser().EatToEndOfStatement();
300 bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
301 return ParseSectionSwitch("__DATA", "__thread_init",
302 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
307 } // end anonymous namespace
309 bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
311 unsigned TAA, unsigned Align,
313 if (getLexer().isNot(AsmToken::EndOfStatement))
314 return TokError("unexpected token in section switching directive");
317 // FIXME: Arch specific.
318 bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
319 getStreamer().SwitchSection(getContext().getMachOSection(
320 Segment, Section, TAA, StubSize,
321 isText ? SectionKind::getText()
322 : SectionKind::getDataRel()));
324 // Set the implicit alignment, if any.
326 // FIXME: This isn't really what 'as' does; I think it just uses the implicit
327 // alignment on the section (e.g., if one manually inserts bytes into the
328 // section, then just issuing the section switch directive will not realign
329 // the section. However, this is arguably more reasonable behavior, and there
330 // is no good reason for someone to intentionally emit incorrectly sized
331 // values into the implicitly aligned sections.
333 getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
338 /// ParseDirectiveDesc
339 /// ::= .desc identifier , expression
340 bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
342 if (getParser().ParseIdentifier(Name))
343 return TokError("expected identifier in directive");
345 // Handle the identifier as the key symbol.
346 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
348 if (getLexer().isNot(AsmToken::Comma))
349 return TokError("unexpected token in '.desc' directive");
353 if (getParser().ParseAbsoluteExpression(DescValue))
356 if (getLexer().isNot(AsmToken::EndOfStatement))
357 return TokError("unexpected token in '.desc' directive");
361 // Set the n_desc field of this Symbol to this DescValue
362 getStreamer().EmitSymbolDesc(Sym, DescValue);
367 /// ParseDirectiveDumpOrLoad
368 /// ::= ( .dump | .load ) "filename"
369 bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
371 bool IsDump = Directive == ".dump";
372 if (getLexer().isNot(AsmToken::String))
373 return TokError("expected string in '.dump' or '.load' directive");
377 if (getLexer().isNot(AsmToken::EndOfStatement))
378 return TokError("unexpected token in '.dump' or '.load' directive");
382 // FIXME: If/when .dump and .load are implemented they will be done in the
383 // the assembly parser and not have any need for an MCStreamer API.
385 return Warning(IDLoc, "ignoring directive .dump for now");
387 return Warning(IDLoc, "ignoring directive .load for now");
390 /// ParseDirectiveLsym
391 /// ::= .lsym identifier , expression
392 bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
394 if (getParser().ParseIdentifier(Name))
395 return TokError("expected identifier in directive");
397 // Handle the identifier as the key symbol.
398 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
400 if (getLexer().isNot(AsmToken::Comma))
401 return TokError("unexpected token in '.lsym' directive");
405 if (getParser().ParseExpression(Value))
408 if (getLexer().isNot(AsmToken::EndOfStatement))
409 return TokError("unexpected token in '.lsym' directive");
413 // We don't currently support this directive.
415 // FIXME: Diagnostic location!
417 return TokError("directive '.lsym' is unsupported");
420 /// ParseDirectiveSection:
421 /// ::= .section identifier (',' identifier)*
422 bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
423 SMLoc Loc = getLexer().getLoc();
425 StringRef SectionName;
426 if (getParser().ParseIdentifier(SectionName))
427 return Error(Loc, "expected identifier after '.section' directive");
429 // Verify there is a following comma.
430 if (!getLexer().is(AsmToken::Comma))
431 return TokError("unexpected token in '.section' directive");
433 std::string SectionSpec = SectionName;
436 // Add all the tokens until the end of the line, ParseSectionSpecifier will
438 StringRef EOL = getLexer().LexUntilEndOfStatement();
439 SectionSpec.append(EOL.begin(), EOL.end());
442 if (getLexer().isNot(AsmToken::EndOfStatement))
443 return TokError("unexpected token in '.section' directive");
447 StringRef Segment, Section;
451 std::string ErrorStr =
452 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
453 TAA, TAAParsed, StubSize);
455 if (!ErrorStr.empty())
456 return Error(Loc, ErrorStr.c_str());
458 // FIXME: Arch specific.
459 bool isText = Segment == "__TEXT"; // FIXME: Hack.
460 getStreamer().SwitchSection(getContext().getMachOSection(
461 Segment, Section, TAA, StubSize,
462 isText ? SectionKind::getText()
463 : SectionKind::getDataRel()));
467 /// ParseDirectivePushSection:
468 /// ::= .pushsection identifier (',' identifier)*
469 bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
470 getStreamer().PushSection();
472 if (ParseDirectiveSection(S, Loc)) {
473 getStreamer().PopSection();
480 /// ParseDirectivePopSection:
482 bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
483 if (!getStreamer().PopSection())
484 return TokError(".popsection without corresponding .pushsection");
488 /// ParseDirectivePrevious:
490 bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
491 const MCSection *PreviousSection = getStreamer().getPreviousSection();
492 if (PreviousSection == NULL)
493 return TokError(".previous without corresponding .section");
494 getStreamer().SwitchSection(PreviousSection);
498 /// ParseDirectiveSecureLogUnique
499 /// ::= .secure_log_unique ... message ...
500 bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
501 StringRef LogMessage = getParser().ParseStringToEndOfStatement();
502 if (getLexer().isNot(AsmToken::EndOfStatement))
503 return TokError("unexpected token in '.secure_log_unique' directive");
505 if (getContext().getSecureLogUsed() != false)
506 return Error(IDLoc, ".secure_log_unique specified multiple times");
508 // Get the secure log path.
509 const char *SecureLogFile = getContext().getSecureLogFile();
510 if (SecureLogFile == NULL)
511 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
512 "environment variable unset.");
514 // Open the secure log file if we haven't already.
515 raw_ostream *OS = getContext().getSecureLog();
518 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
521 return Error(IDLoc, Twine("can't open secure log file: ") +
522 SecureLogFile + " (" + Err + ")");
524 getContext().setSecureLog(OS);
527 // Write the message.
528 int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
529 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
530 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
531 << LogMessage + "\n";
533 getContext().setSecureLogUsed(true);
538 /// ParseDirectiveSecureLogReset
539 /// ::= .secure_log_reset
540 bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
541 if (getLexer().isNot(AsmToken::EndOfStatement))
542 return TokError("unexpected token in '.secure_log_reset' directive");
546 getContext().setSecureLogUsed(false);
551 /// ParseDirectiveSubsectionsViaSymbols
552 /// ::= .subsections_via_symbols
553 bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
554 if (getLexer().isNot(AsmToken::EndOfStatement))
555 return TokError("unexpected token in '.subsections_via_symbols' directive");
559 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
564 /// ParseDirectiveTBSS
565 /// ::= .tbss identifier, size, align
566 bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
567 SMLoc IDLoc = getLexer().getLoc();
569 if (getParser().ParseIdentifier(Name))
570 return TokError("expected identifier in directive");
572 // Handle the identifier as the key symbol.
573 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
575 if (getLexer().isNot(AsmToken::Comma))
576 return TokError("unexpected token in directive");
580 SMLoc SizeLoc = getLexer().getLoc();
581 if (getParser().ParseAbsoluteExpression(Size))
584 int64_t Pow2Alignment = 0;
585 SMLoc Pow2AlignmentLoc;
586 if (getLexer().is(AsmToken::Comma)) {
588 Pow2AlignmentLoc = getLexer().getLoc();
589 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
593 if (getLexer().isNot(AsmToken::EndOfStatement))
594 return TokError("unexpected token in '.tbss' directive");
599 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
602 // FIXME: Diagnose overflow.
603 if (Pow2Alignment < 0)
604 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
607 if (!Sym->isUndefined())
608 return Error(IDLoc, "invalid symbol redefinition");
610 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
611 "__DATA", "__thread_bss",
612 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
613 0, SectionKind::getThreadBSS()),
614 Sym, Size, 1 << Pow2Alignment);
619 /// ParseDirectiveZerofill
620 /// ::= .zerofill segname , sectname [, identifier , size_expression [
621 /// , align_expression ]]
622 bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
624 if (getParser().ParseIdentifier(Segment))
625 return TokError("expected segment name after '.zerofill' directive");
627 if (getLexer().isNot(AsmToken::Comma))
628 return TokError("unexpected token in directive");
632 if (getParser().ParseIdentifier(Section))
633 return TokError("expected section name after comma in '.zerofill' "
636 // If this is the end of the line all that was wanted was to create the
637 // the section but with no symbol.
638 if (getLexer().is(AsmToken::EndOfStatement)) {
639 // Create the zerofill section but no symbol
640 getStreamer().EmitZerofill(getContext().getMachOSection(
641 Segment, Section, MCSectionMachO::S_ZEROFILL,
642 0, SectionKind::getBSS()));
646 if (getLexer().isNot(AsmToken::Comma))
647 return TokError("unexpected token in directive");
650 SMLoc IDLoc = getLexer().getLoc();
652 if (getParser().ParseIdentifier(IDStr))
653 return TokError("expected identifier in directive");
655 // handle the identifier as the key symbol.
656 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
658 if (getLexer().isNot(AsmToken::Comma))
659 return TokError("unexpected token in directive");
663 SMLoc SizeLoc = getLexer().getLoc();
664 if (getParser().ParseAbsoluteExpression(Size))
667 int64_t Pow2Alignment = 0;
668 SMLoc Pow2AlignmentLoc;
669 if (getLexer().is(AsmToken::Comma)) {
671 Pow2AlignmentLoc = getLexer().getLoc();
672 if (getParser().ParseAbsoluteExpression(Pow2Alignment))
676 if (getLexer().isNot(AsmToken::EndOfStatement))
677 return TokError("unexpected token in '.zerofill' directive");
682 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
685 // NOTE: The alignment in the directive is a power of 2 value, the assembler
686 // may internally end up wanting an alignment in bytes.
687 // FIXME: Diagnose overflow.
688 if (Pow2Alignment < 0)
689 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
690 "can't be less than zero");
692 if (!Sym->isUndefined())
693 return Error(IDLoc, "invalid symbol redefinition");
695 // Create the zerofill Symbol with Size and Pow2Alignment
697 // FIXME: Arch specific.
698 getStreamer().EmitZerofill(getContext().getMachOSection(
699 Segment, Section, MCSectionMachO::S_ZEROFILL,
700 0, SectionKind::getBSS()),
701 Sym, Size, 1 << Pow2Alignment);
706 /// ParseDirectiveDataRegion
707 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
708 bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
709 if (getLexer().is(AsmToken::EndOfStatement)) {
711 getStreamer().EmitDataRegion(MCDR_DataRegion);
714 StringRef RegionType;
715 SMLoc Loc = getParser().getTok().getLoc();
716 if (getParser().ParseIdentifier(RegionType))
717 return TokError("expected region type after '.data_region' directive");
718 int Kind = StringSwitch<int>(RegionType)
719 .Case("jt8", MCDR_DataRegionJT8)
720 .Case("jt16", MCDR_DataRegionJT16)
721 .Case("jt32", MCDR_DataRegionJT32)
724 return Error(Loc, "unknown region type in '.data_region' directive");
727 getStreamer().EmitDataRegion((MCDataRegionType)Kind);
731 /// ParseDirectiveDataRegionEnd
732 /// ::= .end_data_region
733 bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
734 if (getLexer().isNot(AsmToken::EndOfStatement))
735 return TokError("unexpected token in '.end_data_region' directive");
738 getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
744 MCAsmParserExtension *createDarwinAsmParser() {
745 return new DarwinAsmParser;
748 } // end llvm namespace