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