LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DarwinAsmParser.cpp
Go to the documentation of this file.
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 
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/ADT/StringSwitch.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCSectionMachO.h"
18 #include "llvm/MC/MCStreamer.h"
19 #include "llvm/MC/MCSymbol.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.
46 
47  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
48  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>(
49  ".indirect_symbol");
50  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
51  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
52  ".subsections_via_symbols");
53  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
54  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
55  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
56  addDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(
57  ".pushsection");
58  addDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(
59  ".popsection");
60  addDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
61  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
62  ".secure_log_unique");
63  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
64  ".secure_log_reset");
65  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
66  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
67 
68  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(
69  ".data_region");
70  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(
71  ".end_data_region");
72 
73  // Special section directives.
74  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveBss>(".bss");
75  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
76  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
77  ".const_data");
78  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(
79  ".constructor");
80  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(
81  ".cstring");
82  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
83  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(
84  ".destructor");
85  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
86  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(
87  ".fvmlib_init0");
88  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(
89  ".fvmlib_init1");
90  addDirectiveHandler<
91  &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(
92  ".lazy_symbol_pointer");
93  addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>(
94  ".linker_option");
95  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(
96  ".literal16");
97  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(
98  ".literal4");
99  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(
100  ".literal8");
101  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(
102  ".mod_init_func");
103  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(
104  ".mod_term_func");
105  addDirectiveHandler<
106  &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(
107  ".non_lazy_symbol_pointer");
108  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(
109  ".objc_cat_cls_meth");
110  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(
111  ".objc_cat_inst_meth");
112  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(
113  ".objc_category");
114  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(
115  ".objc_class");
116  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(
117  ".objc_class_names");
118  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(
119  ".objc_class_vars");
120  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(
121  ".objc_cls_meth");
122  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(
123  ".objc_cls_refs");
124  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(
125  ".objc_inst_meth");
126  addDirectiveHandler<
127  &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(
128  ".objc_instance_vars");
129  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(
130  ".objc_message_refs");
131  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(
132  ".objc_meta_class");
133  addDirectiveHandler<
134  &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(
135  ".objc_meth_var_names");
136  addDirectiveHandler<
137  &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(
138  ".objc_meth_var_types");
139  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(
140  ".objc_module_info");
141  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(
142  ".objc_protocol");
143  addDirectiveHandler<
144  &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(
145  ".objc_selector_strs");
146  addDirectiveHandler<
147  &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(
148  ".objc_string_object");
149  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(
150  ".objc_symbols");
151  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(
152  ".picsymbol_stub");
153  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(
154  ".static_const");
155  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(
156  ".static_data");
157  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(
158  ".symbol_stub");
159  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
160  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
161  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(
162  ".thread_init_func");
163  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
164 
165  addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
166  }
167 
168  bool ParseDirectiveDesc(StringRef, SMLoc);
169  bool ParseDirectiveIndirectSymbol(StringRef, SMLoc);
170  bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
171  bool ParseDirectiveLsym(StringRef, SMLoc);
172  bool ParseDirectiveLinkerOption(StringRef, SMLoc);
173  bool ParseDirectiveSection(StringRef, SMLoc);
174  bool ParseDirectivePushSection(StringRef, SMLoc);
175  bool ParseDirectivePopSection(StringRef, SMLoc);
176  bool ParseDirectivePrevious(StringRef, SMLoc);
177  bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
178  bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
179  bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
180  bool ParseDirectiveTBSS(StringRef, SMLoc);
181  bool ParseDirectiveZerofill(StringRef, SMLoc);
182  bool ParseDirectiveDataRegion(StringRef, SMLoc);
183  bool ParseDirectiveDataRegionEnd(StringRef, SMLoc);
184 
185  // Named Section Directive
186  bool ParseSectionDirectiveBss(StringRef, SMLoc) {
187  return ParseSectionSwitch("__DATA", "__bss");
188  }
189 
190  bool ParseSectionDirectiveConst(StringRef, SMLoc) {
191  return ParseSectionSwitch("__TEXT", "__const");
192  }
193  bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
194  return ParseSectionSwitch("__TEXT", "__static_const");
195  }
196  bool ParseSectionDirectiveCString(StringRef, SMLoc) {
197  return ParseSectionSwitch("__TEXT","__cstring",
199  }
200  bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
201  return ParseSectionSwitch("__TEXT", "__literal4",
203  }
204  bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
205  return ParseSectionSwitch("__TEXT", "__literal8",
207  }
208  bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
209  return ParseSectionSwitch("__TEXT","__literal16",
211  }
212  bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
213  return ParseSectionSwitch("__TEXT","__constructor");
214  }
215  bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
216  return ParseSectionSwitch("__TEXT","__destructor");
217  }
218  bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
219  return ParseSectionSwitch("__TEXT","__fvmlib_init0");
220  }
221  bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
222  return ParseSectionSwitch("__TEXT","__fvmlib_init1");
223  }
224  bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
225  return ParseSectionSwitch("__TEXT","__symbol_stub",
227  MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
228  // FIXME: Different on PPC and ARM.
229  0, 16);
230  }
231  bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
232  return ParseSectionSwitch("__TEXT","__picsymbol_stub",
234  MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
235  }
236  bool ParseSectionDirectiveData(StringRef, SMLoc) {
237  return ParseSectionSwitch("__DATA", "__data");
238  }
239  bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
240  return ParseSectionSwitch("__DATA", "__static_data");
241  }
242  bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
243  return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
245  }
246  bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
247  return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
249  }
250  bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
251  return ParseSectionSwitch("__DATA", "__dyld");
252  }
253  bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
254  return ParseSectionSwitch("__DATA", "__mod_init_func",
256  }
257  bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
258  return ParseSectionSwitch("__DATA", "__mod_term_func",
260  }
261  bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
262  return ParseSectionSwitch("__DATA", "__const");
263  }
264  bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
265  return ParseSectionSwitch("__OBJC", "__class",
266  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
267  }
268  bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
269  return ParseSectionSwitch("__OBJC", "__meta_class",
270  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
271  }
272  bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
273  return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
274  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
275  }
276  bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
277  return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
278  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
279  }
280  bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
281  return ParseSectionSwitch("__OBJC", "__protocol",
282  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
283  }
284  bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
285  return ParseSectionSwitch("__OBJC", "__string_object",
286  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
287  }
288  bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
289  return ParseSectionSwitch("__OBJC", "__cls_meth",
290  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
291  }
292  bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
293  return ParseSectionSwitch("__OBJC", "__inst_meth",
294  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
295  }
296  bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
297  return ParseSectionSwitch("__OBJC", "__cls_refs",
298  MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
300  }
301  bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
302  return ParseSectionSwitch("__OBJC", "__message_refs",
303  MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
305  }
306  bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
307  return ParseSectionSwitch("__OBJC", "__symbols",
308  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
309  }
310  bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
311  return ParseSectionSwitch("__OBJC", "__category",
312  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
313  }
314  bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
315  return ParseSectionSwitch("__OBJC", "__class_vars",
316  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
317  }
318  bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
319  return ParseSectionSwitch("__OBJC", "__instance_vars",
320  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
321  }
322  bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
323  return ParseSectionSwitch("__OBJC", "__module_info",
324  MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
325  }
326  bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
327  return ParseSectionSwitch("__TEXT", "__cstring",
329  }
330  bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
331  return ParseSectionSwitch("__TEXT", "__cstring",
333  }
334  bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
335  return ParseSectionSwitch("__TEXT", "__cstring",
337  }
338  bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
339  return ParseSectionSwitch("__OBJC", "__selector_strs",
341  }
342  bool ParseSectionDirectiveTData(StringRef, SMLoc) {
343  return ParseSectionSwitch("__DATA", "__thread_data",
345  }
346  bool ParseSectionDirectiveText(StringRef, SMLoc) {
347  return ParseSectionSwitch("__TEXT", "__text",
348  MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
349  }
350  bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
351  return ParseSectionSwitch("__DATA", "__thread_vars",
353  }
354  bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
355  // Darwin silently ignores the .ident directive.
356  getParser().eatToEndOfStatement();
357  return false;
358  }
359  bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
360  return ParseSectionSwitch("__DATA", "__thread_init",
362  }
363 
364 };
365 
366 } // end anonymous namespace
367 
368 bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
369  const char *Section,
370  unsigned TAA, unsigned Align,
371  unsigned StubSize) {
372  if (getLexer().isNot(AsmToken::EndOfStatement))
373  return TokError("unexpected token in section switching directive");
374  Lex();
375 
376  // FIXME: Arch specific.
377  bool isText = TAA & MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS;
378  getStreamer().SwitchSection(getContext().getMachOSection(
379  Segment, Section, TAA, StubSize,
380  isText ? SectionKind::getText()
382 
383  // Set the implicit alignment, if any.
384  //
385  // FIXME: This isn't really what 'as' does; I think it just uses the implicit
386  // alignment on the section (e.g., if one manually inserts bytes into the
387  // section, then just issuing the section switch directive will not realign
388  // the section. However, this is arguably more reasonable behavior, and there
389  // is no good reason for someone to intentionally emit incorrectly sized
390  // values into the implicitly aligned sections.
391  if (Align)
392  getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
393 
394  return false;
395 }
396 
397 /// ParseDirectiveDesc
398 /// ::= .desc identifier , expression
399 bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
400  StringRef Name;
401  if (getParser().parseIdentifier(Name))
402  return TokError("expected identifier in directive");
403 
404  // Handle the identifier as the key symbol.
405  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
406 
407  if (getLexer().isNot(AsmToken::Comma))
408  return TokError("unexpected token in '.desc' directive");
409  Lex();
410 
411  int64_t DescValue;
412  if (getParser().parseAbsoluteExpression(DescValue))
413  return true;
414 
415  if (getLexer().isNot(AsmToken::EndOfStatement))
416  return TokError("unexpected token in '.desc' directive");
417 
418  Lex();
419 
420  // Set the n_desc field of this Symbol to this DescValue
421  getStreamer().EmitSymbolDesc(Sym, DescValue);
422 
423  return false;
424 }
425 
426 /// ParseDirectiveIndirectSymbol
427 /// ::= .indirect_symbol identifier
428 bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
429  const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
430  getStreamer().getCurrentSection().first);
431  unsigned SectionType = Current->getType();
432  if (SectionType != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
434  SectionType != MCSectionMachO::S_SYMBOL_STUBS)
435  return Error(Loc, "indirect symbol not in a symbol pointer or stub "
436  "section");
437 
438  StringRef Name;
439  if (getParser().parseIdentifier(Name))
440  return TokError("expected identifier in .indirect_symbol directive");
441 
442  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
443 
444  // Assembler local symbols don't make any sense here. Complain loudly.
445  if (Sym->isTemporary())
446  return TokError("non-local symbol required in directive");
447 
448  if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
449  return TokError("unable to emit indirect symbol attribute for: " + Name);
450 
451  if (getLexer().isNot(AsmToken::EndOfStatement))
452  return TokError("unexpected token in '.indirect_symbol' directive");
453 
454  Lex();
455 
456  return false;
457 }
458 
459 /// ParseDirectiveDumpOrLoad
460 /// ::= ( .dump | .load ) "filename"
461 bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
462  SMLoc IDLoc) {
463  bool IsDump = Directive == ".dump";
464  if (getLexer().isNot(AsmToken::String))
465  return TokError("expected string in '.dump' or '.load' directive");
466 
467  Lex();
468 
469  if (getLexer().isNot(AsmToken::EndOfStatement))
470  return TokError("unexpected token in '.dump' or '.load' directive");
471 
472  Lex();
473 
474  // FIXME: If/when .dump and .load are implemented they will be done in the
475  // the assembly parser and not have any need for an MCStreamer API.
476  if (IsDump)
477  return Warning(IDLoc, "ignoring directive .dump for now");
478  else
479  return Warning(IDLoc, "ignoring directive .load for now");
480 }
481 
482 /// ParseDirectiveLinkerOption
483 /// ::= .linker_option "string" ( , "string" )*
484 bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
486  for (;;) {
487  if (getLexer().isNot(AsmToken::String))
488  return TokError("expected string in '" + Twine(IDVal) + "' directive");
489 
490  std::string Data;
491  if (getParser().parseEscapedString(Data))
492  return true;
493 
494  Args.push_back(Data);
495 
496  Lex();
497  if (getLexer().is(AsmToken::EndOfStatement))
498  break;
499 
500  if (getLexer().isNot(AsmToken::Comma))
501  return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
502  Lex();
503  }
504 
505  getStreamer().EmitLinkerOptions(Args);
506  return false;
507 }
508 
509 /// ParseDirectiveLsym
510 /// ::= .lsym identifier , expression
511 bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
512  StringRef Name;
513  if (getParser().parseIdentifier(Name))
514  return TokError("expected identifier in directive");
515 
516  // Handle the identifier as the key symbol.
517  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
518 
519  if (getLexer().isNot(AsmToken::Comma))
520  return TokError("unexpected token in '.lsym' directive");
521  Lex();
522 
523  const MCExpr *Value;
524  if (getParser().parseExpression(Value))
525  return true;
526 
527  if (getLexer().isNot(AsmToken::EndOfStatement))
528  return TokError("unexpected token in '.lsym' directive");
529 
530  Lex();
531 
532  // We don't currently support this directive.
533  //
534  // FIXME: Diagnostic location!
535  (void) Sym;
536  return TokError("directive '.lsym' is unsupported");
537 }
538 
539 /// ParseDirectiveSection:
540 /// ::= .section identifier (',' identifier)*
541 bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
542  SMLoc Loc = getLexer().getLoc();
543 
544  StringRef SectionName;
545  if (getParser().parseIdentifier(SectionName))
546  return Error(Loc, "expected identifier after '.section' directive");
547 
548  // Verify there is a following comma.
549  if (!getLexer().is(AsmToken::Comma))
550  return TokError("unexpected token in '.section' directive");
551 
552  std::string SectionSpec = SectionName;
553  SectionSpec += ",";
554 
555  // Add all the tokens until the end of the line, ParseSectionSpecifier will
556  // handle this.
557  StringRef EOL = getLexer().LexUntilEndOfStatement();
558  SectionSpec.append(EOL.begin(), EOL.end());
559 
560  Lex();
561  if (getLexer().isNot(AsmToken::EndOfStatement))
562  return TokError("unexpected token in '.section' directive");
563  Lex();
564 
565 
566  StringRef Segment, Section;
567  unsigned StubSize;
568  unsigned TAA;
569  bool TAAParsed;
570  std::string ErrorStr =
571  MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
572  TAA, TAAParsed, StubSize);
573 
574  if (!ErrorStr.empty())
575  return Error(Loc, ErrorStr.c_str());
576 
577  // FIXME: Arch specific.
578  bool isText = Segment == "__TEXT"; // FIXME: Hack.
579  getStreamer().SwitchSection(getContext().getMachOSection(
580  Segment, Section, TAA, StubSize,
581  isText ? SectionKind::getText()
583  return false;
584 }
585 
586 /// ParseDirectivePushSection:
587 /// ::= .pushsection identifier (',' identifier)*
588 bool DarwinAsmParser::ParseDirectivePushSection(StringRef S, SMLoc Loc) {
589  getStreamer().PushSection();
590 
591  if (ParseDirectiveSection(S, Loc)) {
592  getStreamer().PopSection();
593  return true;
594  }
595 
596  return false;
597 }
598 
599 /// ParseDirectivePopSection:
600 /// ::= .popsection
601 bool DarwinAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
602  if (!getStreamer().PopSection())
603  return TokError(".popsection without corresponding .pushsection");
604  return false;
605 }
606 
607 /// ParseDirectivePrevious:
608 /// ::= .previous
609 bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
610  MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
611  if (PreviousSection.first == NULL)
612  return TokError(".previous without corresponding .section");
613  getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
614  return false;
615 }
616 
617 /// ParseDirectiveSecureLogUnique
618 /// ::= .secure_log_unique ... message ...
619 bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
620  StringRef LogMessage = getParser().parseStringToEndOfStatement();
621  if (getLexer().isNot(AsmToken::EndOfStatement))
622  return TokError("unexpected token in '.secure_log_unique' directive");
623 
624  if (getContext().getSecureLogUsed() != false)
625  return Error(IDLoc, ".secure_log_unique specified multiple times");
626 
627  // Get the secure log path.
628  const char *SecureLogFile = getContext().getSecureLogFile();
629  if (SecureLogFile == NULL)
630  return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
631  "environment variable unset.");
632 
633  // Open the secure log file if we haven't already.
634  raw_ostream *OS = getContext().getSecureLog();
635  if (OS == NULL) {
636  std::string Err;
637  OS = new raw_fd_ostream(SecureLogFile, Err, sys::fs::F_Append);
638  if (!Err.empty()) {
639  delete OS;
640  return Error(IDLoc, Twine("can't open secure log file: ") +
641  SecureLogFile + " (" + Err + ")");
642  }
643  getContext().setSecureLog(OS);
644  }
645 
646  // Write the message.
647  int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
648  *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
649  << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
650  << LogMessage + "\n";
651 
652  getContext().setSecureLogUsed(true);
653 
654  return false;
655 }
656 
657 /// ParseDirectiveSecureLogReset
658 /// ::= .secure_log_reset
659 bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
660  if (getLexer().isNot(AsmToken::EndOfStatement))
661  return TokError("unexpected token in '.secure_log_reset' directive");
662 
663  Lex();
664 
665  getContext().setSecureLogUsed(false);
666 
667  return false;
668 }
669 
670 /// ParseDirectiveSubsectionsViaSymbols
671 /// ::= .subsections_via_symbols
672 bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
673  if (getLexer().isNot(AsmToken::EndOfStatement))
674  return TokError("unexpected token in '.subsections_via_symbols' directive");
675 
676  Lex();
677 
678  getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
679 
680  return false;
681 }
682 
683 /// ParseDirectiveTBSS
684 /// ::= .tbss identifier, size, align
685 bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
686  SMLoc IDLoc = getLexer().getLoc();
687  StringRef Name;
688  if (getParser().parseIdentifier(Name))
689  return TokError("expected identifier in directive");
690 
691  // Handle the identifier as the key symbol.
692  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
693 
694  if (getLexer().isNot(AsmToken::Comma))
695  return TokError("unexpected token in directive");
696  Lex();
697 
698  int64_t Size;
699  SMLoc SizeLoc = getLexer().getLoc();
700  if (getParser().parseAbsoluteExpression(Size))
701  return true;
702 
703  int64_t Pow2Alignment = 0;
704  SMLoc Pow2AlignmentLoc;
705  if (getLexer().is(AsmToken::Comma)) {
706  Lex();
707  Pow2AlignmentLoc = getLexer().getLoc();
708  if (getParser().parseAbsoluteExpression(Pow2Alignment))
709  return true;
710  }
711 
712  if (getLexer().isNot(AsmToken::EndOfStatement))
713  return TokError("unexpected token in '.tbss' directive");
714 
715  Lex();
716 
717  if (Size < 0)
718  return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
719  "zero");
720 
721  // FIXME: Diagnose overflow.
722  if (Pow2Alignment < 0)
723  return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
724  "than zero");
725 
726  if (!Sym->isUndefined())
727  return Error(IDLoc, "invalid symbol redefinition");
728 
729  getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
730  "__DATA", "__thread_bss",
733  Sym, Size, 1 << Pow2Alignment);
734 
735  return false;
736 }
737 
738 /// ParseDirectiveZerofill
739 /// ::= .zerofill segname , sectname [, identifier , size_expression [
740 /// , align_expression ]]
741 bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
742  StringRef Segment;
743  if (getParser().parseIdentifier(Segment))
744  return TokError("expected segment name after '.zerofill' directive");
745 
746  if (getLexer().isNot(AsmToken::Comma))
747  return TokError("unexpected token in directive");
748  Lex();
749 
751  if (getParser().parseIdentifier(Section))
752  return TokError("expected section name after comma in '.zerofill' "
753  "directive");
754 
755  // If this is the end of the line all that was wanted was to create the
756  // the section but with no symbol.
757  if (getLexer().is(AsmToken::EndOfStatement)) {
758  // Create the zerofill section but no symbol
759  getStreamer().EmitZerofill(getContext().getMachOSection(
760  Segment, Section, MCSectionMachO::S_ZEROFILL,
761  0, SectionKind::getBSS()));
762  return false;
763  }
764 
765  if (getLexer().isNot(AsmToken::Comma))
766  return TokError("unexpected token in directive");
767  Lex();
768 
769  SMLoc IDLoc = getLexer().getLoc();
770  StringRef IDStr;
771  if (getParser().parseIdentifier(IDStr))
772  return TokError("expected identifier in directive");
773 
774  // handle the identifier as the key symbol.
775  MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
776 
777  if (getLexer().isNot(AsmToken::Comma))
778  return TokError("unexpected token in directive");
779  Lex();
780 
781  int64_t Size;
782  SMLoc SizeLoc = getLexer().getLoc();
783  if (getParser().parseAbsoluteExpression(Size))
784  return true;
785 
786  int64_t Pow2Alignment = 0;
787  SMLoc Pow2AlignmentLoc;
788  if (getLexer().is(AsmToken::Comma)) {
789  Lex();
790  Pow2AlignmentLoc = getLexer().getLoc();
791  if (getParser().parseAbsoluteExpression(Pow2Alignment))
792  return true;
793  }
794 
795  if (getLexer().isNot(AsmToken::EndOfStatement))
796  return TokError("unexpected token in '.zerofill' directive");
797 
798  Lex();
799 
800  if (Size < 0)
801  return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
802  "than zero");
803 
804  // NOTE: The alignment in the directive is a power of 2 value, the assembler
805  // may internally end up wanting an alignment in bytes.
806  // FIXME: Diagnose overflow.
807  if (Pow2Alignment < 0)
808  return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
809  "can't be less than zero");
810 
811  if (!Sym->isUndefined())
812  return Error(IDLoc, "invalid symbol redefinition");
813 
814  // Create the zerofill Symbol with Size and Pow2Alignment
815  //
816  // FIXME: Arch specific.
817  getStreamer().EmitZerofill(getContext().getMachOSection(
818  Segment, Section, MCSectionMachO::S_ZEROFILL,
819  0, SectionKind::getBSS()),
820  Sym, Size, 1 << Pow2Alignment);
821 
822  return false;
823 }
824 
825 /// ParseDirectiveDataRegion
826 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
827 bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
828  if (getLexer().is(AsmToken::EndOfStatement)) {
829  Lex();
830  getStreamer().EmitDataRegion(MCDR_DataRegion);
831  return false;
832  }
833  StringRef RegionType;
834  SMLoc Loc = getParser().getTok().getLoc();
835  if (getParser().parseIdentifier(RegionType))
836  return TokError("expected region type after '.data_region' directive");
837  int Kind = StringSwitch<int>(RegionType)
838  .Case("jt8", MCDR_DataRegionJT8)
839  .Case("jt16", MCDR_DataRegionJT16)
840  .Case("jt32", MCDR_DataRegionJT32)
841  .Default(-1);
842  if (Kind == -1)
843  return Error(Loc, "unknown region type in '.data_region' directive");
844  Lex();
845 
846  getStreamer().EmitDataRegion((MCDataRegionType)Kind);
847  return false;
848 }
849 
850 /// ParseDirectiveDataRegionEnd
851 /// ::= .end_data_region
852 bool DarwinAsmParser::ParseDirectiveDataRegionEnd(StringRef, SMLoc) {
853  if (getLexer().isNot(AsmToken::EndOfStatement))
854  return TokError("unexpected token in '.end_data_region' directive");
855 
856  Lex();
857  getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
858  return false;
859 }
860 
861 namespace llvm {
862 
864  return new DarwinAsmParser;
865 }
866 
867 } // end llvm namespace
void push_back(const T &Elt)
Definition: SmallVector.h:236
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser. The extension should use the AsmParser i...
static SectionKind getDataRel()
Definition: SectionKind.h:229
MCAsmParserExtension * createDarwinAsmParser()
MCDataRegionType
Definition: MCDirectives.h:55
StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:55
static SectionKind getBSS()
Definition: SectionKind.h:225
.data_region jt16
Definition: MCDirectives.h:58
iterator begin() const
Definition: StringRef.h:97
.data_region jt32
Definition: MCDirectives.h:59
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
static std::string ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:49
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
Definition: MCAsmParser.h:68
static SectionKind getThreadBSS()
Definition: SectionKind.h:223
.indirect_symbol (MachO)
Definition: MCDirectives.h:32
std::pair< const MCSection *, const MCExpr * > MCSectionSubPair
Definition: MCStreamer.h:39
R Default(const T &Value) const
Definition: StringSwitch.h:111
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:76
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
.data_region jt8
Definition: MCDirectives.h:57
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
LLVM Value Representation.
Definition: Value.h:66
iterator end() const
Definition: StringRef.h:99
unsigned getType() const
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:100
Represents a location in source code.
Definition: SMLoc.h:23
.end_data_region
Definition: MCDirectives.h:60
static SectionKind getText()
Definition: SectionKind.h:208