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