DarwinAsmParser.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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" 22using namespace llvm; 23 24namespace { 25 26/// \brief Implementation of directive handling which is shared across all 27/// Darwin targets. 28class 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 40public: 41 DarwinAsmParser() {} 42 43 void Initialize(MCAsmParser &Parser) override { 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 addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min"); 167 addDirectiveHandler<&DarwinAsmParser::parseVersionMin>( 168 ".macosx_version_min"); 169 } 170 171 bool parseDirectiveDesc(StringRef, SMLoc); 172 bool parseDirectiveIndirectSymbol(StringRef, SMLoc); 173 bool parseDirectiveDumpOrLoad(StringRef, SMLoc); 174 bool parseDirectiveLsym(StringRef, SMLoc); 175 bool parseDirectiveLinkerOption(StringRef, SMLoc); 176 bool parseDirectiveSection(StringRef, SMLoc); 177 bool parseDirectivePushSection(StringRef, SMLoc); 178 bool parseDirectivePopSection(StringRef, SMLoc); 179 bool parseDirectivePrevious(StringRef, SMLoc); 180 bool parseDirectiveSecureLogReset(StringRef, SMLoc); 181 bool parseDirectiveSecureLogUnique(StringRef, SMLoc); 182 bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); 183 bool parseDirectiveTBSS(StringRef, SMLoc); 184 bool parseDirectiveZerofill(StringRef, SMLoc); 185 bool parseDirectiveDataRegion(StringRef, SMLoc); 186 bool parseDirectiveDataRegionEnd(StringRef, SMLoc); 187 188 // Named Section Directive 189 bool parseSectionDirectiveBss(StringRef, SMLoc) { 190 return parseSectionSwitch("__DATA", "__bss"); 191 } 192 193 bool parseSectionDirectiveConst(StringRef, SMLoc) { 194 return parseSectionSwitch("__TEXT", "__const"); 195 } 196 bool parseSectionDirectiveStaticConst(StringRef, SMLoc) { 197 return parseSectionSwitch("__TEXT", "__static_const"); 198 } 199 bool parseSectionDirectiveCString(StringRef, SMLoc) { 200 return parseSectionSwitch("__TEXT","__cstring", 201 MachO::S_CSTRING_LITERALS); 202 } 203 bool parseSectionDirectiveLiteral4(StringRef, SMLoc) { 204 return parseSectionSwitch("__TEXT", "__literal4", 205 MachO::S_4BYTE_LITERALS, 4); 206 } 207 bool parseSectionDirectiveLiteral8(StringRef, SMLoc) { 208 return parseSectionSwitch("__TEXT", "__literal8", 209 MachO::S_8BYTE_LITERALS, 8); 210 } 211 bool parseSectionDirectiveLiteral16(StringRef, SMLoc) { 212 return parseSectionSwitch("__TEXT","__literal16", 213 MachO::S_16BYTE_LITERALS, 16); 214 } 215 bool parseSectionDirectiveConstructor(StringRef, SMLoc) { 216 return parseSectionSwitch("__TEXT","__constructor"); 217 } 218 bool parseSectionDirectiveDestructor(StringRef, SMLoc) { 219 return parseSectionSwitch("__TEXT","__destructor"); 220 } 221 bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { 222 return parseSectionSwitch("__TEXT","__fvmlib_init0"); 223 } 224 bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { 225 return parseSectionSwitch("__TEXT","__fvmlib_init1"); 226 } 227 bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) { 228 return parseSectionSwitch("__TEXT","__symbol_stub", 229 MachO::S_SYMBOL_STUBS | 230 MachO::S_ATTR_PURE_INSTRUCTIONS, 231 // FIXME: Different on PPC and ARM. 232 0, 16); 233 } 234 bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) { 235 return parseSectionSwitch("__TEXT","__picsymbol_stub", 236 MachO::S_SYMBOL_STUBS | 237 MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); 238 } 239 bool parseSectionDirectiveData(StringRef, SMLoc) { 240 return parseSectionSwitch("__DATA", "__data"); 241 } 242 bool parseSectionDirectiveStaticData(StringRef, SMLoc) { 243 return parseSectionSwitch("__DATA", "__static_data"); 244 } 245 bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { 246 return parseSectionSwitch("__DATA", "__nl_symbol_ptr", 247 MachO::S_NON_LAZY_SYMBOL_POINTERS, 4); 248 } 249 bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { 250 return parseSectionSwitch("__DATA", "__la_symbol_ptr", 251 MachO::S_LAZY_SYMBOL_POINTERS, 4); 252 } 253 bool parseSectionDirectiveDyld(StringRef, SMLoc) { 254 return parseSectionSwitch("__DATA", "__dyld"); 255 } 256 bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) { 257 return parseSectionSwitch("__DATA", "__mod_init_func", 258 MachO::S_MOD_INIT_FUNC_POINTERS, 4); 259 } 260 bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) { 261 return parseSectionSwitch("__DATA", "__mod_term_func", 262 MachO::S_MOD_TERM_FUNC_POINTERS, 4); 263 } 264 bool parseSectionDirectiveConstData(StringRef, SMLoc) { 265 return parseSectionSwitch("__DATA", "__const"); 266 } 267 bool parseSectionDirectiveObjCClass(StringRef, SMLoc) { 268 return parseSectionSwitch("__OBJC", "__class", 269 MachO::S_ATTR_NO_DEAD_STRIP); 270 } 271 bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { 272 return parseSectionSwitch("__OBJC", "__meta_class", 273 MachO::S_ATTR_NO_DEAD_STRIP); 274 } 275 bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { 276 return parseSectionSwitch("__OBJC", "__cat_cls_meth", 277 MachO::S_ATTR_NO_DEAD_STRIP); 278 } 279 bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { 280 return parseSectionSwitch("__OBJC", "__cat_inst_meth", 281 MachO::S_ATTR_NO_DEAD_STRIP); 282 } 283 bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) { 284 return parseSectionSwitch("__OBJC", "__protocol", 285 MachO::S_ATTR_NO_DEAD_STRIP); 286 } 287 bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) { 288 return parseSectionSwitch("__OBJC", "__string_object", 289 MachO::S_ATTR_NO_DEAD_STRIP); 290 } 291 bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { 292 return parseSectionSwitch("__OBJC", "__cls_meth", 293 MachO::S_ATTR_NO_DEAD_STRIP); 294 } 295 bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { 296 return parseSectionSwitch("__OBJC", "__inst_meth", 297 MachO::S_ATTR_NO_DEAD_STRIP); 298 } 299 bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { 300 return parseSectionSwitch("__OBJC", "__cls_refs", 301 MachO::S_ATTR_NO_DEAD_STRIP | 302 MachO::S_LITERAL_POINTERS, 4); 303 } 304 bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { 305 return parseSectionSwitch("__OBJC", "__message_refs", 306 MachO::S_ATTR_NO_DEAD_STRIP | 307 MachO::S_LITERAL_POINTERS, 4); 308 } 309 bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) { 310 return parseSectionSwitch("__OBJC", "__symbols", 311 MachO::S_ATTR_NO_DEAD_STRIP); 312 } 313 bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) { 314 return parseSectionSwitch("__OBJC", "__category", 315 MachO::S_ATTR_NO_DEAD_STRIP); 316 } 317 bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) { 318 return parseSectionSwitch("__OBJC", "__class_vars", 319 MachO::S_ATTR_NO_DEAD_STRIP); 320 } 321 bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { 322 return parseSectionSwitch("__OBJC", "__instance_vars", 323 MachO::S_ATTR_NO_DEAD_STRIP); 324 } 325 bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { 326 return parseSectionSwitch("__OBJC", "__module_info", 327 MachO::S_ATTR_NO_DEAD_STRIP); 328 } 329 bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) { 330 return parseSectionSwitch("__TEXT", "__cstring", 331 MachO::S_CSTRING_LITERALS); 332 } 333 bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { 334 return parseSectionSwitch("__TEXT", "__cstring", 335 MachO::S_CSTRING_LITERALS); 336 } 337 bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { 338 return parseSectionSwitch("__TEXT", "__cstring", 339 MachO::S_CSTRING_LITERALS); 340 } 341 bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { 342 return parseSectionSwitch("__OBJC", "__selector_strs", 343 MachO::S_CSTRING_LITERALS); 344 } 345 bool parseSectionDirectiveTData(StringRef, SMLoc) { 346 return parseSectionSwitch("__DATA", "__thread_data", 347 MachO::S_THREAD_LOCAL_REGULAR); 348 } 349 bool parseSectionDirectiveText(StringRef, SMLoc) { 350 return parseSectionSwitch("__TEXT", "__text", 351 MachO::S_ATTR_PURE_INSTRUCTIONS); 352 } 353 bool parseSectionDirectiveTLV(StringRef, SMLoc) { 354 return parseSectionSwitch("__DATA", "__thread_vars", 355 MachO::S_THREAD_LOCAL_VARIABLES); 356 } 357 bool parseSectionDirectiveIdent(StringRef, SMLoc) { 358 // Darwin silently ignores the .ident directive. 359 getParser().eatToEndOfStatement(); 360 return false; 361 } 362 bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { 363 return parseSectionSwitch("__DATA", "__thread_init", 364 MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); 365 } 366 bool parseVersionMin(StringRef, SMLoc); 367 368}; 369 370} // end anonymous namespace 371 372bool DarwinAsmParser::parseSectionSwitch(const char *Segment, 373 const char *Section, 374 unsigned TAA, unsigned Align, 375 unsigned StubSize) { 376 if (getLexer().isNot(AsmToken::EndOfStatement)) 377 return TokError("unexpected token in section switching directive"); 378 Lex(); 379 380 // FIXME: Arch specific. 381 bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS; 382 getStreamer().SwitchSection(getContext().getMachOSection( 383 Segment, Section, TAA, StubSize, 384 isText ? SectionKind::getText() 385 : SectionKind::getDataRel())); 386 387 // Set the implicit alignment, if any. 388 // 389 // FIXME: This isn't really what 'as' does; I think it just uses the implicit 390 // alignment on the section (e.g., if one manually inserts bytes into the 391 // section, then just issuing the section switch directive will not realign 392 // the section. However, this is arguably more reasonable behavior, and there 393 // is no good reason for someone to intentionally emit incorrectly sized 394 // values into the implicitly aligned sections. 395 if (Align) 396 getStreamer().EmitValueToAlignment(Align); 397 398 return false; 399} 400 401/// parseDirectiveDesc 402/// ::= .desc identifier , expression 403bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { 404 StringRef Name; 405 if (getParser().parseIdentifier(Name)) 406 return TokError("expected identifier in directive"); 407 408 // Handle the identifier as the key symbol. 409 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 410 411 if (getLexer().isNot(AsmToken::Comma)) 412 return TokError("unexpected token in '.desc' directive"); 413 Lex(); 414 415 int64_t DescValue; 416 if (getParser().parseAbsoluteExpression(DescValue)) 417 return true; 418 419 if (getLexer().isNot(AsmToken::EndOfStatement)) 420 return TokError("unexpected token in '.desc' directive"); 421 422 Lex(); 423 424 // Set the n_desc field of this Symbol to this DescValue 425 getStreamer().EmitSymbolDesc(Sym, DescValue); 426 427 return false; 428} 429 430/// parseDirectiveIndirectSymbol 431/// ::= .indirect_symbol identifier 432bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { 433 const MCSectionMachO *Current = static_cast<const MCSectionMachO*>( 434 getStreamer().getCurrentSection().first); 435 MachO::SectionType SectionType = Current->getType(); 436 if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && 437 SectionType != MachO::S_LAZY_SYMBOL_POINTERS && 438 SectionType != MachO::S_SYMBOL_STUBS) 439 return Error(Loc, "indirect symbol not in a symbol pointer or stub " 440 "section"); 441 442 StringRef Name; 443 if (getParser().parseIdentifier(Name)) 444 return TokError("expected identifier in .indirect_symbol directive"); 445 446 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 447 448 // Assembler local symbols don't make any sense here. Complain loudly. 449 if (Sym->isTemporary()) 450 return TokError("non-local symbol required in directive"); 451 452 if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol)) 453 return TokError("unable to emit indirect symbol attribute for: " + Name); 454 455 if (getLexer().isNot(AsmToken::EndOfStatement)) 456 return TokError("unexpected token in '.indirect_symbol' directive"); 457 458 Lex(); 459 460 return false; 461} 462 463/// parseDirectiveDumpOrLoad 464/// ::= ( .dump | .load ) "filename" 465bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive, 466 SMLoc IDLoc) { 467 bool IsDump = Directive == ".dump"; 468 if (getLexer().isNot(AsmToken::String)) 469 return TokError("expected string in '.dump' or '.load' directive"); 470 471 Lex(); 472 473 if (getLexer().isNot(AsmToken::EndOfStatement)) 474 return TokError("unexpected token in '.dump' or '.load' directive"); 475 476 Lex(); 477 478 // FIXME: If/when .dump and .load are implemented they will be done in the 479 // the assembly parser and not have any need for an MCStreamer API. 480 if (IsDump) 481 return Warning(IDLoc, "ignoring directive .dump for now"); 482 else 483 return Warning(IDLoc, "ignoring directive .load for now"); 484} 485 486/// ParseDirectiveLinkerOption 487/// ::= .linker_option "string" ( , "string" )* 488bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) { 489 SmallVector<std::string, 4> Args; 490 for (;;) { 491 if (getLexer().isNot(AsmToken::String)) 492 return TokError("expected string in '" + Twine(IDVal) + "' directive"); 493 494 std::string Data; 495 if (getParser().parseEscapedString(Data)) 496 return true; 497 498 Args.push_back(Data); 499 500 Lex(); 501 if (getLexer().is(AsmToken::EndOfStatement)) 502 break; 503 504 if (getLexer().isNot(AsmToken::Comma)) 505 return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 506 Lex(); 507 } 508 509 getStreamer().EmitLinkerOptions(Args); 510 return false; 511} 512 513/// parseDirectiveLsym 514/// ::= .lsym identifier , expression 515bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { 516 StringRef Name; 517 if (getParser().parseIdentifier(Name)) 518 return TokError("expected identifier in directive"); 519 520 // Handle the identifier as the key symbol. 521 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 522 523 if (getLexer().isNot(AsmToken::Comma)) 524 return TokError("unexpected token in '.lsym' directive"); 525 Lex(); 526 527 const MCExpr *Value; 528 if (getParser().parseExpression(Value)) 529 return true; 530 531 if (getLexer().isNot(AsmToken::EndOfStatement)) 532 return TokError("unexpected token in '.lsym' directive"); 533 534 Lex(); 535 536 // We don't currently support this directive. 537 // 538 // FIXME: Diagnostic location! 539 (void) Sym; 540 return TokError("directive '.lsym' is unsupported"); 541} 542 543/// parseDirectiveSection: 544/// ::= .section identifier (',' identifier)* 545bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { 546 SMLoc Loc = getLexer().getLoc(); 547 548 StringRef SectionName; 549 if (getParser().parseIdentifier(SectionName)) 550 return Error(Loc, "expected identifier after '.section' directive"); 551 552 // Verify there is a following comma. 553 if (!getLexer().is(AsmToken::Comma)) 554 return TokError("unexpected token in '.section' directive"); 555 556 std::string SectionSpec = SectionName; 557 SectionSpec += ","; 558 559 // Add all the tokens until the end of the line, ParseSectionSpecifier will 560 // handle this. 561 StringRef EOL = getLexer().LexUntilEndOfStatement(); 562 SectionSpec.append(EOL.begin(), EOL.end()); 563 564 Lex(); 565 if (getLexer().isNot(AsmToken::EndOfStatement)) 566 return TokError("unexpected token in '.section' directive"); 567 Lex(); 568 569 570 StringRef Segment, Section; 571 unsigned StubSize; 572 unsigned TAA; 573 bool TAAParsed; 574 std::string ErrorStr = 575 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, 576 TAA, TAAParsed, StubSize); 577 578 if (!ErrorStr.empty()) 579 return Error(Loc, ErrorStr.c_str()); 580 581 // FIXME: Arch specific. 582 bool isText = Segment == "__TEXT"; // FIXME: Hack. 583 getStreamer().SwitchSection(getContext().getMachOSection( 584 Segment, Section, TAA, StubSize, 585 isText ? SectionKind::getText() 586 : SectionKind::getDataRel())); 587 return false; 588} 589 590/// ParseDirectivePushSection: 591/// ::= .pushsection identifier (',' identifier)* 592bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) { 593 getStreamer().PushSection(); 594 595 if (parseDirectiveSection(S, Loc)) { 596 getStreamer().PopSection(); 597 return true; 598 } 599 600 return false; 601} 602 603/// ParseDirectivePopSection: 604/// ::= .popsection 605bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { 606 if (!getStreamer().PopSection()) 607 return TokError(".popsection without corresponding .pushsection"); 608 return false; 609} 610 611/// ParseDirectivePrevious: 612/// ::= .previous 613bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { 614 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 615 if (PreviousSection.first == NULL) 616 return TokError(".previous without corresponding .section"); 617 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 618 return false; 619} 620 621/// ParseDirectiveSecureLogUnique 622/// ::= .secure_log_unique ... message ... 623bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { 624 StringRef LogMessage = getParser().parseStringToEndOfStatement(); 625 if (getLexer().isNot(AsmToken::EndOfStatement)) 626 return TokError("unexpected token in '.secure_log_unique' directive"); 627 628 if (getContext().getSecureLogUsed() != false) 629 return Error(IDLoc, ".secure_log_unique specified multiple times"); 630 631 // Get the secure log path. 632 const char *SecureLogFile = getContext().getSecureLogFile(); 633 if (SecureLogFile == NULL) 634 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " 635 "environment variable unset."); 636 637 // Open the secure log file if we haven't already. 638 raw_ostream *OS = getContext().getSecureLog(); 639 if (OS == NULL) { 640 std::string Err; 641 OS = new raw_fd_ostream(SecureLogFile, Err, 642 sys::fs::F_Append | sys::fs::F_Text); 643 if (!Err.empty()) { 644 delete OS; 645 return Error(IDLoc, Twine("can't open secure log file: ") + 646 SecureLogFile + " (" + Err + ")"); 647 } 648 getContext().setSecureLog(OS); 649 } 650 651 // Write the message. 652 int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); 653 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() 654 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" 655 << LogMessage + "\n"; 656 657 getContext().setSecureLogUsed(true); 658 659 return false; 660} 661 662/// ParseDirectiveSecureLogReset 663/// ::= .secure_log_reset 664bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { 665 if (getLexer().isNot(AsmToken::EndOfStatement)) 666 return TokError("unexpected token in '.secure_log_reset' directive"); 667 668 Lex(); 669 670 getContext().setSecureLogUsed(false); 671 672 return false; 673} 674 675/// parseDirectiveSubsectionsViaSymbols 676/// ::= .subsections_via_symbols 677bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { 678 if (getLexer().isNot(AsmToken::EndOfStatement)) 679 return TokError("unexpected token in '.subsections_via_symbols' directive"); 680 681 Lex(); 682 683 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 684 685 return false; 686} 687 688/// ParseDirectiveTBSS 689/// ::= .tbss identifier, size, align 690bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { 691 SMLoc IDLoc = getLexer().getLoc(); 692 StringRef Name; 693 if (getParser().parseIdentifier(Name)) 694 return TokError("expected identifier in directive"); 695 696 // Handle the identifier as the key symbol. 697 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 698 699 if (getLexer().isNot(AsmToken::Comma)) 700 return TokError("unexpected token in directive"); 701 Lex(); 702 703 int64_t Size; 704 SMLoc SizeLoc = getLexer().getLoc(); 705 if (getParser().parseAbsoluteExpression(Size)) 706 return true; 707 708 int64_t Pow2Alignment = 0; 709 SMLoc Pow2AlignmentLoc; 710 if (getLexer().is(AsmToken::Comma)) { 711 Lex(); 712 Pow2AlignmentLoc = getLexer().getLoc(); 713 if (getParser().parseAbsoluteExpression(Pow2Alignment)) 714 return true; 715 } 716 717 if (getLexer().isNot(AsmToken::EndOfStatement)) 718 return TokError("unexpected token in '.tbss' directive"); 719 720 Lex(); 721 722 if (Size < 0) 723 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" 724 "zero"); 725 726 // FIXME: Diagnose overflow. 727 if (Pow2Alignment < 0) 728 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" 729 "than zero"); 730 731 if (!Sym->isUndefined()) 732 return Error(IDLoc, "invalid symbol redefinition"); 733 734 getStreamer().EmitTBSSSymbol(getContext().getMachOSection( 735 "__DATA", "__thread_bss", 736 MachO::S_THREAD_LOCAL_ZEROFILL, 737 0, SectionKind::getThreadBSS()), 738 Sym, Size, 1 << Pow2Alignment); 739 740 return false; 741} 742 743/// ParseDirectiveZerofill 744/// ::= .zerofill segname , sectname [, identifier , size_expression [ 745/// , align_expression ]] 746bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { 747 StringRef Segment; 748 if (getParser().parseIdentifier(Segment)) 749 return TokError("expected segment name after '.zerofill' directive"); 750 751 if (getLexer().isNot(AsmToken::Comma)) 752 return TokError("unexpected token in directive"); 753 Lex(); 754 755 StringRef Section; 756 if (getParser().parseIdentifier(Section)) 757 return TokError("expected section name after comma in '.zerofill' " 758 "directive"); 759 760 // If this is the end of the line all that was wanted was to create the 761 // the section but with no symbol. 762 if (getLexer().is(AsmToken::EndOfStatement)) { 763 // Create the zerofill section but no symbol 764 getStreamer().EmitZerofill(getContext().getMachOSection( 765 Segment, Section, MachO::S_ZEROFILL, 766 0, SectionKind::getBSS())); 767 return false; 768 } 769 770 if (getLexer().isNot(AsmToken::Comma)) 771 return TokError("unexpected token in directive"); 772 Lex(); 773 774 SMLoc IDLoc = getLexer().getLoc(); 775 StringRef IDStr; 776 if (getParser().parseIdentifier(IDStr)) 777 return TokError("expected identifier in directive"); 778 779 // handle the identifier as the key symbol. 780 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr); 781 782 if (getLexer().isNot(AsmToken::Comma)) 783 return TokError("unexpected token in directive"); 784 Lex(); 785 786 int64_t Size; 787 SMLoc SizeLoc = getLexer().getLoc(); 788 if (getParser().parseAbsoluteExpression(Size)) 789 return true; 790 791 int64_t Pow2Alignment = 0; 792 SMLoc Pow2AlignmentLoc; 793 if (getLexer().is(AsmToken::Comma)) { 794 Lex(); 795 Pow2AlignmentLoc = getLexer().getLoc(); 796 if (getParser().parseAbsoluteExpression(Pow2Alignment)) 797 return true; 798 } 799 800 if (getLexer().isNot(AsmToken::EndOfStatement)) 801 return TokError("unexpected token in '.zerofill' directive"); 802 803 Lex(); 804 805 if (Size < 0) 806 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 807 "than zero"); 808 809 // NOTE: The alignment in the directive is a power of 2 value, the assembler 810 // may internally end up wanting an alignment in bytes. 811 // FIXME: Diagnose overflow. 812 if (Pow2Alignment < 0) 813 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 814 "can't be less than zero"); 815 816 if (!Sym->isUndefined()) 817 return Error(IDLoc, "invalid symbol redefinition"); 818 819 // Create the zerofill Symbol with Size and Pow2Alignment 820 // 821 // FIXME: Arch specific. 822 getStreamer().EmitZerofill(getContext().getMachOSection( 823 Segment, Section, MachO::S_ZEROFILL, 824 0, SectionKind::getBSS()), 825 Sym, Size, 1 << Pow2Alignment); 826 827 return false; 828} 829 830/// ParseDirectiveDataRegion 831/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ] 832bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) { 833 if (getLexer().is(AsmToken::EndOfStatement)) { 834 Lex(); 835 getStreamer().EmitDataRegion(MCDR_DataRegion); 836 return false; 837 } 838 StringRef RegionType; 839 SMLoc Loc = getParser().getTok().getLoc(); 840 if (getParser().parseIdentifier(RegionType)) 841 return TokError("expected region type after '.data_region' directive"); 842 int Kind = StringSwitch<int>(RegionType) 843 .Case("jt8", MCDR_DataRegionJT8) 844 .Case("jt16", MCDR_DataRegionJT16) 845 .Case("jt32", MCDR_DataRegionJT32) 846 .Default(-1); 847 if (Kind == -1) 848 return Error(Loc, "unknown region type in '.data_region' directive"); 849 Lex(); 850 851 getStreamer().EmitDataRegion((MCDataRegionType)Kind); 852 return false; 853} 854 855/// ParseDirectiveDataRegionEnd 856/// ::= .end_data_region 857bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) { 858 if (getLexer().isNot(AsmToken::EndOfStatement)) 859 return TokError("unexpected token in '.end_data_region' directive"); 860 861 Lex(); 862 getStreamer().EmitDataRegion(MCDR_DataRegionEnd); 863 return false; 864} 865 866/// parseVersionMin 867/// ::= .ios_version_min major,minor[,update] 868/// ::= .macosx_version_min major,minor[,update] 869bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) { 870 int64_t Major = 0, Minor = 0, Update = 0; 871 int Kind = StringSwitch<int>(Directive) 872 .Case(".ios_version_min", MCVM_IOSVersionMin) 873 .Case(".macosx_version_min", MCVM_OSXVersionMin); 874 // Get the major version number. 875 if (getLexer().isNot(AsmToken::Integer)) 876 return TokError("invalid OS major version number"); 877 Major = getLexer().getTok().getIntVal(); 878 if (Major > 65535 || Major <= 0) 879 return TokError("invalid OS major version number"); 880 Lex(); 881 if (getLexer().isNot(AsmToken::Comma)) 882 return TokError("minor OS version number required, comma expected"); 883 Lex(); 884 // Get the minor version number. 885 if (getLexer().isNot(AsmToken::Integer)) 886 return TokError("invalid OS minor version number"); 887 Minor = getLexer().getTok().getIntVal(); 888 if (Minor > 255 || Minor < 0) 889 return TokError("invalid OS minor version number"); 890 Lex(); 891 // Get the update level, if specified 892 if (getLexer().isNot(AsmToken::EndOfStatement)) { 893 if (getLexer().isNot(AsmToken::Comma)) 894 return TokError("invalid update specifier, comma expected"); 895 Lex(); 896 if (getLexer().isNot(AsmToken::Integer)) 897 return TokError("invalid OS update number"); 898 Update = getLexer().getTok().getIntVal(); 899 if (Update > 255 || Update < 0) 900 return TokError("invalid OS update number"); 901 Lex(); 902 } 903 904 // We've parsed a correct version specifier, so send it to the streamer. 905 getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update); 906 907 return false; 908} 909 910namespace llvm { 911 912MCAsmParserExtension *createDarwinAsmParser() { 913 return new DarwinAsmParser; 914} 915 916} // end llvm namespace 917