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(StringRef Segment, StringRef 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(StringRef Segment, StringRef Section, 393 unsigned TAA, unsigned Align, 394 unsigned StubSize) { 395 if (getLexer().isNot(AsmToken::EndOfStatement)) 396 return TokError("unexpected token in section switching directive"); 397 Lex(); 398 399 // FIXME: Arch specific. 400 bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS; 401 getStreamer().SwitchSection(getContext().getMachOSection( 402 Segment, Section, TAA, StubSize, 403 isText ? SectionKind::getText() : SectionKind::getData())); 404 405 // Set the implicit alignment, if any. 406 // 407 // FIXME: This isn't really what 'as' does; I think it just uses the implicit 408 // alignment on the section (e.g., if one manually inserts bytes into the 409 // section, then just issuing the section switch directive will not realign 410 // the section. However, this is arguably more reasonable behavior, and there 411 // is no good reason for someone to intentionally emit incorrectly sized 412 // values into the implicitly aligned sections. 413 if (Align) 414 getStreamer().EmitValueToAlignment(Align); 415 416 return false; 417 } 418 419 /// parseDirectiveAltEntry 420 /// ::= .alt_entry identifier 421 bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) { 422 StringRef Name; 423 if (getParser().parseIdentifier(Name)) 424 return TokError("expected identifier in directive"); 425 426 // Look up symbol. 427 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 428 429 if (Sym->isDefined()) 430 return TokError(".alt_entry must preceed symbol definition"); 431 432 if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_AltEntry)) 433 return TokError("unable to emit symbol attribute"); 434 435 Lex(); 436 return false; 437 } 438 439 /// parseDirectiveDesc 440 /// ::= .desc identifier , expression 441 bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { 442 StringRef Name; 443 if (getParser().parseIdentifier(Name)) 444 return TokError("expected identifier in directive"); 445 446 // Handle the identifier as the key symbol. 447 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 448 449 if (getLexer().isNot(AsmToken::Comma)) 450 return TokError("unexpected token in '.desc' directive"); 451 Lex(); 452 453 int64_t DescValue; 454 if (getParser().parseAbsoluteExpression(DescValue)) 455 return true; 456 457 if (getLexer().isNot(AsmToken::EndOfStatement)) 458 return TokError("unexpected token in '.desc' directive"); 459 460 Lex(); 461 462 // Set the n_desc field of this Symbol to this DescValue 463 getStreamer().EmitSymbolDesc(Sym, DescValue); 464 465 return false; 466 } 467 468 /// parseDirectiveIndirectSymbol 469 /// ::= .indirect_symbol identifier 470 bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { 471 const MCSectionMachO *Current = static_cast<const MCSectionMachO *>( 472 getStreamer().getCurrentSectionOnly()); 473 MachO::SectionType SectionType = Current->getType(); 474 if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && 475 SectionType != MachO::S_LAZY_SYMBOL_POINTERS && 476 SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS && 477 SectionType != MachO::S_SYMBOL_STUBS) 478 return Error(Loc, "indirect symbol not in a symbol pointer or stub " 479 "section"); 480 481 StringRef Name; 482 if (getParser().parseIdentifier(Name)) 483 return TokError("expected identifier in .indirect_symbol directive"); 484 485 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 486 487 // Assembler local symbols don't make any sense here. Complain loudly. 488 if (Sym->isTemporary()) 489 return TokError("non-local symbol required in directive"); 490 491 if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol)) 492 return TokError("unable to emit indirect symbol attribute for: " + Name); 493 494 if (getLexer().isNot(AsmToken::EndOfStatement)) 495 return TokError("unexpected token in '.indirect_symbol' directive"); 496 497 Lex(); 498 499 return false; 500 } 501 502 /// parseDirectiveDumpOrLoad 503 /// ::= ( .dump | .load ) "filename" 504 bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive, 505 SMLoc IDLoc) { 506 bool IsDump = Directive == ".dump"; 507 if (getLexer().isNot(AsmToken::String)) 508 return TokError("expected string in '.dump' or '.load' directive"); 509 510 Lex(); 511 512 if (getLexer().isNot(AsmToken::EndOfStatement)) 513 return TokError("unexpected token in '.dump' or '.load' directive"); 514 515 Lex(); 516 517 // FIXME: If/when .dump and .load are implemented they will be done in the 518 // the assembly parser and not have any need for an MCStreamer API. 519 if (IsDump) 520 return Warning(IDLoc, "ignoring directive .dump for now"); 521 else 522 return Warning(IDLoc, "ignoring directive .load for now"); 523 } 524 525 /// ParseDirectiveLinkerOption 526 /// ::= .linker_option "string" ( , "string" )* 527 bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) { 528 SmallVector<std::string, 4> Args; 529 for (;;) { 530 if (getLexer().isNot(AsmToken::String)) 531 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 532 533 std::string Data; 534 if (getParser().parseEscapedString(Data)) 535 return true; 536 537 Args.push_back(Data); 538 539 if (getLexer().is(AsmToken::EndOfStatement)) 540 break; 541 542 if (getLexer().isNot(AsmToken::Comma)) 543 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 544 Lex(); 545 } 546 547 getStreamer().EmitLinkerOptions(Args); 548 return false; 549 } 550 551 /// parseDirectiveLsym 552 /// ::= .lsym identifier , expression 553 bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { 554 StringRef Name; 555 if (getParser().parseIdentifier(Name)) 556 return TokError("expected identifier in directive"); 557 558 // Handle the identifier as the key symbol. 559 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 560 561 if (getLexer().isNot(AsmToken::Comma)) 562 return TokError("unexpected token in '.lsym' directive"); 563 Lex(); 564 565 const MCExpr *Value; 566 if (getParser().parseExpression(Value)) 567 return true; 568 569 if (getLexer().isNot(AsmToken::EndOfStatement)) 570 return TokError("unexpected token in '.lsym' directive"); 571 572 Lex(); 573 574 // We don't currently support this directive. 575 // 576 // FIXME: Diagnostic location! 577 (void) Sym; 578 return TokError("directive '.lsym' is unsupported"); 579 } 580 581 /// parseDirectiveSection: 582 /// ::= .section identifier (',' identifier)* 583 bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { 584 SMLoc Loc = getLexer().getLoc(); 585 586 StringRef SectionName; 587 if (getParser().parseIdentifier(SectionName)) 588 return Error(Loc, "expected identifier after '.section' directive"); 589 590 // Verify there is a following comma. 591 if (!getLexer().is(AsmToken::Comma)) 592 return TokError("unexpected token in '.section' directive"); 593 594 std::string SectionSpec = SectionName; 595 SectionSpec += ","; 596 597 // Add all the tokens until the end of the line, ParseSectionSpecifier will 598 // handle this. 599 StringRef EOL = getLexer().LexUntilEndOfStatement(); 600 SectionSpec.append(EOL.begin(), EOL.end()); 601 602 Lex(); 603 if (getLexer().isNot(AsmToken::EndOfStatement)) 604 return TokError("unexpected token in '.section' directive"); 605 Lex(); 606 607 608 StringRef Segment, Section; 609 unsigned StubSize; 610 unsigned TAA; 611 bool TAAParsed; 612 std::string ErrorStr = 613 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, 614 TAA, TAAParsed, StubSize); 615 616 if (!ErrorStr.empty()) 617 return Error(Loc, ErrorStr); 618 619 // Issue a warning if the target is not powerpc and Section is a *coal* section. 620 Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple(); 621 Triple::ArchType ArchTy = TT.getArch(); 622 623 if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) { 624 StringRef NonCoalSection = StringSwitch<StringRef>(Section) 625 .Case("__textcoal_nt", "__text") 626 .Case("__const_coal", "__const") 627 .Case("__datacoal_nt", "__data") 628 .Default(Section); 629 630 if (!Section.equals(NonCoalSection)) { 631 StringRef SectionVal(Loc.getPointer()); 632 size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B); 633 SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B); 634 SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E); 635 getParser().Warning(Loc, "section \"" + Section + "\" is deprecated", 636 SMRange(BLoc, ELoc)); 637 getParser().Note(Loc, "change section name to \"" + NonCoalSection + 638 "\"", SMRange(BLoc, ELoc)); 639 } 640 } 641 642 // FIXME: Arch specific. 643 bool isText = Segment == "__TEXT"; // FIXME: Hack. 644 getStreamer().SwitchSection(getContext().getMachOSection( 645 Segment, Section, TAA, StubSize, 646 isText ? SectionKind::getText() : SectionKind::getData())); 647 return false; 648 } 649 650 /// ParseDirectivePushSection: 651 /// ::= .pushsection identifier (',' identifier)* 652 bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) { 653 getStreamer().PushSection(); 654 655 if (parseDirectiveSection(S, Loc)) { 656 getStreamer().PopSection(); 657 return true; 658 } 659 660 return false; 661 } 662 663 /// ParseDirectivePopSection: 664 /// ::= .popsection 665 bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { 666 if (!getStreamer().PopSection()) 667 return TokError(".popsection without corresponding .pushsection"); 668 return false; 669 } 670 671 /// ParseDirectivePrevious: 672 /// ::= .previous 673 bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { 674 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 675 if (!PreviousSection.first) 676 return TokError(".previous without corresponding .section"); 677 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 678 return false; 679 } 680 681 /// ParseDirectiveSecureLogUnique 682 /// ::= .secure_log_unique ... message ... 683 bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { 684 StringRef LogMessage = getParser().parseStringToEndOfStatement(); 685 if (getLexer().isNot(AsmToken::EndOfStatement)) 686 return TokError("unexpected token in '.secure_log_unique' directive"); 687 688 if (getContext().getSecureLogUsed()) 689 return Error(IDLoc, ".secure_log_unique specified multiple times"); 690 691 // Get the secure log path. 692 const char *SecureLogFile = getContext().getSecureLogFile(); 693 if (!SecureLogFile) 694 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " 695 "environment variable unset."); 696 697 // Open the secure log file if we haven't already. 698 raw_fd_ostream *OS = getContext().getSecureLog(); 699 if (!OS) { 700 std::error_code EC; 701 auto NewOS = llvm::make_unique<raw_fd_ostream>( 702 StringRef(SecureLogFile), EC, sys::fs::F_Append | sys::fs::F_Text); 703 if (EC) 704 return Error(IDLoc, Twine("can't open secure log file: ") + 705 SecureLogFile + " (" + EC.message() + ")"); 706 OS = NewOS.get(); 707 getContext().setSecureLog(std::move(NewOS)); 708 } 709 710 // Write the message. 711 unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); 712 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() 713 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" 714 << LogMessage + "\n"; 715 716 getContext().setSecureLogUsed(true); 717 718 return false; 719 } 720 721 /// ParseDirectiveSecureLogReset 722 /// ::= .secure_log_reset 723 bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { 724 if (getLexer().isNot(AsmToken::EndOfStatement)) 725 return TokError("unexpected token in '.secure_log_reset' directive"); 726 727 Lex(); 728 729 getContext().setSecureLogUsed(false); 730 731 return false; 732 } 733 734 /// parseDirectiveSubsectionsViaSymbols 735 /// ::= .subsections_via_symbols 736 bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { 737 if (getLexer().isNot(AsmToken::EndOfStatement)) 738 return TokError("unexpected token in '.subsections_via_symbols' directive"); 739 740 Lex(); 741 742 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 743 744 return false; 745 } 746 747 /// ParseDirectiveTBSS 748 /// ::= .tbss identifier, size, align 749 bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { 750 SMLoc IDLoc = getLexer().getLoc(); 751 StringRef Name; 752 if (getParser().parseIdentifier(Name)) 753 return TokError("expected identifier in directive"); 754 755 // Handle the identifier as the key symbol. 756 MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 757 758 if (getLexer().isNot(AsmToken::Comma)) 759 return TokError("unexpected token in directive"); 760 Lex(); 761 762 int64_t Size; 763 SMLoc SizeLoc = getLexer().getLoc(); 764 if (getParser().parseAbsoluteExpression(Size)) 765 return true; 766 767 int64_t Pow2Alignment = 0; 768 SMLoc Pow2AlignmentLoc; 769 if (getLexer().is(AsmToken::Comma)) { 770 Lex(); 771 Pow2AlignmentLoc = getLexer().getLoc(); 772 if (getParser().parseAbsoluteExpression(Pow2Alignment)) 773 return true; 774 } 775 776 if (getLexer().isNot(AsmToken::EndOfStatement)) 777 return TokError("unexpected token in '.tbss' directive"); 778 779 Lex(); 780 781 if (Size < 0) 782 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" 783 "zero"); 784 785 // FIXME: Diagnose overflow. 786 if (Pow2Alignment < 0) 787 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" 788 "than zero"); 789 790 if (!Sym->isUndefined()) 791 return Error(IDLoc, "invalid symbol redefinition"); 792 793 getStreamer().EmitTBSSSymbol(getContext().getMachOSection( 794 "__DATA", "__thread_bss", 795 MachO::S_THREAD_LOCAL_ZEROFILL, 796 0, SectionKind::getThreadBSS()), 797 Sym, Size, 1 << Pow2Alignment); 798 799 return false; 800 } 801 802 /// ParseDirectiveZerofill 803 /// ::= .zerofill segname , sectname [, identifier , size_expression [ 804 /// , align_expression ]] 805 bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { 806 StringRef Segment; 807 if (getParser().parseIdentifier(Segment)) 808 return TokError("expected segment name after '.zerofill' directive"); 809 810 if (getLexer().isNot(AsmToken::Comma)) 811 return TokError("unexpected token in directive"); 812 Lex(); 813 814 StringRef Section; 815 if (getParser().parseIdentifier(Section)) 816 return TokError("expected section name after comma in '.zerofill' " 817 "directive"); 818 819 // If this is the end of the line all that was wanted was to create the 820 // the section but with no symbol. 821 if (getLexer().is(AsmToken::EndOfStatement)) { 822 // Create the zerofill section but no symbol 823 getStreamer().EmitZerofill(getContext().getMachOSection( 824 Segment, Section, MachO::S_ZEROFILL, 825 0, SectionKind::getBSS())); 826 return false; 827 } 828 829 if (getLexer().isNot(AsmToken::Comma)) 830 return TokError("unexpected token in directive"); 831 Lex(); 832 833 SMLoc IDLoc = getLexer().getLoc(); 834 StringRef IDStr; 835 if (getParser().parseIdentifier(IDStr)) 836 return TokError("expected identifier in directive"); 837 838 // handle the identifier as the key symbol. 839 MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr); 840 841 if (getLexer().isNot(AsmToken::Comma)) 842 return TokError("unexpected token in directive"); 843 Lex(); 844 845 int64_t Size; 846 SMLoc SizeLoc = getLexer().getLoc(); 847 if (getParser().parseAbsoluteExpression(Size)) 848 return true; 849 850 int64_t Pow2Alignment = 0; 851 SMLoc Pow2AlignmentLoc; 852 if (getLexer().is(AsmToken::Comma)) { 853 Lex(); 854 Pow2AlignmentLoc = getLexer().getLoc(); 855 if (getParser().parseAbsoluteExpression(Pow2Alignment)) 856 return true; 857 } 858 859 if (getLexer().isNot(AsmToken::EndOfStatement)) 860 return TokError("unexpected token in '.zerofill' directive"); 861 862 Lex(); 863 864 if (Size < 0) 865 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 866 "than zero"); 867 868 // NOTE: The alignment in the directive is a power of 2 value, the assembler 869 // may internally end up wanting an alignment in bytes. 870 // FIXME: Diagnose overflow. 871 if (Pow2Alignment < 0) 872 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 873 "can't be less than zero"); 874 875 if (!Sym->isUndefined()) 876 return Error(IDLoc, "invalid symbol redefinition"); 877 878 // Create the zerofill Symbol with Size and Pow2Alignment 879 // 880 // FIXME: Arch specific. 881 getStreamer().EmitZerofill(getContext().getMachOSection( 882 Segment, Section, MachO::S_ZEROFILL, 883 0, SectionKind::getBSS()), 884 Sym, Size, 1 << Pow2Alignment); 885 886 return false; 887 } 888 889 /// ParseDirectiveDataRegion 890 /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ] 891 bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) { 892 if (getLexer().is(AsmToken::EndOfStatement)) { 893 Lex(); 894 getStreamer().EmitDataRegion(MCDR_DataRegion); 895 return false; 896 } 897 StringRef RegionType; 898 SMLoc Loc = getParser().getTok().getLoc(); 899 if (getParser().parseIdentifier(RegionType)) 900 return TokError("expected region type after '.data_region' directive"); 901 int Kind = StringSwitch<int>(RegionType) 902 .Case("jt8", MCDR_DataRegionJT8) 903 .Case("jt16", MCDR_DataRegionJT16) 904 .Case("jt32", MCDR_DataRegionJT32) 905 .Default(-1); 906 if (Kind == -1) 907 return Error(Loc, "unknown region type in '.data_region' directive"); 908 Lex(); 909 910 getStreamer().EmitDataRegion((MCDataRegionType)Kind); 911 return false; 912 } 913 914 /// ParseDirectiveDataRegionEnd 915 /// ::= .end_data_region 916 bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) { 917 if (getLexer().isNot(AsmToken::EndOfStatement)) 918 return TokError("unexpected token in '.end_data_region' directive"); 919 920 Lex(); 921 getStreamer().EmitDataRegion(MCDR_DataRegionEnd); 922 return false; 923 } 924 925 /// parseVersionMin 926 /// ::= .ios_version_min major,minor[,update] 927 /// ::= .macosx_version_min major,minor[,update] 928 bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) { 929 int64_t Major = 0, Minor = 0, Update = 0; 930 int Kind = StringSwitch<int>(Directive) 931 .Case(".watchos_version_min", MCVM_WatchOSVersionMin) 932 .Case(".tvos_version_min", MCVM_TvOSVersionMin) 933 .Case(".ios_version_min", MCVM_IOSVersionMin) 934 .Case(".macosx_version_min", MCVM_OSXVersionMin); 935 // Get the major version number. 936 if (getLexer().isNot(AsmToken::Integer)) 937 return TokError("invalid OS major version number"); 938 Major = getLexer().getTok().getIntVal(); 939 if (Major > 65535 || Major <= 0) 940 return TokError("invalid OS major version number"); 941 Lex(); 942 if (getLexer().isNot(AsmToken::Comma)) 943 return TokError("minor OS version number required, comma expected"); 944 Lex(); 945 // Get the minor version number. 946 if (getLexer().isNot(AsmToken::Integer)) 947 return TokError("invalid OS minor version number"); 948 Minor = getLexer().getTok().getIntVal(); 949 if (Minor > 255 || Minor < 0) 950 return TokError("invalid OS minor version number"); 951 Lex(); 952 // Get the update level, if specified 953 if (getLexer().isNot(AsmToken::EndOfStatement)) { 954 if (getLexer().isNot(AsmToken::Comma)) 955 return TokError("invalid update specifier, comma expected"); 956 Lex(); 957 if (getLexer().isNot(AsmToken::Integer)) 958 return TokError("invalid OS update number"); 959 Update = getLexer().getTok().getIntVal(); 960 if (Update > 255 || Update < 0) 961 return TokError("invalid OS update number"); 962 Lex(); 963 } 964 965 const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); 966 Triple::OSType ExpectedOS = Triple::UnknownOS; 967 switch ((MCVersionMinType)Kind) { 968 case MCVM_WatchOSVersionMin: ExpectedOS = Triple::WatchOS; break; 969 case MCVM_TvOSVersionMin: ExpectedOS = Triple::TvOS; break; 970 case MCVM_IOSVersionMin: ExpectedOS = Triple::IOS; break; 971 case MCVM_OSXVersionMin: ExpectedOS = Triple::MacOSX; break; 972 } 973 if (T.getOS() != ExpectedOS) 974 Warning(Loc, Directive + " should only be used for " + 975 Triple::getOSTypeName(ExpectedOS) + " targets"); 976 977 if (LastVersionMinDirective.isValid()) { 978 Warning(Loc, "overriding previous version_min directive"); 979 Note(LastVersionMinDirective, "previous definition is here"); 980 } 981 LastVersionMinDirective = Loc; 982 983 // We've parsed a correct version specifier, so send it to the streamer. 984 getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update); 985 986 return false; 987 } 988 989 namespace llvm { 990 991 MCAsmParserExtension *createDarwinAsmParser() { 992 return new DarwinAsmParser; 993 } 994 995 } // end llvm namespace 996