LLVM API Documentation
00001 //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 00011 #include "llvm/ADT/StringRef.h" 00012 #include "llvm/ADT/StringSwitch.h" 00013 #include "llvm/ADT/Twine.h" 00014 #include "llvm/MC/MCContext.h" 00015 #include "llvm/MC/MCParser/MCAsmLexer.h" 00016 #include "llvm/MC/MCParser/MCAsmParser.h" 00017 #include "llvm/MC/MCSectionMachO.h" 00018 #include "llvm/MC/MCStreamer.h" 00019 #include "llvm/MC/MCSymbol.h" 00020 #include "llvm/Support/FileSystem.h" 00021 #include "llvm/Support/MemoryBuffer.h" 00022 #include "llvm/Support/SourceMgr.h" 00023 using namespace llvm; 00024 00025 namespace { 00026 00027 /// \brief Implementation of directive handling which is shared across all 00028 /// Darwin targets. 00029 class DarwinAsmParser : public MCAsmParserExtension { 00030 template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)> 00031 void addDirectiveHandler(StringRef Directive) { 00032 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( 00033 this, HandleDirective<DarwinAsmParser, HandlerMethod>); 00034 getParser().addDirectiveHandler(Directive, Handler); 00035 } 00036 00037 bool parseSectionSwitch(const char *Segment, const char *Section, 00038 unsigned TAA = 0, unsigned ImplicitAlign = 0, 00039 unsigned StubSize = 0); 00040 00041 public: 00042 DarwinAsmParser() {} 00043 00044 void Initialize(MCAsmParser &Parser) override { 00045 // Call the base implementation. 00046 this->MCAsmParserExtension::Initialize(Parser); 00047 00048 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc"); 00049 addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>( 00050 ".indirect_symbol"); 00051 addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym"); 00052 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>( 00053 ".subsections_via_symbols"); 00054 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump"); 00055 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load"); 00056 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section"); 00057 addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>( 00058 ".pushsection"); 00059 addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>( 00060 ".popsection"); 00061 addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous"); 00062 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>( 00063 ".secure_log_unique"); 00064 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>( 00065 ".secure_log_reset"); 00066 addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss"); 00067 addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill"); 00068 00069 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>( 00070 ".data_region"); 00071 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>( 00072 ".end_data_region"); 00073 00074 // Special section directives. 00075 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss"); 00076 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const"); 00077 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>( 00078 ".const_data"); 00079 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>( 00080 ".constructor"); 00081 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>( 00082 ".cstring"); 00083 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data"); 00084 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>( 00085 ".destructor"); 00086 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld"); 00087 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>( 00088 ".fvmlib_init0"); 00089 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>( 00090 ".fvmlib_init1"); 00091 addDirectiveHandler< 00092 &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>( 00093 ".lazy_symbol_pointer"); 00094 addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>( 00095 ".linker_option"); 00096 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>( 00097 ".literal16"); 00098 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>( 00099 ".literal4"); 00100 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>( 00101 ".literal8"); 00102 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>( 00103 ".mod_init_func"); 00104 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>( 00105 ".mod_term_func"); 00106 addDirectiveHandler< 00107 &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>( 00108 ".non_lazy_symbol_pointer"); 00109 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>( 00110 ".objc_cat_cls_meth"); 00111 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>( 00112 ".objc_cat_inst_meth"); 00113 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>( 00114 ".objc_category"); 00115 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>( 00116 ".objc_class"); 00117 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>( 00118 ".objc_class_names"); 00119 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>( 00120 ".objc_class_vars"); 00121 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>( 00122 ".objc_cls_meth"); 00123 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>( 00124 ".objc_cls_refs"); 00125 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>( 00126 ".objc_inst_meth"); 00127 addDirectiveHandler< 00128 &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>( 00129 ".objc_instance_vars"); 00130 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>( 00131 ".objc_message_refs"); 00132 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>( 00133 ".objc_meta_class"); 00134 addDirectiveHandler< 00135 &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>( 00136 ".objc_meth_var_names"); 00137 addDirectiveHandler< 00138 &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>( 00139 ".objc_meth_var_types"); 00140 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>( 00141 ".objc_module_info"); 00142 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>( 00143 ".objc_protocol"); 00144 addDirectiveHandler< 00145 &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>( 00146 ".objc_selector_strs"); 00147 addDirectiveHandler< 00148 &DarwinAsmParser::parseSectionDirectiveObjCStringObject>( 00149 ".objc_string_object"); 00150 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>( 00151 ".objc_symbols"); 00152 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>( 00153 ".picsymbol_stub"); 00154 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>( 00155 ".static_const"); 00156 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>( 00157 ".static_data"); 00158 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>( 00159 ".symbol_stub"); 00160 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata"); 00161 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text"); 00162 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>( 00163 ".thread_init_func"); 00164 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv"); 00165 00166 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident"); 00167 addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min"); 00168 addDirectiveHandler<&DarwinAsmParser::parseVersionMin>( 00169 ".macosx_version_min"); 00170 } 00171 00172 bool parseDirectiveDesc(StringRef, SMLoc); 00173 bool parseDirectiveIndirectSymbol(StringRef, SMLoc); 00174 bool parseDirectiveDumpOrLoad(StringRef, SMLoc); 00175 bool parseDirectiveLsym(StringRef, SMLoc); 00176 bool parseDirectiveLinkerOption(StringRef, SMLoc); 00177 bool parseDirectiveSection(StringRef, SMLoc); 00178 bool parseDirectivePushSection(StringRef, SMLoc); 00179 bool parseDirectivePopSection(StringRef, SMLoc); 00180 bool parseDirectivePrevious(StringRef, SMLoc); 00181 bool parseDirectiveSecureLogReset(StringRef, SMLoc); 00182 bool parseDirectiveSecureLogUnique(StringRef, SMLoc); 00183 bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); 00184 bool parseDirectiveTBSS(StringRef, SMLoc); 00185 bool parseDirectiveZerofill(StringRef, SMLoc); 00186 bool parseDirectiveDataRegion(StringRef, SMLoc); 00187 bool parseDirectiveDataRegionEnd(StringRef, SMLoc); 00188 00189 // Named Section Directive 00190 bool parseSectionDirectiveBss(StringRef, SMLoc) { 00191 return parseSectionSwitch("__DATA", "__bss"); 00192 } 00193 00194 bool parseSectionDirectiveConst(StringRef, SMLoc) { 00195 return parseSectionSwitch("__TEXT", "__const"); 00196 } 00197 bool parseSectionDirectiveStaticConst(StringRef, SMLoc) { 00198 return parseSectionSwitch("__TEXT", "__static_const"); 00199 } 00200 bool parseSectionDirectiveCString(StringRef, SMLoc) { 00201 return parseSectionSwitch("__TEXT","__cstring", 00202 MachO::S_CSTRING_LITERALS); 00203 } 00204 bool parseSectionDirectiveLiteral4(StringRef, SMLoc) { 00205 return parseSectionSwitch("__TEXT", "__literal4", 00206 MachO::S_4BYTE_LITERALS, 4); 00207 } 00208 bool parseSectionDirectiveLiteral8(StringRef, SMLoc) { 00209 return parseSectionSwitch("__TEXT", "__literal8", 00210 MachO::S_8BYTE_LITERALS, 8); 00211 } 00212 bool parseSectionDirectiveLiteral16(StringRef, SMLoc) { 00213 return parseSectionSwitch("__TEXT","__literal16", 00214 MachO::S_16BYTE_LITERALS, 16); 00215 } 00216 bool parseSectionDirectiveConstructor(StringRef, SMLoc) { 00217 return parseSectionSwitch("__TEXT","__constructor"); 00218 } 00219 bool parseSectionDirectiveDestructor(StringRef, SMLoc) { 00220 return parseSectionSwitch("__TEXT","__destructor"); 00221 } 00222 bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { 00223 return parseSectionSwitch("__TEXT","__fvmlib_init0"); 00224 } 00225 bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { 00226 return parseSectionSwitch("__TEXT","__fvmlib_init1"); 00227 } 00228 bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) { 00229 return parseSectionSwitch("__TEXT","__symbol_stub", 00230 MachO::S_SYMBOL_STUBS | 00231 MachO::S_ATTR_PURE_INSTRUCTIONS, 00232 // FIXME: Different on PPC and ARM. 00233 0, 16); 00234 } 00235 bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) { 00236 return parseSectionSwitch("__TEXT","__picsymbol_stub", 00237 MachO::S_SYMBOL_STUBS | 00238 MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); 00239 } 00240 bool parseSectionDirectiveData(StringRef, SMLoc) { 00241 return parseSectionSwitch("__DATA", "__data"); 00242 } 00243 bool parseSectionDirectiveStaticData(StringRef, SMLoc) { 00244 return parseSectionSwitch("__DATA", "__static_data"); 00245 } 00246 bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { 00247 return parseSectionSwitch("__DATA", "__nl_symbol_ptr", 00248 MachO::S_NON_LAZY_SYMBOL_POINTERS, 4); 00249 } 00250 bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { 00251 return parseSectionSwitch("__DATA", "__la_symbol_ptr", 00252 MachO::S_LAZY_SYMBOL_POINTERS, 4); 00253 } 00254 bool parseSectionDirectiveDyld(StringRef, SMLoc) { 00255 return parseSectionSwitch("__DATA", "__dyld"); 00256 } 00257 bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) { 00258 return parseSectionSwitch("__DATA", "__mod_init_func", 00259 MachO::S_MOD_INIT_FUNC_POINTERS, 4); 00260 } 00261 bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) { 00262 return parseSectionSwitch("__DATA", "__mod_term_func", 00263 MachO::S_MOD_TERM_FUNC_POINTERS, 4); 00264 } 00265 bool parseSectionDirectiveConstData(StringRef, SMLoc) { 00266 return parseSectionSwitch("__DATA", "__const"); 00267 } 00268 bool parseSectionDirectiveObjCClass(StringRef, SMLoc) { 00269 return parseSectionSwitch("__OBJC", "__class", 00270 MachO::S_ATTR_NO_DEAD_STRIP); 00271 } 00272 bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { 00273 return parseSectionSwitch("__OBJC", "__meta_class", 00274 MachO::S_ATTR_NO_DEAD_STRIP); 00275 } 00276 bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { 00277 return parseSectionSwitch("__OBJC", "__cat_cls_meth", 00278 MachO::S_ATTR_NO_DEAD_STRIP); 00279 } 00280 bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { 00281 return parseSectionSwitch("__OBJC", "__cat_inst_meth", 00282 MachO::S_ATTR_NO_DEAD_STRIP); 00283 } 00284 bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) { 00285 return parseSectionSwitch("__OBJC", "__protocol", 00286 MachO::S_ATTR_NO_DEAD_STRIP); 00287 } 00288 bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) { 00289 return parseSectionSwitch("__OBJC", "__string_object", 00290 MachO::S_ATTR_NO_DEAD_STRIP); 00291 } 00292 bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { 00293 return parseSectionSwitch("__OBJC", "__cls_meth", 00294 MachO::S_ATTR_NO_DEAD_STRIP); 00295 } 00296 bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { 00297 return parseSectionSwitch("__OBJC", "__inst_meth", 00298 MachO::S_ATTR_NO_DEAD_STRIP); 00299 } 00300 bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { 00301 return parseSectionSwitch("__OBJC", "__cls_refs", 00302 MachO::S_ATTR_NO_DEAD_STRIP | 00303 MachO::S_LITERAL_POINTERS, 4); 00304 } 00305 bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { 00306 return parseSectionSwitch("__OBJC", "__message_refs", 00307 MachO::S_ATTR_NO_DEAD_STRIP | 00308 MachO::S_LITERAL_POINTERS, 4); 00309 } 00310 bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) { 00311 return parseSectionSwitch("__OBJC", "__symbols", 00312 MachO::S_ATTR_NO_DEAD_STRIP); 00313 } 00314 bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) { 00315 return parseSectionSwitch("__OBJC", "__category", 00316 MachO::S_ATTR_NO_DEAD_STRIP); 00317 } 00318 bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) { 00319 return parseSectionSwitch("__OBJC", "__class_vars", 00320 MachO::S_ATTR_NO_DEAD_STRIP); 00321 } 00322 bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { 00323 return parseSectionSwitch("__OBJC", "__instance_vars", 00324 MachO::S_ATTR_NO_DEAD_STRIP); 00325 } 00326 bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { 00327 return parseSectionSwitch("__OBJC", "__module_info", 00328 MachO::S_ATTR_NO_DEAD_STRIP); 00329 } 00330 bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) { 00331 return parseSectionSwitch("__TEXT", "__cstring", 00332 MachO::S_CSTRING_LITERALS); 00333 } 00334 bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { 00335 return parseSectionSwitch("__TEXT", "__cstring", 00336 MachO::S_CSTRING_LITERALS); 00337 } 00338 bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { 00339 return parseSectionSwitch("__TEXT", "__cstring", 00340 MachO::S_CSTRING_LITERALS); 00341 } 00342 bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { 00343 return parseSectionSwitch("__OBJC", "__selector_strs", 00344 MachO::S_CSTRING_LITERALS); 00345 } 00346 bool parseSectionDirectiveTData(StringRef, SMLoc) { 00347 return parseSectionSwitch("__DATA", "__thread_data", 00348 MachO::S_THREAD_LOCAL_REGULAR); 00349 } 00350 bool parseSectionDirectiveText(StringRef, SMLoc) { 00351 return parseSectionSwitch("__TEXT", "__text", 00352 MachO::S_ATTR_PURE_INSTRUCTIONS); 00353 } 00354 bool parseSectionDirectiveTLV(StringRef, SMLoc) { 00355 return parseSectionSwitch("__DATA", "__thread_vars", 00356 MachO::S_THREAD_LOCAL_VARIABLES); 00357 } 00358 bool parseSectionDirectiveIdent(StringRef, SMLoc) { 00359 // Darwin silently ignores the .ident directive. 00360 getParser().eatToEndOfStatement(); 00361 return false; 00362 } 00363 bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { 00364 return parseSectionSwitch("__DATA", "__thread_init", 00365 MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); 00366 } 00367 bool parseVersionMin(StringRef, SMLoc); 00368 00369 }; 00370 00371 } // end anonymous namespace 00372 00373 bool DarwinAsmParser::parseSectionSwitch(const char *Segment, 00374 const char *Section, 00375 unsigned TAA, unsigned Align, 00376 unsigned StubSize) { 00377 if (getLexer().isNot(AsmToken::EndOfStatement)) 00378 return TokError("unexpected token in section switching directive"); 00379 Lex(); 00380 00381 // FIXME: Arch specific. 00382 bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS; 00383 getStreamer().SwitchSection(getContext().getMachOSection( 00384 Segment, Section, TAA, StubSize, 00385 isText ? SectionKind::getText() 00386 : SectionKind::getDataRel())); 00387 00388 // Set the implicit alignment, if any. 00389 // 00390 // FIXME: This isn't really what 'as' does; I think it just uses the implicit 00391 // alignment on the section (e.g., if one manually inserts bytes into the 00392 // section, then just issuing the section switch directive will not realign 00393 // the section. However, this is arguably more reasonable behavior, and there 00394 // is no good reason for someone to intentionally emit incorrectly sized 00395 // values into the implicitly aligned sections. 00396 if (Align) 00397 getStreamer().EmitValueToAlignment(Align); 00398 00399 return false; 00400 } 00401 00402 /// parseDirectiveDesc 00403 /// ::= .desc identifier , expression 00404 bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { 00405 StringRef Name; 00406 if (getParser().parseIdentifier(Name)) 00407 return TokError("expected identifier in directive"); 00408 00409 // Handle the identifier as the key symbol. 00410 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00411 00412 if (getLexer().isNot(AsmToken::Comma)) 00413 return TokError("unexpected token in '.desc' directive"); 00414 Lex(); 00415 00416 int64_t DescValue; 00417 if (getParser().parseAbsoluteExpression(DescValue)) 00418 return true; 00419 00420 if (getLexer().isNot(AsmToken::EndOfStatement)) 00421 return TokError("unexpected token in '.desc' directive"); 00422 00423 Lex(); 00424 00425 // Set the n_desc field of this Symbol to this DescValue 00426 getStreamer().EmitSymbolDesc(Sym, DescValue); 00427 00428 return false; 00429 } 00430 00431 /// parseDirectiveIndirectSymbol 00432 /// ::= .indirect_symbol identifier 00433 bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { 00434 const MCSectionMachO *Current = static_cast<const MCSectionMachO*>( 00435 getStreamer().getCurrentSection().first); 00436 MachO::SectionType SectionType = Current->getType(); 00437 if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && 00438 SectionType != MachO::S_LAZY_SYMBOL_POINTERS && 00439 SectionType != MachO::S_SYMBOL_STUBS) 00440 return Error(Loc, "indirect symbol not in a symbol pointer or stub " 00441 "section"); 00442 00443 StringRef Name; 00444 if (getParser().parseIdentifier(Name)) 00445 return TokError("expected identifier in .indirect_symbol directive"); 00446 00447 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00448 00449 // Assembler local symbols don't make any sense here. Complain loudly. 00450 if (Sym->isTemporary()) 00451 return TokError("non-local symbol required in directive"); 00452 00453 if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol)) 00454 return TokError("unable to emit indirect symbol attribute for: " + Name); 00455 00456 if (getLexer().isNot(AsmToken::EndOfStatement)) 00457 return TokError("unexpected token in '.indirect_symbol' directive"); 00458 00459 Lex(); 00460 00461 return false; 00462 } 00463 00464 /// parseDirectiveDumpOrLoad 00465 /// ::= ( .dump | .load ) "filename" 00466 bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive, 00467 SMLoc IDLoc) { 00468 bool IsDump = Directive == ".dump"; 00469 if (getLexer().isNot(AsmToken::String)) 00470 return TokError("expected string in '.dump' or '.load' directive"); 00471 00472 Lex(); 00473 00474 if (getLexer().isNot(AsmToken::EndOfStatement)) 00475 return TokError("unexpected token in '.dump' or '.load' directive"); 00476 00477 Lex(); 00478 00479 // FIXME: If/when .dump and .load are implemented they will be done in the 00480 // the assembly parser and not have any need for an MCStreamer API. 00481 if (IsDump) 00482 return Warning(IDLoc, "ignoring directive .dump for now"); 00483 else 00484 return Warning(IDLoc, "ignoring directive .load for now"); 00485 } 00486 00487 /// ParseDirectiveLinkerOption 00488 /// ::= .linker_option "string" ( , "string" )* 00489 bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) { 00490 SmallVector<std::string, 4> Args; 00491 for (;;) { 00492 if (getLexer().isNot(AsmToken::String)) 00493 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 00494 00495 std::string Data; 00496 if (getParser().parseEscapedString(Data)) 00497 return true; 00498 00499 Args.push_back(Data); 00500 00501 Lex(); 00502 if (getLexer().is(AsmToken::EndOfStatement)) 00503 break; 00504 00505 if (getLexer().isNot(AsmToken::Comma)) 00506 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 00507 Lex(); 00508 } 00509 00510 getStreamer().EmitLinkerOptions(Args); 00511 return false; 00512 } 00513 00514 /// parseDirectiveLsym 00515 /// ::= .lsym identifier , expression 00516 bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { 00517 StringRef Name; 00518 if (getParser().parseIdentifier(Name)) 00519 return TokError("expected identifier in directive"); 00520 00521 // Handle the identifier as the key symbol. 00522 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00523 00524 if (getLexer().isNot(AsmToken::Comma)) 00525 return TokError("unexpected token in '.lsym' directive"); 00526 Lex(); 00527 00528 const MCExpr *Value; 00529 if (getParser().parseExpression(Value)) 00530 return true; 00531 00532 if (getLexer().isNot(AsmToken::EndOfStatement)) 00533 return TokError("unexpected token in '.lsym' directive"); 00534 00535 Lex(); 00536 00537 // We don't currently support this directive. 00538 // 00539 // FIXME: Diagnostic location! 00540 (void) Sym; 00541 return TokError("directive '.lsym' is unsupported"); 00542 } 00543 00544 /// parseDirectiveSection: 00545 /// ::= .section identifier (',' identifier)* 00546 bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { 00547 SMLoc Loc = getLexer().getLoc(); 00548 00549 StringRef SectionName; 00550 if (getParser().parseIdentifier(SectionName)) 00551 return Error(Loc, "expected identifier after '.section' directive"); 00552 00553 // Verify there is a following comma. 00554 if (!getLexer().is(AsmToken::Comma)) 00555 return TokError("unexpected token in '.section' directive"); 00556 00557 std::string SectionSpec = SectionName; 00558 SectionSpec += ","; 00559 00560 // Add all the tokens until the end of the line, ParseSectionSpecifier will 00561 // handle this. 00562 StringRef EOL = getLexer().LexUntilEndOfStatement(); 00563 SectionSpec.append(EOL.begin(), EOL.end()); 00564 00565 Lex(); 00566 if (getLexer().isNot(AsmToken::EndOfStatement)) 00567 return TokError("unexpected token in '.section' directive"); 00568 Lex(); 00569 00570 00571 StringRef Segment, Section; 00572 unsigned StubSize; 00573 unsigned TAA; 00574 bool TAAParsed; 00575 std::string ErrorStr = 00576 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, 00577 TAA, TAAParsed, StubSize); 00578 00579 if (!ErrorStr.empty()) 00580 return Error(Loc, ErrorStr.c_str()); 00581 00582 // FIXME: Arch specific. 00583 bool isText = Segment == "__TEXT"; // FIXME: Hack. 00584 getStreamer().SwitchSection(getContext().getMachOSection( 00585 Segment, Section, TAA, StubSize, 00586 isText ? SectionKind::getText() 00587 : SectionKind::getDataRel())); 00588 return false; 00589 } 00590 00591 /// ParseDirectivePushSection: 00592 /// ::= .pushsection identifier (',' identifier)* 00593 bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) { 00594 getStreamer().PushSection(); 00595 00596 if (parseDirectiveSection(S, Loc)) { 00597 getStreamer().PopSection(); 00598 return true; 00599 } 00600 00601 return false; 00602 } 00603 00604 /// ParseDirectivePopSection: 00605 /// ::= .popsection 00606 bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { 00607 if (!getStreamer().PopSection()) 00608 return TokError(".popsection without corresponding .pushsection"); 00609 return false; 00610 } 00611 00612 /// ParseDirectivePrevious: 00613 /// ::= .previous 00614 bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { 00615 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 00616 if (!PreviousSection.first) 00617 return TokError(".previous without corresponding .section"); 00618 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 00619 return false; 00620 } 00621 00622 /// ParseDirectiveSecureLogUnique 00623 /// ::= .secure_log_unique ... message ... 00624 bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { 00625 StringRef LogMessage = getParser().parseStringToEndOfStatement(); 00626 if (getLexer().isNot(AsmToken::EndOfStatement)) 00627 return TokError("unexpected token in '.secure_log_unique' directive"); 00628 00629 if (getContext().getSecureLogUsed() != false) 00630 return Error(IDLoc, ".secure_log_unique specified multiple times"); 00631 00632 // Get the secure log path. 00633 const char *SecureLogFile = getContext().getSecureLogFile(); 00634 if (!SecureLogFile) 00635 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " 00636 "environment variable unset."); 00637 00638 // Open the secure log file if we haven't already. 00639 raw_ostream *OS = getContext().getSecureLog(); 00640 if (!OS) { 00641 std::error_code EC; 00642 OS = new raw_fd_ostream(SecureLogFile, EC, 00643 sys::fs::F_Append | sys::fs::F_Text); 00644 if (EC) { 00645 delete OS; 00646 return Error(IDLoc, Twine("can't open secure log file: ") + 00647 SecureLogFile + " (" + EC.message() + ")"); 00648 } 00649 getContext().setSecureLog(OS); 00650 } 00651 00652 // Write the message. 00653 unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); 00654 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() 00655 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" 00656 << LogMessage + "\n"; 00657 00658 getContext().setSecureLogUsed(true); 00659 00660 return false; 00661 } 00662 00663 /// ParseDirectiveSecureLogReset 00664 /// ::= .secure_log_reset 00665 bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { 00666 if (getLexer().isNot(AsmToken::EndOfStatement)) 00667 return TokError("unexpected token in '.secure_log_reset' directive"); 00668 00669 Lex(); 00670 00671 getContext().setSecureLogUsed(false); 00672 00673 return false; 00674 } 00675 00676 /// parseDirectiveSubsectionsViaSymbols 00677 /// ::= .subsections_via_symbols 00678 bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { 00679 if (getLexer().isNot(AsmToken::EndOfStatement)) 00680 return TokError("unexpected token in '.subsections_via_symbols' directive"); 00681 00682 Lex(); 00683 00684 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 00685 00686 return false; 00687 } 00688 00689 /// ParseDirectiveTBSS 00690 /// ::= .tbss identifier, size, align 00691 bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { 00692 SMLoc IDLoc = getLexer().getLoc(); 00693 StringRef Name; 00694 if (getParser().parseIdentifier(Name)) 00695 return TokError("expected identifier in directive"); 00696 00697 // Handle the identifier as the key symbol. 00698 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 00699 00700 if (getLexer().isNot(AsmToken::Comma)) 00701 return TokError("unexpected token in directive"); 00702 Lex(); 00703 00704 int64_t Size; 00705 SMLoc SizeLoc = getLexer().getLoc(); 00706 if (getParser().parseAbsoluteExpression(Size)) 00707 return true; 00708 00709 int64_t Pow2Alignment = 0; 00710 SMLoc Pow2AlignmentLoc; 00711 if (getLexer().is(AsmToken::Comma)) { 00712 Lex(); 00713 Pow2AlignmentLoc = getLexer().getLoc(); 00714 if (getParser().parseAbsoluteExpression(Pow2Alignment)) 00715 return true; 00716 } 00717 00718 if (getLexer().isNot(AsmToken::EndOfStatement)) 00719 return TokError("unexpected token in '.tbss' directive"); 00720 00721 Lex(); 00722 00723 if (Size < 0) 00724 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" 00725 "zero"); 00726 00727 // FIXME: Diagnose overflow. 00728 if (Pow2Alignment < 0) 00729 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" 00730 "than zero"); 00731 00732 if (!Sym->isUndefined()) 00733 return Error(IDLoc, "invalid symbol redefinition"); 00734 00735 getStreamer().EmitTBSSSymbol(getContext().getMachOSection( 00736 "__DATA", "__thread_bss", 00737 MachO::S_THREAD_LOCAL_ZEROFILL, 00738 0, SectionKind::getThreadBSS()), 00739 Sym, Size, 1 << Pow2Alignment); 00740 00741 return false; 00742 } 00743 00744 /// ParseDirectiveZerofill 00745 /// ::= .zerofill segname , sectname [, identifier , size_expression [ 00746 /// , align_expression ]] 00747 bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { 00748 StringRef Segment; 00749 if (getParser().parseIdentifier(Segment)) 00750 return TokError("expected segment name after '.zerofill' directive"); 00751 00752 if (getLexer().isNot(AsmToken::Comma)) 00753 return TokError("unexpected token in directive"); 00754 Lex(); 00755 00756 StringRef Section; 00757 if (getParser().parseIdentifier(Section)) 00758 return TokError("expected section name after comma in '.zerofill' " 00759 "directive"); 00760 00761 // If this is the end of the line all that was wanted was to create the 00762 // the section but with no symbol. 00763 if (getLexer().is(AsmToken::EndOfStatement)) { 00764 // Create the zerofill section but no symbol 00765 getStreamer().EmitZerofill(getContext().getMachOSection( 00766 Segment, Section, MachO::S_ZEROFILL, 00767 0, SectionKind::getBSS())); 00768 return false; 00769 } 00770 00771 if (getLexer().isNot(AsmToken::Comma)) 00772 return TokError("unexpected token in directive"); 00773 Lex(); 00774 00775 SMLoc IDLoc = getLexer().getLoc(); 00776 StringRef IDStr; 00777 if (getParser().parseIdentifier(IDStr)) 00778 return TokError("expected identifier in directive"); 00779 00780 // handle the identifier as the key symbol. 00781 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr); 00782 00783 if (getLexer().isNot(AsmToken::Comma)) 00784 return TokError("unexpected token in directive"); 00785 Lex(); 00786 00787 int64_t Size; 00788 SMLoc SizeLoc = getLexer().getLoc(); 00789 if (getParser().parseAbsoluteExpression(Size)) 00790 return true; 00791 00792 int64_t Pow2Alignment = 0; 00793 SMLoc Pow2AlignmentLoc; 00794 if (getLexer().is(AsmToken::Comma)) { 00795 Lex(); 00796 Pow2AlignmentLoc = getLexer().getLoc(); 00797 if (getParser().parseAbsoluteExpression(Pow2Alignment)) 00798 return true; 00799 } 00800 00801 if (getLexer().isNot(AsmToken::EndOfStatement)) 00802 return TokError("unexpected token in '.zerofill' directive"); 00803 00804 Lex(); 00805 00806 if (Size < 0) 00807 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 00808 "than zero"); 00809 00810 // NOTE: The alignment in the directive is a power of 2 value, the assembler 00811 // may internally end up wanting an alignment in bytes. 00812 // FIXME: Diagnose overflow. 00813 if (Pow2Alignment < 0) 00814 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 00815 "can't be less than zero"); 00816 00817 if (!Sym->isUndefined()) 00818 return Error(IDLoc, "invalid symbol redefinition"); 00819 00820 // Create the zerofill Symbol with Size and Pow2Alignment 00821 // 00822 // FIXME: Arch specific. 00823 getStreamer().EmitZerofill(getContext().getMachOSection( 00824 Segment, Section, MachO::S_ZEROFILL, 00825 0, SectionKind::getBSS()), 00826 Sym, Size, 1 << Pow2Alignment); 00827 00828 return false; 00829 } 00830 00831 /// ParseDirectiveDataRegion 00832 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ] 00833 bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) { 00834 if (getLexer().is(AsmToken::EndOfStatement)) { 00835 Lex(); 00836 getStreamer().EmitDataRegion(MCDR_DataRegion); 00837 return false; 00838 } 00839 StringRef RegionType; 00840 SMLoc Loc = getParser().getTok().getLoc(); 00841 if (getParser().parseIdentifier(RegionType)) 00842 return TokError("expected region type after '.data_region' directive"); 00843 int Kind = StringSwitch<int>(RegionType) 00844 .Case("jt8", MCDR_DataRegionJT8) 00845 .Case("jt16", MCDR_DataRegionJT16) 00846 .Case("jt32", MCDR_DataRegionJT32) 00847 .Default(-1); 00848 if (Kind == -1) 00849 return Error(Loc, "unknown region type in '.data_region' directive"); 00850 Lex(); 00851 00852 getStreamer().EmitDataRegion((MCDataRegionType)Kind); 00853 return false; 00854 } 00855 00856 /// ParseDirectiveDataRegionEnd 00857 /// ::= .end_data_region 00858 bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) { 00859 if (getLexer().isNot(AsmToken::EndOfStatement)) 00860 return TokError("unexpected token in '.end_data_region' directive"); 00861 00862 Lex(); 00863 getStreamer().EmitDataRegion(MCDR_DataRegionEnd); 00864 return false; 00865 } 00866 00867 /// parseVersionMin 00868 /// ::= .ios_version_min major,minor[,update] 00869 /// ::= .macosx_version_min major,minor[,update] 00870 bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) { 00871 int64_t Major = 0, Minor = 0, Update = 0; 00872 int Kind = StringSwitch<int>(Directive) 00873 .Case(".ios_version_min", MCVM_IOSVersionMin) 00874 .Case(".macosx_version_min", MCVM_OSXVersionMin); 00875 // Get the major version number. 00876 if (getLexer().isNot(AsmToken::Integer)) 00877 return TokError("invalid OS major version number"); 00878 Major = getLexer().getTok().getIntVal(); 00879 if (Major > 65535 || Major <= 0) 00880 return TokError("invalid OS major version number"); 00881 Lex(); 00882 if (getLexer().isNot(AsmToken::Comma)) 00883 return TokError("minor OS version number required, comma expected"); 00884 Lex(); 00885 // Get the minor version number. 00886 if (getLexer().isNot(AsmToken::Integer)) 00887 return TokError("invalid OS minor version number"); 00888 Minor = getLexer().getTok().getIntVal(); 00889 if (Minor > 255 || Minor < 0) 00890 return TokError("invalid OS minor version number"); 00891 Lex(); 00892 // Get the update level, if specified 00893 if (getLexer().isNot(AsmToken::EndOfStatement)) { 00894 if (getLexer().isNot(AsmToken::Comma)) 00895 return TokError("invalid update specifier, comma expected"); 00896 Lex(); 00897 if (getLexer().isNot(AsmToken::Integer)) 00898 return TokError("invalid OS update number"); 00899 Update = getLexer().getTok().getIntVal(); 00900 if (Update > 255 || Update < 0) 00901 return TokError("invalid OS update number"); 00902 Lex(); 00903 } 00904 00905 // We've parsed a correct version specifier, so send it to the streamer. 00906 getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update); 00907 00908 return false; 00909 } 00910 00911 namespace llvm { 00912 00913 MCAsmParserExtension *createDarwinAsmParser() { 00914 return new DarwinAsmParser; 00915 } 00916 00917 } // end llvm namespace