1 //===- DarwinAsmParser.cpp - Darwin (Mach-O) Assembly Parser --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 11 #include "llvm/MC/MCContext.h" 12 #include "llvm/MC/MCSectionMachO.h" 13 #include "llvm/MC/MCStreamer.h" 14 #include "llvm/MC/MCSymbol.h" 15 #include "llvm/MC/MCParser/MCAsmLexer.h" 16 #include "llvm/MC/MCParser/MCAsmParser.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/Twine.h" 19 #include "llvm/Support/MemoryBuffer.h" 20 #include "llvm/Support/SourceMgr.h" 21 using namespace llvm; 22 23 namespace { 24 25 /// \brief Implementation of directive handling which is shared across all 26 /// Darwin targets. 27 class DarwinAsmParser : public MCAsmParserExtension { 28 template<bool (DarwinAsmParser::*Handler)(StringRef, SMLoc)> 29 void AddDirectiveHandler(StringRef Directive) { 30 getParser().AddDirectiveHandler(this, Directive, 31 HandleDirective<DarwinAsmParser, Handler>); 32 } 33 34 bool ParseSectionSwitch(const char *Segment, const char *Section, 35 unsigned TAA = 0, unsigned ImplicitAlign = 0, 36 unsigned StubSize = 0); 37 38 public: 39 DarwinAsmParser() {} 40 41 virtual void Initialize(MCAsmParser &Parser) { 42 // Call the base implementation. 43 this->MCAsmParserExtension::Initialize(Parser); 44 45 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc"); 46 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym"); 47 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>( 48 ".subsections_via_symbols"); 49 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump"); 50 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load"); 51 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section"); 52 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>( 53 ".secure_log_unique"); 54 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>( 55 ".secure_log_reset"); 56 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss"); 57 AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill"); 58 59 // Special section directives. 60 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const"); 61 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data"); 62 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(".constructor"); 63 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(".cstring"); 64 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data"); 65 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(".destructor"); 66 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld"); 67 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(".fvmlib_init0"); 68 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(".fvmlib_init1"); 69 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(".lazy_symbol_pointer"); 70 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(".literal16"); 71 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(".literal4"); 72 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(".literal8"); 73 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(".mod_init_func"); 74 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(".mod_term_func"); 75 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(".non_lazy_symbol_pointer"); 76 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(".objc_cat_cls_meth"); 77 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(".objc_cat_inst_meth"); 78 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(".objc_category"); 79 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(".objc_class"); 80 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(".objc_class_names"); 81 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(".objc_class_vars"); 82 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(".objc_cls_meth"); 83 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(".objc_cls_refs"); 84 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(".objc_inst_meth"); 85 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(".objc_instance_vars"); 86 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(".objc_message_refs"); 87 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(".objc_meta_class"); 88 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(".objc_meth_var_names"); 89 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(".objc_meth_var_types"); 90 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(".objc_module_info"); 91 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(".objc_protocol"); 92 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(".objc_selector_strs"); 93 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(".objc_string_object"); 94 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(".objc_symbols"); 95 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(".picsymbol_stub"); 96 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(".static_const"); 97 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(".static_data"); 98 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(".symbol_stub"); 99 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata"); 100 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text"); 101 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(".thread_init_func"); 102 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv"); 103 104 AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident"); 105 } 106 107 bool ParseDirectiveDesc(StringRef, SMLoc); 108 bool ParseDirectiveDumpOrLoad(StringRef, SMLoc); 109 bool ParseDirectiveLsym(StringRef, SMLoc); 110 bool ParseDirectiveSection(StringRef, SMLoc); 111 bool ParseDirectiveSecureLogReset(StringRef, SMLoc); 112 bool ParseDirectiveSecureLogUnique(StringRef, SMLoc); 113 bool ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc); 114 bool ParseDirectiveTBSS(StringRef, SMLoc); 115 bool ParseDirectiveZerofill(StringRef, SMLoc); 116 117 // Named Section Directive 118 bool ParseSectionDirectiveConst(StringRef, SMLoc) { 119 return ParseSectionSwitch("__TEXT", "__const"); 120 } 121 bool ParseSectionDirectiveStaticConst(StringRef, SMLoc) { 122 return ParseSectionSwitch("__TEXT", "__static_const"); 123 } 124 bool ParseSectionDirectiveCString(StringRef, SMLoc) { 125 return ParseSectionSwitch("__TEXT","__cstring", 126 MCSectionMachO::S_CSTRING_LITERALS); 127 } 128 bool ParseSectionDirectiveLiteral4(StringRef, SMLoc) { 129 return ParseSectionSwitch("__TEXT", "__literal4", 130 MCSectionMachO::S_4BYTE_LITERALS, 4); 131 } 132 bool ParseSectionDirectiveLiteral8(StringRef, SMLoc) { 133 return ParseSectionSwitch("__TEXT", "__literal8", 134 MCSectionMachO::S_8BYTE_LITERALS, 8); 135 } 136 bool ParseSectionDirectiveLiteral16(StringRef, SMLoc) { 137 return ParseSectionSwitch("__TEXT","__literal16", 138 MCSectionMachO::S_16BYTE_LITERALS, 16); 139 } 140 bool ParseSectionDirectiveConstructor(StringRef, SMLoc) { 141 return ParseSectionSwitch("__TEXT","__constructor"); 142 } 143 bool ParseSectionDirectiveDestructor(StringRef, SMLoc) { 144 return ParseSectionSwitch("__TEXT","__destructor"); 145 } 146 bool ParseSectionDirectiveFVMLibInit0(StringRef, SMLoc) { 147 return ParseSectionSwitch("__TEXT","__fvmlib_init0"); 148 } 149 bool ParseSectionDirectiveFVMLibInit1(StringRef, SMLoc) { 150 return ParseSectionSwitch("__TEXT","__fvmlib_init1"); 151 } 152 bool ParseSectionDirectiveSymbolStub(StringRef, SMLoc) { 153 return ParseSectionSwitch("__TEXT","__symbol_stub", 154 MCSectionMachO::S_SYMBOL_STUBS | 155 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 156 // FIXME: Different on PPC and ARM. 157 0, 16); 158 } 159 bool ParseSectionDirectivePICSymbolStub(StringRef, SMLoc) { 160 return ParseSectionSwitch("__TEXT","__picsymbol_stub", 161 MCSectionMachO::S_SYMBOL_STUBS | 162 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 0, 26); 163 } 164 bool ParseSectionDirectiveData(StringRef, SMLoc) { 165 return ParseSectionSwitch("__DATA", "__data"); 166 } 167 bool ParseSectionDirectiveStaticData(StringRef, SMLoc) { 168 return ParseSectionSwitch("__DATA", "__static_data"); 169 } 170 bool ParseSectionDirectiveNonLazySymbolPointers(StringRef, SMLoc) { 171 return ParseSectionSwitch("__DATA", "__nl_symbol_ptr", 172 MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS, 4); 173 } 174 bool ParseSectionDirectiveLazySymbolPointers(StringRef, SMLoc) { 175 return ParseSectionSwitch("__DATA", "__la_symbol_ptr", 176 MCSectionMachO::S_LAZY_SYMBOL_POINTERS, 4); 177 } 178 bool ParseSectionDirectiveDyld(StringRef, SMLoc) { 179 return ParseSectionSwitch("__DATA", "__dyld"); 180 } 181 bool ParseSectionDirectiveModInitFunc(StringRef, SMLoc) { 182 return ParseSectionSwitch("__DATA", "__mod_init_func", 183 MCSectionMachO::S_MOD_INIT_FUNC_POINTERS, 4); 184 } 185 bool ParseSectionDirectiveModTermFunc(StringRef, SMLoc) { 186 return ParseSectionSwitch("__DATA", "__mod_term_func", 187 MCSectionMachO::S_MOD_TERM_FUNC_POINTERS, 4); 188 } 189 bool ParseSectionDirectiveConstData(StringRef, SMLoc) { 190 return ParseSectionSwitch("__DATA", "__const"); 191 } 192 bool ParseSectionDirectiveObjCClass(StringRef, SMLoc) { 193 return ParseSectionSwitch("__OBJC", "__class", 194 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 195 } 196 bool ParseSectionDirectiveObjCMetaClass(StringRef, SMLoc) { 197 return ParseSectionSwitch("__OBJC", "__meta_class", 198 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 199 } 200 bool ParseSectionDirectiveObjCCatClsMeth(StringRef, SMLoc) { 201 return ParseSectionSwitch("__OBJC", "__cat_cls_meth", 202 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 203 } 204 bool ParseSectionDirectiveObjCCatInstMeth(StringRef, SMLoc) { 205 return ParseSectionSwitch("__OBJC", "__cat_inst_meth", 206 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 207 } 208 bool ParseSectionDirectiveObjCProtocol(StringRef, SMLoc) { 209 return ParseSectionSwitch("__OBJC", "__protocol", 210 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 211 } 212 bool ParseSectionDirectiveObjCStringObject(StringRef, SMLoc) { 213 return ParseSectionSwitch("__OBJC", "__string_object", 214 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 215 } 216 bool ParseSectionDirectiveObjCClsMeth(StringRef, SMLoc) { 217 return ParseSectionSwitch("__OBJC", "__cls_meth", 218 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 219 } 220 bool ParseSectionDirectiveObjCInstMeth(StringRef, SMLoc) { 221 return ParseSectionSwitch("__OBJC", "__inst_meth", 222 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 223 } 224 bool ParseSectionDirectiveObjCClsRefs(StringRef, SMLoc) { 225 return ParseSectionSwitch("__OBJC", "__cls_refs", 226 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 227 MCSectionMachO::S_LITERAL_POINTERS, 4); 228 } 229 bool ParseSectionDirectiveObjCMessageRefs(StringRef, SMLoc) { 230 return ParseSectionSwitch("__OBJC", "__message_refs", 231 MCSectionMachO::S_ATTR_NO_DEAD_STRIP | 232 MCSectionMachO::S_LITERAL_POINTERS, 4); 233 } 234 bool ParseSectionDirectiveObjCSymbols(StringRef, SMLoc) { 235 return ParseSectionSwitch("__OBJC", "__symbols", 236 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 237 } 238 bool ParseSectionDirectiveObjCCategory(StringRef, SMLoc) { 239 return ParseSectionSwitch("__OBJC", "__category", 240 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 241 } 242 bool ParseSectionDirectiveObjCClassVars(StringRef, SMLoc) { 243 return ParseSectionSwitch("__OBJC", "__class_vars", 244 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 245 } 246 bool ParseSectionDirectiveObjCInstanceVars(StringRef, SMLoc) { 247 return ParseSectionSwitch("__OBJC", "__instance_vars", 248 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 249 } 250 bool ParseSectionDirectiveObjCModuleInfo(StringRef, SMLoc) { 251 return ParseSectionSwitch("__OBJC", "__module_info", 252 MCSectionMachO::S_ATTR_NO_DEAD_STRIP); 253 } 254 bool ParseSectionDirectiveObjCClassNames(StringRef, SMLoc) { 255 return ParseSectionSwitch("__TEXT", "__cstring", 256 MCSectionMachO::S_CSTRING_LITERALS); 257 } 258 bool ParseSectionDirectiveObjCMethVarTypes(StringRef, SMLoc) { 259 return ParseSectionSwitch("__TEXT", "__cstring", 260 MCSectionMachO::S_CSTRING_LITERALS); 261 } 262 bool ParseSectionDirectiveObjCMethVarNames(StringRef, SMLoc) { 263 return ParseSectionSwitch("__TEXT", "__cstring", 264 MCSectionMachO::S_CSTRING_LITERALS); 265 } 266 bool ParseSectionDirectiveObjCSelectorStrs(StringRef, SMLoc) { 267 return ParseSectionSwitch("__OBJC", "__selector_strs", 268 MCSectionMachO::S_CSTRING_LITERALS); 269 } 270 bool ParseSectionDirectiveTData(StringRef, SMLoc) { 271 return ParseSectionSwitch("__DATA", "__thread_data", 272 MCSectionMachO::S_THREAD_LOCAL_REGULAR); 273 } 274 bool ParseSectionDirectiveText(StringRef, SMLoc) { 275 return ParseSectionSwitch("__TEXT", "__text", 276 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); 277 } 278 bool ParseSectionDirectiveTLV(StringRef, SMLoc) { 279 return ParseSectionSwitch("__DATA", "__thread_vars", 280 MCSectionMachO::S_THREAD_LOCAL_VARIABLES); 281 } 282 bool ParseSectionDirectiveIdent(StringRef, SMLoc) { 283 // Darwin silently ignores the .ident directive. 284 getParser().EatToEndOfStatement(); 285 return false; 286 } 287 bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) { 288 return ParseSectionSwitch("__DATA", "__thread_init", 289 MCSectionMachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS); 290 } 291 292 }; 293 294 } 295 296 bool DarwinAsmParser::ParseSectionSwitch(const char *Segment, 297 const char *Section, 298 unsigned TAA, unsigned Align, 299 unsigned StubSize) { 300 if (getLexer().isNot(AsmToken::EndOfStatement)) 301 return TokError("unexpected token in section switching directive"); 302 Lex(); 303 304 // FIXME: Arch specific. 305 bool isText = StringRef(Segment) == "__TEXT"; // FIXME: Hack. 306 getStreamer().SwitchSection(getContext().getMachOSection( 307 Segment, Section, TAA, StubSize, 308 isText ? SectionKind::getText() 309 : SectionKind::getDataRel())); 310 311 // Set the implicit alignment, if any. 312 // 313 // FIXME: This isn't really what 'as' does; I think it just uses the implicit 314 // alignment on the section (e.g., if one manually inserts bytes into the 315 // section, then just issuing the section switch directive will not realign 316 // the section. However, this is arguably more reasonable behavior, and there 317 // is no good reason for someone to intentionally emit incorrectly sized 318 // values into the implicitly aligned sections. 319 if (Align) 320 getStreamer().EmitValueToAlignment(Align, 0, 1, 0); 321 322 return false; 323 } 324 325 /// ParseDirectiveDesc 326 /// ::= .desc identifier , expression 327 bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) { 328 StringRef Name; 329 if (getParser().ParseIdentifier(Name)) 330 return TokError("expected identifier in directive"); 331 332 // Handle the identifier as the key symbol. 333 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 334 335 if (getLexer().isNot(AsmToken::Comma)) 336 return TokError("unexpected token in '.desc' directive"); 337 Lex(); 338 339 int64_t DescValue; 340 if (getParser().ParseAbsoluteExpression(DescValue)) 341 return true; 342 343 if (getLexer().isNot(AsmToken::EndOfStatement)) 344 return TokError("unexpected token in '.desc' directive"); 345 346 Lex(); 347 348 // Set the n_desc field of this Symbol to this DescValue 349 getStreamer().EmitSymbolDesc(Sym, DescValue); 350 351 return false; 352 } 353 354 /// ParseDirectiveDumpOrLoad 355 /// ::= ( .dump | .load ) "filename" 356 bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive, 357 SMLoc IDLoc) { 358 bool IsDump = Directive == ".dump"; 359 if (getLexer().isNot(AsmToken::String)) 360 return TokError("expected string in '.dump' or '.load' directive"); 361 362 Lex(); 363 364 if (getLexer().isNot(AsmToken::EndOfStatement)) 365 return TokError("unexpected token in '.dump' or '.load' directive"); 366 367 Lex(); 368 369 // FIXME: If/when .dump and .load are implemented they will be done in the 370 // the assembly parser and not have any need for an MCStreamer API. 371 if (IsDump) 372 return Warning(IDLoc, "ignoring directive .dump for now"); 373 else 374 return Warning(IDLoc, "ignoring directive .load for now"); 375 } 376 377 /// ParseDirectiveLsym 378 /// ::= .lsym identifier , expression 379 bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) { 380 StringRef Name; 381 if (getParser().ParseIdentifier(Name)) 382 return TokError("expected identifier in directive"); 383 384 // Handle the identifier as the key symbol. 385 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 386 387 if (getLexer().isNot(AsmToken::Comma)) 388 return TokError("unexpected token in '.lsym' directive"); 389 Lex(); 390 391 const MCExpr *Value; 392 if (getParser().ParseExpression(Value)) 393 return true; 394 395 if (getLexer().isNot(AsmToken::EndOfStatement)) 396 return TokError("unexpected token in '.lsym' directive"); 397 398 Lex(); 399 400 // We don't currently support this directive. 401 // 402 // FIXME: Diagnostic location! 403 (void) Sym; 404 return TokError("directive '.lsym' is unsupported"); 405 } 406 407 /// ParseDirectiveSection: 408 /// ::= .section identifier (',' identifier)* 409 bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) { 410 SMLoc Loc = getLexer().getLoc(); 411 412 StringRef SectionName; 413 if (getParser().ParseIdentifier(SectionName)) 414 return Error(Loc, "expected identifier after '.section' directive"); 415 416 // Verify there is a following comma. 417 if (!getLexer().is(AsmToken::Comma)) 418 return TokError("unexpected token in '.section' directive"); 419 420 std::string SectionSpec = SectionName; 421 SectionSpec += ","; 422 423 // Add all the tokens until the end of the line, ParseSectionSpecifier will 424 // handle this. 425 StringRef EOL = getLexer().LexUntilEndOfStatement(); 426 SectionSpec.append(EOL.begin(), EOL.end()); 427 428 Lex(); 429 if (getLexer().isNot(AsmToken::EndOfStatement)) 430 return TokError("unexpected token in '.section' directive"); 431 Lex(); 432 433 434 StringRef Segment, Section; 435 unsigned StubSize; 436 unsigned TAA; 437 bool TAAParsed; 438 std::string ErrorStr = 439 MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, 440 TAA, TAAParsed, StubSize); 441 442 if (!ErrorStr.empty()) 443 return Error(Loc, ErrorStr.c_str()); 444 445 // FIXME: Arch specific. 446 bool isText = Segment == "__TEXT"; // FIXME: Hack. 447 getStreamer().SwitchSection(getContext().getMachOSection( 448 Segment, Section, TAA, StubSize, 449 isText ? SectionKind::getText() 450 : SectionKind::getDataRel())); 451 return false; 452 } 453 454 /// ParseDirectiveSecureLogUnique 455 /// ::= .secure_log_unique ... message ... 456 bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) { 457 StringRef LogMessage = getParser().ParseStringToEndOfStatement(); 458 if (getLexer().isNot(AsmToken::EndOfStatement)) 459 return TokError("unexpected token in '.secure_log_unique' directive"); 460 461 if (getContext().getSecureLogUsed() != false) 462 return Error(IDLoc, ".secure_log_unique specified multiple times"); 463 464 // Get the secure log path. 465 const char *SecureLogFile = getContext().getSecureLogFile(); 466 if (SecureLogFile == NULL) 467 return Error(IDLoc, ".secure_log_unique used but AS_SECURE_LOG_FILE " 468 "environment variable unset."); 469 470 // Open the secure log file if we haven't already. 471 raw_ostream *OS = getContext().getSecureLog(); 472 if (OS == NULL) { 473 std::string Err; 474 OS = new raw_fd_ostream(SecureLogFile, Err, raw_fd_ostream::F_Append); 475 if (!Err.empty()) { 476 delete OS; 477 return Error(IDLoc, Twine("can't open secure log file: ") + 478 SecureLogFile + " (" + Err + ")"); 479 } 480 getContext().setSecureLog(OS); 481 } 482 483 // Write the message. 484 int CurBuf = getSourceManager().FindBufferContainingLoc(IDLoc); 485 *OS << getSourceManager().getBufferInfo(CurBuf).Buffer->getBufferIdentifier() 486 << ":" << getSourceManager().FindLineNumber(IDLoc, CurBuf) << ":" 487 << LogMessage + "\n"; 488 489 getContext().setSecureLogUsed(true); 490 491 return false; 492 } 493 494 /// ParseDirectiveSecureLogReset 495 /// ::= .secure_log_reset 496 bool DarwinAsmParser::ParseDirectiveSecureLogReset(StringRef, SMLoc IDLoc) { 497 if (getLexer().isNot(AsmToken::EndOfStatement)) 498 return TokError("unexpected token in '.secure_log_reset' directive"); 499 500 Lex(); 501 502 getContext().setSecureLogUsed(false); 503 504 return false; 505 } 506 507 /// ParseDirectiveSubsectionsViaSymbols 508 /// ::= .subsections_via_symbols 509 bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) { 510 if (getLexer().isNot(AsmToken::EndOfStatement)) 511 return TokError("unexpected token in '.subsections_via_symbols' directive"); 512 513 Lex(); 514 515 getStreamer().EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 516 517 return false; 518 } 519 520 /// ParseDirectiveTBSS 521 /// ::= .tbss identifier, size, align 522 bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) { 523 SMLoc IDLoc = getLexer().getLoc(); 524 StringRef Name; 525 if (getParser().ParseIdentifier(Name)) 526 return TokError("expected identifier in directive"); 527 528 // Handle the identifier as the key symbol. 529 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 530 531 if (getLexer().isNot(AsmToken::Comma)) 532 return TokError("unexpected token in directive"); 533 Lex(); 534 535 int64_t Size; 536 SMLoc SizeLoc = getLexer().getLoc(); 537 if (getParser().ParseAbsoluteExpression(Size)) 538 return true; 539 540 int64_t Pow2Alignment = 0; 541 SMLoc Pow2AlignmentLoc; 542 if (getLexer().is(AsmToken::Comma)) { 543 Lex(); 544 Pow2AlignmentLoc = getLexer().getLoc(); 545 if (getParser().ParseAbsoluteExpression(Pow2Alignment)) 546 return true; 547 } 548 549 if (getLexer().isNot(AsmToken::EndOfStatement)) 550 return TokError("unexpected token in '.tbss' directive"); 551 552 Lex(); 553 554 if (Size < 0) 555 return Error(SizeLoc, "invalid '.tbss' directive size, can't be less than" 556 "zero"); 557 558 // FIXME: Diagnose overflow. 559 if (Pow2Alignment < 0) 560 return Error(Pow2AlignmentLoc, "invalid '.tbss' alignment, can't be less" 561 "than zero"); 562 563 if (!Sym->isUndefined()) 564 return Error(IDLoc, "invalid symbol redefinition"); 565 566 getStreamer().EmitTBSSSymbol(getContext().getMachOSection( 567 "__DATA", "__thread_bss", 568 MCSectionMachO::S_THREAD_LOCAL_ZEROFILL, 569 0, SectionKind::getThreadBSS()), 570 Sym, Size, 1 << Pow2Alignment); 571 572 return false; 573 } 574 575 /// ParseDirectiveZerofill 576 /// ::= .zerofill segname , sectname [, identifier , size_expression [ 577 /// , align_expression ]] 578 bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) { 579 StringRef Segment; 580 if (getParser().ParseIdentifier(Segment)) 581 return TokError("expected segment name after '.zerofill' directive"); 582 583 if (getLexer().isNot(AsmToken::Comma)) 584 return TokError("unexpected token in directive"); 585 Lex(); 586 587 StringRef Section; 588 if (getParser().ParseIdentifier(Section)) 589 return TokError("expected section name after comma in '.zerofill' " 590 "directive"); 591 592 // If this is the end of the line all that was wanted was to create the 593 // the section but with no symbol. 594 if (getLexer().is(AsmToken::EndOfStatement)) { 595 // Create the zerofill section but no symbol 596 getStreamer().EmitZerofill(getContext().getMachOSection( 597 Segment, Section, MCSectionMachO::S_ZEROFILL, 598 0, SectionKind::getBSS())); 599 return false; 600 } 601 602 if (getLexer().isNot(AsmToken::Comma)) 603 return TokError("unexpected token in directive"); 604 Lex(); 605 606 SMLoc IDLoc = getLexer().getLoc(); 607 StringRef IDStr; 608 if (getParser().ParseIdentifier(IDStr)) 609 return TokError("expected identifier in directive"); 610 611 // handle the identifier as the key symbol. 612 MCSymbol *Sym = getContext().GetOrCreateSymbol(IDStr); 613 614 if (getLexer().isNot(AsmToken::Comma)) 615 return TokError("unexpected token in directive"); 616 Lex(); 617 618 int64_t Size; 619 SMLoc SizeLoc = getLexer().getLoc(); 620 if (getParser().ParseAbsoluteExpression(Size)) 621 return true; 622 623 int64_t Pow2Alignment = 0; 624 SMLoc Pow2AlignmentLoc; 625 if (getLexer().is(AsmToken::Comma)) { 626 Lex(); 627 Pow2AlignmentLoc = getLexer().getLoc(); 628 if (getParser().ParseAbsoluteExpression(Pow2Alignment)) 629 return true; 630 } 631 632 if (getLexer().isNot(AsmToken::EndOfStatement)) 633 return TokError("unexpected token in '.zerofill' directive"); 634 635 Lex(); 636 637 if (Size < 0) 638 return Error(SizeLoc, "invalid '.zerofill' directive size, can't be less " 639 "than zero"); 640 641 // NOTE: The alignment in the directive is a power of 2 value, the assembler 642 // may internally end up wanting an alignment in bytes. 643 // FIXME: Diagnose overflow. 644 if (Pow2Alignment < 0) 645 return Error(Pow2AlignmentLoc, "invalid '.zerofill' directive alignment, " 646 "can't be less than zero"); 647 648 if (!Sym->isUndefined()) 649 return Error(IDLoc, "invalid symbol redefinition"); 650 651 // Create the zerofill Symbol with Size and Pow2Alignment 652 // 653 // FIXME: Arch specific. 654 getStreamer().EmitZerofill(getContext().getMachOSection( 655 Segment, Section, MCSectionMachO::S_ZEROFILL, 656 0, SectionKind::getBSS()), 657 Sym, Size, 1 << Pow2Alignment); 658 659 return false; 660 } 661 662 namespace llvm { 663 664 MCAsmParserExtension *createDarwinAsmParser() { 665 return new DarwinAsmParser; 666 } 667 668 } 669