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