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