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