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