1 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===// 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 // This file contains a printer that converts from our internal representation 11 // of machine-dependent LLVM code to X86 machine code. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "X86AsmPrinter.h" 16 #include "InstPrinter/X86ATTInstPrinter.h" 17 #include "MCTargetDesc/X86BaseInfo.h" 18 #include "X86InstrInfo.h" 19 #include "X86MachineFunctionInfo.h" 20 #include "llvm/CodeGen/MachineConstantPool.h" 21 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 22 #include "llvm/CodeGen/MachineValueType.h" 23 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 24 #include "llvm/IR/DebugInfo.h" 25 #include "llvm/IR/DerivedTypes.h" 26 #include "llvm/IR/Mangler.h" 27 #include "llvm/IR/Module.h" 28 #include "llvm/IR/Type.h" 29 #include "llvm/MC/MCAsmInfo.h" 30 #include "llvm/MC/MCCodeEmitter.h" 31 #include "llvm/MC/MCContext.h" 32 #include "llvm/MC/MCExpr.h" 33 #include "llvm/MC/MCSectionCOFF.h" 34 #include "llvm/MC/MCSectionMachO.h" 35 #include "llvm/MC/MCStreamer.h" 36 #include "llvm/MC/MCSymbol.h" 37 #include "llvm/Support/COFF.h" 38 #include "llvm/Support/Debug.h" 39 #include "llvm/Support/ErrorHandling.h" 40 #include "llvm/Support/TargetRegistry.h" 41 using namespace llvm; 42 43 //===----------------------------------------------------------------------===// 44 // Primitive Helper Functions. 45 //===----------------------------------------------------------------------===// 46 47 /// runOnMachineFunction - Emit the function body. 48 /// 49 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 50 Subtarget = &MF.getSubtarget<X86Subtarget>(); 51 52 SMShadowTracker.startFunction(MF); 53 CodeEmitter.reset(TM.getTarget().createMCCodeEmitter( 54 *MF.getSubtarget().getInstrInfo(), *MF.getSubtarget().getRegisterInfo(), 55 MF.getContext())); 56 57 SetupMachineFunction(MF); 58 59 if (Subtarget->isTargetCOFF()) { 60 bool Intrn = MF.getFunction()->hasInternalLinkage(); 61 OutStreamer->BeginCOFFSymbolDef(CurrentFnSym); 62 OutStreamer->EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC 63 : COFF::IMAGE_SYM_CLASS_EXTERNAL); 64 OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 65 << COFF::SCT_COMPLEX_TYPE_SHIFT); 66 OutStreamer->EndCOFFSymbolDef(); 67 } 68 69 // Emit the rest of the function body. 70 EmitFunctionBody(); 71 72 // We didn't modify anything. 73 return false; 74 } 75 76 /// printSymbolOperand - Print a raw symbol reference operand. This handles 77 /// jump tables, constant pools, global address and external symbols, all of 78 /// which print to a label with various suffixes for relocation types etc. 79 static void printSymbolOperand(X86AsmPrinter &P, const MachineOperand &MO, 80 raw_ostream &O) { 81 switch (MO.getType()) { 82 default: llvm_unreachable("unknown symbol type!"); 83 case MachineOperand::MO_ConstantPoolIndex: 84 P.GetCPISymbol(MO.getIndex())->print(O, P.MAI); 85 P.printOffset(MO.getOffset(), O); 86 break; 87 case MachineOperand::MO_GlobalAddress: { 88 const GlobalValue *GV = MO.getGlobal(); 89 90 MCSymbol *GVSym; 91 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 92 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) 93 GVSym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 94 else 95 GVSym = P.getSymbol(GV); 96 97 // Handle dllimport linkage. 98 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) 99 GVSym = 100 P.OutContext.getOrCreateSymbol(Twine("__imp_") + GVSym->getName()); 101 102 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 103 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { 104 MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 105 MachineModuleInfoImpl::StubValueTy &StubSym = 106 P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym); 107 if (!StubSym.getPointer()) 108 StubSym = MachineModuleInfoImpl:: 109 StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage()); 110 } 111 112 // If the name begins with a dollar-sign, enclose it in parens. We do this 113 // to avoid having it look like an integer immediate to the assembler. 114 if (GVSym->getName()[0] != '$') 115 GVSym->print(O, P.MAI); 116 else { 117 O << '('; 118 GVSym->print(O, P.MAI); 119 O << ')'; 120 } 121 P.printOffset(MO.getOffset(), O); 122 break; 123 } 124 } 125 126 switch (MO.getTargetFlags()) { 127 default: 128 llvm_unreachable("Unknown target flag on GV operand"); 129 case X86II::MO_NO_FLAG: // No flag. 130 break; 131 case X86II::MO_DARWIN_NONLAZY: 132 case X86II::MO_DLLIMPORT: 133 // These affect the name of the symbol, not any suffix. 134 break; 135 case X86II::MO_GOT_ABSOLUTE_ADDRESS: 136 O << " + [.-"; 137 P.MF->getPICBaseSymbol()->print(O, P.MAI); 138 O << ']'; 139 break; 140 case X86II::MO_PIC_BASE_OFFSET: 141 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 142 O << '-'; 143 P.MF->getPICBaseSymbol()->print(O, P.MAI); 144 break; 145 case X86II::MO_TLSGD: O << "@TLSGD"; break; 146 case X86II::MO_TLSLD: O << "@TLSLD"; break; 147 case X86II::MO_TLSLDM: O << "@TLSLDM"; break; 148 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; 149 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; 150 case X86II::MO_TPOFF: O << "@TPOFF"; break; 151 case X86II::MO_DTPOFF: O << "@DTPOFF"; break; 152 case X86II::MO_NTPOFF: O << "@NTPOFF"; break; 153 case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break; 154 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; 155 case X86II::MO_GOT: O << "@GOT"; break; 156 case X86II::MO_GOTOFF: O << "@GOTOFF"; break; 157 case X86II::MO_PLT: O << "@PLT"; break; 158 case X86II::MO_TLVP: O << "@TLVP"; break; 159 case X86II::MO_TLVP_PIC_BASE: 160 O << "@TLVP" << '-'; 161 P.MF->getPICBaseSymbol()->print(O, P.MAI); 162 break; 163 case X86II::MO_SECREL: O << "@SECREL32"; break; 164 } 165 } 166 167 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI, 168 unsigned OpNo, raw_ostream &O, 169 const char *Modifier = nullptr, unsigned AsmVariant = 0); 170 171 /// printPCRelImm - This is used to print an immediate value that ends up 172 /// being encoded as a pc-relative value. These print slightly differently, for 173 /// example, a $ is not emitted. 174 static void printPCRelImm(X86AsmPrinter &P, const MachineInstr *MI, 175 unsigned OpNo, raw_ostream &O) { 176 const MachineOperand &MO = MI->getOperand(OpNo); 177 switch (MO.getType()) { 178 default: llvm_unreachable("Unknown pcrel immediate operand"); 179 case MachineOperand::MO_Register: 180 // pc-relativeness was handled when computing the value in the reg. 181 printOperand(P, MI, OpNo, O); 182 return; 183 case MachineOperand::MO_Immediate: 184 O << MO.getImm(); 185 return; 186 case MachineOperand::MO_GlobalAddress: 187 printSymbolOperand(P, MO, O); 188 return; 189 } 190 } 191 192 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI, 193 unsigned OpNo, raw_ostream &O, const char *Modifier, 194 unsigned AsmVariant) { 195 const MachineOperand &MO = MI->getOperand(OpNo); 196 switch (MO.getType()) { 197 default: llvm_unreachable("unknown operand type!"); 198 case MachineOperand::MO_Register: { 199 // FIXME: Enumerating AsmVariant, so we can remove magic number. 200 if (AsmVariant == 0) O << '%'; 201 unsigned Reg = MO.getReg(); 202 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 203 unsigned Size = (strcmp(Modifier+6,"64") == 0) ? 64 : 204 (strcmp(Modifier+6,"32") == 0) ? 32 : 205 (strcmp(Modifier+6,"16") == 0) ? 16 : 8; 206 Reg = getX86SubSuperRegister(Reg, Size); 207 } 208 O << X86ATTInstPrinter::getRegisterName(Reg); 209 return; 210 } 211 212 case MachineOperand::MO_Immediate: 213 if (AsmVariant == 0) O << '$'; 214 O << MO.getImm(); 215 return; 216 217 case MachineOperand::MO_GlobalAddress: { 218 if (AsmVariant == 0) O << '$'; 219 printSymbolOperand(P, MO, O); 220 break; 221 } 222 } 223 } 224 225 static void printLeaMemReference(X86AsmPrinter &P, const MachineInstr *MI, 226 unsigned Op, raw_ostream &O, 227 const char *Modifier = nullptr) { 228 const MachineOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); 229 const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); 230 const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); 231 232 // If we really don't want to print out (rip), don't. 233 bool HasBaseReg = BaseReg.getReg() != 0; 234 if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") && 235 BaseReg.getReg() == X86::RIP) 236 HasBaseReg = false; 237 238 // HasParenPart - True if we will print out the () part of the mem ref. 239 bool HasParenPart = IndexReg.getReg() || HasBaseReg; 240 241 switch (DispSpec.getType()) { 242 default: 243 llvm_unreachable("unknown operand type!"); 244 case MachineOperand::MO_Immediate: { 245 int DispVal = DispSpec.getImm(); 246 if (DispVal || !HasParenPart) 247 O << DispVal; 248 break; 249 } 250 case MachineOperand::MO_GlobalAddress: 251 case MachineOperand::MO_ConstantPoolIndex: 252 printSymbolOperand(P, DispSpec, O); 253 } 254 255 if (Modifier && strcmp(Modifier, "H") == 0) 256 O << "+8"; 257 258 if (HasParenPart) { 259 assert(IndexReg.getReg() != X86::ESP && 260 "X86 doesn't allow scaling by ESP"); 261 262 O << '('; 263 if (HasBaseReg) 264 printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier); 265 266 if (IndexReg.getReg()) { 267 O << ','; 268 printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier); 269 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); 270 if (ScaleVal != 1) 271 O << ',' << ScaleVal; 272 } 273 O << ')'; 274 } 275 } 276 277 static void printMemReference(X86AsmPrinter &P, const MachineInstr *MI, 278 unsigned Op, raw_ostream &O, 279 const char *Modifier = nullptr) { 280 assert(isMem(MI, Op) && "Invalid memory reference!"); 281 const MachineOperand &Segment = MI->getOperand(Op+X86::AddrSegmentReg); 282 if (Segment.getReg()) { 283 printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier); 284 O << ':'; 285 } 286 printLeaMemReference(P, MI, Op, O, Modifier); 287 } 288 289 static void printIntelMemReference(X86AsmPrinter &P, const MachineInstr *MI, 290 unsigned Op, raw_ostream &O, 291 const char *Modifier = nullptr, 292 unsigned AsmVariant = 1) { 293 const MachineOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); 294 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); 295 const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); 296 const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); 297 const MachineOperand &SegReg = MI->getOperand(Op+X86::AddrSegmentReg); 298 299 // If this has a segment register, print it. 300 if (SegReg.getReg()) { 301 printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier, AsmVariant); 302 O << ':'; 303 } 304 305 O << '['; 306 307 bool NeedPlus = false; 308 if (BaseReg.getReg()) { 309 printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier, AsmVariant); 310 NeedPlus = true; 311 } 312 313 if (IndexReg.getReg()) { 314 if (NeedPlus) O << " + "; 315 if (ScaleVal != 1) 316 O << ScaleVal << '*'; 317 printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier, AsmVariant); 318 NeedPlus = true; 319 } 320 321 if (!DispSpec.isImm()) { 322 if (NeedPlus) O << " + "; 323 printOperand(P, MI, Op+X86::AddrDisp, O, Modifier, AsmVariant); 324 } else { 325 int64_t DispVal = DispSpec.getImm(); 326 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { 327 if (NeedPlus) { 328 if (DispVal > 0) 329 O << " + "; 330 else { 331 O << " - "; 332 DispVal = -DispVal; 333 } 334 } 335 O << DispVal; 336 } 337 } 338 O << ']'; 339 } 340 341 static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO, 342 char Mode, raw_ostream &O) { 343 unsigned Reg = MO.getReg(); 344 switch (Mode) { 345 default: return true; // Unknown mode. 346 case 'b': // Print QImode register 347 Reg = getX86SubSuperRegister(Reg, 8); 348 break; 349 case 'h': // Print QImode high register 350 Reg = getX86SubSuperRegister(Reg, 8, true); 351 break; 352 case 'w': // Print HImode register 353 Reg = getX86SubSuperRegister(Reg, 16); 354 break; 355 case 'k': // Print SImode register 356 Reg = getX86SubSuperRegister(Reg, 32); 357 break; 358 case 'q': 359 // Print 64-bit register names if 64-bit integer registers are available. 360 // Otherwise, print 32-bit register names. 361 Reg = getX86SubSuperRegister(Reg, P.getSubtarget().is64Bit() ? 64 : 32); 362 break; 363 } 364 365 O << '%' << X86ATTInstPrinter::getRegisterName(Reg); 366 return false; 367 } 368 369 /// PrintAsmOperand - Print out an operand for an inline asm expression. 370 /// 371 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 372 unsigned AsmVariant, 373 const char *ExtraCode, raw_ostream &O) { 374 // Does this asm operand have a single letter operand modifier? 375 if (ExtraCode && ExtraCode[0]) { 376 if (ExtraCode[1] != 0) return true; // Unknown modifier. 377 378 const MachineOperand &MO = MI->getOperand(OpNo); 379 380 switch (ExtraCode[0]) { 381 default: 382 // See if this is a generic print operand 383 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 384 case 'a': // This is an address. Currently only 'i' and 'r' are expected. 385 switch (MO.getType()) { 386 default: 387 return true; 388 case MachineOperand::MO_Immediate: 389 O << MO.getImm(); 390 return false; 391 case MachineOperand::MO_ConstantPoolIndex: 392 case MachineOperand::MO_JumpTableIndex: 393 case MachineOperand::MO_ExternalSymbol: 394 llvm_unreachable("unexpected operand type!"); 395 case MachineOperand::MO_GlobalAddress: 396 printSymbolOperand(*this, MO, O); 397 if (Subtarget->isPICStyleRIPRel()) 398 O << "(%rip)"; 399 return false; 400 case MachineOperand::MO_Register: 401 O << '('; 402 printOperand(*this, MI, OpNo, O); 403 O << ')'; 404 return false; 405 } 406 407 case 'c': // Don't print "$" before a global var name or constant. 408 switch (MO.getType()) { 409 default: 410 printOperand(*this, MI, OpNo, O); 411 break; 412 case MachineOperand::MO_Immediate: 413 O << MO.getImm(); 414 break; 415 case MachineOperand::MO_ConstantPoolIndex: 416 case MachineOperand::MO_JumpTableIndex: 417 case MachineOperand::MO_ExternalSymbol: 418 llvm_unreachable("unexpected operand type!"); 419 case MachineOperand::MO_GlobalAddress: 420 printSymbolOperand(*this, MO, O); 421 break; 422 } 423 return false; 424 425 case 'A': // Print '*' before a register (it must be a register) 426 if (MO.isReg()) { 427 O << '*'; 428 printOperand(*this, MI, OpNo, O); 429 return false; 430 } 431 return true; 432 433 case 'b': // Print QImode register 434 case 'h': // Print QImode high register 435 case 'w': // Print HImode register 436 case 'k': // Print SImode register 437 case 'q': // Print DImode register 438 if (MO.isReg()) 439 return printAsmMRegister(*this, MO, ExtraCode[0], O); 440 printOperand(*this, MI, OpNo, O); 441 return false; 442 443 case 'P': // This is the operand of a call, treat specially. 444 printPCRelImm(*this, MI, OpNo, O); 445 return false; 446 447 case 'n': // Negate the immediate or print a '-' before the operand. 448 // Note: this is a temporary solution. It should be handled target 449 // independently as part of the 'MC' work. 450 if (MO.isImm()) { 451 O << -MO.getImm(); 452 return false; 453 } 454 O << '-'; 455 } 456 } 457 458 printOperand(*this, MI, OpNo, O, /*Modifier*/ nullptr, AsmVariant); 459 return false; 460 } 461 462 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 463 unsigned OpNo, unsigned AsmVariant, 464 const char *ExtraCode, 465 raw_ostream &O) { 466 if (AsmVariant) { 467 printIntelMemReference(*this, MI, OpNo, O); 468 return false; 469 } 470 471 if (ExtraCode && ExtraCode[0]) { 472 if (ExtraCode[1] != 0) return true; // Unknown modifier. 473 474 switch (ExtraCode[0]) { 475 default: return true; // Unknown modifier. 476 case 'b': // Print QImode register 477 case 'h': // Print QImode high register 478 case 'w': // Print HImode register 479 case 'k': // Print SImode register 480 case 'q': // Print SImode register 481 // These only apply to registers, ignore on mem. 482 break; 483 case 'H': 484 printMemReference(*this, MI, OpNo, O, "H"); 485 return false; 486 case 'P': // Don't print @PLT, but do print as memory. 487 printMemReference(*this, MI, OpNo, O, "no-rip"); 488 return false; 489 } 490 } 491 printMemReference(*this, MI, OpNo, O); 492 return false; 493 } 494 495 void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { 496 const Triple &TT = TM.getTargetTriple(); 497 498 if (TT.isOSBinFormatMachO()) 499 OutStreamer->SwitchSection(getObjFileLowering().getTextSection()); 500 501 if (TT.isOSBinFormatCOFF()) { 502 // Emit an absolute @feat.00 symbol. This appears to be some kind of 503 // compiler features bitfield read by link.exe. 504 if (TT.getArch() == Triple::x86) { 505 MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00")); 506 OutStreamer->BeginCOFFSymbolDef(S); 507 OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); 508 OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL); 509 OutStreamer->EndCOFFSymbolDef(); 510 // According to the PE-COFF spec, the LSB of this value marks the object 511 // for "registered SEH". This means that all SEH handler entry points 512 // must be registered in .sxdata. Use of any unregistered handlers will 513 // cause the process to terminate immediately. LLVM does not know how to 514 // register any SEH handlers, so its object files should be safe. 515 OutStreamer->EmitSymbolAttribute(S, MCSA_Global); 516 OutStreamer->EmitAssignment( 517 S, MCConstantExpr::create(int64_t(1), MMI->getContext())); 518 } 519 } 520 OutStreamer->EmitSyntaxDirective(); 521 522 // If this is not inline asm and we're in 16-bit 523 // mode prefix assembly with .code16. 524 bool is16 = TT.getEnvironment() == Triple::CODE16; 525 if (M.getModuleInlineAsm().empty() && is16) 526 OutStreamer->EmitAssemblerFlag(MCAF_Code16); 527 } 528 529 static void 530 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, 531 MachineModuleInfoImpl::StubValueTy &MCSym) { 532 // L_foo$stub: 533 OutStreamer.EmitLabel(StubLabel); 534 // .indirect_symbol _foo 535 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 536 537 if (MCSym.getInt()) 538 // External to current translation unit. 539 OutStreamer.EmitIntValue(0, 4/*size*/); 540 else 541 // Internal to current translation unit. 542 // 543 // When we place the LSDA into the TEXT section, the type info 544 // pointers need to be indirect and pc-rel. We accomplish this by 545 // using NLPs; however, sometimes the types are local to the file. 546 // We need to fill in the value for the NLP in those cases. 547 OutStreamer.EmitValue( 548 MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()), 549 4 /*size*/); 550 } 551 552 MCSymbol *X86AsmPrinter::GetCPISymbol(unsigned CPID) const { 553 if (Subtarget->isTargetKnownWindowsMSVC()) { 554 const MachineConstantPoolEntry &CPE = 555 MF->getConstantPool()->getConstants()[CPID]; 556 if (!CPE.isMachineConstantPoolEntry()) { 557 const DataLayout &DL = MF->getDataLayout(); 558 SectionKind Kind = CPE.getSectionKind(&DL); 559 const Constant *C = CPE.Val.ConstVal; 560 unsigned Align = CPE.Alignment; 561 if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>( 562 getObjFileLowering().getSectionForConstant(DL, Kind, C, Align))) { 563 if (MCSymbol *Sym = S->getCOMDATSymbol()) { 564 if (Sym->isUndefined()) 565 OutStreamer->EmitSymbolAttribute(Sym, MCSA_Global); 566 return Sym; 567 } 568 } 569 } 570 } 571 572 return AsmPrinter::GetCPISymbol(CPID); 573 } 574 575 void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { 576 const Triple &TT = TM.getTargetTriple(); 577 578 if (TT.isOSBinFormatMachO()) { 579 // All darwin targets use mach-o. 580 MachineModuleInfoMachO &MMIMacho = 581 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 582 583 // Output stubs for dynamically-linked functions. 584 MachineModuleInfoMachO::SymbolListTy Stubs; 585 586 // Output stubs for external and common global variables. 587 Stubs = MMIMacho.GetGVStubList(); 588 if (!Stubs.empty()) { 589 MCSection *TheSection = OutContext.getMachOSection( 590 "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS, 591 SectionKind::getMetadata()); 592 OutStreamer->SwitchSection(TheSection); 593 594 for (auto &Stub : Stubs) 595 emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second); 596 597 Stubs.clear(); 598 OutStreamer->AddBlankLine(); 599 } 600 601 SM.serializeToStackMapSection(); 602 FM.serializeToFaultMapSection(); 603 604 // Funny Darwin hack: This flag tells the linker that no global symbols 605 // contain code that falls through to other global symbols (e.g. the obvious 606 // implementation of multiple entry points). If this doesn't occur, the 607 // linker can safely perform dead code stripping. Since LLVM never 608 // generates code that does this, it is always safe to set. 609 OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 610 } 611 612 if (TT.isKnownWindowsMSVCEnvironment() && MMI->usesVAFloatArgument()) { 613 StringRef SymbolName = 614 (TT.getArch() == Triple::x86_64) ? "_fltused" : "__fltused"; 615 MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName); 616 OutStreamer->EmitSymbolAttribute(S, MCSA_Global); 617 } 618 619 if (TT.isOSBinFormatCOFF()) { 620 const TargetLoweringObjectFileCOFF &TLOFCOFF = 621 static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering()); 622 623 std::string Flags; 624 raw_string_ostream FlagsOS(Flags); 625 626 for (const auto &Function : M) 627 TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Function, *Mang); 628 for (const auto &Global : M.globals()) 629 TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Global, *Mang); 630 for (const auto &Alias : M.aliases()) 631 TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Alias, *Mang); 632 633 FlagsOS.flush(); 634 635 // Output collected flags. 636 if (!Flags.empty()) { 637 OutStreamer->SwitchSection(TLOFCOFF.getDrectveSection()); 638 OutStreamer->EmitBytes(Flags); 639 } 640 641 SM.serializeToStackMapSection(); 642 } 643 644 if (TT.isOSBinFormatELF()) { 645 SM.serializeToStackMapSection(); 646 FM.serializeToFaultMapSection(); 647 } 648 } 649 650 //===----------------------------------------------------------------------===// 651 // Target Registry Stuff 652 //===----------------------------------------------------------------------===// 653 654 // Force static initialization. 655 extern "C" void LLVMInitializeX86AsmPrinter() { 656 RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target); 657 RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target); 658 } 659