1198 lines · cpp
1//===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/SmallVector.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/ADT/StringSwitch.h"12#include "llvm/ADT/Twine.h"13#include "llvm/BinaryFormat/MachO.h"14#include "llvm/MC/MCContext.h"15#include "llvm/MC/MCDirectives.h"16#include "llvm/MC/MCParser/AsmLexer.h"17#include "llvm/MC/MCParser/MCAsmParser.h"18#include "llvm/MC/MCParser/MCAsmParserExtension.h"19#include "llvm/MC/MCSectionMachO.h"20#include "llvm/MC/MCStreamer.h"21#include "llvm/MC/MCSymbol.h"22#include "llvm/MC/SectionKind.h"23#include "llvm/Support/Error.h"24#include "llvm/Support/FileSystem.h"25#include "llvm/Support/MemoryBuffer.h"26#include "llvm/Support/SMLoc.h"27#include "llvm/Support/SourceMgr.h"28#include "llvm/Support/raw_ostream.h"29#include "llvm/TargetParser/Triple.h"30#include <cstddef>31#include <cstdint>32#include <string>33#include <system_error>34#include <utility>35 36using namespace llvm;37 38namespace {39 40/// Implementation of directive handling which is shared across all41/// Darwin targets.42class DarwinAsmParser : public MCAsmParserExtension {43 template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>44 void addDirectiveHandler(StringRef Directive) {45 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(46 this, HandleDirective<DarwinAsmParser, HandlerMethod>);47 getParser().addDirectiveHandler(Directive, Handler);48 }49 50 bool parseSectionSwitch(StringRef Segment, StringRef Section,51 unsigned TAA = 0, unsigned ImplicitAlign = 0,52 unsigned StubSize = 0);53 54 SMLoc LastVersionDirective;55 56public:57 DarwinAsmParser() = default;58 59 void Initialize(MCAsmParser &Parser) override {60 // Call the base implementation.61 this->MCAsmParserExtension::Initialize(Parser);62 63 addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry");64 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc");65 addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>(66 ".indirect_symbol");67 addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym");68 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>(69 ".subsections_via_symbols");70 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump");71 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load");72 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section");73 addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>(74 ".pushsection");75 addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>(76 ".popsection");77 addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous");78 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>(79 ".secure_log_unique");80 addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>(81 ".secure_log_reset");82 addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss");83 addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill");84 85 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>(86 ".data_region");87 addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>(88 ".end_data_region");89 90 // Special section directives.91 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss");92 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const");93 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>(94 ".const_data");95 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>(96 ".constructor");97 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>(98 ".cstring");99 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data");100 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>(101 ".destructor");102 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld");103 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>(104 ".fvmlib_init0");105 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>(106 ".fvmlib_init1");107 addDirectiveHandler<108 &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>(109 ".lazy_symbol_pointer");110 addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>(111 ".linker_option");112 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>(113 ".literal16");114 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>(115 ".literal4");116 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>(117 ".literal8");118 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>(119 ".mod_init_func");120 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>(121 ".mod_term_func");122 addDirectiveHandler<123 &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>(124 ".non_lazy_symbol_pointer");125 addDirectiveHandler<126 &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>(127 ".thread_local_variable_pointer");128 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>(129 ".objc_cat_cls_meth");130 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>(131 ".objc_cat_inst_meth");132 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>(133 ".objc_category");134 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>(135 ".objc_class");136 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>(137 ".objc_class_names");138 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>(139 ".objc_class_vars");140 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>(141 ".objc_cls_meth");142 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>(143 ".objc_cls_refs");144 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>(145 ".objc_inst_meth");146 addDirectiveHandler<147 &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>(148 ".objc_instance_vars");149 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>(150 ".objc_message_refs");151 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>(152 ".objc_meta_class");153 addDirectiveHandler<154 &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>(155 ".objc_meth_var_names");156 addDirectiveHandler<157 &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>(158 ".objc_meth_var_types");159 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>(160 ".objc_module_info");161 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>(162 ".objc_protocol");163 addDirectiveHandler<164 &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>(165 ".objc_selector_strs");166 addDirectiveHandler<167 &DarwinAsmParser::parseSectionDirectiveObjCStringObject>(168 ".objc_string_object");169 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>(170 ".objc_symbols");171 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>(172 ".picsymbol_stub");173 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>(174 ".static_const");175 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>(176 ".static_data");177 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>(178 ".symbol_stub");179 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata");180 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text");181 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>(182 ".thread_init_func");183 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");184 185 addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");186 addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>(187 ".watchos_version_min");188 addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>(189 ".tvos_version_min");190 addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>(191 ".ios_version_min");192 addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>(193 ".macosx_version_min");194 addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version");195 addDirectiveHandler<&DarwinAsmParser::parseDirectiveCGProfile>(196 ".cg_profile");197 198 LastVersionDirective = SMLoc();199 }200 201 bool parseDirectiveAltEntry(StringRef, SMLoc);202 bool parseDirectiveDesc(StringRef, SMLoc);203 bool parseDirectiveIndirectSymbol(StringRef, SMLoc);204 bool parseDirectiveDumpOrLoad(StringRef, SMLoc);205 bool parseDirectiveLsym(StringRef, SMLoc);206 bool parseDirectiveLinkerOption(StringRef, SMLoc);207 bool parseDirectiveSection(StringRef, SMLoc);208 bool parseDirectivePushSection(StringRef, SMLoc);209 bool parseDirectivePopSection(StringRef, SMLoc);210 bool parseDirectivePrevious(StringRef, SMLoc);211 bool parseDirectiveSecureLogReset(StringRef, SMLoc);212 bool parseDirectiveSecureLogUnique(StringRef, SMLoc);213 bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc);214 bool parseDirectiveTBSS(StringRef, SMLoc);215 bool parseDirectiveZerofill(StringRef, SMLoc);216 bool parseDirectiveDataRegion(StringRef, SMLoc);217 bool parseDirectiveDataRegionEnd(StringRef, SMLoc);218 219 // Named Section Directive220 bool parseSectionDirectiveBss(StringRef, SMLoc) {221 return parseSectionSwitch("__DATA", "__bss");222 }223 224 bool parseSectionDirectiveConst(StringRef, SMLoc) {225 return parseSectionSwitch("__TEXT", "__const");226 }227 228 bool parseSectionDirectiveStaticConst(StringRef, SMLoc) {229 return parseSectionSwitch("__TEXT", "__static_const");230 }231 232 bool parseSectionDirectiveCString(StringRef, SMLoc) {233 return parseSectionSwitch("__TEXT","__cstring",234 MachO::S_CSTRING_LITERALS);235 }236 237 bool parseSectionDirectiveLiteral4(StringRef, SMLoc) {238 return parseSectionSwitch("__TEXT", "__literal4",239 MachO::S_4BYTE_LITERALS, 4);240 }241 242 bool parseSectionDirectiveLiteral8(StringRef, SMLoc) {243 return parseSectionSwitch("__TEXT", "__literal8",244 MachO::S_8BYTE_LITERALS, 8);245 }246 247 bool parseSectionDirectiveLiteral16(StringRef, SMLoc) {248 return parseSectionSwitch("__TEXT","__literal16",249 MachO::S_16BYTE_LITERALS, 16);250 }251 252 bool parseSectionDirectiveConstructor(StringRef, SMLoc) {253 return parseSectionSwitch("__TEXT","__constructor");254 }255 256 bool parseSectionDirectiveDestructor(StringRef, SMLoc) {257 return parseSectionSwitch("__TEXT","__destructor");258 }259 260 bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) {261 return parseSectionSwitch("__TEXT","__fvmlib_init0");262 }263 264 bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) {265 return parseSectionSwitch("__TEXT","__fvmlib_init1");266 }267 268 bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) {269 return parseSectionSwitch("__TEXT","__symbol_stub",270 MachO::S_SYMBOL_STUBS |271 MachO::S_ATTR_PURE_INSTRUCTIONS,272 // FIXME: Different on PPC and ARM.273 0, 16);274 }275 276 bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) {277 return parseSectionSwitch("__TEXT","__picsymbol_stub",278 MachO::S_SYMBOL_STUBS |279 MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26);280 }281 282 bool parseSectionDirectiveData(StringRef, SMLoc) {283 return parseSectionSwitch("__DATA", "__data");284 }285 286 bool parseSectionDirectiveStaticData(StringRef, SMLoc) {287 return parseSectionSwitch("__DATA", "__static_data");288 }289 290 bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) {291 return parseSectionSwitch("__DATA", "__nl_symbol_ptr",292 MachO::S_NON_LAZY_SYMBOL_POINTERS, 4);293 }294 295 bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) {296 return parseSectionSwitch("__DATA", "__la_symbol_ptr",297 MachO::S_LAZY_SYMBOL_POINTERS, 4);298 }299 300 bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) {301 return parseSectionSwitch("__DATA", "__thread_ptr",302 MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4);303 }304 305 bool parseSectionDirectiveDyld(StringRef, SMLoc) {306 return parseSectionSwitch("__DATA", "__dyld");307 }308 309 bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) {310 return parseSectionSwitch("__DATA", "__mod_init_func",311 MachO::S_MOD_INIT_FUNC_POINTERS, 4);312 }313 314 bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) {315 return parseSectionSwitch("__DATA", "__mod_term_func",316 MachO::S_MOD_TERM_FUNC_POINTERS, 4);317 }318 319 bool parseSectionDirectiveConstData(StringRef, SMLoc) {320 return parseSectionSwitch("__DATA", "__const");321 }322 323 bool parseSectionDirectiveObjCClass(StringRef, SMLoc) {324 return parseSectionSwitch("__OBJC", "__class",325 MachO::S_ATTR_NO_DEAD_STRIP);326 }327 328 bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) {329 return parseSectionSwitch("__OBJC", "__meta_class",330 MachO::S_ATTR_NO_DEAD_STRIP);331 }332 333 bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) {334 return parseSectionSwitch("__OBJC", "__cat_cls_meth",335 MachO::S_ATTR_NO_DEAD_STRIP);336 }337 338 bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) {339 return parseSectionSwitch("__OBJC", "__cat_inst_meth",340 MachO::S_ATTR_NO_DEAD_STRIP);341 }342 343 bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) {344 return parseSectionSwitch("__OBJC", "__protocol",345 MachO::S_ATTR_NO_DEAD_STRIP);346 }347 348 bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) {349 return parseSectionSwitch("__OBJC", "__string_object",350 MachO::S_ATTR_NO_DEAD_STRIP);351 }352 353 bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) {354 return parseSectionSwitch("__OBJC", "__cls_meth",355 MachO::S_ATTR_NO_DEAD_STRIP);356 }357 358 bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) {359 return parseSectionSwitch("__OBJC", "__inst_meth",360 MachO::S_ATTR_NO_DEAD_STRIP);361 }362 363 bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) {364 return parseSectionSwitch("__OBJC", "__cls_refs",365 MachO::S_ATTR_NO_DEAD_STRIP |366 MachO::S_LITERAL_POINTERS, 4);367 }368 369 bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) {370 return parseSectionSwitch("__OBJC", "__message_refs",371 MachO::S_ATTR_NO_DEAD_STRIP |372 MachO::S_LITERAL_POINTERS, 4);373 }374 375 bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) {376 return parseSectionSwitch("__OBJC", "__symbols",377 MachO::S_ATTR_NO_DEAD_STRIP);378 }379 380 bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) {381 return parseSectionSwitch("__OBJC", "__category",382 MachO::S_ATTR_NO_DEAD_STRIP);383 }384 385 bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) {386 return parseSectionSwitch("__OBJC", "__class_vars",387 MachO::S_ATTR_NO_DEAD_STRIP);388 }389 390 bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) {391 return parseSectionSwitch("__OBJC", "__instance_vars",392 MachO::S_ATTR_NO_DEAD_STRIP);393 }394 395 bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) {396 return parseSectionSwitch("__OBJC", "__module_info",397 MachO::S_ATTR_NO_DEAD_STRIP);398 }399 400 bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) {401 return parseSectionSwitch("__TEXT", "__cstring",402 MachO::S_CSTRING_LITERALS);403 }404 405 bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) {406 return parseSectionSwitch("__TEXT", "__cstring",407 MachO::S_CSTRING_LITERALS);408 }409 410 bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) {411 return parseSectionSwitch("__TEXT", "__cstring",412 MachO::S_CSTRING_LITERALS);413 }414 415 bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) {416 return parseSectionSwitch("__OBJC", "__selector_strs",417 MachO::S_CSTRING_LITERALS);418 }419 420 bool parseSectionDirectiveTData(StringRef, SMLoc) {421 return parseSectionSwitch("__DATA", "__thread_data",422 MachO::S_THREAD_LOCAL_REGULAR);423 }424 425 bool parseSectionDirectiveText(StringRef, SMLoc) {426 return parseSectionSwitch("__TEXT", "__text",427 MachO::S_ATTR_PURE_INSTRUCTIONS);428 }429 430 bool parseSectionDirectiveTLV(StringRef, SMLoc) {431 return parseSectionSwitch("__DATA", "__thread_vars",432 MachO::S_THREAD_LOCAL_VARIABLES);433 }434 435 bool parseSectionDirectiveIdent(StringRef, SMLoc) {436 // Darwin silently ignores the .ident directive.437 getParser().eatToEndOfStatement();438 return false;439 }440 441 bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {442 return parseSectionSwitch("__DATA", "__thread_init",443 MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);444 }445 446 bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) {447 return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin);448 }449 bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) {450 return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin);451 }452 bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) {453 return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin);454 }455 bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) {456 return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin);457 }458 459 bool parseBuildVersion(StringRef Directive, SMLoc Loc);460 bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type);461 bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor,462 const char *VersionName);463 bool parseOptionalTrailingVersionComponent(unsigned *Component,464 const char *ComponentName);465 bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update);466 bool parseSDKVersion(VersionTuple &SDKVersion);467 void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc,468 Triple::OSType ExpectedOS);469 bool parseDirectiveCGProfile(StringRef Directive, SMLoc Loc);470};471 472} // end anonymous namespace473 474bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section,475 unsigned TAA, unsigned Alignment,476 unsigned StubSize) {477 if (getLexer().isNot(AsmToken::EndOfStatement))478 return TokError("unexpected token in section switching directive");479 Lex();480 481 // FIXME: Arch specific.482 bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS;483 getStreamer().switchSection(getContext().getMachOSection(484 Segment, Section, TAA, StubSize,485 isText ? SectionKind::getText() : SectionKind::getData()));486 487 // Set the implicit alignment, if any.488 //489 // FIXME: This isn't really what 'as' does; I think it just uses the implicit490 // alignment on the section (e.g., if one manually inserts bytes into the491 // section, then just issuing the section switch directive will not realign492 // the section. However, this is arguably more reasonable behavior, and there493 // is no good reason for someone to intentionally emit incorrectly sized494 // values into the implicitly aligned sections.495 if (Alignment)496 getStreamer().emitValueToAlignment(Align(Alignment));497 498 return false;499}500 501/// parseDirectiveAltEntry502/// ::= .alt_entry identifier503bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) {504 MCSymbol *Sym;505 if (getParser().parseSymbol(Sym))506 return TokError("expected identifier in directive");507 508 if (Sym->isDefined())509 return TokError(".alt_entry must preceed symbol definition");510 511 if (!getStreamer().emitSymbolAttribute(Sym, MCSA_AltEntry))512 return TokError("unable to emit symbol attribute");513 514 Lex();515 return false;516}517 518/// parseDirectiveDesc519/// ::= .desc identifier , expression520bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) {521 MCSymbol *Sym;522 if (getParser().parseSymbol(Sym))523 return TokError("expected identifier in directive");524 525 if (getLexer().isNot(AsmToken::Comma))526 return TokError("unexpected token in '.desc' directive");527 Lex();528 529 int64_t DescValue;530 if (getParser().parseAbsoluteExpression(DescValue))531 return true;532 533 if (getLexer().isNot(AsmToken::EndOfStatement))534 return TokError("unexpected token in '.desc' directive");535 536 Lex();537 538 // Set the n_desc field of this Symbol to this DescValue539 getStreamer().emitSymbolDesc(Sym, DescValue);540 541 return false;542}543 544/// parseDirectiveIndirectSymbol545/// ::= .indirect_symbol identifier546bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {547 const MCSectionMachO *Current = static_cast<const MCSectionMachO *>(548 getStreamer().getCurrentSectionOnly());549 MachO::SectionType SectionType = Current->getType();550 if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS &&551 SectionType != MachO::S_LAZY_SYMBOL_POINTERS &&552 SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS &&553 SectionType != MachO::S_SYMBOL_STUBS)554 return Error(Loc, "indirect symbol not in a symbol pointer or stub "555 "section");556 557 MCSymbol *Sym;558 if (getParser().parseSymbol(Sym))559 return TokError("expected identifier in .indirect_symbol directive");560 561 // Assembler local symbols don't make any sense here. Complain loudly.562 if (Sym->isTemporary())563 return TokError("non-local symbol required in directive");564 565 if (!getStreamer().emitSymbolAttribute(Sym, MCSA_IndirectSymbol))566 return TokError("unable to emit indirect symbol attribute for: " +567 Sym->getName());568 569 if (getLexer().isNot(AsmToken::EndOfStatement))570 return TokError("unexpected token in '.indirect_symbol' directive");571 572 Lex();573 574 return false;575}576 577/// parseDirectiveDumpOrLoad578/// ::= ( .dump | .load ) "filename"579bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive,580 SMLoc IDLoc) {581 bool IsDump = Directive == ".dump";582 if (getLexer().isNot(AsmToken::String))583 return TokError("expected string in '.dump' or '.load' directive");584 585 Lex();586 587 if (getLexer().isNot(AsmToken::EndOfStatement))588 return TokError("unexpected token in '.dump' or '.load' directive");589 590 Lex();591 592 // FIXME: If/when .dump and .load are implemented they will be done in the593 // the assembly parser and not have any need for an MCStreamer API.594 if (IsDump)595 return Warning(IDLoc, "ignoring directive .dump for now");596 else597 return Warning(IDLoc, "ignoring directive .load for now");598}599 600/// ParseDirectiveLinkerOption601/// ::= .linker_option "string" ( , "string" )*602bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) {603 SmallVector<std::string, 4> Args;604 while (true) {605 if (getLexer().isNot(AsmToken::String))606 return TokError("expected string in '" + Twine(IDVal) + "' directive");607 608 std::string Data;609 if (getParser().parseEscapedString(Data))610 return true;611 612 Args.push_back(Data);613 614 if (getLexer().is(AsmToken::EndOfStatement))615 break;616 617 if (getLexer().isNot(AsmToken::Comma))618 return TokError("unexpected token in '" + Twine(IDVal) + "' directive");619 Lex();620 }621 622 getStreamer().emitLinkerOptions(Args);623 return false;624}625 626/// parseDirectiveLsym627/// ::= .lsym identifier , expression628bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) {629 MCSymbol *Sym;630 if (getParser().parseSymbol(Sym))631 return TokError("expected identifier in directive");632 633 if (getLexer().isNot(AsmToken::Comma))634 return TokError("unexpected token in '.lsym' directive");635 Lex();636 637 const MCExpr *Value;638 if (getParser().parseExpression(Value))639 return true;640 641 if (getLexer().isNot(AsmToken::EndOfStatement))642 return TokError("unexpected token in '.lsym' directive");643 644 Lex();645 646 // We don't currently support this directive.647 //648 // FIXME: Diagnostic location!649 (void) Sym;650 return TokError("directive '.lsym' is unsupported");651}652 653/// parseDirectiveSection:654/// ::= .section identifier (',' identifier)*655bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {656 SMLoc Loc = getLexer().getLoc();657 658 StringRef SectionName;659 if (getParser().parseIdentifier(SectionName))660 return Error(Loc, "expected identifier after '.section' directive");661 662 // Verify there is a following comma.663 if (!getLexer().is(AsmToken::Comma))664 return TokError("unexpected token in '.section' directive");665 666 std::string SectionSpec = std::string(SectionName);667 SectionSpec += ",";668 669 // Add all the tokens until the end of the line, ParseSectionSpecifier will670 // handle this.671 StringRef EOL = getLexer().LexUntilEndOfStatement();672 SectionSpec.append(EOL.begin(), EOL.end());673 674 Lex();675 if (getLexer().isNot(AsmToken::EndOfStatement))676 return TokError("unexpected token in '.section' directive");677 Lex();678 679 StringRef Segment, Section;680 unsigned StubSize;681 unsigned TAA;682 bool TAAParsed;683 if (class Error E = MCSectionMachO::ParseSectionSpecifier(684 SectionSpec, Segment, Section, TAA, TAAParsed, StubSize))685 return Error(Loc, toString(std::move(E)));686 687 // Issue a warning if the target is not powerpc and Section is a *coal* section.688 Triple TT = getParser().getContext().getTargetTriple();689 Triple::ArchType ArchTy = TT.getArch();690 691 if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) {692 StringRef NonCoalSection = StringSwitch<StringRef>(Section)693 .Case("__textcoal_nt", "__text")694 .Case("__const_coal", "__const")695 .Case("__datacoal_nt", "__data")696 .Default(Section);697 698 if (Section != NonCoalSection) {699 StringRef SectionVal(Loc.getPointer());700 size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B);701 SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B);702 SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E);703 getParser().Warning(Loc, "section \"" + Section + "\" is deprecated",704 SMRange(BLoc, ELoc));705 getParser().Note(Loc, "change section name to \"" + NonCoalSection +706 "\"", SMRange(BLoc, ELoc));707 }708 }709 710 // FIXME: Arch specific.711 bool isText = Segment == "__TEXT"; // FIXME: Hack.712 getStreamer().switchSection(getContext().getMachOSection(713 Segment, Section, TAA, StubSize,714 isText ? SectionKind::getText() : SectionKind::getData()));715 return false;716}717 718/// ParseDirectivePushSection:719/// ::= .pushsection identifier (',' identifier)*720bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) {721 getStreamer().pushSection();722 723 if (parseDirectiveSection(S, Loc)) {724 getStreamer().popSection();725 return true;726 }727 728 return false;729}730 731/// ParseDirectivePopSection:732/// ::= .popsection733bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) {734 if (!getStreamer().popSection())735 return TokError(".popsection without corresponding .pushsection");736 return false;737}738 739/// ParseDirectivePrevious:740/// ::= .previous741bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {742 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();743 if (!PreviousSection.first)744 return TokError(".previous without corresponding .section");745 getStreamer().switchSection(PreviousSection.first, PreviousSection.second);746 return false;747}748 749/// ParseDirectiveSecureLogUnique750/// ::= .secure_log_unique ... message ...751bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {752 StringRef LogMessage = getParser().parseStringToEndOfStatement();753 if (getLexer().isNot(AsmToken::EndOfStatement))754 return TokError("unexpected token in '.secure_log_unique' directive");755 756 if (getContext().getSecureLogUsed())757 return Error(IDLoc, ".secure_log_unique specified multiple times");758 759 // Get the secure log path.760 StringRef SecureLogFile = getContext().getSecureLogFile();761 if (SecureLogFile.empty())762 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE "763 "environment variable unset.");764 765 // Open the secure log file if we haven't already.766 raw_fd_ostream *OS = getContext().getSecureLog();767 if (!OS) {768 std::error_code EC;769 auto NewOS = std::make_unique<raw_fd_ostream>(770 SecureLogFile, EC, sys::fs::OF_Append | sys::fs::OF_TextWithCRLF);771 if (EC)772 return Error(IDLoc, Twine("can't open secure log file: ") +773 SecureLogFile + " (" + EC.message() + ")");774 OS = NewOS.get();775 getContext().setSecureLog(std::move(NewOS));776 }777 778 // Write the message.779 unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc);780 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier()781 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":"782 << LogMessage + "\n";783 784 getContext().setSecureLogUsed(true);785 786 return false;787}788 789/// ParseDirectiveSecureLogReset790/// ::= .secure_log_reset791bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) {792 if (getLexer().isNot(AsmToken::EndOfStatement))793 return TokError("unexpected token in '.secure_log_reset' directive");794 795 Lex();796 797 getContext().setSecureLogUsed(false);798 799 return false;800}801 802/// parseDirectiveSubsectionsViaSymbols803/// ::= .subsections_via_symbols804bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {805 if (getLexer().isNot(AsmToken::EndOfStatement))806 return TokError("unexpected token in '.subsections_via_symbols' directive");807 808 Lex();809 810 getStreamer().emitSubsectionsViaSymbols();811 812 return false;813}814 815/// ParseDirectiveTBSS816/// ::= .tbss identifier, size, align817bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) {818 SMLoc IDLoc = getLexer().getLoc();819 MCSymbol *Sym;820 if (getParser().parseSymbol(Sym))821 return TokError("expected identifier in directive");822 823 if (getLexer().isNot(AsmToken::Comma))824 return TokError("unexpected token in directive");825 Lex();826 827 int64_t Size;828 SMLoc SizeLoc = getLexer().getLoc();829 if (getParser().parseAbsoluteExpression(Size))830 return true;831 832 int64_t Pow2Alignment = 0;833 SMLoc Pow2AlignmentLoc;834 if (getLexer().is(AsmToken::Comma)) {835 Lex();836 Pow2AlignmentLoc = getLexer().getLoc();837 if (getParser().parseAbsoluteExpression(Pow2Alignment))838 return true;839 }840 841 if (getLexer().isNot(AsmToken::EndOfStatement))842 return TokError("unexpected token in '.tbss' directive");843 844 Lex();845 846 if (Size < 0)847 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than"848 "zero");849 850 // FIXME: Diagnose overflow.851 if (Pow2Alignment < 0)852 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less"853 "than zero");854 855 if (!Sym->isUndefined())856 return Error(IDLoc, "invalid symbol redefinition");857 858 getStreamer().emitTBSSSymbol(859 getContext().getMachOSection("__DATA", "__thread_bss",860 MachO::S_THREAD_LOCAL_ZEROFILL, 0,861 SectionKind::getThreadBSS()),862 Sym, Size, Align(1ULL << Pow2Alignment));863 864 return false;865}866 867/// ParseDirectiveZerofill868/// ::= .zerofill segname , sectname [, identifier , size_expression [869/// , align_expression ]]870bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) {871 StringRef Segment;872 if (getParser().parseIdentifier(Segment))873 return TokError("expected segment name after '.zerofill' directive");874 875 if (getLexer().isNot(AsmToken::Comma))876 return TokError("unexpected token in directive");877 Lex();878 879 StringRef Section;880 SMLoc SectionLoc = getLexer().getLoc();881 if (getParser().parseIdentifier(Section))882 return TokError("expected section name after comma in '.zerofill' "883 "directive");884 885 // If this is the end of the line all that was wanted was to create the886 // the section but with no symbol.887 if (getLexer().is(AsmToken::EndOfStatement)) {888 // Create the zerofill section but no symbol889 getStreamer().emitZerofill(890 getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,891 SectionKind::getBSS()),892 /*Symbol=*/nullptr, /*Size=*/0, Align(1), SectionLoc);893 return false;894 }895 896 if (getLexer().isNot(AsmToken::Comma))897 return TokError("unexpected token in directive");898 Lex();899 900 SMLoc IDLoc = getLexer().getLoc();901 MCSymbol *Sym;902 if (getParser().parseSymbol(Sym))903 return TokError("expected identifier in directive");904 905 if (getLexer().isNot(AsmToken::Comma))906 return TokError("unexpected token in directive");907 Lex();908 909 int64_t Size;910 SMLoc SizeLoc = getLexer().getLoc();911 if (getParser().parseAbsoluteExpression(Size))912 return true;913 914 int64_t Pow2Alignment = 0;915 SMLoc Pow2AlignmentLoc;916 if (getLexer().is(AsmToken::Comma)) {917 Lex();918 Pow2AlignmentLoc = getLexer().getLoc();919 if (getParser().parseAbsoluteExpression(Pow2Alignment))920 return true;921 }922 923 if (getLexer().isNot(AsmToken::EndOfStatement))924 return TokError("unexpected token in '.zerofill' directive");925 926 Lex();927 928 if (Size < 0)929 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less "930 "than zero");931 932 // NOTE: The alignment in the directive is a power of 2 value, the assembler933 // may internally end up wanting an alignment in bytes.934 // FIXME: Diagnose overflow.935 if (Pow2Alignment < 0)936 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, "937 "can't be less than zero");938 939 if (!Sym->isUndefined())940 return Error(IDLoc, "invalid symbol redefinition");941 942 // Create the zerofill Symbol with Size and Pow2Alignment943 //944 // FIXME: Arch specific.945 getStreamer().emitZerofill(946 getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0,947 SectionKind::getBSS()),948 Sym, Size, Align(1ULL << Pow2Alignment), SectionLoc);949 950 return false;951}952 953/// ParseDirectiveDataRegion954/// ::= .data_region [ ( jt8 | jt16 | jt32 ) ]955bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) {956 if (getLexer().is(AsmToken::EndOfStatement)) {957 Lex();958 getStreamer().emitDataRegion(MCDR_DataRegion);959 return false;960 }961 StringRef RegionType;962 SMLoc Loc = getParser().getTok().getLoc();963 if (getParser().parseIdentifier(RegionType))964 return TokError("expected region type after '.data_region' directive");965 int Kind = StringSwitch<int>(RegionType)966 .Case("jt8", MCDR_DataRegionJT8)967 .Case("jt16", MCDR_DataRegionJT16)968 .Case("jt32", MCDR_DataRegionJT32)969 .Default(-1);970 if (Kind == -1)971 return Error(Loc, "unknown region type in '.data_region' directive");972 Lex();973 974 getStreamer().emitDataRegion((MCDataRegionType)Kind);975 return false;976}977 978/// ParseDirectiveDataRegionEnd979/// ::= .end_data_region980bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {981 if (getLexer().isNot(AsmToken::EndOfStatement))982 return TokError("unexpected token in '.end_data_region' directive");983 984 Lex();985 getStreamer().emitDataRegion(MCDR_DataRegionEnd);986 return false;987}988 989static bool isSDKVersionToken(const AsmToken &Tok) {990 return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version";991}992 993/// parseMajorMinorVersionComponent ::= major, minor994bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major,995 unsigned *Minor,996 const char *VersionName) {997 // Get the major version number.998 if (getLexer().isNot(AsmToken::Integer))999 return TokError(Twine("invalid ") + VersionName +1000 " major version number, integer expected");1001 int64_t MajorVal = getLexer().getTok().getIntVal();1002 if (MajorVal > 65535 || MajorVal <= 0)1003 return TokError(Twine("invalid ") + VersionName + " major version number");1004 *Major = (unsigned)MajorVal;1005 Lex();1006 if (getLexer().isNot(AsmToken::Comma))1007 return TokError(Twine(VersionName) +1008 " minor version number required, comma expected");1009 Lex();1010 // Get the minor version number.1011 if (getLexer().isNot(AsmToken::Integer))1012 return TokError(Twine("invalid ") + VersionName +1013 " minor version number, integer expected");1014 int64_t MinorVal = getLexer().getTok().getIntVal();1015 if (MinorVal > 255 || MinorVal < 0)1016 return TokError(Twine("invalid ") + VersionName + " minor version number");1017 *Minor = MinorVal;1018 Lex();1019 return false;1020}1021 1022/// parseOptionalTrailingVersionComponent ::= , version_number1023bool DarwinAsmParser::parseOptionalTrailingVersionComponent(1024 unsigned *Component, const char *ComponentName) {1025 assert(getLexer().is(AsmToken::Comma) && "comma expected");1026 Lex();1027 if (getLexer().isNot(AsmToken::Integer))1028 return TokError(Twine("invalid ") + ComponentName +1029 " version number, integer expected");1030 int64_t Val = getLexer().getTok().getIntVal();1031 if (Val > 255 || Val < 0)1032 return TokError(Twine("invalid ") + ComponentName + " version number");1033 *Component = Val;1034 Lex();1035 return false;1036}1037 1038/// parseVersion ::= parseMajorMinorVersionComponent1039/// parseOptionalTrailingVersionComponent1040bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor,1041 unsigned *Update) {1042 if (parseMajorMinorVersionComponent(Major, Minor, "OS"))1043 return true;1044 1045 // Get the update level, if specified1046 *Update = 0;1047 if (getLexer().is(AsmToken::EndOfStatement) ||1048 isSDKVersionToken(getLexer().getTok()))1049 return false;1050 if (getLexer().isNot(AsmToken::Comma))1051 return TokError("invalid OS update specifier, comma expected");1052 if (parseOptionalTrailingVersionComponent(Update, "OS update"))1053 return true;1054 return false;1055}1056 1057bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) {1058 assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version");1059 Lex();1060 unsigned Major, Minor;1061 if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK"))1062 return true;1063 SDKVersion = VersionTuple(Major, Minor);1064 1065 // Get the subminor version, if specified.1066 if (getLexer().is(AsmToken::Comma)) {1067 unsigned Subminor;1068 if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor"))1069 return true;1070 SDKVersion = VersionTuple(Major, Minor, Subminor);1071 }1072 return false;1073}1074 1075void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg,1076 SMLoc Loc, Triple::OSType ExpectedOS) {1077 const Triple &Target = getContext().getTargetTriple();1078 if (Target.getOS() != ExpectedOS)1079 Warning(Loc, Twine(Directive) +1080 (Arg.empty() ? Twine() : Twine(' ') + Arg) +1081 " used while targeting " + Target.getOSName());1082 1083 if (LastVersionDirective.isValid()) {1084 Warning(Loc, "overriding previous version directive");1085 Note(LastVersionDirective, "previous definition is here");1086 }1087 LastVersionDirective = Loc;1088}1089 1090static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) {1091 switch (Type) {1092 case MCVM_WatchOSVersionMin: return Triple::WatchOS;1093 case MCVM_TvOSVersionMin: return Triple::TvOS;1094 case MCVM_IOSVersionMin: return Triple::IOS;1095 case MCVM_OSXVersionMin: return Triple::MacOSX;1096 }1097 llvm_unreachable("Invalid mc version min type");1098}1099 1100/// parseVersionMin1101/// ::= .ios_version_min parseVersion parseSDKVersion1102/// | .macosx_version_min parseVersion parseSDKVersion1103/// | .tvos_version_min parseVersion parseSDKVersion1104/// | .watchos_version_min parseVersion parseSDKVersion1105bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc,1106 MCVersionMinType Type) {1107 unsigned Major;1108 unsigned Minor;1109 unsigned Update;1110 if (parseVersion(&Major, &Minor, &Update))1111 return true;1112 1113 VersionTuple SDKVersion;1114 if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))1115 return true;1116 1117 if (parseEOL())1118 return addErrorSuffix(Twine(" in '") + Directive + "' directive");1119 1120 Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type);1121 checkVersion(Directive, StringRef(), Loc, ExpectedOS);1122 getStreamer().emitVersionMin(Type, Major, Minor, Update, SDKVersion);1123 return false;1124}1125 1126static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) {1127 switch (Type) {1128 case MachO::PLATFORM_UNKNOWN: /* silence warning */1129 break;1130 case MachO::PLATFORM_MACOS: return Triple::MacOSX;1131 case MachO::PLATFORM_IOS: return Triple::IOS;1132 case MachO::PLATFORM_TVOS: return Triple::TvOS;1133 case MachO::PLATFORM_WATCHOS: return Triple::WatchOS;1134 case MachO::PLATFORM_XROS: return Triple::XROS;1135 case MachO::PLATFORM_BRIDGEOS: /* silence warning */ break;1136 case MachO::PLATFORM_DRIVERKIT:1137 return Triple::DriverKit;1138 case MachO::PLATFORM_MACCATALYST: return Triple::IOS;1139 case MachO::PLATFORM_IOSSIMULATOR: /* silence warning */ break;1140 case MachO::PLATFORM_TVOSSIMULATOR: /* silence warning */ break;1141 case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break;1142 case MachO::PLATFORM_XROS_SIMULATOR: /* silence warning */ break;1143 }1144 llvm_unreachable("Invalid mach-o platform type");1145}1146 1147/// parseBuildVersion1148/// ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion1149bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) {1150 StringRef PlatformName;1151 SMLoc PlatformLoc = getTok().getLoc();1152 if (getParser().parseIdentifier(PlatformName))1153 return TokError("platform name expected");1154 1155 unsigned Platform = StringSwitch<unsigned>(PlatformName)1156#define PLATFORM(platform, id, name, build_name, target, tapi_target, \1157 marketing) \1158 .Case(#build_name, MachO::PLATFORM_##platform)1159#include "llvm/BinaryFormat/MachO.def"1160 .Default(MachO::PLATFORM_UNKNOWN);1161 1162 if (Platform == MachO::PLATFORM_UNKNOWN)1163 return Error(PlatformLoc, "unknown platform name");1164 1165 if (getLexer().isNot(AsmToken::Comma))1166 return TokError("version number required, comma expected");1167 Lex();1168 1169 unsigned Major;1170 unsigned Minor;1171 unsigned Update;1172 if (parseVersion(&Major, &Minor, &Update))1173 return true;1174 1175 VersionTuple SDKVersion;1176 if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion))1177 return true;1178 1179 if (parseEOL())1180 return addErrorSuffix(" in '.build_version' directive");1181 1182 Triple::OSType ExpectedOS1183 = getOSTypeFromPlatform((MachO::PlatformType)Platform);1184 checkVersion(Directive, PlatformName, Loc, ExpectedOS);1185 getStreamer().emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);1186 return false;1187}1188 1189/// parseDirectiveCGProfile1190/// ::= .cg_profile from, to, count1191bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {1192 return MCAsmParserExtension::parseDirectiveCGProfile(S, Loc);1193}1194 1195MCAsmParserExtension *llvm::createDarwinAsmParser() {1196 return new DarwinAsmParser;1197}1198