Home | History | Annotate | Download | only in MCParser
      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/FileSystem.h"
     21 #include "llvm/Support/MemoryBuffer.h"
     22 #include "llvm/Support/SourceMgr.h"
     23 using namespace llvm;
     24 
     25 namespace {
     26 
     27 /// \brief Implementation of directive handling which is shared across all
     28 /// Darwin targets.
     29 class DarwinAsmParser : public MCAsmParserExtension {
     30   template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
     31   void addDirectiveHandler(StringRef Directive) {
     32     MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
     33         this, HandleDirective<DarwinAsmParser, HandlerMethod>);
     34     getParser().addDirectiveHandler(Directive, Handler);
     35   }
     36 
     37   bool parseSectionSwitch(const char *Segment, const char *Section,
     38                           unsigned TAA = 0, unsigned ImplicitAlign = 0,
     39                           unsigned StubSize = 0);
     40 
     41 public:
     42   DarwinAsmParser() {}
     43 
     44   void Initialize(MCAsmParser &Parser) override {
     45     // Call the base implementation.
     46     this->MCAsmParserExtension::Initialize(Parser);
     47 
     48     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");
     49     addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(
     50       ".indirect_symbol");
     51     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");
     52     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(
     53       ".subsections_via_symbols");
     54     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");
     55     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");
     56     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");
     57     addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(
     58       ".pushsection");
     59     addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(
     60       ".popsection");
     61     addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");
     62     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(
     63       ".secure_log_unique");
     64     addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(
     65       ".secure_log_reset");
     66     addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");
     67     addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");
     68 
     69     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(
     70       ".data_region");
     71     addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(
     72       ".end_data_region");
     73 
     74     // Special section directives.
     75     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");
     76     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");
     77     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(
     78       ".const_data");
     79     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(
     80       ".constructor");
     81     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(
     82       ".cstring");
     83     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");
     84     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(
     85       ".destructor");
     86     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");
     87     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(
     88       ".fvmlib_init0");
     89     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(
     90       ".fvmlib_init1");
     91     addDirectiveHandler<
     92       &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(
     93         ".lazy_symbol_pointer");
     94     addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(
     95       ".linker_option");
     96     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(
     97       ".literal16");
     98     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(
     99       ".literal4");
    100     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(
    101       ".literal8");
    102     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(
    103       ".mod_init_func");
    104     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(
    105       ".mod_term_func");
    106     addDirectiveHandler<
    107       &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(
    108         ".non_lazy_symbol_pointer");
    109     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(
    110       ".objc_cat_cls_meth");
    111     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(
    112       ".objc_cat_inst_meth");
    113     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(
    114       ".objc_category");
    115     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(
    116       ".objc_class");
    117     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(
    118       ".objc_class_names");
    119     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(
    120       ".objc_class_vars");
    121     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(
    122       ".objc_cls_meth");
    123     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(
    124       ".objc_cls_refs");
    125     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(
    126       ".objc_inst_meth");
    127     addDirectiveHandler<
    128       &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(
    129         ".objc_instance_vars");
    130     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(
    131       ".objc_message_refs");
    132     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(
    133       ".objc_meta_class");
    134     addDirectiveHandler<
    135       &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(
    136         ".objc_meth_var_names");
    137     addDirectiveHandler<
    138       &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(
    139         ".objc_meth_var_types");
    140     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(
    141       ".objc_module_info");
    142     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(
    143       ".objc_protocol");
    144     addDirectiveHandler<
    145       &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(
    146         ".objc_selector_strs");
    147     addDirectiveHandler<
    148       &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(
    149         ".objc_string_object");
    150     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(
    151       ".objc_symbols");
    152     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(
    153       ".picsymbol_stub");
    154     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(
    155       ".static_const");
    156     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(
    157       ".static_data");
    158     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(
    159       ".symbol_stub");
    160     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");
    161     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");
    162     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(
    163       ".thread_init_func");
    164     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
    165 
    166     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
    167     addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
    168     addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
    169       ".macosx_version_min");
    170   }
    171 
    172   bool parseDirectiveDesc(StringRef, SMLoc);
    173   bool parseDirectiveIndirectSymbol(StringRef, SMLoc);
    174   bool parseDirectiveDumpOrLoad(StringRef, SMLoc);
    175   bool parseDirectiveLsym(StringRef, SMLoc);
    176   bool parseDirectiveLinkerOption(StringRef, SMLoc);
    177   bool parseDirectiveSection(StringRef, SMLoc);
    178   bool parseDirectivePushSection(StringRef, SMLoc);
    179   bool parseDirectivePopSection(StringRef, SMLoc);
    180   bool parseDirectivePrevious(StringRef, SMLoc);
    181   bool parseDirectiveSecureLogReset(StringRef, SMLoc);
    182   bool parseDirectiveSecureLogUnique(StringRef, SMLoc);
    183   bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);
    184   bool parseDirectiveTBSS(StringRef, SMLoc);
    185   bool parseDirectiveZerofill(StringRef, SMLoc);
    186   bool parseDirectiveDataRegion(StringRef, SMLoc);
    187   bool parseDirectiveDataRegionEnd(StringRef, SMLoc);
    188 
    189   // Named Section Directive
    190   bool parseSectionDirectiveBss(StringRef, SMLoc) {
    191     return parseSectionSwitch("__DATA", "__bss");
    192   }
    193 
    194   bool parseSectionDirectiveConst(StringRef, SMLoc) {
    195     return parseSectionSwitch("__TEXT", "__const");
    196   }
    197   bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {
    198     return parseSectionSwitch("__TEXT", "__static_const");
    199   }
    200   bool parseSectionDirectiveCString(StringRef, SMLoc) {
    201     return parseSectionSwitch("__TEXT","__cstring",
    202                               MachO::S_CSTRING_LITERALS);
    203   }
    204   bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {
    205     return parseSectionSwitch("__TEXT", "__literal4",
    206                               MachO::S_4BYTE_LITERALS, 4);
    207   }
    208   bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {
    209     return parseSectionSwitch("__TEXT", "__literal8",
    210                               MachO::S_8BYTE_LITERALS, 8);
    211   }
    212   bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {
    213     return parseSectionSwitch("__TEXT","__literal16",
    214                               MachO::S_16BYTE_LITERALS, 16);
    215   }
    216   bool parseSectionDirectiveConstructor(StringRef, SMLoc) {
    217     return parseSectionSwitch("__TEXT","__constructor");
    218   }
    219   bool parseSectionDirectiveDestructor(StringRef, SMLoc) {
    220     return parseSectionSwitch("__TEXT","__destructor");
    221   }
    222   bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {
    223     return parseSectionSwitch("__TEXT","__fvmlib_init0");
    224   }
    225   bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {
    226     return parseSectionSwitch("__TEXT","__fvmlib_init1");
    227   }
    228   bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {
    229     return parseSectionSwitch("__TEXT","__symbol_stub",
    230                               MachO::S_SYMBOL_STUBS |
    231                               MachO::S_ATTR_PURE_INSTRUCTIONS,
    232                               // FIXME: Different on PPC and ARM.
    233                               0, 16);
    234   }
    235   bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {
    236     return parseSectionSwitch("__TEXT","__picsymbol_stub",
    237                               MachO::S_SYMBOL_STUBS |
    238                               MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);
    239   }
    240   bool parseSectionDirectiveData(StringRef, SMLoc) {
    241     return parseSectionSwitch("__DATA", "__data");
    242   }
    243   bool parseSectionDirectiveStaticData(StringRef, SMLoc) {
    244     return parseSectionSwitch("__DATA", "__static_data");
    245   }
    246   bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {
    247     return parseSectionSwitch("__DATA", "__nl_symbol_ptr",
    248                               MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);
    249   }
    250   bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {
    251     return parseSectionSwitch("__DATA", "__la_symbol_ptr",
    252                               MachO::S_LAZY_SYMBOL_POINTERS, 4);
    253   }
    254   bool parseSectionDirectiveDyld(StringRef, SMLoc) {
    255     return parseSectionSwitch("__DATA", "__dyld");
    256   }
    257   bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {
    258     return parseSectionSwitch("__DATA", "__mod_init_func",
    259                               MachO::S_MOD_INIT_FUNC_POINTERS, 4);
    260   }
    261   bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {
    262     return parseSectionSwitch("__DATA", "__mod_term_func",
    263                               MachO::S_MOD_TERM_FUNC_POINTERS, 4);
    264   }
    265   bool parseSectionDirectiveConstData(StringRef, SMLoc) {
    266     return parseSectionSwitch("__DATA", "__const");
    267   }
    268   bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {
    269     return parseSectionSwitch("__OBJC", "__class",
    270                               MachO::S_ATTR_NO_DEAD_STRIP);
    271   }
    272   bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {
    273     return parseSectionSwitch("__OBJC", "__meta_class",
    274                               MachO::S_ATTR_NO_DEAD_STRIP);
    275   }
    276   bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {
    277     return parseSectionSwitch("__OBJC", "__cat_cls_meth",
    278                               MachO::S_ATTR_NO_DEAD_STRIP);
    279   }
    280   bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {
    281     return parseSectionSwitch("__OBJC", "__cat_inst_meth",
    282                               MachO::S_ATTR_NO_DEAD_STRIP);
    283   }
    284   bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {
    285     return parseSectionSwitch("__OBJC", "__protocol",
    286                               MachO::S_ATTR_NO_DEAD_STRIP);
    287   }
    288   bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {
    289     return parseSectionSwitch("__OBJC", "__string_object",
    290                               MachO::S_ATTR_NO_DEAD_STRIP);
    291   }
    292   bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {
    293     return parseSectionSwitch("__OBJC", "__cls_meth",
    294                               MachO::S_ATTR_NO_DEAD_STRIP);
    295   }
    296   bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {
    297     return parseSectionSwitch("__OBJC", "__inst_meth",
    298                               MachO::S_ATTR_NO_DEAD_STRIP);
    299   }
    300   bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {
    301     return parseSectionSwitch("__OBJC", "__cls_refs",
    302                               MachO::S_ATTR_NO_DEAD_STRIP |
    303                               MachO::S_LITERAL_POINTERS, 4);
    304   }
    305   bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {
    306     return parseSectionSwitch("__OBJC", "__message_refs",
    307                               MachO::S_ATTR_NO_DEAD_STRIP |
    308                               MachO::S_LITERAL_POINTERS, 4);
    309   }
    310   bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {
    311     return parseSectionSwitch("__OBJC", "__symbols",
    312                               MachO::S_ATTR_NO_DEAD_STRIP);
    313   }
    314   bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {
    315     return parseSectionSwitch("__OBJC", "__category",
    316                               MachO::S_ATTR_NO_DEAD_STRIP);
    317   }
    318   bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {
    319     return parseSectionSwitch("__OBJC", "__class_vars",
    320                               MachO::S_ATTR_NO_DEAD_STRIP);
    321   }
    322   bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {
    323     return parseSectionSwitch("__OBJC", "__instance_vars",
    324                               MachO::S_ATTR_NO_DEAD_STRIP);
    325   }
    326   bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {
    327     return parseSectionSwitch("__OBJC", "__module_info",
    328                               MachO::S_ATTR_NO_DEAD_STRIP);
    329   }
    330   bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {
    331     return parseSectionSwitch("__TEXT", "__cstring",
    332                               MachO::S_CSTRING_LITERALS);
    333   }
    334   bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {
    335     return parseSectionSwitch("__TEXT", "__cstring",
    336                               MachO::S_CSTRING_LITERALS);
    337   }
    338   bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {
    339     return parseSectionSwitch("__TEXT", "__cstring",
    340                               MachO::S_CSTRING_LITERALS);
    341   }
    342   bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {
    343     return parseSectionSwitch("__OBJC", "__selector_strs",
    344                               MachO::S_CSTRING_LITERALS);
    345   }
    346   bool parseSectionDirectiveTData(StringRef, SMLoc) {
    347     return parseSectionSwitch("__DATA", "__thread_data",
    348                               MachO::S_THREAD_LOCAL_REGULAR);
    349   }
    350   bool parseSectionDirectiveText(StringRef, SMLoc) {
    351     return parseSectionSwitch("__TEXT", "__text",
    352                               MachO::S_ATTR_PURE_INSTRUCTIONS);
    353   }
    354   bool parseSectionDirectiveTLV(StringRef, SMLoc) {
    355     return parseSectionSwitch("__DATA", "__thread_vars",
    356                               MachO::S_THREAD_LOCAL_VARIABLES);
    357   }
    358   bool parseSectionDirectiveIdent(StringRef, SMLoc) {
    359     // Darwin silently ignores the .ident directive.
    360     getParser().eatToEndOfStatement();
    361     return false;
    362   }
    363   bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
    364     return parseSectionSwitch("__DATA", "__thread_init",
    365                          MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
    366   }
    367   bool parseVersionMin(StringRef, SMLoc);
    368 
    369 };
    370 
    371 } // end anonymous namespace
    372 
    373 bool DarwinAsmParser::parseSectionSwitch(const char *Segment,
    374                                          const char *Section,
    375                                          unsigned TAA, unsigned Align,
    376                                          unsigned StubSize) {
    377   if (getLexer().isNot(AsmToken::EndOfStatement))
    378     return TokError("unexpected token in section switching directive");
    379   Lex();
    380 
    381   // FIXME: Arch specific.
    382   bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;
    383   getStreamer().SwitchSection(getContext().getMachOSection(
    384                                 Segment, Section, TAA, StubSize,
    385                                 isText ? SectionKind::getText()
    386                                        : SectionKind::getDataRel()));
    387 
    388   // Set the implicit alignment, if any.
    389   //
    390   // FIXME: This isn't really what 'as' does; I think it just uses the implicit
    391   // alignment on the section (e.g., if one manually inserts bytes into the
    392   // section, then just issuing the section switch directive will not realign
    393   // the section. However, this is arguably more reasonable behavior, and there
    394   // is no good reason for someone to intentionally emit incorrectly sized
    395   // values into the implicitly aligned sections.
    396   if (Align)
    397     getStreamer().EmitValueToAlignment(Align);
    398 
    399   return false;
    400 }
    401 
    402 /// parseDirectiveDesc
    403 ///  ::= .desc identifier , expression
    404 bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {
    405   StringRef Name;
    406   if (getParser().parseIdentifier(Name))
    407     return TokError("expected identifier in directive");
    408 
    409   // Handle the identifier as the key symbol.
    410   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
    411 
    412   if (getLexer().isNot(AsmToken::Comma))
    413     return TokError("unexpected token in '.desc' directive");
    414   Lex();
    415 
    416   int64_t DescValue;
    417   if (getParser().parseAbsoluteExpression(DescValue))
    418     return true;
    419 
    420   if (getLexer().isNot(AsmToken::EndOfStatement))
    421     return TokError("unexpected token in '.desc' directive");
    422 
    423   Lex();
    424 
    425   // Set the n_desc field of this Symbol to this DescValue
    426   getStreamer().EmitSymbolDesc(Sym, DescValue);
    427 
    428   return false;
    429 }
    430 
    431 /// parseDirectiveIndirectSymbol
    432 ///  ::= .indirect_symbol identifier
    433 bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
    434   const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
    435                                        getStreamer().getCurrentSection().first);
    436   MachO::SectionType SectionType = Current->getType();
    437   if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&
    438       SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&
    439       SectionType != MachO::S_SYMBOL_STUBS)
    440     return Error(Loc, "indirect symbol not in a symbol pointer or stub "
    441                       "section");
    442 
    443   StringRef Name;
    444   if (getParser().parseIdentifier(Name))
    445     return TokError("expected identifier in .indirect_symbol directive");
    446 
    447   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
    448 
    449   // Assembler local symbols don't make any sense here. Complain loudly.
    450   if (Sym->isTemporary())
    451     return TokError("non-local symbol required in directive");
    452 
    453   if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
    454     return TokError("unable to emit indirect symbol attribute for: " + Name);
    455 
    456   if (getLexer().isNot(AsmToken::EndOfStatement))
    457     return TokError("unexpected token in '.indirect_symbol' directive");
    458 
    459   Lex();
    460 
    461   return false;
    462 }
    463 
    464 /// parseDirectiveDumpOrLoad
    465 ///  ::= ( .dump | .load ) "filename"
    466 bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,
    467                                                SMLoc IDLoc) {
    468   bool IsDump = Directive == ".dump";
    469   if (getLexer().isNot(AsmToken::String))
    470     return TokError("expected string in '.dump' or '.load' directive");
    471 
    472   Lex();
    473 
    474   if (getLexer().isNot(AsmToken::EndOfStatement))
    475     return TokError("unexpected token in '.dump' or '.load' directive");
    476 
    477   Lex();
    478 
    479   // FIXME: If/when .dump and .load are implemented they will be done in the
    480   // the assembly parser and not have any need for an MCStreamer API.
    481   if (IsDump)
    482     return Warning(IDLoc, "ignoring directive .dump for now");
    483   else
    484     return Warning(IDLoc, "ignoring directive .load for now");
    485 }
    486 
    487 /// ParseDirectiveLinkerOption
    488 ///  ::= .linker_option "string" ( , "string" )*
    489 bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
    490   SmallVector<std::string, 4> Args;
    491   for (;;) {
    492     if (getLexer().isNot(AsmToken::String))
    493       return TokError("expected string in '" + Twine(IDVal) + "' directive");
    494 
    495     std::string Data;
    496     if (getParser().parseEscapedString(Data))
    497       return true;
    498 
    499     Args.push_back(Data);
    500 
    501     Lex();
    502     if (getLexer().is(AsmToken::EndOfStatement))
    503       break;
    504 
    505     if (getLexer().isNot(AsmToken::Comma))
    506       return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
    507     Lex();
    508   }
    509 
    510   getStreamer().EmitLinkerOptions(Args);
    511   return false;
    512 }
    513 
    514 /// parseDirectiveLsym
    515 ///  ::= .lsym identifier , expression
    516 bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {
    517   StringRef Name;
    518   if (getParser().parseIdentifier(Name))
    519     return TokError("expected identifier in directive");
    520 
    521   // Handle the identifier as the key symbol.
    522   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
    523 
    524   if (getLexer().isNot(AsmToken::Comma))
    525     return TokError("unexpected token in '.lsym' directive");
    526   Lex();
    527 
    528   const MCExpr *Value;
    529   if (getParser().parseExpression(Value))
    530     return true;
    531 
    532   if (getLexer().isNot(AsmToken::EndOfStatement))
    533     return TokError("unexpected token in '.lsym' directive");
    534 
    535   Lex();
    536 
    537   // We don't currently support this directive.
    538   //
    539   // FIXME: Diagnostic location!
    540   (void) Sym;
    541   return TokError("directive '.lsym' is unsupported");
    542 }
    543 
    544 /// parseDirectiveSection:
    545 ///   ::= .section identifier (',' identifier)*
    546 bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
    547   SMLoc Loc = getLexer().getLoc();
    548 
    549   StringRef SectionName;
    550   if (getParser().parseIdentifier(SectionName))
    551     return Error(Loc, "expected identifier after '.section' directive");
    552 
    553   // Verify there is a following comma.
    554   if (!getLexer().is(AsmToken::Comma))
    555     return TokError("unexpected token in '.section' directive");
    556 
    557   std::string SectionSpec = SectionName;
    558   SectionSpec += ",";
    559 
    560   // Add all the tokens until the end of the line, ParseSectionSpecifier will
    561   // handle this.
    562   StringRef EOL = getLexer().LexUntilEndOfStatement();
    563   SectionSpec.append(EOL.begin(), EOL.end());
    564 
    565   Lex();
    566   if (getLexer().isNot(AsmToken::EndOfStatement))
    567     return TokError("unexpected token in '.section' directive");
    568   Lex();
    569 
    570 
    571   StringRef Segment, Section;
    572   unsigned StubSize;
    573   unsigned TAA;
    574   bool TAAParsed;
    575   std::string ErrorStr =
    576     MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
    577                                           TAA, TAAParsed, StubSize);
    578 
    579   if (!ErrorStr.empty())
    580     return Error(Loc, ErrorStr.c_str());
    581 
    582   // FIXME: Arch specific.
    583   bool isText = Segment == "__TEXT";  // FIXME: Hack.
    584   getStreamer().SwitchSection(getContext().getMachOSection(
    585                                 Segment, Section, TAA, StubSize,
    586                                 isText ? SectionKind::getText()
    587                                 : SectionKind::getDataRel()));
    588   return false;
    589 }
    590 
    591 /// ParseDirectivePushSection:
    592 ///   ::= .pushsection identifier (',' identifier)*
    593 bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {
    594   getStreamer().PushSection();
    595 
    596   if (parseDirectiveSection(S, Loc)) {
    597     getStreamer().PopSection();
    598     return true;
    599   }
    600 
    601   return false;
    602 }
    603 
    604 /// ParseDirectivePopSection:
    605 ///   ::= .popsection
    606 bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
    607   if (!getStreamer().PopSection())
    608     return TokError(".popsection without corresponding .pushsection");
    609   return false;
    610 }
    611 
    612 /// ParseDirectivePrevious:
    613 ///   ::= .previous
    614 bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
    615   MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
    616   if (!PreviousSection.first)
    617     return TokError(".previous without corresponding .section");
    618   getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
    619   return false;
    620 }
    621 
    622 /// ParseDirectiveSecureLogUnique
    623 ///  ::= .secure_log_unique ... message ...
    624 bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
    625   StringRef LogMessage = getParser().parseStringToEndOfStatement();
    626   if (getLexer().isNot(AsmToken::EndOfStatement))
    627     return TokError("unexpected token in '.secure_log_unique' directive");
    628 
    629   if (getContext().getSecureLogUsed() != false)
    630     return Error(IDLoc, ".secure_log_unique specified multiple times");
    631 
    632   // Get the secure log path.
    633   const char *SecureLogFile = getContext().getSecureLogFile();
    634   if (!SecureLogFile)
    635     return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "
    636                  "environment variable unset.");
    637 
    638   // Open the secure log file if we haven't already.
    639   raw_ostream *OS = getContext().getSecureLog();
    640   if (!OS) {
    641     std::string Err;
    642     OS = new raw_fd_ostream(SecureLogFile, Err,
    643                             sys::fs::F_Append | sys::fs::F_Text);
    644     if (!Err.empty()) {
    645        delete OS;
    646        return Error(IDLoc, Twine("can't open secure log file: ") +
    647                     SecureLogFile + " (" + Err + ")");
    648     }
    649     getContext().setSecureLog(OS);
    650   }
    651 
    652   // Write the message.
    653   unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);
    654   *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()
    655       << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"
    656       << LogMessage + "\n";
    657 
    658   getContext().setSecureLogUsed(true);
    659 
    660   return false;
    661 }
    662 
    663 /// ParseDirectiveSecureLogReset
    664 ///  ::= .secure_log_reset
    665 bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {
    666   if (getLexer().isNot(AsmToken::EndOfStatement))
    667     return TokError("unexpected token in '.secure_log_reset' directive");
    668 
    669   Lex();
    670 
    671   getContext().setSecureLogUsed(false);
    672 
    673   return false;
    674 }
    675 
    676 /// parseDirectiveSubsectionsViaSymbols
    677 ///  ::= .subsections_via_symbols
    678 bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
    679   if (getLexer().isNot(AsmToken::EndOfStatement))
    680     return TokError("unexpected token in '.subsections_via_symbols' directive");
    681 
    682   Lex();
    683 
    684   getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
    685 
    686   return false;
    687 }
    688 
    689 /// ParseDirectiveTBSS
    690 ///  ::= .tbss identifier, size, align
    691 bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {
    692   SMLoc IDLoc = getLexer().getLoc();
    693   StringRef Name;
    694   if (getParser().parseIdentifier(Name))
    695     return TokError("expected identifier in directive");
    696 
    697   // Handle the identifier as the key symbol.
    698   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
    699 
    700   if (getLexer().isNot(AsmToken::Comma))
    701     return TokError("unexpected token in directive");
    702   Lex();
    703 
    704   int64_t Size;
    705   SMLoc SizeLoc = getLexer().getLoc();
    706   if (getParser().parseAbsoluteExpression(Size))
    707     return true;
    708 
    709   int64_t Pow2Alignment = 0;
    710   SMLoc Pow2AlignmentLoc;
    711   if (getLexer().is(AsmToken::Comma)) {
    712     Lex();
    713     Pow2AlignmentLoc = getLexer().getLoc();
    714     if (getParser().parseAbsoluteExpression(Pow2Alignment))
    715       return true;
    716   }
    717 
    718   if (getLexer().isNot(AsmToken::EndOfStatement))
    719     return TokError("unexpected token in '.tbss' directive");
    720 
    721   Lex();
    722 
    723   if (Size < 0)
    724     return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"
    725                  "zero");
    726 
    727   // FIXME: Diagnose overflow.
    728   if (Pow2Alignment < 0)
    729     return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"
    730                  "than zero");
    731 
    732   if (!Sym->isUndefined())
    733     return Error(IDLoc, "invalid symbol redefinition");
    734 
    735   getStreamer().EmitTBSSSymbol(getContext().getMachOSection(
    736                                  "__DATA", "__thread_bss",
    737                                  MachO::S_THREAD_LOCAL_ZEROFILL,
    738                                  0, SectionKind::getThreadBSS()),
    739                                Sym, Size, 1 << Pow2Alignment);
    740 
    741   return false;
    742 }
    743 
    744 /// ParseDirectiveZerofill
    745 ///  ::= .zerofill segname , sectname [, identifier , size_expression [
    746 ///      , align_expression ]]
    747 bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {
    748   StringRef Segment;
    749   if (getParser().parseIdentifier(Segment))
    750     return TokError("expected segment name after '.zerofill' directive");
    751 
    752   if (getLexer().isNot(AsmToken::Comma))
    753     return TokError("unexpected token in directive");
    754   Lex();
    755 
    756   StringRef Section;
    757   if (getParser().parseIdentifier(Section))
    758     return TokError("expected section name after comma in '.zerofill' "
    759                     "directive");
    760 
    761   // If this is the end of the line all that was wanted was to create the
    762   // the section but with no symbol.
    763   if (getLexer().is(AsmToken::EndOfStatement)) {
    764     // Create the zerofill section but no symbol
    765     getStreamer().EmitZerofill(getContext().getMachOSection(
    766                                  Segment, Section, MachO::S_ZEROFILL,
    767                                  0, SectionKind::getBSS()));
    768     return false;
    769   }
    770 
    771   if (getLexer().isNot(AsmToken::Comma))
    772     return TokError("unexpected token in directive");
    773   Lex();
    774 
    775   SMLoc IDLoc = getLexer().getLoc();
    776   StringRef IDStr;
    777   if (getParser().parseIdentifier(IDStr))
    778     return TokError("expected identifier in directive");
    779 
    780   // handle the identifier as the key symbol.
    781   MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr);
    782 
    783   if (getLexer().isNot(AsmToken::Comma))
    784     return TokError("unexpected token in directive");
    785   Lex();
    786 
    787   int64_t Size;
    788   SMLoc SizeLoc = getLexer().getLoc();
    789   if (getParser().parseAbsoluteExpression(Size))
    790     return true;
    791 
    792   int64_t Pow2Alignment = 0;
    793   SMLoc Pow2AlignmentLoc;
    794   if (getLexer().is(AsmToken::Comma)) {
    795     Lex();
    796     Pow2AlignmentLoc = getLexer().getLoc();
    797     if (getParser().parseAbsoluteExpression(Pow2Alignment))
    798       return true;
    799   }
    800 
    801   if (getLexer().isNot(AsmToken::EndOfStatement))
    802     return TokError("unexpected token in '.zerofill' directive");
    803 
    804   Lex();
    805 
    806   if (Size < 0)
    807     return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "
    808                  "than zero");
    809 
    810   // NOTE: The alignment in the directive is a power of 2 value, the assembler
    811   // may internally end up wanting an alignment in bytes.
    812   // FIXME: Diagnose overflow.
    813   if (Pow2Alignment < 0)
    814     return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "
    815                  "can't be less than zero");
    816 
    817   if (!Sym->isUndefined())
    818     return Error(IDLoc, "invalid symbol redefinition");
    819 
    820   // Create the zerofill Symbol with Size and Pow2Alignment
    821   //
    822   // FIXME: Arch specific.
    823   getStreamer().EmitZerofill(getContext().getMachOSection(
    824                                Segment, Section, MachO::S_ZEROFILL,
    825                                0, SectionKind::getBSS()),
    826                              Sym, Size, 1 << Pow2Alignment);
    827 
    828   return false;
    829 }
    830 
    831 /// ParseDirectiveDataRegion
    832 ///  ::= .data_region [ ( jt8 | jt16 | jt32 ) ]
    833 bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {
    834   if (getLexer().is(AsmToken::EndOfStatement)) {
    835     Lex();
    836     getStreamer().EmitDataRegion(MCDR_DataRegion);
    837     return false;
    838   }
    839   StringRef RegionType;
    840   SMLoc Loc = getParser().getTok().getLoc();
    841   if (getParser().parseIdentifier(RegionType))
    842     return TokError("expected region type after '.data_region' directive");
    843   int Kind = StringSwitch<int>(RegionType)
    844     .Case("jt8", MCDR_DataRegionJT8)
    845     .Case("jt16", MCDR_DataRegionJT16)
    846     .Case("jt32", MCDR_DataRegionJT32)
    847     .Default(-1);
    848   if (Kind == -1)
    849     return Error(Loc, "unknown region type in '.data_region' directive");
    850   Lex();
    851 
    852   getStreamer().EmitDataRegion((MCDataRegionType)Kind);
    853   return false;
    854 }
    855 
    856 /// ParseDirectiveDataRegionEnd
    857 ///  ::= .end_data_region
    858 bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
    859   if (getLexer().isNot(AsmToken::EndOfStatement))
    860     return TokError("unexpected token in '.end_data_region' directive");
    861 
    862   Lex();
    863   getStreamer().EmitDataRegion(MCDR_DataRegionEnd);
    864   return false;
    865 }
    866 
    867 /// parseVersionMin
    868 ///  ::= .ios_version_min major,minor[,update]
    869 ///  ::= .macosx_version_min major,minor[,update]
    870 bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
    871   int64_t Major = 0, Minor = 0, Update = 0;
    872   int Kind = StringSwitch<int>(Directive)
    873     .Case(".ios_version_min", MCVM_IOSVersionMin)
    874     .Case(".macosx_version_min", MCVM_OSXVersionMin);
    875   // Get the major version number.
    876   if (getLexer().isNot(AsmToken::Integer))
    877     return TokError("invalid OS major version number");
    878   Major = getLexer().getTok().getIntVal();
    879   if (Major > 65535 || Major <= 0)
    880     return TokError("invalid OS major version number");
    881   Lex();
    882   if (getLexer().isNot(AsmToken::Comma))
    883     return TokError("minor OS version number required, comma expected");
    884   Lex();
    885   // Get the minor version number.
    886   if (getLexer().isNot(AsmToken::Integer))
    887     return TokError("invalid OS minor version number");
    888   Minor = getLexer().getTok().getIntVal();
    889   if (Minor > 255 || Minor < 0)
    890     return TokError("invalid OS minor version number");
    891   Lex();
    892   // Get the update level, if specified
    893   if (getLexer().isNot(AsmToken::EndOfStatement)) {
    894     if (getLexer().isNot(AsmToken::Comma))
    895       return TokError("invalid update specifier, comma expected");
    896     Lex();
    897     if (getLexer().isNot(AsmToken::Integer))
    898       return TokError("invalid OS update number");
    899     Update = getLexer().getTok().getIntVal();
    900   if (Update > 255 || Update < 0)
    901     return TokError("invalid OS update number");
    902     Lex();
    903   }
    904 
    905   // We've parsed a correct version specifier, so send it to the streamer.
    906   getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
    907 
    908   return false;
    909 }
    910 
    911 namespace llvm {
    912 
    913 MCAsmParserExtension *createDarwinAsmParser() {
    914   return new DarwinAsmParser;
    915 }
    916 
    917 } // end llvm namespace
    918