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