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