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/MC/MCContext.h"
12#include "llvm/MC/MCSectionMachO.h"
13#include "llvm/MC/MCStreamer.h"
14#include "llvm/MC/MCSymbol.h"
15#include "llvm/MC/MCParser/MCAsmLexer.h"
16#include "llvm/MC/MCParser/MCAsmParser.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/Twine.h"
19#include "llvm/Support/MemoryBuffer.h"
20#include "llvm/Support/SourceMgr.h"
21using namespace llvm;
22
23namespace {
24
25/// \brief Implementation of directive handling which is shared across all
26/// Darwin targets.
27class DarwinAsmParser : public MCAsmParserExtension {
28  template<bool (DarwinAsmParser::*Handler)(StringRef, SMLoc)>
29  void AddDirectiveHandler(StringRef Directive) {
30    getParser().AddDirectiveHandler(this, Directive,
31                                    HandleDirective<DarwinAsmParser, Handler>);
32  }
33
34  bool ParseSectionSwitch(const char *Segment, const char *Section,
35                          unsigned TAA = 0, unsigned ImplicitAlign = 0,
36                          unsigned StubSize = 0);
37
38public:
39  DarwinAsmParser() {}
40
41  virtual void Initialize(MCAsmParser &Parser) {
42    // Call the base implementation.
43    this->MCAsmParserExtension::Initialize(Parser);
44
45    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
46    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
47    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
48      ".subsections_via_symbols");
49    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
50    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
51    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
52    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
53      ".secure_log_unique");
54    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
55      ".secure_log_reset");
56    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
57    AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
58
59    // Special section directives.
60    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
61    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data");
62    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(".constructor");
63    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(".cstring");
64    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
65    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(".destructor");
66    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
67    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(".fvmlib_init0");
68    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(".fvmlib_init1");
69    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(".lazy_symbol_pointer");
70    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(".literal16");
71    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(".literal4");
72    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(".literal8");
73    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(".mod_init_func");
74    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(".mod_term_func");
75    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(".non_lazy_symbol_pointer");
76    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(".objc_cat_cls_meth");
77    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(".objc_cat_inst_meth");
78    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(".objc_category");
79    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(".objc_class");
80    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(".objc_class_names");
81    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(".objc_class_vars");
82    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(".objc_cls_meth");
83    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(".objc_cls_refs");
84    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(".objc_inst_meth");
85    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(".objc_instance_vars");
86    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(".objc_message_refs");
87    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(".objc_meta_class");
88    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(".objc_meth_var_names");
89    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(".objc_meth_var_types");
90    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(".objc_module_info");
91    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(".objc_protocol");
92    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(".objc_selector_strs");
93    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(".objc_string_object");
94    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(".objc_symbols");
95    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(".picsymbol_stub");
96    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(".static_const");
97    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(".static_data");
98    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(".symbol_stub");
99    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
100    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
101    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(".thread_init_func");
102    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
103
104    AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
105  }
106
107  bool ParseDirectiveDesc(StringRef, SMLoc);
108  bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
109  bool ParseDirectiveLsym(StringRef, SMLoc);
110  bool ParseDirectiveSection(StringRef, SMLoc);
111  bool ParseDirectiveSecureLogReset(StringRef, SMLoc);
112  bool ParseDirectiveSecureLogUnique(StringRef, SMLoc);
113  bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
114  bool ParseDirectiveTBSS(StringRef, SMLoc);
115  bool ParseDirectiveZerofill(StringRef, SMLoc);
116
117  // Named Section Directive
118  bool ParseSectionDirectiveConst(StringRef, SMLoc) {
119    return ParseSectionSwitch("__TEXT", "__const");
120  }
121  bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) {
122    return ParseSectionSwitch("__TEXT", "__static_const");
123  }
124  bool ParseSectionDirectiveCString(StringRef, SMLoc) {
125    return ParseSectionSwitch("__TEXT","__cstring",
126                              MCSectionMachO::S_CSTRING_LITERALS);
127  }
128  bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) {
129    return ParseSectionSwitch("__TEXT", "__literal4",
130                              MCSectionMachO::S_4BYTE_LITERALS, 4);
131  }
132  bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) {
133    return ParseSectionSwitch("__TEXT", "__literal8",
134                              MCSectionMachO::S_8BYTE_LITERALS, 8);
135  }
136  bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) {
137    return ParseSectionSwitch("__TEXT","__literal16",
138                              MCSectionMachO::S_16BYTE_LITERALS, 16);
139  }
140  bool ParseSectionDirectiveConstructor(StringRef, SMLoc) {
141    return ParseSectionSwitch("__TEXT","__constructor");
142  }
143  bool ParseSectionDirectiveDestructor(StringRef, SMLoc) {
144    return ParseSectionSwitch("__TEXT","__destructor");
145  }
146  bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
147    return ParseSectionSwitch("__TEXT","__fvmlib_init0");
148  }
149  bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
150    return ParseSectionSwitch("__TEXT","__fvmlib_init1");
151  }
152  bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) {
153    return ParseSectionSwitch("__TEXT","__symbol_stub",
154                              MCSectionMachO::S_SYMBOL_STUBS |
155                              MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
156                              // FIXME: Different on PPC and ARM.
157                              0, 16);
158  }
159  bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
160    return ParseSectionSwitch("__TEXT","__picsymbol_stub",
161                              MCSectionMachO::S_SYMBOL_STUBS |
162                              MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
163  }
164  bool ParseSectionDirectiveData(StringRef, SMLoc) {
165    return ParseSectionSwitch("__DATA", "__data");
166  }
167  bool ParseSectionDirectiveStaticData(StringRef, SMLoc) {
168    return ParseSectionSwitch("__DATA", "__static_data");
169  }
170  bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
171    return ParseSectionSwitch("__DATA", "__nl_symbol_ptr",
172                              MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
173  }
174  bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
175    return ParseSectionSwitch("__DATA", "__la_symbol_ptr",
176                              MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4);
177  }
178  bool ParseSectionDirectiveDyld(StringRef, SMLoc) {
179    return ParseSectionSwitch("__DATA", "__dyld");
180  }
181  bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) {
182    return ParseSectionSwitch("__DATA", "__mod_init_func",
183                              MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4);
184  }
185  bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) {
186    return ParseSectionSwitch("__DATA", "__mod_term_func",
187                              MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4);
188  }
189  bool ParseSectionDirectiveConstData(StringRef, SMLoc) {
190    return ParseSectionSwitch("__DATA", "__const");
191  }
192  bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) {
193    return ParseSectionSwitch("__OBJC", "__class",
194                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
195  }
196  bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
197    return ParseSectionSwitch("__OBJC", "__meta_class",
198                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
199  }
200  bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
201    return ParseSectionSwitch("__OBJC", "__cat_cls_meth",
202                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
203  }
204  bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
205    return ParseSectionSwitch("__OBJC", "__cat_inst_meth",
206                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
207  }
208  bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
209    return ParseSectionSwitch("__OBJC", "__protocol",
210                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
211  }
212  bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
213    return ParseSectionSwitch("__OBJC", "__string_object",
214                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
215  }
216  bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
217    return ParseSectionSwitch("__OBJC", "__cls_meth",
218                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
219  }
220  bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
221    return ParseSectionSwitch("__OBJC", "__inst_meth",
222                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
223  }
224  bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
225    return ParseSectionSwitch("__OBJC", "__cls_refs",
226                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
227                              MCSectionMachO::S_LITERAL_POINTERS, 4);
228  }
229  bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
230    return ParseSectionSwitch("__OBJC", "__message_refs",
231                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP |
232                              MCSectionMachO::S_LITERAL_POINTERS, 4);
233  }
234  bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
235    return ParseSectionSwitch("__OBJC", "__symbols",
236                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
237  }
238  bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) {
239    return ParseSectionSwitch("__OBJC", "__category",
240                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
241  }
242  bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
243    return ParseSectionSwitch("__OBJC", "__class_vars",
244                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
245  }
246  bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
247    return ParseSectionSwitch("__OBJC", "__instance_vars",
248                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
249  }
250  bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
251    return ParseSectionSwitch("__OBJC", "__module_info",
252                              MCSectionMachO::S_ATTR_NO_DEAD_STRIP);
253  }
254  bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
255    return ParseSectionSwitch("__TEXT", "__cstring",
256                              MCSectionMachO::S_CSTRING_LITERALS);
257  }
258  bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
259    return ParseSectionSwitch("__TEXT", "__cstring",
260                              MCSectionMachO::S_CSTRING_LITERALS);
261  }
262  bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
263    return ParseSectionSwitch("__TEXT", "__cstring",
264                              MCSectionMachO::S_CSTRING_LITERALS);
265  }
266  bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
267    return ParseSectionSwitch("__OBJC", "__selector_strs",
268                              MCSectionMachO::S_CSTRING_LITERALS);
269  }
270  bool ParseSectionDirectiveTData(StringRef, SMLoc) {
271    return ParseSectionSwitch("__DATA", "__thread_data",
272                              MCSectionMachO::S_THREAD_LOCAL_REGULAR);
273  }
274  bool ParseSectionDirectiveText(StringRef, SMLoc) {
275    return ParseSectionSwitch("__TEXT", "__text",
276                              MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
277  }
278  bool ParseSectionDirectiveTLV(StringRef, SMLoc) {
279    return ParseSectionSwitch("__DATA", "__thread_vars",
280                              MCSectionMachO::S_THREAD_LOCAL_VARIABLES);
281  }
282  bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
283    // Darwin silently ignores the .ident directive.
284    getParser().EatToEndOfStatement();
285    return false;
286  }
287  bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
288    return ParseSectionSwitch("__DATA", "__thread_init",
289                         MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
290  }
291
292};
293
294}
295
296bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
297                                         const char *Section,
298                                         unsigned TAA, unsigned Align,
299                                         unsigned StubSize) {
300  if (getLexer().isNot(AsmToken::EndOfStatement))
301    return TokError("unexpected token in section switching directive");
302  Lex();
303
304  // FIXME: Arch specific.
305  bool isText = StringRef(Segment) == "__TEXT";  // FIXME: Hack.
306  getStreamer().SwitchSection(getContext().getMachOSection(
307                                Segment, Section, TAA, StubSize,
308                                isText ? SectionKind::getText()
309                                       : SectionKind::getDataRel()));
310
311  // Set the implicit alignment, if any.
312  //
313  // FIXME: This isn't really what 'as' does; I think it just uses the implicit
314  // alignment on the section (e.g., if one manually inserts bytes into the
315  // section, then just issuing the section switch directive will not realign
316  // the section. However, this is arguably more reasonable behavior, and there
317  // is no good reason for someone to intentionally emit incorrectly sized
318  // values into the implicitly aligned sections.
319  if (Align)
320    getStreamer().EmitValueToAlignment(Align, 0, 1, 0);
321
322  return false;
323}
324
325/// ParseDirectiveDesc
326///  ::= .desc identifier , expression
327bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
328  StringRef Name;
329  if (getParser().ParseIdentifier(Name))
330    return TokError("expected identifier in directive");
331
332  // Handle the identifier as the key symbol.
333  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
334
335  if (getLexer().isNot(AsmToken::Comma))
336    return TokError("unexpected token in '.desc' directive");
337  Lex();
338
339  int64_t DescValue;
340  if (getParser().ParseAbsoluteExpression(DescValue))
341    return true;
342
343  if (getLexer().isNot(AsmToken::EndOfStatement))
344    return TokError("unexpected token in '.desc' directive");
345
346  Lex();
347
348  // Set the n_desc field of this Symbol to this DescValue
349  getStreamer().EmitSymbolDesc(Sym, DescValue);
350
351  return false;
352}
353
354/// ParseDirectiveDumpOrLoad
355///  ::= ( .dump | .load ) "filename"
356bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
357                                               SMLoc IDLoc) {
358  bool IsDump = Directive == ".dump";
359  if (getLexer().isNot(AsmToken::String))
360    return TokError("expected string in '.dump' or '.load' directive");
361
362  Lex();
363
364  if (getLexer().isNot(AsmToken::EndOfStatement))
365    return TokError("unexpected token in '.dump' or '.load' directive");
366
367  Lex();
368
369  // FIXME: If/when .dump and .load are implemented they will be done in the
370  // the assembly parser and not have any need for an MCStreamer API.
371  if (IsDump)
372    return Warning(IDLoc, "ignoring directive .dump for now");
373  else
374    return Warning(IDLoc, "ignoring directive .load for now");
375}
376
377/// ParseDirectiveLsym
378///  ::= .lsym identifier , expression
379bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
380  StringRef Name;
381  if (getParser().ParseIdentifier(Name))
382    return TokError("expected identifier in directive");
383
384  // Handle the identifier as the key symbol.
385  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
386
387  if (getLexer().isNot(AsmToken::Comma))
388    return TokError("unexpected token in '.lsym' directive");
389  Lex();
390
391  const MCExpr *Value;
392  if (getParser().ParseExpression(Value))
393    return true;
394
395  if (getLexer().isNot(AsmToken::EndOfStatement))
396    return TokError("unexpected token in '.lsym' directive");
397
398  Lex();
399
400  // We don't currently support this directive.
401  //
402  // FIXME: Diagnostic location!
403  (void) Sym;
404  return TokError("directive '.lsym' is unsupported");
405}
406
407/// ParseDirectiveSection:
408///   ::= .section identifier (',' identifier)*
409bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
410  SMLoc Loc = getLexer().getLoc();
411
412  StringRef SectionName;
413  if (getParser().ParseIdentifier(SectionName))
414    return Error(Loc, "expected identifier after '.section' directive");
415
416  // Verify there is a following comma.
417  if (!getLexer().is(AsmToken::Comma))
418    return TokError("unexpected token in '.section' directive");
419
420  std::string SectionSpec = SectionName;
421  SectionSpec += ",";
422
423  // Add all the tokens until the end of the line, ParseSectionSpecifier will
424  // handle this.
425  StringRef EOL = getLexer().LexUntilEndOfStatement();
426  SectionSpec.append(EOL.begin(), EOL.end());
427
428  Lex();
429  if (getLexer().isNot(AsmToken::EndOfStatement))
430    return TokError("unexpected token in '.section' directive");
431  Lex();
432
433
434  StringRef Segment, Section;
435  unsigned StubSize;
436  unsigned TAA;
437  bool TAAParsed;
438  std::string ErrorStr =
439    MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
440                                          TAA, TAAParsed, StubSize);
441
442  if (!ErrorStr.empty())
443    return Error(Loc, ErrorStr.c_str());
444
445  // FIXME: Arch specific.
446  bool isText = Segment == "__TEXT";  // FIXME: Hack.
447  getStreamer().SwitchSection(getContext().getMachOSection(
448                                Segment, Section, TAA, StubSize,
449                                isText ? SectionKind::getText()
450                                : SectionKind::getDataRel()));
451  return false;
452}
453
454/// ParseDirectiveSecureLogUnique
455///  ::= .secure_log_unique ... message ...
456bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
457  StringRef LogMessage = getParser().ParseStringToEndOfStatement();
458  if (getLexer().isNot(AsmToken::EndOfStatement))
459    return TokError("unexpected token in '.secure_log_unique' directive");
460
461  if (getContext().getSecureLogUsed() != false)
462    return Error(IDLoc, ".secure_log_unique specified multiple times");
463
464  // Get the secure log path.
465  const char *SecureLogFile = getContext().getSecureLogFile();
466  if (SecureLogFile == NULL)
467    return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
468                 "environment variable unset.");
469
470  // Open the secure log file if we haven't already.
471  raw_ostream *OS = getContext().getSecureLog();
472  if (OS == NULL) {
473    std::string Err;
474    OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append);
475    if (!Err.empty()) {
476       delete OS;
477       return Error(IDLoc, Twine("can't open secure log file: ") +
478                    SecureLogFile + " (" + Err + ")");
479    }
480    getContext().setSecureLog(OS);
481  }
482
483  // Write the message.
484  int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
485  *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
486      << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
487      << LogMessage + "\n";
488
489  getContext().setSecureLogUsed(true);
490
491  return false;
492}
493
494/// ParseDirectiveSecureLogReset
495///  ::= .secure_log_reset
496bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
497  if (getLexer().isNot(AsmToken::EndOfStatement))
498    return TokError("unexpected token in '.secure_log_reset' directive");
499
500  Lex();
501
502  getContext().setSecureLogUsed(false);
503
504  return false;
505}
506
507/// ParseDirectiveSubsectionsViaSymbols
508///  ::= .subsections_via_symbols
509bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
510  if (getLexer().isNot(AsmToken::EndOfStatement))
511    return TokError("unexpected token in '.subsections_via_symbols' directive");
512
513  Lex();
514
515  getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
516
517  return false;
518}
519
520/// ParseDirectiveTBSS
521///  ::= .tbss identifier, size, align
522bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
523  SMLoc IDLoc = getLexer().getLoc();
524  StringRef Name;
525  if (getParser().ParseIdentifier(Name))
526    return TokError("expected identifier in directive");
527
528  // Handle the identifier as the key symbol.
529  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
530
531  if (getLexer().isNot(AsmToken::Comma))
532    return TokError("unexpected token in directive");
533  Lex();
534
535  int64_t Size;
536  SMLoc SizeLoc = getLexer().getLoc();
537  if (getParser().ParseAbsoluteExpression(Size))
538    return true;
539
540  int64_t Pow2Alignment = 0;
541  SMLoc Pow2AlignmentLoc;
542  if (getLexer().is(AsmToken::Comma)) {
543    Lex();
544    Pow2AlignmentLoc = getLexer().getLoc();
545    if (getParser().ParseAbsoluteExpression(Pow2Alignment))
546      return true;
547  }
548
549  if (getLexer().isNot(AsmToken::EndOfStatement))
550    return TokError("unexpected token in '.tbss' directive");
551
552  Lex();
553
554  if (Size < 0)
555    return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
556                 "zero");
557
558  // FIXME: Diagnose overflow.
559  if (Pow2Alignment < 0)
560    return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
561                 "than zero");
562
563  if (!Sym->isUndefined())
564    return Error(IDLoc, "invalid symbol redefinition");
565
566  getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
567                                 "__DATA", "__thread_bss",
568                                 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL,
569                                 0, SectionKind::getThreadBSS()),
570                               Sym, Size, 1 << Pow2Alignment);
571
572  return false;
573}
574
575/// ParseDirectiveZerofill
576///  ::= .zerofill segname , sectname [, identifier , size_expression [
577///      , align_expression ]]
578bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
579  StringRef Segment;
580  if (getParser().ParseIdentifier(Segment))
581    return TokError("expected segment name after '.zerofill' directive");
582
583  if (getLexer().isNot(AsmToken::Comma))
584    return TokError("unexpected token in directive");
585  Lex();
586
587  StringRef Section;
588  if (getParser().ParseIdentifier(Section))
589    return TokError("expected section name after comma in '.zerofill' "
590                    "directive");
591
592  // If this is the end of the line all that was wanted was to create the
593  // the section but with no symbol.
594  if (getLexer().is(AsmToken::EndOfStatement)) {
595    // Create the zerofill section but no symbol
596    getStreamer().EmitZerofill(getContext().getMachOSection(
597                                 Segment, Section, MCSectionMachO::S_ZEROFILL,
598                                 0, SectionKind::getBSS()));
599    return false;
600  }
601
602  if (getLexer().isNot(AsmToken::Comma))
603    return TokError("unexpected token in directive");
604  Lex();
605
606  SMLoc IDLoc = getLexer().getLoc();
607  StringRef IDStr;
608  if (getParser().ParseIdentifier(IDStr))
609    return TokError("expected identifier in directive");
610
611  // handle the identifier as the key symbol.
612  MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
613
614  if (getLexer().isNot(AsmToken::Comma))
615    return TokError("unexpected token in directive");
616  Lex();
617
618  int64_t Size;
619  SMLoc SizeLoc = getLexer().getLoc();
620  if (getParser().ParseAbsoluteExpression(Size))
621    return true;
622
623  int64_t Pow2Alignment = 0;
624  SMLoc Pow2AlignmentLoc;
625  if (getLexer().is(AsmToken::Comma)) {
626    Lex();
627    Pow2AlignmentLoc = getLexer().getLoc();
628    if (getParser().ParseAbsoluteExpression(Pow2Alignment))
629      return true;
630  }
631
632  if (getLexer().isNot(AsmToken::EndOfStatement))
633    return TokError("unexpected token in '.zerofill' directive");
634
635  Lex();
636
637  if (Size < 0)
638    return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
639                 "than zero");
640
641  // NOTE: The alignment in the directive is a power of 2 value, the assembler
642  // may internally end up wanting an alignment in bytes.
643  // FIXME: Diagnose overflow.
644  if (Pow2Alignment < 0)
645    return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
646                 "can't be less than zero");
647
648  if (!Sym->isUndefined())
649    return Error(IDLoc, "invalid symbol redefinition");
650
651  // Create the zerofill Symbol with Size and Pow2Alignment
652  //
653  // FIXME: Arch specific.
654  getStreamer().EmitZerofill(getContext().getMachOSection(
655                               Segment, Section, MCSectionMachO::S_ZEROFILL,
656                               0, SectionKind::getBSS()),
657                             Sym, Size, 1 << Pow2Alignment);
658
659  return false;
660}
661
662namespace llvm {
663
664MCAsmParserExtension *createDarwinAsmParser() {
665  return new DarwinAsmParser;
666}
667
668}
669