]> git.proxmox.com Git - rustc.git/blob - src/llvm/lib/MC/MCParser/DarwinAsmParser.cpp
Imported Upstream version 0.7
[rustc.git] / src / llvm / lib / MC / MCParser / DarwinAsmParser.cpp
1 //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
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"
22 using namespace llvm;
23
24 namespace {
25
26 /// \brief Implementation of directive handling which is shared across all
27 /// Darwin targets.
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);
34 }
35
36 bool ParseSectionSwitch(const char *Segment, const char *Section,
37 unsigned TAA = 0, unsigned ImplicitAlign = 0,
38 unsigned StubSize = 0);
39
40 public:
41 DarwinAsmParser() {}
42
43 virtual void Initialize(MCAsmParser &Parser) {
44 // Call the base implementation.
45 this->MCAsmParserExtension::Initialize(Parser);
46
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>(
55 ".pushsection");
56 addDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(
57 ".popsection");
58 addDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
59 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
60 ".secure_log_unique");
61 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
62 ".secure_log_reset");
63 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
64 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
65
66 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(
67 ".data_region");
68 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(
69 ".end_data_region");
70
71 // Special section directives.
72 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
73 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
74 ".const_data");
75 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(
76 ".constructor");
77 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(
78 ".cstring");
79 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
80 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(
81 ".destructor");
82 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
83 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(
84 ".fvmlib_init0");
85 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(
86 ".fvmlib_init1");
87 addDirectiveHandler<
88 &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(
89 ".lazy_symbol_pointer");
90 addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>(
91 ".linker_option");
92 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(
93 ".literal16");
94 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(
95 ".literal4");
96 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(
97 ".literal8");
98 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(
99 ".mod_init_func");
100 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(
101 ".mod_term_func");
102 addDirectiveHandler<
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>(
110 ".objc_category");
111 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(
112 ".objc_class");
113 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(
114 ".objc_class_names");
115 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(
116 ".objc_class_vars");
117 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(
118 ".objc_cls_meth");
119 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(
120 ".objc_cls_refs");
121 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(
122 ".objc_inst_meth");
123 addDirectiveHandler<
124 &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(
125 ".objc_instance_vars");
126 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(
127 ".objc_message_refs");
128 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(
129 ".objc_meta_class");
130 addDirectiveHandler<
131 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(
132 ".objc_meth_var_names");
133 addDirectiveHandler<
134 &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(
135 ".objc_meth_var_types");
136 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(
137 ".objc_module_info");
138 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(
139 ".objc_protocol");
140 addDirectiveHandler<
141 &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(
142 ".objc_selector_strs");
143 addDirectiveHandler<
144 &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(
145 ".objc_string_object");
146 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(
147 ".objc_symbols");
148 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(
149 ".picsymbol_stub");
150 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(
151 ".static_const");
152 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(
153 ".static_data");
154 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(
155 ".symbol_stub");
156 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
157 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
158 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(
159 ".thread_init_func");
160 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
161
162 addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
163 }
164
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);
180
181 // Named Section Directive
182 bool ParseSectionDirectiveConst(StringRef, SMLoc) {
183 return ParseSectionSwitch("__TEXT", "__const");
184 }
185 bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
186 return ParseSectionSwitch("__TEXT", "__static_const");
187 }
188 bool ParseSectionDirectiveCString(StringRef, SMLoc) {
189 return ParseSectionSwitch("__TEXT","__cstring",
190 MCSectionMachO::S_CSTRING_LITERALS);
191 }
192 bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
193 return ParseSectionSwitch("__TEXT", "__literal4",
194 MCSectionMachO::S_4BYTE_LITERALS, 4);
195 }
196 bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
197 return ParseSectionSwitch("__TEXT", "__literal8",
198 MCSectionMachO::S_8BYTE_LITERALS, 8);
199 }
200 bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
201 return ParseSectionSwitch("__TEXT","__literal16",
202 MCSectionMachO::S_16BYTE_LITERALS, 16);
203 }
204 bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
205 return ParseSectionSwitch("__TEXT","__constructor");
206 }
207 bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
208 return ParseSectionSwitch("__TEXT","__destructor");
209 }
210 bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
211 return ParseSectionSwitch("__TEXT","__fvmlib_init0");
212 }
213 bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
214 return ParseSectionSwitch("__TEXT","__fvmlib_init1");
215 }
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.
221 0, 16);
222 }
223 bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
224 return ParseSectionSwitch("__TEXT","__picsymbol_stub",
225 MCSectionMachO::S_SYMBOL_STUBS |
226 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
227 }
228 bool ParseSectionDirectiveData(StringRef, SMLoc) {
229 return ParseSectionSwitch("__DATA", "__data");
230 }
231 bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
232 return ParseSectionSwitch("__DATA", "__static_data");
233 }
234 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
235 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
236 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
237 }
238 bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
239 return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
240 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
241 }
242 bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
243 return ParseSectionSwitch("__DATA", "__dyld");
244 }
245 bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
246 return ParseSectionSwitch("__DATA", "__mod_init_func",
247 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
248 }
249 bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
250 return ParseSectionSwitch("__DATA", "__mod_term_func",
251 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
252 }
253 bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
254 return ParseSectionSwitch("__DATA", "__const");
255 }
256 bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
257 return ParseSectionSwitch("__OBJC", "__class",
258 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
259 }
260 bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
261 return ParseSectionSwitch("__OBJC", "__meta_class",
262 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
263 }
264 bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
265 return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
266 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
267 }
268 bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
269 return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
270 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
271 }
272 bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
273 return ParseSectionSwitch("__OBJC", "__protocol",
274 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
275 }
276 bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
277 return ParseSectionSwitch("__OBJC", "__string_object",
278 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
279 }
280 bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
281 return ParseSectionSwitch("__OBJC", "__cls_meth",
282 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
283 }
284 bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
285 return ParseSectionSwitch("__OBJC", "__inst_meth",
286 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
287 }
288 bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
289 return ParseSectionSwitch("__OBJC", "__cls_refs",
290 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
291 MCSectionMachO::S_LITERAL_POINTERS, 4);
292 }
293 bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
294 return ParseSectionSwitch("__OBJC", "__message_refs",
295 MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
296 MCSectionMachO::S_LITERAL_POINTERS, 4);
297 }
298 bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
299 return ParseSectionSwitch("__OBJC", "__symbols",
300 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
301 }
302 bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
303 return ParseSectionSwitch("__OBJC", "__category",
304 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
305 }
306 bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
307 return ParseSectionSwitch("__OBJC", "__class_vars",
308 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
309 }
310 bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
311 return ParseSectionSwitch("__OBJC", "__instance_vars",
312 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
313 }
314 bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
315 return ParseSectionSwitch("__OBJC", "__module_info",
316 MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
317 }
318 bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
319 return ParseSectionSwitch("__TEXT", "__cstring",
320 MCSectionMachO::S_CSTRING_LITERALS);
321 }
322 bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
323 return ParseSectionSwitch("__TEXT", "__cstring",
324 MCSectionMachO::S_CSTRING_LITERALS);
325 }
326 bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
327 return ParseSectionSwitch("__TEXT", "__cstring",
328 MCSectionMachO::S_CSTRING_LITERALS);
329 }
330 bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
331 return ParseSectionSwitch("__OBJC", "__selector_strs",
332 MCSectionMachO::S_CSTRING_LITERALS);
333 }
334 bool ParseSectionDirectiveTData(StringRef, SMLoc) {
335 return ParseSectionSwitch("__DATA", "__thread_data",
336 MCSectionMachO::S_THREAD_LOCAL_REGULAR);
337 }
338 bool ParseSectionDirectiveText(StringRef, SMLoc) {
339 return ParseSectionSwitch("__TEXT", "__text",
340 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
341 }
342 bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
343 return ParseSectionSwitch("__DATA", "__thread_vars",
344 MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
345 }
346 bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
347 // Darwin silently ignores the .ident directive.
348 getParser().eatToEndOfStatement();
349 return false;
350 }
351 bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
352 return ParseSectionSwitch("__DATA", "__thread_init",
353 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
354 }
355
356 };
357
358 } // end anonymous namespace
359
360 bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
361 const char *Section,
362 unsigned TAA, unsigned Align,
363 unsigned StubSize) {
364 if (getLexer().isNot(AsmToken::EndOfStatement))
365 return TokError("unexpected token in section switching directive");
366 Lex();
367
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()));
374
375 // Set the implicit alignment, if any.
376 //
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.
383 if (Align)
384 getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
385
386 return false;
387 }
388
389 /// ParseDirectiveDesc
390 /// ::= .desc identifier , expression
391 bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
392 StringRef Name;
393 if (getParser().parseIdentifier(Name))
394 return TokError("expected identifier in directive");
395
396 // Handle the identifier as the key symbol.
397 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
398
399 if (getLexer().isNot(AsmToken::Comma))
400 return TokError("unexpected token in '.desc' directive");
401 Lex();
402
403 int64_t DescValue;
404 if (getParser().parseAbsoluteExpression(DescValue))
405 return true;
406
407 if (getLexer().isNot(AsmToken::EndOfStatement))
408 return TokError("unexpected token in '.desc' directive");
409
410 Lex();
411
412 // Set the n_desc field of this Symbol to this DescValue
413 getStreamer().EmitSymbolDesc(Sym, DescValue);
414
415 return false;
416 }
417
418 /// ParseDirectiveDumpOrLoad
419 /// ::= ( .dump | .load ) "filename"
420 bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
421 SMLoc IDLoc) {
422 bool IsDump = Directive == ".dump";
423 if (getLexer().isNot(AsmToken::String))
424 return TokError("expected string in '.dump' or '.load' directive");
425
426 Lex();
427
428 if (getLexer().isNot(AsmToken::EndOfStatement))
429 return TokError("unexpected token in '.dump' or '.load' directive");
430
431 Lex();
432
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.
435 if (IsDump)
436 return Warning(IDLoc, "ignoring directive .dump for now");
437 else
438 return Warning(IDLoc, "ignoring directive .load for now");
439 }
440
441 /// ParseDirectiveLinkerOption
442 /// ::= .linker_option "string" ( , "string" )*
443 bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
444 SmallVector<std::string, 4> Args;
445 for (;;) {
446 if (getLexer().isNot(AsmToken::String))
447 return TokError("expected string in '" + Twine(IDVal) + "' directive");
448
449 std::string Data;
450 if (getParser().parseEscapedString(Data))
451 return true;
452
453 Args.push_back(Data);
454
455 Lex();
456 if (getLexer().is(AsmToken::EndOfStatement))
457 break;
458
459 if (getLexer().isNot(AsmToken::Comma))
460 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
461 Lex();
462 }
463
464 getStreamer().EmitLinkerOptions(Args);
465 return false;
466 }
467
468 /// ParseDirectiveLsym
469 /// ::= .lsym identifier , expression
470 bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
471 StringRef Name;
472 if (getParser().parseIdentifier(Name))
473 return TokError("expected identifier in directive");
474
475 // Handle the identifier as the key symbol.
476 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
477
478 if (getLexer().isNot(AsmToken::Comma))
479 return TokError("unexpected token in '.lsym' directive");
480 Lex();
481
482 const MCExpr *Value;
483 if (getParser().parseExpression(Value))
484 return true;
485
486 if (getLexer().isNot(AsmToken::EndOfStatement))
487 return TokError("unexpected token in '.lsym' directive");
488
489 Lex();
490
491 // We don't currently support this directive.
492 //
493 // FIXME: Diagnostic location!
494 (void) Sym;
495 return TokError("directive '.lsym' is unsupported");
496 }
497
498 /// ParseDirectiveSection:
499 /// ::= .section identifier (',' identifier)*
500 bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
501 SMLoc Loc = getLexer().getLoc();
502
503 StringRef SectionName;
504 if (getParser().parseIdentifier(SectionName))
505 return Error(Loc, "expected identifier after '.section' directive");
506
507 // Verify there is a following comma.
508 if (!getLexer().is(AsmToken::Comma))
509 return TokError("unexpected token in '.section' directive");
510
511 std::string SectionSpec = SectionName;
512 SectionSpec += ",";
513
514 // Add all the tokens until the end of the line, ParseSectionSpecifier will
515 // handle this.
516 StringRef EOL = getLexer().LexUntilEndOfStatement();
517 SectionSpec.append(EOL.begin(), EOL.end());
518
519 Lex();
520 if (getLexer().isNot(AsmToken::EndOfStatement))
521 return TokError("unexpected token in '.section' directive");
522 Lex();
523
524
525 StringRef Segment, Section;
526 unsigned StubSize;
527 unsigned TAA;
528 bool TAAParsed;
529 std::string ErrorStr =
530 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
531 TAA, TAAParsed, StubSize);
532
533 if (!ErrorStr.empty())
534 return Error(Loc, ErrorStr.c_str());
535
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()));
542 return false;
543 }
544
545 /// ParseDirectivePushSection:
546 /// ::= .pushsection identifier (',' identifier)*
547 bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
548 getStreamer().PushSection();
549
550 if (ParseDirectiveSection(S, Loc)) {
551 getStreamer().PopSection();
552 return true;
553 }
554
555 return false;
556 }
557
558 /// ParseDirectivePopSection:
559 /// ::= .popsection
560 bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
561 if (!getStreamer().PopSection())
562 return TokError(".popsection without corresponding .pushsection");
563 return false;
564 }
565
566 /// ParseDirectivePrevious:
567 /// ::= .previous
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);
573 return false;
574 }
575
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");
582
583 if (getContext().getSecureLogUsed() != false)
584 return Error(IDLoc, ".secure_log_unique specified multiple times");
585
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.");
591
592 // Open the secure log file if we haven't already.
593 raw_ostream *OS = getContext().getSecureLog();
594 if (OS == NULL) {
595 std::string Err;
596 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
597 if (!Err.empty()) {
598 delete OS;
599 return Error(IDLoc, Twine("can't open secure log file: ") +
600 SecureLogFile + " (" + Err + ")");
601 }
602 getContext().setSecureLog(OS);
603 }
604
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";
610
611 getContext().setSecureLogUsed(true);
612
613 return false;
614 }
615
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");
621
622 Lex();
623
624 getContext().setSecureLogUsed(false);
625
626 return false;
627 }
628
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");
634
635 Lex();
636
637 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
638
639 return false;
640 }
641
642 /// ParseDirectiveTBSS
643 /// ::= .tbss identifier, size, align
644 bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
645 SMLoc IDLoc = getLexer().getLoc();
646 StringRef Name;
647 if (getParser().parseIdentifier(Name))
648 return TokError("expected identifier in directive");
649
650 // Handle the identifier as the key symbol.
651 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
652
653 if (getLexer().isNot(AsmToken::Comma))
654 return TokError("unexpected token in directive");
655 Lex();
656
657 int64_t Size;
658 SMLoc SizeLoc = getLexer().getLoc();
659 if (getParser().parseAbsoluteExpression(Size))
660 return true;
661
662 int64_t Pow2Alignment = 0;
663 SMLoc Pow2AlignmentLoc;
664 if (getLexer().is(AsmToken::Comma)) {
665 Lex();
666 Pow2AlignmentLoc = getLexer().getLoc();
667 if (getParser().parseAbsoluteExpression(Pow2Alignment))
668 return true;
669 }
670
671 if (getLexer().isNot(AsmToken::EndOfStatement))
672 return TokError("unexpected token in '.tbss' directive");
673
674 Lex();
675
676 if (Size < 0)
677 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
678 "zero");
679
680 // FIXME: Diagnose overflow.
681 if (Pow2Alignment < 0)
682 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
683 "than zero");
684
685 if (!Sym->isUndefined())
686 return Error(IDLoc, "invalid symbol redefinition");
687
688 getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
689 "__DATA", "__thread_bss",
690 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
691 0, SectionKind::getThreadBSS()),
692 Sym, Size, 1 << Pow2Alignment);
693
694 return false;
695 }
696
697 /// ParseDirectiveZerofill
698 /// ::= .zerofill segname , sectname [, identifier , size_expression [
699 /// , align_expression ]]
700 bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
701 StringRef Segment;
702 if (getParser().parseIdentifier(Segment))
703 return TokError("expected segment name after '.zerofill' directive");
704
705 if (getLexer().isNot(AsmToken::Comma))
706 return TokError("unexpected token in directive");
707 Lex();
708
709 StringRef Section;
710 if (getParser().parseIdentifier(Section))
711 return TokError("expected section name after comma in '.zerofill' "
712 "directive");
713
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()));
721 return false;
722 }
723
724 if (getLexer().isNot(AsmToken::Comma))
725 return TokError("unexpected token in directive");
726 Lex();
727
728 SMLoc IDLoc = getLexer().getLoc();
729 StringRef IDStr;
730 if (getParser().parseIdentifier(IDStr))
731 return TokError("expected identifier in directive");
732
733 // handle the identifier as the key symbol.
734 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
735
736 if (getLexer().isNot(AsmToken::Comma))
737 return TokError("unexpected token in directive");
738 Lex();
739
740 int64_t Size;
741 SMLoc SizeLoc = getLexer().getLoc();
742 if (getParser().parseAbsoluteExpression(Size))
743 return true;
744
745 int64_t Pow2Alignment = 0;
746 SMLoc Pow2AlignmentLoc;
747 if (getLexer().is(AsmToken::Comma)) {
748 Lex();
749 Pow2AlignmentLoc = getLexer().getLoc();
750 if (getParser().parseAbsoluteExpression(Pow2Alignment))
751 return true;
752 }
753
754 if (getLexer().isNot(AsmToken::EndOfStatement))
755 return TokError("unexpected token in '.zerofill' directive");
756
757 Lex();
758
759 if (Size < 0)
760 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
761 "than zero");
762
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");
769
770 if (!Sym->isUndefined())
771 return Error(IDLoc, "invalid symbol redefinition");
772
773 // Create the zerofill Symbol with Size and Pow2Alignment
774 //
775 // FIXME: Arch specific.
776 getStreamer().EmitZerofill(getContext().getMachOSection(
777 Segment, Section, MCSectionMachO::S_ZEROFILL,
778 0, SectionKind::getBSS()),
779 Sym, Size, 1 << Pow2Alignment);
780
781 return false;
782 }
783
784 /// ParseDirectiveDataRegion
785 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
786 bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
787 if (getLexer().is(AsmToken::EndOfStatement)) {
788 Lex();
789 getStreamer().EmitDataRegion(MCDR_DataRegion);
790 return false;
791 }
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)
800 .Default(-1);
801 if (Kind == -1)
802 return Error(Loc, "unknown region type in '.data_region' directive");
803 Lex();
804
805 getStreamer().EmitDataRegion((MCDataRegionType)Kind);
806 return false;
807 }
808
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");
814
815 Lex();
816 getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
817 return false;
818 }
819
820 namespace llvm {
821
822 MCAsmParserExtension *createDarwinAsmParser() {
823 return new DarwinAsmParser;
824 }
825
826 } // end llvm namespace