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