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