10b57cec5SDimitry Andric //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 100b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 110b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 120b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h" 130b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 140b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 150b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCDirectives.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmParserExtension.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 250b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 26fe6060f1SDimitry Andric #include "llvm/Support/Error.h" 270b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 280b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 290b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 300b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 310b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 320b57cec5SDimitry Andric #include <algorithm> 330b57cec5SDimitry Andric #include <cstddef> 340b57cec5SDimitry Andric #include <cstdint> 350b57cec5SDimitry Andric #include <string> 360b57cec5SDimitry Andric #include <system_error> 370b57cec5SDimitry Andric #include <utility> 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric using namespace llvm; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric namespace { 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric /// Implementation of directive handling which is shared across all 440b57cec5SDimitry Andric /// Darwin targets. 450b57cec5SDimitry Andric class DarwinAsmParser : public MCAsmParserExtension { 460b57cec5SDimitry Andric template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)> 470b57cec5SDimitry Andric void addDirectiveHandler(StringRef Directive) { 480b57cec5SDimitry Andric MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( 490b57cec5SDimitry Andric this, HandleDirective<DarwinAsmParser, HandlerMethod>); 500b57cec5SDimitry Andric getParser().addDirectiveHandler(Directive, Handler); 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric bool parseSectionSwitch(StringRef Segment, StringRef Section, 540b57cec5SDimitry Andric unsigned TAA = 0, unsigned ImplicitAlign = 0, 550b57cec5SDimitry Andric unsigned StubSize = 0); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric SMLoc LastVersionDirective; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric public: 600b57cec5SDimitry Andric DarwinAsmParser() = default; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric void Initialize(MCAsmParser &Parser) override { 630b57cec5SDimitry Andric // Call the base implementation. 640b57cec5SDimitry Andric this->MCAsmParserExtension::Initialize(Parser); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveAltEntry>(".alt_entry"); 670b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveDesc>(".desc"); 680b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveIndirectSymbol>( 690b57cec5SDimitry Andric ".indirect_symbol"); 700b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveLsym>(".lsym"); 710b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveSubsectionsViaSymbols>( 720b57cec5SDimitry Andric ".subsections_via_symbols"); 730b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".dump"); 740b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveDumpOrLoad>(".load"); 750b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveSection>(".section"); 760b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectivePushSection>( 770b57cec5SDimitry Andric ".pushsection"); 780b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectivePopSection>( 790b57cec5SDimitry Andric ".popsection"); 800b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectivePrevious>(".previous"); 810b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogUnique>( 820b57cec5SDimitry Andric ".secure_log_unique"); 830b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveSecureLogReset>( 840b57cec5SDimitry Andric ".secure_log_reset"); 850b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveTBSS>(".tbss"); 860b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveZerofill>(".zerofill"); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegion>( 890b57cec5SDimitry Andric ".data_region"); 900b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveDataRegionEnd>( 910b57cec5SDimitry Andric ".end_data_region"); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric // Special section directives. 940b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveBss>(".bss"); 950b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConst>(".const"); 960b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstData>( 970b57cec5SDimitry Andric ".const_data"); 980b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveConstructor>( 990b57cec5SDimitry Andric ".constructor"); 1000b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveCString>( 1010b57cec5SDimitry Andric ".cstring"); 1020b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveData>(".data"); 1030b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDestructor>( 1040b57cec5SDimitry Andric ".destructor"); 1050b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveDyld>(".dyld"); 1060b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit0>( 1070b57cec5SDimitry Andric ".fvmlib_init0"); 1080b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveFVMLibInit1>( 1090b57cec5SDimitry Andric ".fvmlib_init1"); 1100b57cec5SDimitry Andric addDirectiveHandler< 1110b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveLazySymbolPointers>( 1120b57cec5SDimitry Andric ".lazy_symbol_pointer"); 1130b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveLinkerOption>( 1140b57cec5SDimitry Andric ".linker_option"); 1150b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral16>( 1160b57cec5SDimitry Andric ".literal16"); 1170b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral4>( 1180b57cec5SDimitry Andric ".literal4"); 1190b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveLiteral8>( 1200b57cec5SDimitry Andric ".literal8"); 1210b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModInitFunc>( 1220b57cec5SDimitry Andric ".mod_init_func"); 1230b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveModTermFunc>( 1240b57cec5SDimitry Andric ".mod_term_func"); 1250b57cec5SDimitry Andric addDirectiveHandler< 1260b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>( 1270b57cec5SDimitry Andric ".non_lazy_symbol_pointer"); 1280b57cec5SDimitry Andric addDirectiveHandler< 1290b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>( 1300b57cec5SDimitry Andric ".thread_local_variable_pointer"); 1310b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>( 1320b57cec5SDimitry Andric ".objc_cat_cls_meth"); 1330b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>( 1340b57cec5SDimitry Andric ".objc_cat_inst_meth"); 1350b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCategory>( 1360b57cec5SDimitry Andric ".objc_category"); 1370b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClass>( 1380b57cec5SDimitry Andric ".objc_class"); 1390b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassNames>( 1400b57cec5SDimitry Andric ".objc_class_names"); 1410b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClassVars>( 1420b57cec5SDimitry Andric ".objc_class_vars"); 1430b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsMeth>( 1440b57cec5SDimitry Andric ".objc_cls_meth"); 1450b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCClsRefs>( 1460b57cec5SDimitry Andric ".objc_cls_refs"); 1470b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCInstMeth>( 1480b57cec5SDimitry Andric ".objc_inst_meth"); 1490b57cec5SDimitry Andric addDirectiveHandler< 1500b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveObjCInstanceVars>( 1510b57cec5SDimitry Andric ".objc_instance_vars"); 1520b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMessageRefs>( 1530b57cec5SDimitry Andric ".objc_message_refs"); 1540b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCMetaClass>( 1550b57cec5SDimitry Andric ".objc_meta_class"); 1560b57cec5SDimitry Andric addDirectiveHandler< 1570b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveObjCMethVarNames>( 1580b57cec5SDimitry Andric ".objc_meth_var_names"); 1590b57cec5SDimitry Andric addDirectiveHandler< 1600b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveObjCMethVarTypes>( 1610b57cec5SDimitry Andric ".objc_meth_var_types"); 1620b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCModuleInfo>( 1630b57cec5SDimitry Andric ".objc_module_info"); 1640b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCProtocol>( 1650b57cec5SDimitry Andric ".objc_protocol"); 1660b57cec5SDimitry Andric addDirectiveHandler< 1670b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveObjCSelectorStrs>( 1680b57cec5SDimitry Andric ".objc_selector_strs"); 1690b57cec5SDimitry Andric addDirectiveHandler< 1700b57cec5SDimitry Andric &DarwinAsmParser::parseSectionDirectiveObjCStringObject>( 1710b57cec5SDimitry Andric ".objc_string_object"); 1720b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCSymbols>( 1730b57cec5SDimitry Andric ".objc_symbols"); 1740b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectivePICSymbolStub>( 1750b57cec5SDimitry Andric ".picsymbol_stub"); 1760b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticConst>( 1770b57cec5SDimitry Andric ".static_const"); 1780b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveStaticData>( 1790b57cec5SDimitry Andric ".static_data"); 1800b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveSymbolStub>( 1810b57cec5SDimitry Andric ".symbol_stub"); 1820b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTData>(".tdata"); 1830b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveText>(".text"); 1840b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveThreadInitFunc>( 1850b57cec5SDimitry Andric ".thread_init_func"); 1860b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv"); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident"); 1890b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseWatchOSVersionMin>( 1900b57cec5SDimitry Andric ".watchos_version_min"); 1910b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseTvOSVersionMin>( 1920b57cec5SDimitry Andric ".tvos_version_min"); 1930b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseIOSVersionMin>( 1940b57cec5SDimitry Andric ".ios_version_min"); 1950b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseMacOSXVersionMin>( 1960b57cec5SDimitry Andric ".macosx_version_min"); 1970b57cec5SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseBuildVersion>(".build_version"); 198*04eeddc0SDimitry Andric addDirectiveHandler<&DarwinAsmParser::parseDirectiveCGProfile>( 199*04eeddc0SDimitry Andric ".cg_profile"); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric LastVersionDirective = SMLoc(); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric bool parseDirectiveAltEntry(StringRef, SMLoc); 2050b57cec5SDimitry Andric bool parseDirectiveDesc(StringRef, SMLoc); 2060b57cec5SDimitry Andric bool parseDirectiveIndirectSymbol(StringRef, SMLoc); 2070b57cec5SDimitry Andric bool parseDirectiveDumpOrLoad(StringRef, SMLoc); 2080b57cec5SDimitry Andric bool parseDirectiveLsym(StringRef, SMLoc); 2090b57cec5SDimitry Andric bool parseDirectiveLinkerOption(StringRef, SMLoc); 2100b57cec5SDimitry Andric bool parseDirectiveSection(StringRef, SMLoc); 2110b57cec5SDimitry Andric bool parseDirectivePushSection(StringRef, SMLoc); 2120b57cec5SDimitry Andric bool parseDirectivePopSection(StringRef, SMLoc); 2130b57cec5SDimitry Andric bool parseDirectivePrevious(StringRef, SMLoc); 2140b57cec5SDimitry Andric bool parseDirectiveSecureLogReset(StringRef, SMLoc); 2150b57cec5SDimitry Andric bool parseDirectiveSecureLogUnique(StringRef, SMLoc); 2160b57cec5SDimitry Andric bool parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); 2170b57cec5SDimitry Andric bool parseDirectiveTBSS(StringRef, SMLoc); 2180b57cec5SDimitry Andric bool parseDirectiveZerofill(StringRef, SMLoc); 2190b57cec5SDimitry Andric bool parseDirectiveDataRegion(StringRef, SMLoc); 2200b57cec5SDimitry Andric bool parseDirectiveDataRegionEnd(StringRef, SMLoc); 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric // Named Section Directive 2230b57cec5SDimitry Andric bool parseSectionDirectiveBss(StringRef, SMLoc) { 2240b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__bss"); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric bool parseSectionDirectiveConst(StringRef, SMLoc) { 2280b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__const"); 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric bool parseSectionDirectiveStaticConst(StringRef, SMLoc) { 2320b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__static_const"); 2330b57cec5SDimitry Andric } 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric bool parseSectionDirectiveCString(StringRef, SMLoc) { 2360b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__cstring", 2370b57cec5SDimitry Andric MachO::S_CSTRING_LITERALS); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric bool parseSectionDirectiveLiteral4(StringRef, SMLoc) { 2410b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__literal4", 2420b57cec5SDimitry Andric MachO::S_4BYTE_LITERALS, 4); 2430b57cec5SDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric bool parseSectionDirectiveLiteral8(StringRef, SMLoc) { 2460b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__literal8", 2470b57cec5SDimitry Andric MachO::S_8BYTE_LITERALS, 8); 2480b57cec5SDimitry Andric } 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric bool parseSectionDirectiveLiteral16(StringRef, SMLoc) { 2510b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__literal16", 2520b57cec5SDimitry Andric MachO::S_16BYTE_LITERALS, 16); 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric bool parseSectionDirectiveConstructor(StringRef, SMLoc) { 2560b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__constructor"); 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric bool parseSectionDirectiveDestructor(StringRef, SMLoc) { 2600b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__destructor"); 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric bool parseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { 2640b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__fvmlib_init0"); 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric bool parseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { 2680b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__fvmlib_init1"); 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric bool parseSectionDirectiveSymbolStub(StringRef, SMLoc) { 2720b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__symbol_stub", 2730b57cec5SDimitry Andric MachO::S_SYMBOL_STUBS | 2740b57cec5SDimitry Andric MachO::S_ATTR_PURE_INSTRUCTIONS, 2750b57cec5SDimitry Andric // FIXME: Different on PPC and ARM. 2760b57cec5SDimitry Andric 0, 16); 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric 2790b57cec5SDimitry Andric bool parseSectionDirectivePICSymbolStub(StringRef, SMLoc) { 2800b57cec5SDimitry Andric return parseSectionSwitch("__TEXT","__picsymbol_stub", 2810b57cec5SDimitry Andric MachO::S_SYMBOL_STUBS | 2820b57cec5SDimitry Andric MachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric bool parseSectionDirectiveData(StringRef, SMLoc) { 2860b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__data"); 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric bool parseSectionDirectiveStaticData(StringRef, SMLoc) { 2900b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__static_data"); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric bool parseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { 2940b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__nl_symbol_ptr", 2950b57cec5SDimitry Andric MachO::S_NON_LAZY_SYMBOL_POINTERS, 4); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric bool parseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { 2990b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__la_symbol_ptr", 3000b57cec5SDimitry Andric MachO::S_LAZY_SYMBOL_POINTERS, 4); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric 3030b57cec5SDimitry Andric bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) { 3040b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__thread_ptr", 3050b57cec5SDimitry Andric MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4); 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric bool parseSectionDirectiveDyld(StringRef, SMLoc) { 3090b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__dyld"); 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric bool parseSectionDirectiveModInitFunc(StringRef, SMLoc) { 3130b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__mod_init_func", 3140b57cec5SDimitry Andric MachO::S_MOD_INIT_FUNC_POINTERS, 4); 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric bool parseSectionDirectiveModTermFunc(StringRef, SMLoc) { 3180b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__mod_term_func", 3190b57cec5SDimitry Andric MachO::S_MOD_TERM_FUNC_POINTERS, 4); 3200b57cec5SDimitry Andric } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric bool parseSectionDirectiveConstData(StringRef, SMLoc) { 3230b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__const"); 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric bool parseSectionDirectiveObjCClass(StringRef, SMLoc) { 3270b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__class", 3280b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric bool parseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { 3320b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__meta_class", 3330b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric bool parseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { 3370b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__cat_cls_meth", 3380b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric bool parseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { 3420b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__cat_inst_meth", 3430b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric bool parseSectionDirectiveObjCProtocol(StringRef, SMLoc) { 3470b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__protocol", 3480b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric bool parseSectionDirectiveObjCStringObject(StringRef, SMLoc) { 3520b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__string_object", 3530b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3540b57cec5SDimitry Andric } 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric bool parseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { 3570b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__cls_meth", 3580b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric bool parseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { 3620b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__inst_meth", 3630b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3640b57cec5SDimitry Andric } 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric bool parseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { 3670b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__cls_refs", 3680b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP | 3690b57cec5SDimitry Andric MachO::S_LITERAL_POINTERS, 4); 3700b57cec5SDimitry Andric } 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric bool parseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { 3730b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__message_refs", 3740b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP | 3750b57cec5SDimitry Andric MachO::S_LITERAL_POINTERS, 4); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric bool parseSectionDirectiveObjCSymbols(StringRef, SMLoc) { 3790b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__symbols", 3800b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric bool parseSectionDirectiveObjCCategory(StringRef, SMLoc) { 3840b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__category", 3850b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric bool parseSectionDirectiveObjCClassVars(StringRef, SMLoc) { 3890b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__class_vars", 3900b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric bool parseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { 3940b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__instance_vars", 3950b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric bool parseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { 3990b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__module_info", 4000b57cec5SDimitry Andric MachO::S_ATTR_NO_DEAD_STRIP); 4010b57cec5SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric bool parseSectionDirectiveObjCClassNames(StringRef, SMLoc) { 4040b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__cstring", 4050b57cec5SDimitry Andric MachO::S_CSTRING_LITERALS); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric bool parseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { 4090b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__cstring", 4100b57cec5SDimitry Andric MachO::S_CSTRING_LITERALS); 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric bool parseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { 4140b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__cstring", 4150b57cec5SDimitry Andric MachO::S_CSTRING_LITERALS); 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric bool parseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { 4190b57cec5SDimitry Andric return parseSectionSwitch("__OBJC", "__selector_strs", 4200b57cec5SDimitry Andric MachO::S_CSTRING_LITERALS); 4210b57cec5SDimitry Andric } 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric bool parseSectionDirectiveTData(StringRef, SMLoc) { 4240b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__thread_data", 4250b57cec5SDimitry Andric MachO::S_THREAD_LOCAL_REGULAR); 4260b57cec5SDimitry Andric } 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric bool parseSectionDirectiveText(StringRef, SMLoc) { 4290b57cec5SDimitry Andric return parseSectionSwitch("__TEXT", "__text", 4300b57cec5SDimitry Andric MachO::S_ATTR_PURE_INSTRUCTIONS); 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric bool parseSectionDirectiveTLV(StringRef, SMLoc) { 4340b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__thread_vars", 4350b57cec5SDimitry Andric MachO::S_THREAD_LOCAL_VARIABLES); 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric bool parseSectionDirectiveIdent(StringRef, SMLoc) { 4390b57cec5SDimitry Andric // Darwin silently ignores the .ident directive. 4400b57cec5SDimitry Andric getParser().eatToEndOfStatement(); 4410b57cec5SDimitry Andric return false; 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric bool parseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { 4450b57cec5SDimitry Andric return parseSectionSwitch("__DATA", "__thread_init", 4460b57cec5SDimitry Andric MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric bool parseWatchOSVersionMin(StringRef Directive, SMLoc Loc) { 4500b57cec5SDimitry Andric return parseVersionMin(Directive, Loc, MCVM_WatchOSVersionMin); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric bool parseTvOSVersionMin(StringRef Directive, SMLoc Loc) { 4530b57cec5SDimitry Andric return parseVersionMin(Directive, Loc, MCVM_TvOSVersionMin); 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric bool parseIOSVersionMin(StringRef Directive, SMLoc Loc) { 4560b57cec5SDimitry Andric return parseVersionMin(Directive, Loc, MCVM_IOSVersionMin); 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric bool parseMacOSXVersionMin(StringRef Directive, SMLoc Loc) { 4590b57cec5SDimitry Andric return parseVersionMin(Directive, Loc, MCVM_OSXVersionMin); 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric bool parseBuildVersion(StringRef Directive, SMLoc Loc); 4630b57cec5SDimitry Andric bool parseVersionMin(StringRef Directive, SMLoc Loc, MCVersionMinType Type); 4640b57cec5SDimitry Andric bool parseMajorMinorVersionComponent(unsigned *Major, unsigned *Minor, 4650b57cec5SDimitry Andric const char *VersionName); 4660b57cec5SDimitry Andric bool parseOptionalTrailingVersionComponent(unsigned *Component, 4670b57cec5SDimitry Andric const char *ComponentName); 4680b57cec5SDimitry Andric bool parseVersion(unsigned *Major, unsigned *Minor, unsigned *Update); 4690b57cec5SDimitry Andric bool parseSDKVersion(VersionTuple &SDKVersion); 4700b57cec5SDimitry Andric void checkVersion(StringRef Directive, StringRef Arg, SMLoc Loc, 4710b57cec5SDimitry Andric Triple::OSType ExpectedOS); 472*04eeddc0SDimitry Andric bool parseDirectiveCGProfile(StringRef Directive, SMLoc Loc); 4730b57cec5SDimitry Andric }; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric } // end anonymous namespace 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric bool DarwinAsmParser::parseSectionSwitch(StringRef Segment, StringRef Section, 4780b57cec5SDimitry Andric unsigned TAA, unsigned Align, 4790b57cec5SDimitry Andric unsigned StubSize) { 4800b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 4810b57cec5SDimitry Andric return TokError("unexpected token in section switching directive"); 4820b57cec5SDimitry Andric Lex(); 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric // FIXME: Arch specific. 4850b57cec5SDimitry Andric bool isText = TAA & MachO::S_ATTR_PURE_INSTRUCTIONS; 4860b57cec5SDimitry Andric getStreamer().SwitchSection(getContext().getMachOSection( 4870b57cec5SDimitry Andric Segment, Section, TAA, StubSize, 4880b57cec5SDimitry Andric isText ? SectionKind::getText() : SectionKind::getData())); 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric // Set the implicit alignment, if any. 4910b57cec5SDimitry Andric // 4920b57cec5SDimitry Andric // FIXME: This isn't really what 'as' does; I think it just uses the implicit 4930b57cec5SDimitry Andric // alignment on the section (e.g., if one manually inserts bytes into the 4940b57cec5SDimitry Andric // section, then just issuing the section switch directive will not realign 4950b57cec5SDimitry Andric // the section. However, this is arguably more reasonable behavior, and there 4960b57cec5SDimitry Andric // is no good reason for someone to intentionally emit incorrectly sized 4970b57cec5SDimitry Andric // values into the implicitly aligned sections. 4980b57cec5SDimitry Andric if (Align) 4995ffd83dbSDimitry Andric getStreamer().emitValueToAlignment(Align); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric return false; 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric /// parseDirectiveAltEntry 5050b57cec5SDimitry Andric /// ::= .alt_entry identifier 5060b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveAltEntry(StringRef, SMLoc) { 5070b57cec5SDimitry Andric StringRef Name; 5080b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 5090b57cec5SDimitry Andric return TokError("expected identifier in directive"); 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric // Look up symbol. 5120b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric if (Sym->isDefined()) 5150b57cec5SDimitry Andric return TokError(".alt_entry must preceed symbol definition"); 5160b57cec5SDimitry Andric 5175ffd83dbSDimitry Andric if (!getStreamer().emitSymbolAttribute(Sym, MCSA_AltEntry)) 5180b57cec5SDimitry Andric return TokError("unable to emit symbol attribute"); 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric Lex(); 5210b57cec5SDimitry Andric return false; 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric /// parseDirectiveDesc 5250b57cec5SDimitry Andric /// ::= .desc identifier , expression 5260b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDesc(StringRef, SMLoc) { 5270b57cec5SDimitry Andric StringRef Name; 5280b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 5290b57cec5SDimitry Andric return TokError("expected identifier in directive"); 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric // Handle the identifier as the key symbol. 5320b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 5350b57cec5SDimitry Andric return TokError("unexpected token in '.desc' directive"); 5360b57cec5SDimitry Andric Lex(); 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric int64_t DescValue; 5390b57cec5SDimitry Andric if (getParser().parseAbsoluteExpression(DescValue)) 5400b57cec5SDimitry Andric return true; 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 5430b57cec5SDimitry Andric return TokError("unexpected token in '.desc' directive"); 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric Lex(); 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric // Set the n_desc field of this Symbol to this DescValue 5485ffd83dbSDimitry Andric getStreamer().emitSymbolDesc(Sym, DescValue); 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric return false; 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric /// parseDirectiveIndirectSymbol 5540b57cec5SDimitry Andric /// ::= .indirect_symbol identifier 5550b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { 5560b57cec5SDimitry Andric const MCSectionMachO *Current = static_cast<const MCSectionMachO *>( 5570b57cec5SDimitry Andric getStreamer().getCurrentSectionOnly()); 5580b57cec5SDimitry Andric MachO::SectionType SectionType = Current->getType(); 5590b57cec5SDimitry Andric if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && 5600b57cec5SDimitry Andric SectionType != MachO::S_LAZY_SYMBOL_POINTERS && 5610b57cec5SDimitry Andric SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS && 5620b57cec5SDimitry Andric SectionType != MachO::S_SYMBOL_STUBS) 5630b57cec5SDimitry Andric return Error(Loc, "indirect symbol not in a symbol pointer or stub " 5640b57cec5SDimitry Andric "section"); 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andric StringRef Name; 5670b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 5680b57cec5SDimitry Andric return TokError("expected identifier in .indirect_symbol directive"); 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric // Assembler local symbols don't make any sense here. Complain loudly. 5730b57cec5SDimitry Andric if (Sym->isTemporary()) 5740b57cec5SDimitry Andric return TokError("non-local symbol required in directive"); 5750b57cec5SDimitry Andric 5765ffd83dbSDimitry Andric if (!getStreamer().emitSymbolAttribute(Sym, MCSA_IndirectSymbol)) 5770b57cec5SDimitry Andric return TokError("unable to emit indirect symbol attribute for: " + Name); 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 5800b57cec5SDimitry Andric return TokError("unexpected token in '.indirect_symbol' directive"); 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric Lex(); 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric return false; 5850b57cec5SDimitry Andric } 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric /// parseDirectiveDumpOrLoad 5880b57cec5SDimitry Andric /// ::= ( .dump | .load ) "filename" 5890b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDumpOrLoad(StringRef Directive, 5900b57cec5SDimitry Andric SMLoc IDLoc) { 5910b57cec5SDimitry Andric bool IsDump = Directive == ".dump"; 5920b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::String)) 5930b57cec5SDimitry Andric return TokError("expected string in '.dump' or '.load' directive"); 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric Lex(); 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 5980b57cec5SDimitry Andric return TokError("unexpected token in '.dump' or '.load' directive"); 5990b57cec5SDimitry Andric 6000b57cec5SDimitry Andric Lex(); 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric // FIXME: If/when .dump and .load are implemented they will be done in the 6030b57cec5SDimitry Andric // the assembly parser and not have any need for an MCStreamer API. 6040b57cec5SDimitry Andric if (IsDump) 6050b57cec5SDimitry Andric return Warning(IDLoc, "ignoring directive .dump for now"); 6060b57cec5SDimitry Andric else 6070b57cec5SDimitry Andric return Warning(IDLoc, "ignoring directive .load for now"); 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric /// ParseDirectiveLinkerOption 6110b57cec5SDimitry Andric /// ::= .linker_option "string" ( , "string" )* 6120b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveLinkerOption(StringRef IDVal, SMLoc) { 6130b57cec5SDimitry Andric SmallVector<std::string, 4> Args; 6140b57cec5SDimitry Andric while (true) { 6150b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::String)) 6160b57cec5SDimitry Andric return TokError("expected string in '" + Twine(IDVal) + "' directive"); 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric std::string Data; 6190b57cec5SDimitry Andric if (getParser().parseEscapedString(Data)) 6200b57cec5SDimitry Andric return true; 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric Args.push_back(Data); 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) 6250b57cec5SDimitry Andric break; 6260b57cec5SDimitry Andric 6270b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 6280b57cec5SDimitry Andric return TokError("unexpected token in '" + Twine(IDVal) + "' directive"); 6290b57cec5SDimitry Andric Lex(); 6300b57cec5SDimitry Andric } 6310b57cec5SDimitry Andric 6325ffd83dbSDimitry Andric getStreamer().emitLinkerOptions(Args); 6330b57cec5SDimitry Andric return false; 6340b57cec5SDimitry Andric } 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric /// parseDirectiveLsym 6370b57cec5SDimitry Andric /// ::= .lsym identifier , expression 6380b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveLsym(StringRef, SMLoc) { 6390b57cec5SDimitry Andric StringRef Name; 6400b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 6410b57cec5SDimitry Andric return TokError("expected identifier in directive"); 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric // Handle the identifier as the key symbol. 6440b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 6470b57cec5SDimitry Andric return TokError("unexpected token in '.lsym' directive"); 6480b57cec5SDimitry Andric Lex(); 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric const MCExpr *Value; 6510b57cec5SDimitry Andric if (getParser().parseExpression(Value)) 6520b57cec5SDimitry Andric return true; 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 6550b57cec5SDimitry Andric return TokError("unexpected token in '.lsym' directive"); 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric Lex(); 6580b57cec5SDimitry Andric 6590b57cec5SDimitry Andric // We don't currently support this directive. 6600b57cec5SDimitry Andric // 6610b57cec5SDimitry Andric // FIXME: Diagnostic location! 6620b57cec5SDimitry Andric (void) Sym; 6630b57cec5SDimitry Andric return TokError("directive '.lsym' is unsupported"); 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric /// parseDirectiveSection: 6670b57cec5SDimitry Andric /// ::= .section identifier (',' identifier)* 6680b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { 6690b57cec5SDimitry Andric SMLoc Loc = getLexer().getLoc(); 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric StringRef SectionName; 6720b57cec5SDimitry Andric if (getParser().parseIdentifier(SectionName)) 6730b57cec5SDimitry Andric return Error(Loc, "expected identifier after '.section' directive"); 6740b57cec5SDimitry Andric 6750b57cec5SDimitry Andric // Verify there is a following comma. 6760b57cec5SDimitry Andric if (!getLexer().is(AsmToken::Comma)) 6770b57cec5SDimitry Andric return TokError("unexpected token in '.section' directive"); 6780b57cec5SDimitry Andric 6795ffd83dbSDimitry Andric std::string SectionSpec = std::string(SectionName); 6800b57cec5SDimitry Andric SectionSpec += ","; 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric // Add all the tokens until the end of the line, ParseSectionSpecifier will 6830b57cec5SDimitry Andric // handle this. 6840b57cec5SDimitry Andric StringRef EOL = getLexer().LexUntilEndOfStatement(); 6850b57cec5SDimitry Andric SectionSpec.append(EOL.begin(), EOL.end()); 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric Lex(); 6880b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 6890b57cec5SDimitry Andric return TokError("unexpected token in '.section' directive"); 6900b57cec5SDimitry Andric Lex(); 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric StringRef Segment, Section; 6930b57cec5SDimitry Andric unsigned StubSize; 6940b57cec5SDimitry Andric unsigned TAA; 6950b57cec5SDimitry Andric bool TAAParsed; 696fe6060f1SDimitry Andric if (class Error E = MCSectionMachO::ParseSectionSpecifier( 697fe6060f1SDimitry Andric SectionSpec, Segment, Section, TAA, TAAParsed, StubSize)) 698fe6060f1SDimitry Andric return Error(Loc, toString(std::move(E))); 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric // Issue a warning if the target is not powerpc and Section is a *coal* section. 701fe6060f1SDimitry Andric Triple TT = getParser().getContext().getTargetTriple(); 7020b57cec5SDimitry Andric Triple::ArchType ArchTy = TT.getArch(); 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric if (ArchTy != Triple::ppc && ArchTy != Triple::ppc64) { 7050b57cec5SDimitry Andric StringRef NonCoalSection = StringSwitch<StringRef>(Section) 7060b57cec5SDimitry Andric .Case("__textcoal_nt", "__text") 7070b57cec5SDimitry Andric .Case("__const_coal", "__const") 7080b57cec5SDimitry Andric .Case("__datacoal_nt", "__data") 7090b57cec5SDimitry Andric .Default(Section); 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric if (!Section.equals(NonCoalSection)) { 7120b57cec5SDimitry Andric StringRef SectionVal(Loc.getPointer()); 7130b57cec5SDimitry Andric size_t B = SectionVal.find(',') + 1, E = SectionVal.find(',', B); 7140b57cec5SDimitry Andric SMLoc BLoc = SMLoc::getFromPointer(SectionVal.data() + B); 7150b57cec5SDimitry Andric SMLoc ELoc = SMLoc::getFromPointer(SectionVal.data() + E); 7160b57cec5SDimitry Andric getParser().Warning(Loc, "section \"" + Section + "\" is deprecated", 7170b57cec5SDimitry Andric SMRange(BLoc, ELoc)); 7180b57cec5SDimitry Andric getParser().Note(Loc, "change section name to \"" + NonCoalSection + 7190b57cec5SDimitry Andric "\"", SMRange(BLoc, ELoc)); 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric } 7220b57cec5SDimitry Andric 7230b57cec5SDimitry Andric // FIXME: Arch specific. 7240b57cec5SDimitry Andric bool isText = Segment == "__TEXT"; // FIXME: Hack. 7250b57cec5SDimitry Andric getStreamer().SwitchSection(getContext().getMachOSection( 7260b57cec5SDimitry Andric Segment, Section, TAA, StubSize, 7270b57cec5SDimitry Andric isText ? SectionKind::getText() : SectionKind::getData())); 7280b57cec5SDimitry Andric return false; 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric /// ParseDirectivePushSection: 7320b57cec5SDimitry Andric /// ::= .pushsection identifier (',' identifier)* 7330b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePushSection(StringRef S, SMLoc Loc) { 7340b57cec5SDimitry Andric getStreamer().PushSection(); 7350b57cec5SDimitry Andric 7360b57cec5SDimitry Andric if (parseDirectiveSection(S, Loc)) { 7370b57cec5SDimitry Andric getStreamer().PopSection(); 7380b57cec5SDimitry Andric return true; 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric return false; 7420b57cec5SDimitry Andric } 7430b57cec5SDimitry Andric 7440b57cec5SDimitry Andric /// ParseDirectivePopSection: 7450b57cec5SDimitry Andric /// ::= .popsection 7460b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePopSection(StringRef, SMLoc) { 7470b57cec5SDimitry Andric if (!getStreamer().PopSection()) 7480b57cec5SDimitry Andric return TokError(".popsection without corresponding .pushsection"); 7490b57cec5SDimitry Andric return false; 7500b57cec5SDimitry Andric } 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric /// ParseDirectivePrevious: 7530b57cec5SDimitry Andric /// ::= .previous 7540b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) { 7550b57cec5SDimitry Andric MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 7560b57cec5SDimitry Andric if (!PreviousSection.first) 7570b57cec5SDimitry Andric return TokError(".previous without corresponding .section"); 7580b57cec5SDimitry Andric getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 7590b57cec5SDimitry Andric return false; 7600b57cec5SDimitry Andric } 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric /// ParseDirectiveSecureLogUnique 7630b57cec5SDimitry Andric /// ::= .secure_log_unique ... message ... 7640b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { 7650b57cec5SDimitry Andric StringRef LogMessage = getParser().parseStringToEndOfStatement(); 7660b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 7670b57cec5SDimitry Andric return TokError("unexpected token in '.secure_log_unique' directive"); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric if (getContext().getSecureLogUsed()) 7700b57cec5SDimitry Andric return Error(IDLoc, ".secure_log_unique specified multiple times"); 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric // Get the secure log path. 7730b57cec5SDimitry Andric const char *SecureLogFile = getContext().getSecureLogFile(); 7740b57cec5SDimitry Andric if (!SecureLogFile) 7750b57cec5SDimitry Andric return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " 7760b57cec5SDimitry Andric "environment variable unset."); 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric // Open the secure log file if we haven't already. 7790b57cec5SDimitry Andric raw_fd_ostream *OS = getContext().getSecureLog(); 7800b57cec5SDimitry Andric if (!OS) { 7810b57cec5SDimitry Andric std::error_code EC; 782fe6060f1SDimitry Andric auto NewOS = std::make_unique<raw_fd_ostream>(StringRef(SecureLogFile), EC, 783fe6060f1SDimitry Andric sys::fs::OF_Append | 784fe6060f1SDimitry Andric sys::fs::OF_TextWithCRLF); 7850b57cec5SDimitry Andric if (EC) 7860b57cec5SDimitry Andric return Error(IDLoc, Twine("can't open secure log file: ") + 7870b57cec5SDimitry Andric SecureLogFile + " (" + EC.message() + ")"); 7880b57cec5SDimitry Andric OS = NewOS.get(); 7890b57cec5SDimitry Andric getContext().setSecureLog(std::move(NewOS)); 7900b57cec5SDimitry Andric } 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric // Write the message. 7930b57cec5SDimitry Andric unsigned CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); 7940b57cec5SDimitry Andric *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() 7950b57cec5SDimitry Andric << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" 7960b57cec5SDimitry Andric << LogMessage + "\n"; 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric getContext().setSecureLogUsed(true); 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andric return false; 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric /// ParseDirectiveSecureLogReset 8040b57cec5SDimitry Andric /// ::= .secure_log_reset 8050b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { 8060b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 8070b57cec5SDimitry Andric return TokError("unexpected token in '.secure_log_reset' directive"); 8080b57cec5SDimitry Andric 8090b57cec5SDimitry Andric Lex(); 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric getContext().setSecureLogUsed(false); 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric return false; 8140b57cec5SDimitry Andric } 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric /// parseDirectiveSubsectionsViaSymbols 8170b57cec5SDimitry Andric /// ::= .subsections_via_symbols 8180b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { 8190b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 8200b57cec5SDimitry Andric return TokError("unexpected token in '.subsections_via_symbols' directive"); 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric Lex(); 8230b57cec5SDimitry Andric 8245ffd83dbSDimitry Andric getStreamer().emitAssemblerFlag(MCAF_SubsectionsViaSymbols); 8250b57cec5SDimitry Andric 8260b57cec5SDimitry Andric return false; 8270b57cec5SDimitry Andric } 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric /// ParseDirectiveTBSS 8300b57cec5SDimitry Andric /// ::= .tbss identifier, size, align 8310b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveTBSS(StringRef, SMLoc) { 8320b57cec5SDimitry Andric SMLoc IDLoc = getLexer().getLoc(); 8330b57cec5SDimitry Andric StringRef Name; 8340b57cec5SDimitry Andric if (getParser().parseIdentifier(Name)) 8350b57cec5SDimitry Andric return TokError("expected identifier in directive"); 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric // Handle the identifier as the key symbol. 8380b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(Name); 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 8410b57cec5SDimitry Andric return TokError("unexpected token in directive"); 8420b57cec5SDimitry Andric Lex(); 8430b57cec5SDimitry Andric 8440b57cec5SDimitry Andric int64_t Size; 8450b57cec5SDimitry Andric SMLoc SizeLoc = getLexer().getLoc(); 8460b57cec5SDimitry Andric if (getParser().parseAbsoluteExpression(Size)) 8470b57cec5SDimitry Andric return true; 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric int64_t Pow2Alignment = 0; 8500b57cec5SDimitry Andric SMLoc Pow2AlignmentLoc; 8510b57cec5SDimitry Andric if (getLexer().is(AsmToken::Comma)) { 8520b57cec5SDimitry Andric Lex(); 8530b57cec5SDimitry Andric Pow2AlignmentLoc = getLexer().getLoc(); 8540b57cec5SDimitry Andric if (getParser().parseAbsoluteExpression(Pow2Alignment)) 8550b57cec5SDimitry Andric return true; 8560b57cec5SDimitry Andric } 8570b57cec5SDimitry Andric 8580b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 8590b57cec5SDimitry Andric return TokError("unexpected token in '.tbss' directive"); 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric Lex(); 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric if (Size < 0) 8640b57cec5SDimitry Andric return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" 8650b57cec5SDimitry Andric "zero"); 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric // FIXME: Diagnose overflow. 8680b57cec5SDimitry Andric if (Pow2Alignment < 0) 8690b57cec5SDimitry Andric return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" 8700b57cec5SDimitry Andric "than zero"); 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric if (!Sym->isUndefined()) 8730b57cec5SDimitry Andric return Error(IDLoc, "invalid symbol redefinition"); 8740b57cec5SDimitry Andric 8755ffd83dbSDimitry Andric getStreamer().emitTBSSSymbol( 8765ffd83dbSDimitry Andric getContext().getMachOSection("__DATA", "__thread_bss", 8775ffd83dbSDimitry Andric MachO::S_THREAD_LOCAL_ZEROFILL, 0, 8785ffd83dbSDimitry Andric SectionKind::getThreadBSS()), 8790b57cec5SDimitry Andric Sym, Size, 1 << Pow2Alignment); 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric return false; 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric /// ParseDirectiveZerofill 8850b57cec5SDimitry Andric /// ::= .zerofill segname , sectname [, identifier , size_expression [ 8860b57cec5SDimitry Andric /// , align_expression ]] 8870b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveZerofill(StringRef, SMLoc) { 8880b57cec5SDimitry Andric StringRef Segment; 8890b57cec5SDimitry Andric if (getParser().parseIdentifier(Segment)) 8900b57cec5SDimitry Andric return TokError("expected segment name after '.zerofill' directive"); 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 8930b57cec5SDimitry Andric return TokError("unexpected token in directive"); 8940b57cec5SDimitry Andric Lex(); 8950b57cec5SDimitry Andric 8960b57cec5SDimitry Andric StringRef Section; 8970b57cec5SDimitry Andric SMLoc SectionLoc = getLexer().getLoc(); 8980b57cec5SDimitry Andric if (getParser().parseIdentifier(Section)) 8990b57cec5SDimitry Andric return TokError("expected section name after comma in '.zerofill' " 9000b57cec5SDimitry Andric "directive"); 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric // If this is the end of the line all that was wanted was to create the 9030b57cec5SDimitry Andric // the section but with no symbol. 9040b57cec5SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) { 9050b57cec5SDimitry Andric // Create the zerofill section but no symbol 9065ffd83dbSDimitry Andric getStreamer().emitZerofill( 9070b57cec5SDimitry Andric getContext().getMachOSection(Segment, Section, MachO::S_ZEROFILL, 0, 9080b57cec5SDimitry Andric SectionKind::getBSS()), 9090b57cec5SDimitry Andric /*Symbol=*/nullptr, /*Size=*/0, /*ByteAlignment=*/0, SectionLoc); 9100b57cec5SDimitry Andric return false; 9110b57cec5SDimitry Andric } 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 9140b57cec5SDimitry Andric return TokError("unexpected token in directive"); 9150b57cec5SDimitry Andric Lex(); 9160b57cec5SDimitry Andric 9170b57cec5SDimitry Andric SMLoc IDLoc = getLexer().getLoc(); 9180b57cec5SDimitry Andric StringRef IDStr; 9190b57cec5SDimitry Andric if (getParser().parseIdentifier(IDStr)) 9200b57cec5SDimitry Andric return TokError("expected identifier in directive"); 9210b57cec5SDimitry Andric 9220b57cec5SDimitry Andric // handle the identifier as the key symbol. 9230b57cec5SDimitry Andric MCSymbol *Sym = getContext().getOrCreateSymbol(IDStr); 9240b57cec5SDimitry Andric 9250b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 9260b57cec5SDimitry Andric return TokError("unexpected token in directive"); 9270b57cec5SDimitry Andric Lex(); 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric int64_t Size; 9300b57cec5SDimitry Andric SMLoc SizeLoc = getLexer().getLoc(); 9310b57cec5SDimitry Andric if (getParser().parseAbsoluteExpression(Size)) 9320b57cec5SDimitry Andric return true; 9330b57cec5SDimitry Andric 9340b57cec5SDimitry Andric int64_t Pow2Alignment = 0; 9350b57cec5SDimitry Andric SMLoc Pow2AlignmentLoc; 9360b57cec5SDimitry Andric if (getLexer().is(AsmToken::Comma)) { 9370b57cec5SDimitry Andric Lex(); 9380b57cec5SDimitry Andric Pow2AlignmentLoc = getLexer().getLoc(); 9390b57cec5SDimitry Andric if (getParser().parseAbsoluteExpression(Pow2Alignment)) 9400b57cec5SDimitry Andric return true; 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric 9430b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 9440b57cec5SDimitry Andric return TokError("unexpected token in '.zerofill' directive"); 9450b57cec5SDimitry Andric 9460b57cec5SDimitry Andric Lex(); 9470b57cec5SDimitry Andric 9480b57cec5SDimitry Andric if (Size < 0) 9490b57cec5SDimitry Andric return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 9500b57cec5SDimitry Andric "than zero"); 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric // NOTE: The alignment in the directive is a power of 2 value, the assembler 9530b57cec5SDimitry Andric // may internally end up wanting an alignment in bytes. 9540b57cec5SDimitry Andric // FIXME: Diagnose overflow. 9550b57cec5SDimitry Andric if (Pow2Alignment < 0) 9560b57cec5SDimitry Andric return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 9570b57cec5SDimitry Andric "can't be less than zero"); 9580b57cec5SDimitry Andric 9590b57cec5SDimitry Andric if (!Sym->isUndefined()) 9600b57cec5SDimitry Andric return Error(IDLoc, "invalid symbol redefinition"); 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andric // Create the zerofill Symbol with Size and Pow2Alignment 9630b57cec5SDimitry Andric // 9640b57cec5SDimitry Andric // FIXME: Arch specific. 9655ffd83dbSDimitry Andric getStreamer().emitZerofill(getContext().getMachOSection( 9660b57cec5SDimitry Andric Segment, Section, MachO::S_ZEROFILL, 9670b57cec5SDimitry Andric 0, SectionKind::getBSS()), 9680b57cec5SDimitry Andric Sym, Size, 1 << Pow2Alignment, SectionLoc); 9690b57cec5SDimitry Andric 9700b57cec5SDimitry Andric return false; 9710b57cec5SDimitry Andric } 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric /// ParseDirectiveDataRegion 9740b57cec5SDimitry Andric /// ::= .data_region [ ( jt8 | jt16 | jt32 ) ] 9750b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegion(StringRef, SMLoc) { 9760b57cec5SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement)) { 9770b57cec5SDimitry Andric Lex(); 9785ffd83dbSDimitry Andric getStreamer().emitDataRegion(MCDR_DataRegion); 9790b57cec5SDimitry Andric return false; 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric StringRef RegionType; 9820b57cec5SDimitry Andric SMLoc Loc = getParser().getTok().getLoc(); 9830b57cec5SDimitry Andric if (getParser().parseIdentifier(RegionType)) 9840b57cec5SDimitry Andric return TokError("expected region type after '.data_region' directive"); 9850b57cec5SDimitry Andric int Kind = StringSwitch<int>(RegionType) 9860b57cec5SDimitry Andric .Case("jt8", MCDR_DataRegionJT8) 9870b57cec5SDimitry Andric .Case("jt16", MCDR_DataRegionJT16) 9880b57cec5SDimitry Andric .Case("jt32", MCDR_DataRegionJT32) 9890b57cec5SDimitry Andric .Default(-1); 9900b57cec5SDimitry Andric if (Kind == -1) 9910b57cec5SDimitry Andric return Error(Loc, "unknown region type in '.data_region' directive"); 9920b57cec5SDimitry Andric Lex(); 9930b57cec5SDimitry Andric 9945ffd83dbSDimitry Andric getStreamer().emitDataRegion((MCDataRegionType)Kind); 9950b57cec5SDimitry Andric return false; 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric /// ParseDirectiveDataRegionEnd 9990b57cec5SDimitry Andric /// ::= .end_data_region 10000b57cec5SDimitry Andric bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) { 10010b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) 10020b57cec5SDimitry Andric return TokError("unexpected token in '.end_data_region' directive"); 10030b57cec5SDimitry Andric 10040b57cec5SDimitry Andric Lex(); 10055ffd83dbSDimitry Andric getStreamer().emitDataRegion(MCDR_DataRegionEnd); 10060b57cec5SDimitry Andric return false; 10070b57cec5SDimitry Andric } 10080b57cec5SDimitry Andric 10090b57cec5SDimitry Andric static bool isSDKVersionToken(const AsmToken &Tok) { 10100b57cec5SDimitry Andric return Tok.is(AsmToken::Identifier) && Tok.getIdentifier() == "sdk_version"; 10110b57cec5SDimitry Andric } 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andric /// parseMajorMinorVersionComponent ::= major, minor 10140b57cec5SDimitry Andric bool DarwinAsmParser::parseMajorMinorVersionComponent(unsigned *Major, 10150b57cec5SDimitry Andric unsigned *Minor, 10160b57cec5SDimitry Andric const char *VersionName) { 10170b57cec5SDimitry Andric // Get the major version number. 10180b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Integer)) 10190b57cec5SDimitry Andric return TokError(Twine("invalid ") + VersionName + 10200b57cec5SDimitry Andric " major version number, integer expected"); 10210b57cec5SDimitry Andric int64_t MajorVal = getLexer().getTok().getIntVal(); 10220b57cec5SDimitry Andric if (MajorVal > 65535 || MajorVal <= 0) 10230b57cec5SDimitry Andric return TokError(Twine("invalid ") + VersionName + " major version number"); 10240b57cec5SDimitry Andric *Major = (unsigned)MajorVal; 10250b57cec5SDimitry Andric Lex(); 10260b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 10270b57cec5SDimitry Andric return TokError(Twine(VersionName) + 10280b57cec5SDimitry Andric " minor version number required, comma expected"); 10290b57cec5SDimitry Andric Lex(); 10300b57cec5SDimitry Andric // Get the minor version number. 10310b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Integer)) 10320b57cec5SDimitry Andric return TokError(Twine("invalid ") + VersionName + 10330b57cec5SDimitry Andric " minor version number, integer expected"); 10340b57cec5SDimitry Andric int64_t MinorVal = getLexer().getTok().getIntVal(); 10350b57cec5SDimitry Andric if (MinorVal > 255 || MinorVal < 0) 10360b57cec5SDimitry Andric return TokError(Twine("invalid ") + VersionName + " minor version number"); 10370b57cec5SDimitry Andric *Minor = MinorVal; 10380b57cec5SDimitry Andric Lex(); 10390b57cec5SDimitry Andric return false; 10400b57cec5SDimitry Andric } 10410b57cec5SDimitry Andric 10420b57cec5SDimitry Andric /// parseOptionalTrailingVersionComponent ::= , version_number 10430b57cec5SDimitry Andric bool DarwinAsmParser::parseOptionalTrailingVersionComponent( 10440b57cec5SDimitry Andric unsigned *Component, const char *ComponentName) { 10450b57cec5SDimitry Andric assert(getLexer().is(AsmToken::Comma) && "comma expected"); 10460b57cec5SDimitry Andric Lex(); 10470b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Integer)) 10480b57cec5SDimitry Andric return TokError(Twine("invalid ") + ComponentName + 10490b57cec5SDimitry Andric " version number, integer expected"); 10500b57cec5SDimitry Andric int64_t Val = getLexer().getTok().getIntVal(); 10510b57cec5SDimitry Andric if (Val > 255 || Val < 0) 10520b57cec5SDimitry Andric return TokError(Twine("invalid ") + ComponentName + " version number"); 10530b57cec5SDimitry Andric *Component = Val; 10540b57cec5SDimitry Andric Lex(); 10550b57cec5SDimitry Andric return false; 10560b57cec5SDimitry Andric } 10570b57cec5SDimitry Andric 10580b57cec5SDimitry Andric /// parseVersion ::= parseMajorMinorVersionComponent 10590b57cec5SDimitry Andric /// parseOptionalTrailingVersionComponent 10600b57cec5SDimitry Andric bool DarwinAsmParser::parseVersion(unsigned *Major, unsigned *Minor, 10610b57cec5SDimitry Andric unsigned *Update) { 10620b57cec5SDimitry Andric if (parseMajorMinorVersionComponent(Major, Minor, "OS")) 10630b57cec5SDimitry Andric return true; 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric // Get the update level, if specified 10660b57cec5SDimitry Andric *Update = 0; 10670b57cec5SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement) || 10680b57cec5SDimitry Andric isSDKVersionToken(getLexer().getTok())) 10690b57cec5SDimitry Andric return false; 10700b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 10710b57cec5SDimitry Andric return TokError("invalid OS update specifier, comma expected"); 10720b57cec5SDimitry Andric if (parseOptionalTrailingVersionComponent(Update, "OS update")) 10730b57cec5SDimitry Andric return true; 10740b57cec5SDimitry Andric return false; 10750b57cec5SDimitry Andric } 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric bool DarwinAsmParser::parseSDKVersion(VersionTuple &SDKVersion) { 10780b57cec5SDimitry Andric assert(isSDKVersionToken(getLexer().getTok()) && "expected sdk_version"); 10790b57cec5SDimitry Andric Lex(); 10800b57cec5SDimitry Andric unsigned Major, Minor; 10810b57cec5SDimitry Andric if (parseMajorMinorVersionComponent(&Major, &Minor, "SDK")) 10820b57cec5SDimitry Andric return true; 10830b57cec5SDimitry Andric SDKVersion = VersionTuple(Major, Minor); 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric // Get the subminor version, if specified. 10860b57cec5SDimitry Andric if (getLexer().is(AsmToken::Comma)) { 10870b57cec5SDimitry Andric unsigned Subminor; 10880b57cec5SDimitry Andric if (parseOptionalTrailingVersionComponent(&Subminor, "SDK subminor")) 10890b57cec5SDimitry Andric return true; 10900b57cec5SDimitry Andric SDKVersion = VersionTuple(Major, Minor, Subminor); 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric return false; 10930b57cec5SDimitry Andric } 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric void DarwinAsmParser::checkVersion(StringRef Directive, StringRef Arg, 10960b57cec5SDimitry Andric SMLoc Loc, Triple::OSType ExpectedOS) { 1097fe6060f1SDimitry Andric const Triple &Target = getContext().getTargetTriple(); 10980b57cec5SDimitry Andric if (Target.getOS() != ExpectedOS) 10990b57cec5SDimitry Andric Warning(Loc, Twine(Directive) + 11000b57cec5SDimitry Andric (Arg.empty() ? Twine() : Twine(' ') + Arg) + 11010b57cec5SDimitry Andric " used while targeting " + Target.getOSName()); 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric if (LastVersionDirective.isValid()) { 11040b57cec5SDimitry Andric Warning(Loc, "overriding previous version directive"); 11050b57cec5SDimitry Andric Note(LastVersionDirective, "previous definition is here"); 11060b57cec5SDimitry Andric } 11070b57cec5SDimitry Andric LastVersionDirective = Loc; 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric static Triple::OSType getOSTypeFromMCVM(MCVersionMinType Type) { 11110b57cec5SDimitry Andric switch (Type) { 11120b57cec5SDimitry Andric case MCVM_WatchOSVersionMin: return Triple::WatchOS; 11130b57cec5SDimitry Andric case MCVM_TvOSVersionMin: return Triple::TvOS; 11140b57cec5SDimitry Andric case MCVM_IOSVersionMin: return Triple::IOS; 11150b57cec5SDimitry Andric case MCVM_OSXVersionMin: return Triple::MacOSX; 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric llvm_unreachable("Invalid mc version min type"); 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric /// parseVersionMin 11210b57cec5SDimitry Andric /// ::= .ios_version_min parseVersion parseSDKVersion 11220b57cec5SDimitry Andric /// | .macosx_version_min parseVersion parseSDKVersion 11230b57cec5SDimitry Andric /// | .tvos_version_min parseVersion parseSDKVersion 11240b57cec5SDimitry Andric /// | .watchos_version_min parseVersion parseSDKVersion 11250b57cec5SDimitry Andric bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc, 11260b57cec5SDimitry Andric MCVersionMinType Type) { 11270b57cec5SDimitry Andric unsigned Major; 11280b57cec5SDimitry Andric unsigned Minor; 11290b57cec5SDimitry Andric unsigned Update; 11300b57cec5SDimitry Andric if (parseVersion(&Major, &Minor, &Update)) 11310b57cec5SDimitry Andric return true; 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric VersionTuple SDKVersion; 11340b57cec5SDimitry Andric if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion)) 11350b57cec5SDimitry Andric return true; 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric if (parseToken(AsmToken::EndOfStatement)) 11380b57cec5SDimitry Andric return addErrorSuffix(Twine(" in '") + Directive + "' directive"); 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric Triple::OSType ExpectedOS = getOSTypeFromMCVM(Type); 11410b57cec5SDimitry Andric checkVersion(Directive, StringRef(), Loc, ExpectedOS); 11425ffd83dbSDimitry Andric getStreamer().emitVersionMin(Type, Major, Minor, Update, SDKVersion); 11430b57cec5SDimitry Andric return false; 11440b57cec5SDimitry Andric } 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric static Triple::OSType getOSTypeFromPlatform(MachO::PlatformType Type) { 11470b57cec5SDimitry Andric switch (Type) { 1148*04eeddc0SDimitry Andric case MachO::PLATFORM_UNKNOWN: /* silence warning */ 1149*04eeddc0SDimitry Andric break; 11500b57cec5SDimitry Andric case MachO::PLATFORM_MACOS: return Triple::MacOSX; 11510b57cec5SDimitry Andric case MachO::PLATFORM_IOS: return Triple::IOS; 11520b57cec5SDimitry Andric case MachO::PLATFORM_TVOS: return Triple::TvOS; 11530b57cec5SDimitry Andric case MachO::PLATFORM_WATCHOS: return Triple::WatchOS; 11540b57cec5SDimitry Andric case MachO::PLATFORM_BRIDGEOS: /* silence warning */ break; 11550b57cec5SDimitry Andric case MachO::PLATFORM_MACCATALYST: return Triple::IOS; 11560b57cec5SDimitry Andric case MachO::PLATFORM_IOSSIMULATOR: /* silence warning */ break; 11570b57cec5SDimitry Andric case MachO::PLATFORM_TVOSSIMULATOR: /* silence warning */ break; 11580b57cec5SDimitry Andric case MachO::PLATFORM_WATCHOSSIMULATOR: /* silence warning */ break; 1159e8d8bef9SDimitry Andric case MachO::PLATFORM_DRIVERKIT: /* silence warning */ break; 11600b57cec5SDimitry Andric } 11610b57cec5SDimitry Andric llvm_unreachable("Invalid mach-o platform type"); 11620b57cec5SDimitry Andric } 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric /// parseBuildVersion 11650b57cec5SDimitry Andric /// ::= .build_version (macos|ios|tvos|watchos), parseVersion parseSDKVersion 11660b57cec5SDimitry Andric bool DarwinAsmParser::parseBuildVersion(StringRef Directive, SMLoc Loc) { 11670b57cec5SDimitry Andric StringRef PlatformName; 11680b57cec5SDimitry Andric SMLoc PlatformLoc = getTok().getLoc(); 11690b57cec5SDimitry Andric if (getParser().parseIdentifier(PlatformName)) 11700b57cec5SDimitry Andric return TokError("platform name expected"); 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric unsigned Platform = StringSwitch<unsigned>(PlatformName) 11730b57cec5SDimitry Andric .Case("macos", MachO::PLATFORM_MACOS) 11740b57cec5SDimitry Andric .Case("ios", MachO::PLATFORM_IOS) 11750b57cec5SDimitry Andric .Case("tvos", MachO::PLATFORM_TVOS) 11760b57cec5SDimitry Andric .Case("watchos", MachO::PLATFORM_WATCHOS) 11770b57cec5SDimitry Andric .Case("macCatalyst", MachO::PLATFORM_MACCATALYST) 11780b57cec5SDimitry Andric .Default(0); 11790b57cec5SDimitry Andric if (Platform == 0) 11800b57cec5SDimitry Andric return Error(PlatformLoc, "unknown platform name"); 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric if (getLexer().isNot(AsmToken::Comma)) 11830b57cec5SDimitry Andric return TokError("version number required, comma expected"); 11840b57cec5SDimitry Andric Lex(); 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric unsigned Major; 11870b57cec5SDimitry Andric unsigned Minor; 11880b57cec5SDimitry Andric unsigned Update; 11890b57cec5SDimitry Andric if (parseVersion(&Major, &Minor, &Update)) 11900b57cec5SDimitry Andric return true; 11910b57cec5SDimitry Andric 11920b57cec5SDimitry Andric VersionTuple SDKVersion; 11930b57cec5SDimitry Andric if (isSDKVersionToken(getLexer().getTok()) && parseSDKVersion(SDKVersion)) 11940b57cec5SDimitry Andric return true; 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric if (parseToken(AsmToken::EndOfStatement)) 11970b57cec5SDimitry Andric return addErrorSuffix(" in '.build_version' directive"); 11980b57cec5SDimitry Andric 11990b57cec5SDimitry Andric Triple::OSType ExpectedOS 12000b57cec5SDimitry Andric = getOSTypeFromPlatform((MachO::PlatformType)Platform); 12010b57cec5SDimitry Andric checkVersion(Directive, PlatformName, Loc, ExpectedOS); 12025ffd83dbSDimitry Andric getStreamer().emitBuildVersion(Platform, Major, Minor, Update, SDKVersion); 12030b57cec5SDimitry Andric return false; 12040b57cec5SDimitry Andric } 12050b57cec5SDimitry Andric 1206*04eeddc0SDimitry Andric /// parseDirectiveCGProfile 1207*04eeddc0SDimitry Andric /// ::= .cg_profile from, to, count 1208*04eeddc0SDimitry Andric bool DarwinAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) { 1209*04eeddc0SDimitry Andric return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc); 1210*04eeddc0SDimitry Andric } 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric namespace llvm { 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric MCAsmParserExtension *createDarwinAsmParser() { 12150b57cec5SDimitry Andric return new DarwinAsmParser; 12160b57cec5SDimitry Andric } 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric } // end llvm namespace 1219