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