LLVM API Documentation
00001 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains a printer that converts from our internal representation 00011 // of machine-dependent LLVM code to X86 machine code. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "X86AsmPrinter.h" 00016 #include "InstPrinter/X86ATTInstPrinter.h" 00017 #include "MCTargetDesc/X86BaseInfo.h" 00018 #include "X86InstrInfo.h" 00019 #include "X86MachineFunctionInfo.h" 00020 #include "llvm/ADT/SmallString.h" 00021 #include "llvm/CodeGen/MachineConstantPool.h" 00022 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 00023 #include "llvm/CodeGen/MachineValueType.h" 00024 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 00025 #include "llvm/IR/DebugInfo.h" 00026 #include "llvm/IR/DerivedTypes.h" 00027 #include "llvm/IR/Mangler.h" 00028 #include "llvm/IR/Module.h" 00029 #include "llvm/IR/Type.h" 00030 #include "llvm/MC/MCAsmInfo.h" 00031 #include "llvm/MC/MCContext.h" 00032 #include "llvm/MC/MCExpr.h" 00033 #include "llvm/MC/MCSectionCOFF.h" 00034 #include "llvm/MC/MCSectionMachO.h" 00035 #include "llvm/MC/MCStreamer.h" 00036 #include "llvm/MC/MCSymbol.h" 00037 #include "llvm/Support/COFF.h" 00038 #include "llvm/Support/Debug.h" 00039 #include "llvm/Support/ErrorHandling.h" 00040 #include "llvm/Support/TargetRegistry.h" 00041 using namespace llvm; 00042 00043 //===----------------------------------------------------------------------===// 00044 // Primitive Helper Functions. 00045 //===----------------------------------------------------------------------===// 00046 00047 /// runOnMachineFunction - Emit the function body. 00048 /// 00049 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00050 SMShadowTracker.startFunction(MF); 00051 00052 SetupMachineFunction(MF); 00053 00054 if (Subtarget->isTargetCOFF()) { 00055 bool Intrn = MF.getFunction()->hasInternalLinkage(); 00056 OutStreamer.BeginCOFFSymbolDef(CurrentFnSym); 00057 OutStreamer.EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC 00058 : COFF::IMAGE_SYM_CLASS_EXTERNAL); 00059 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION 00060 << COFF::SCT_COMPLEX_TYPE_SHIFT); 00061 OutStreamer.EndCOFFSymbolDef(); 00062 } 00063 00064 // Have common code print out the function header with linkage info etc. 00065 EmitFunctionHeader(); 00066 00067 // Emit the rest of the function body. 00068 EmitFunctionBody(); 00069 00070 // We didn't modify anything. 00071 return false; 00072 } 00073 00074 /// printSymbolOperand - Print a raw symbol reference operand. This handles 00075 /// jump tables, constant pools, global address and external symbols, all of 00076 /// which print to a label with various suffixes for relocation types etc. 00077 static void printSymbolOperand(X86AsmPrinter &P, const MachineOperand &MO, 00078 raw_ostream &O) { 00079 switch (MO.getType()) { 00080 default: llvm_unreachable("unknown symbol type!"); 00081 case MachineOperand::MO_ConstantPoolIndex: 00082 O << *P.GetCPISymbol(MO.getIndex()); 00083 P.printOffset(MO.getOffset(), O); 00084 break; 00085 case MachineOperand::MO_GlobalAddress: { 00086 const GlobalValue *GV = MO.getGlobal(); 00087 00088 MCSymbol *GVSym; 00089 if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) 00090 GVSym = P.getSymbolWithGlobalValueBase(GV, "$stub"); 00091 else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 00092 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE || 00093 MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE) 00094 GVSym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 00095 else 00096 GVSym = P.getSymbol(GV); 00097 00098 // Handle dllimport linkage. 00099 if (MO.getTargetFlags() == X86II::MO_DLLIMPORT) 00100 GVSym = 00101 P.OutContext.GetOrCreateSymbol(Twine("__imp_") + GVSym->getName()); 00102 00103 if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || 00104 MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { 00105 MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 00106 MachineModuleInfoImpl::StubValueTy &StubSym = 00107 P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym); 00108 if (!StubSym.getPointer()) 00109 StubSym = MachineModuleInfoImpl:: 00110 StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage()); 00111 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){ 00112 MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 00113 MachineModuleInfoImpl::StubValueTy &StubSym = 00114 P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry( 00115 Sym); 00116 if (!StubSym.getPointer()) 00117 StubSym = MachineModuleInfoImpl:: 00118 StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage()); 00119 } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { 00120 MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$stub"); 00121 MachineModuleInfoImpl::StubValueTy &StubSym = 00122 P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 00123 if (!StubSym.getPointer()) 00124 StubSym = MachineModuleInfoImpl:: 00125 StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage()); 00126 } 00127 00128 // If the name begins with a dollar-sign, enclose it in parens. We do this 00129 // to avoid having it look like an integer immediate to the assembler. 00130 if (GVSym->getName()[0] != '$') 00131 O << *GVSym; 00132 else 00133 O << '(' << *GVSym << ')'; 00134 P.printOffset(MO.getOffset(), O); 00135 break; 00136 } 00137 } 00138 00139 switch (MO.getTargetFlags()) { 00140 default: 00141 llvm_unreachable("Unknown target flag on GV operand"); 00142 case X86II::MO_NO_FLAG: // No flag. 00143 break; 00144 case X86II::MO_DARWIN_NONLAZY: 00145 case X86II::MO_DLLIMPORT: 00146 case X86II::MO_DARWIN_STUB: 00147 // These affect the name of the symbol, not any suffix. 00148 break; 00149 case X86II::MO_GOT_ABSOLUTE_ADDRESS: 00150 O << " + [.-" << *P.MF->getPICBaseSymbol() << ']'; 00151 break; 00152 case X86II::MO_PIC_BASE_OFFSET: 00153 case X86II::MO_DARWIN_NONLAZY_PIC_BASE: 00154 case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: 00155 O << '-' << *P.MF->getPICBaseSymbol(); 00156 break; 00157 case X86II::MO_TLSGD: O << "@TLSGD"; break; 00158 case X86II::MO_TLSLD: O << "@TLSLD"; break; 00159 case X86II::MO_TLSLDM: O << "@TLSLDM"; break; 00160 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break; 00161 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break; 00162 case X86II::MO_TPOFF: O << "@TPOFF"; break; 00163 case X86II::MO_DTPOFF: O << "@DTPOFF"; break; 00164 case X86II::MO_NTPOFF: O << "@NTPOFF"; break; 00165 case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break; 00166 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break; 00167 case X86II::MO_GOT: O << "@GOT"; break; 00168 case X86II::MO_GOTOFF: O << "@GOTOFF"; break; 00169 case X86II::MO_PLT: O << "@PLT"; break; 00170 case X86II::MO_TLVP: O << "@TLVP"; break; 00171 case X86II::MO_TLVP_PIC_BASE: 00172 O << "@TLVP" << '-' << *P.MF->getPICBaseSymbol(); 00173 break; 00174 case X86II::MO_SECREL: O << "@SECREL32"; break; 00175 } 00176 } 00177 00178 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI, 00179 unsigned OpNo, raw_ostream &O, 00180 const char *Modifier = nullptr, unsigned AsmVariant = 0); 00181 00182 /// printPCRelImm - This is used to print an immediate value that ends up 00183 /// being encoded as a pc-relative value. These print slightly differently, for 00184 /// example, a $ is not emitted. 00185 static void printPCRelImm(X86AsmPrinter &P, const MachineInstr *MI, 00186 unsigned OpNo, raw_ostream &O) { 00187 const MachineOperand &MO = MI->getOperand(OpNo); 00188 switch (MO.getType()) { 00189 default: llvm_unreachable("Unknown pcrel immediate operand"); 00190 case MachineOperand::MO_Register: 00191 // pc-relativeness was handled when computing the value in the reg. 00192 printOperand(P, MI, OpNo, O); 00193 return; 00194 case MachineOperand::MO_Immediate: 00195 O << MO.getImm(); 00196 return; 00197 case MachineOperand::MO_GlobalAddress: 00198 printSymbolOperand(P, MO, O); 00199 return; 00200 } 00201 } 00202 00203 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI, 00204 unsigned OpNo, raw_ostream &O, const char *Modifier, 00205 unsigned AsmVariant) { 00206 const MachineOperand &MO = MI->getOperand(OpNo); 00207 switch (MO.getType()) { 00208 default: llvm_unreachable("unknown operand type!"); 00209 case MachineOperand::MO_Register: { 00210 // FIXME: Enumerating AsmVariant, so we can remove magic number. 00211 if (AsmVariant == 0) O << '%'; 00212 unsigned Reg = MO.getReg(); 00213 if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) { 00214 MVT::SimpleValueType VT = (strcmp(Modifier+6,"64") == 0) ? 00215 MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 : 00216 ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8)); 00217 Reg = getX86SubSuperRegister(Reg, VT); 00218 } 00219 O << X86ATTInstPrinter::getRegisterName(Reg); 00220 return; 00221 } 00222 00223 case MachineOperand::MO_Immediate: 00224 if (AsmVariant == 0) O << '$'; 00225 O << MO.getImm(); 00226 return; 00227 00228 case MachineOperand::MO_GlobalAddress: { 00229 if (AsmVariant == 0) O << '$'; 00230 printSymbolOperand(P, MO, O); 00231 break; 00232 } 00233 } 00234 } 00235 00236 static void printLeaMemReference(X86AsmPrinter &P, const MachineInstr *MI, 00237 unsigned Op, raw_ostream &O, 00238 const char *Modifier = nullptr) { 00239 const MachineOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); 00240 const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); 00241 const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); 00242 00243 // If we really don't want to print out (rip), don't. 00244 bool HasBaseReg = BaseReg.getReg() != 0; 00245 if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") && 00246 BaseReg.getReg() == X86::RIP) 00247 HasBaseReg = false; 00248 00249 // HasParenPart - True if we will print out the () part of the mem ref. 00250 bool HasParenPart = IndexReg.getReg() || HasBaseReg; 00251 00252 switch (DispSpec.getType()) { 00253 default: 00254 llvm_unreachable("unknown operand type!"); 00255 case MachineOperand::MO_Immediate: { 00256 int DispVal = DispSpec.getImm(); 00257 if (DispVal || !HasParenPart) 00258 O << DispVal; 00259 break; 00260 } 00261 case MachineOperand::MO_GlobalAddress: 00262 case MachineOperand::MO_ConstantPoolIndex: 00263 printSymbolOperand(P, DispSpec, O); 00264 } 00265 00266 if (Modifier && strcmp(Modifier, "H") == 0) 00267 O << "+8"; 00268 00269 if (HasParenPart) { 00270 assert(IndexReg.getReg() != X86::ESP && 00271 "X86 doesn't allow scaling by ESP"); 00272 00273 O << '('; 00274 if (HasBaseReg) 00275 printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier); 00276 00277 if (IndexReg.getReg()) { 00278 O << ','; 00279 printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier); 00280 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); 00281 if (ScaleVal != 1) 00282 O << ',' << ScaleVal; 00283 } 00284 O << ')'; 00285 } 00286 } 00287 00288 static void printMemReference(X86AsmPrinter &P, const MachineInstr *MI, 00289 unsigned Op, raw_ostream &O, 00290 const char *Modifier = nullptr) { 00291 assert(isMem(MI, Op) && "Invalid memory reference!"); 00292 const MachineOperand &Segment = MI->getOperand(Op+X86::AddrSegmentReg); 00293 if (Segment.getReg()) { 00294 printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier); 00295 O << ':'; 00296 } 00297 printLeaMemReference(P, MI, Op, O, Modifier); 00298 } 00299 00300 static void printIntelMemReference(X86AsmPrinter &P, const MachineInstr *MI, 00301 unsigned Op, raw_ostream &O, 00302 const char *Modifier = nullptr, 00303 unsigned AsmVariant = 1) { 00304 const MachineOperand &BaseReg = MI->getOperand(Op+X86::AddrBaseReg); 00305 unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm(); 00306 const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg); 00307 const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp); 00308 const MachineOperand &SegReg = MI->getOperand(Op+X86::AddrSegmentReg); 00309 00310 // If this has a segment register, print it. 00311 if (SegReg.getReg()) { 00312 printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier, AsmVariant); 00313 O << ':'; 00314 } 00315 00316 O << '['; 00317 00318 bool NeedPlus = false; 00319 if (BaseReg.getReg()) { 00320 printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier, AsmVariant); 00321 NeedPlus = true; 00322 } 00323 00324 if (IndexReg.getReg()) { 00325 if (NeedPlus) O << " + "; 00326 if (ScaleVal != 1) 00327 O << ScaleVal << '*'; 00328 printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier, AsmVariant); 00329 NeedPlus = true; 00330 } 00331 00332 if (!DispSpec.isImm()) { 00333 if (NeedPlus) O << " + "; 00334 printOperand(P, MI, Op+X86::AddrDisp, O, Modifier, AsmVariant); 00335 } else { 00336 int64_t DispVal = DispSpec.getImm(); 00337 if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) { 00338 if (NeedPlus) { 00339 if (DispVal > 0) 00340 O << " + "; 00341 else { 00342 O << " - "; 00343 DispVal = -DispVal; 00344 } 00345 } 00346 O << DispVal; 00347 } 00348 } 00349 O << ']'; 00350 } 00351 00352 static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO, 00353 char Mode, raw_ostream &O) { 00354 unsigned Reg = MO.getReg(); 00355 switch (Mode) { 00356 default: return true; // Unknown mode. 00357 case 'b': // Print QImode register 00358 Reg = getX86SubSuperRegister(Reg, MVT::i8); 00359 break; 00360 case 'h': // Print QImode high register 00361 Reg = getX86SubSuperRegister(Reg, MVT::i8, true); 00362 break; 00363 case 'w': // Print HImode register 00364 Reg = getX86SubSuperRegister(Reg, MVT::i16); 00365 break; 00366 case 'k': // Print SImode register 00367 Reg = getX86SubSuperRegister(Reg, MVT::i32); 00368 break; 00369 case 'q': 00370 // Print 64-bit register names if 64-bit integer registers are available. 00371 // Otherwise, print 32-bit register names. 00372 MVT::SimpleValueType Ty = P.getSubtarget().is64Bit() ? MVT::i64 : MVT::i32; 00373 Reg = getX86SubSuperRegister(Reg, Ty); 00374 break; 00375 } 00376 00377 O << '%' << X86ATTInstPrinter::getRegisterName(Reg); 00378 return false; 00379 } 00380 00381 /// PrintAsmOperand - Print out an operand for an inline asm expression. 00382 /// 00383 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 00384 unsigned AsmVariant, 00385 const char *ExtraCode, raw_ostream &O) { 00386 // Does this asm operand have a single letter operand modifier? 00387 if (ExtraCode && ExtraCode[0]) { 00388 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00389 00390 const MachineOperand &MO = MI->getOperand(OpNo); 00391 00392 switch (ExtraCode[0]) { 00393 default: 00394 // See if this is a generic print operand 00395 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 00396 case 'a': // This is an address. Currently only 'i' and 'r' are expected. 00397 switch (MO.getType()) { 00398 default: 00399 return true; 00400 case MachineOperand::MO_Immediate: 00401 O << MO.getImm(); 00402 return false; 00403 case MachineOperand::MO_ConstantPoolIndex: 00404 case MachineOperand::MO_JumpTableIndex: 00405 case MachineOperand::MO_ExternalSymbol: 00406 llvm_unreachable("unexpected operand type!"); 00407 case MachineOperand::MO_GlobalAddress: 00408 printSymbolOperand(*this, MO, O); 00409 if (Subtarget->isPICStyleRIPRel()) 00410 O << "(%rip)"; 00411 return false; 00412 case MachineOperand::MO_Register: 00413 O << '('; 00414 printOperand(*this, MI, OpNo, O); 00415 O << ')'; 00416 return false; 00417 } 00418 00419 case 'c': // Don't print "$" before a global var name or constant. 00420 switch (MO.getType()) { 00421 default: 00422 printOperand(*this, MI, OpNo, O); 00423 break; 00424 case MachineOperand::MO_Immediate: 00425 O << MO.getImm(); 00426 break; 00427 case MachineOperand::MO_ConstantPoolIndex: 00428 case MachineOperand::MO_JumpTableIndex: 00429 case MachineOperand::MO_ExternalSymbol: 00430 llvm_unreachable("unexpected operand type!"); 00431 case MachineOperand::MO_GlobalAddress: 00432 printSymbolOperand(*this, MO, O); 00433 break; 00434 } 00435 return false; 00436 00437 case 'A': // Print '*' before a register (it must be a register) 00438 if (MO.isReg()) { 00439 O << '*'; 00440 printOperand(*this, MI, OpNo, O); 00441 return false; 00442 } 00443 return true; 00444 00445 case 'b': // Print QImode register 00446 case 'h': // Print QImode high register 00447 case 'w': // Print HImode register 00448 case 'k': // Print SImode register 00449 case 'q': // Print DImode register 00450 if (MO.isReg()) 00451 return printAsmMRegister(*this, MO, ExtraCode[0], O); 00452 printOperand(*this, MI, OpNo, O); 00453 return false; 00454 00455 case 'P': // This is the operand of a call, treat specially. 00456 printPCRelImm(*this, MI, OpNo, O); 00457 return false; 00458 00459 case 'n': // Negate the immediate or print a '-' before the operand. 00460 // Note: this is a temporary solution. It should be handled target 00461 // independently as part of the 'MC' work. 00462 if (MO.isImm()) { 00463 O << -MO.getImm(); 00464 return false; 00465 } 00466 O << '-'; 00467 } 00468 } 00469 00470 printOperand(*this, MI, OpNo, O, /*Modifier*/ nullptr, AsmVariant); 00471 return false; 00472 } 00473 00474 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00475 unsigned OpNo, unsigned AsmVariant, 00476 const char *ExtraCode, 00477 raw_ostream &O) { 00478 if (AsmVariant) { 00479 printIntelMemReference(*this, MI, OpNo, O); 00480 return false; 00481 } 00482 00483 if (ExtraCode && ExtraCode[0]) { 00484 if (ExtraCode[1] != 0) return true; // Unknown modifier. 00485 00486 switch (ExtraCode[0]) { 00487 default: return true; // Unknown modifier. 00488 case 'b': // Print QImode register 00489 case 'h': // Print QImode high register 00490 case 'w': // Print HImode register 00491 case 'k': // Print SImode register 00492 case 'q': // Print SImode register 00493 // These only apply to registers, ignore on mem. 00494 break; 00495 case 'H': 00496 printMemReference(*this, MI, OpNo, O, "H"); 00497 return false; 00498 case 'P': // Don't print @PLT, but do print as memory. 00499 printMemReference(*this, MI, OpNo, O, "no-rip"); 00500 return false; 00501 } 00502 } 00503 printMemReference(*this, MI, OpNo, O); 00504 return false; 00505 } 00506 00507 void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { 00508 if (Subtarget->isTargetMacho()) 00509 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 00510 00511 if (Subtarget->isTargetCOFF()) { 00512 // Emit an absolute @feat.00 symbol. This appears to be some kind of 00513 // compiler features bitfield read by link.exe. 00514 if (!Subtarget->is64Bit()) { 00515 MCSymbol *S = MMI->getContext().GetOrCreateSymbol(StringRef("@feat.00")); 00516 OutStreamer.BeginCOFFSymbolDef(S); 00517 OutStreamer.EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC); 00518 OutStreamer.EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL); 00519 OutStreamer.EndCOFFSymbolDef(); 00520 // According to the PE-COFF spec, the LSB of this value marks the object 00521 // for "registered SEH". This means that all SEH handler entry points 00522 // must be registered in .sxdata. Use of any unregistered handlers will 00523 // cause the process to terminate immediately. LLVM does not know how to 00524 // register any SEH handlers, so its object files should be safe. 00525 S->setAbsolute(); 00526 OutStreamer.EmitSymbolAttribute(S, MCSA_Global); 00527 OutStreamer.EmitAssignment( 00528 S, MCConstantExpr::Create(int64_t(1), MMI->getContext())); 00529 } 00530 } 00531 } 00532 00533 static void 00534 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, 00535 MachineModuleInfoImpl::StubValueTy &MCSym) { 00536 // L_foo$stub: 00537 OutStreamer.EmitLabel(StubLabel); 00538 // .indirect_symbol _foo 00539 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 00540 00541 if (MCSym.getInt()) 00542 // External to current translation unit. 00543 OutStreamer.EmitIntValue(0, 4/*size*/); 00544 else 00545 // Internal to current translation unit. 00546 // 00547 // When we place the LSDA into the TEXT section, the type info 00548 // pointers need to be indirect and pc-rel. We accomplish this by 00549 // using NLPs; however, sometimes the types are local to the file. 00550 // We need to fill in the value for the NLP in those cases. 00551 OutStreamer.EmitValue( 00552 MCSymbolRefExpr::Create(MCSym.getPointer(), OutStreamer.getContext()), 00553 4 /*size*/); 00554 } 00555 00556 MCSymbol *X86AsmPrinter::GetCPISymbol(unsigned CPID) const { 00557 if (Subtarget->isTargetKnownWindowsMSVC()) { 00558 const MachineConstantPoolEntry &CPE = 00559 MF->getConstantPool()->getConstants()[CPID]; 00560 if (!CPE.isMachineConstantPoolEntry()) { 00561 SectionKind Kind = 00562 CPE.getSectionKind(TM.getSubtargetImpl()->getDataLayout()); 00563 const Constant *C = CPE.Val.ConstVal; 00564 if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>( 00565 getObjFileLowering().getSectionForConstant(Kind, C))) { 00566 if (MCSymbol *Sym = S->getCOMDATSymbol()) { 00567 if (Sym->isUndefined()) 00568 OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global); 00569 return Sym; 00570 } 00571 } 00572 } 00573 } 00574 00575 return AsmPrinter::GetCPISymbol(CPID); 00576 } 00577 00578 void X86AsmPrinter::GenerateExportDirective(const MCSymbol *Sym, bool IsData) { 00579 SmallString<128> Directive; 00580 raw_svector_ostream OS(Directive); 00581 StringRef Name = Sym->getName(); 00582 00583 if (Subtarget->isTargetKnownWindowsMSVC()) 00584 OS << " /EXPORT:"; 00585 else 00586 OS << " -export:"; 00587 00588 if ((Subtarget->isTargetWindowsGNU() || Subtarget->isTargetWindowsCygwin()) && 00589 (Name[0] == getDataLayout().getGlobalPrefix())) 00590 Name = Name.drop_front(); 00591 00592 OS << Name; 00593 00594 if (IsData) { 00595 if (Subtarget->isTargetKnownWindowsMSVC()) 00596 OS << ",DATA"; 00597 else 00598 OS << ",data"; 00599 } 00600 00601 OS.flush(); 00602 OutStreamer.EmitBytes(Directive); 00603 } 00604 00605 void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { 00606 if (Subtarget->isTargetMacho()) { 00607 // All darwin targets use mach-o. 00608 MachineModuleInfoMachO &MMIMacho = 00609 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 00610 00611 // Output stubs for dynamically-linked functions. 00612 MachineModuleInfoMachO::SymbolListTy Stubs; 00613 00614 Stubs = MMIMacho.GetFnStubList(); 00615 if (!Stubs.empty()) { 00616 const MCSection *TheSection = 00617 OutContext.getMachOSection("__IMPORT", "__jump_table", 00618 MachO::S_SYMBOL_STUBS | 00619 MachO::S_ATTR_SELF_MODIFYING_CODE | 00620 MachO::S_ATTR_PURE_INSTRUCTIONS, 00621 5, SectionKind::getMetadata()); 00622 OutStreamer.SwitchSection(TheSection); 00623 00624 for (const auto &Stub : Stubs) { 00625 // L_foo$stub: 00626 OutStreamer.EmitLabel(Stub.first); 00627 // .indirect_symbol _foo 00628 OutStreamer.EmitSymbolAttribute(Stub.second.getPointer(), 00629 MCSA_IndirectSymbol); 00630 // hlt; hlt; hlt; hlt; hlt hlt = 0xf4. 00631 const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4"; 00632 OutStreamer.EmitBytes(StringRef(HltInsts, 5)); 00633 } 00634 00635 Stubs.clear(); 00636 OutStreamer.AddBlankLine(); 00637 } 00638 00639 // Output stubs for external and common global variables. 00640 Stubs = MMIMacho.GetGVStubList(); 00641 if (!Stubs.empty()) { 00642 const MCSection *TheSection = 00643 OutContext.getMachOSection("__IMPORT", "__pointers", 00644 MachO::S_NON_LAZY_SYMBOL_POINTERS, 00645 SectionKind::getMetadata()); 00646 OutStreamer.SwitchSection(TheSection); 00647 00648 for (auto &Stub : Stubs) 00649 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 00650 00651 Stubs.clear(); 00652 OutStreamer.AddBlankLine(); 00653 } 00654 00655 Stubs = MMIMacho.GetHiddenGVStubList(); 00656 if (!Stubs.empty()) { 00657 const MCSection *TheSection = 00658 OutContext.getMachOSection("__IMPORT", "__pointers", 00659 MachO::S_NON_LAZY_SYMBOL_POINTERS, 00660 SectionKind::getMetadata()); 00661 OutStreamer.SwitchSection(TheSection); 00662 00663 for (auto &Stub : Stubs) 00664 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); 00665 00666 Stubs.clear(); 00667 OutStreamer.AddBlankLine(); 00668 } 00669 00670 SM.serializeToStackMapSection(); 00671 00672 // Funny Darwin hack: This flag tells the linker that no global symbols 00673 // contain code that falls through to other global symbols (e.g. the obvious 00674 // implementation of multiple entry points). If this doesn't occur, the 00675 // linker can safely perform dead code stripping. Since LLVM never 00676 // generates code that does this, it is always safe to set. 00677 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 00678 } 00679 00680 if (Subtarget->isTargetKnownWindowsMSVC() && MMI->usesVAFloatArgument()) { 00681 StringRef SymbolName = Subtarget->is64Bit() ? "_fltused" : "__fltused"; 00682 MCSymbol *S = MMI->getContext().GetOrCreateSymbol(SymbolName); 00683 OutStreamer.EmitSymbolAttribute(S, MCSA_Global); 00684 } 00685 00686 if (Subtarget->isTargetCOFF()) { 00687 // Necessary for dllexport support 00688 std::vector<const MCSymbol*> DLLExportedFns, DLLExportedGlobals; 00689 00690 for (const auto &Function : M) 00691 if (Function.hasDLLExportStorageClass()) 00692 DLLExportedFns.push_back(getSymbol(&Function)); 00693 00694 for (const auto &Global : M.globals()) 00695 if (Global.hasDLLExportStorageClass()) 00696 DLLExportedGlobals.push_back(getSymbol(&Global)); 00697 00698 for (const auto &Alias : M.aliases()) { 00699 if (!Alias.hasDLLExportStorageClass()) 00700 continue; 00701 00702 if (Alias.getType()->getElementType()->isFunctionTy()) 00703 DLLExportedFns.push_back(getSymbol(&Alias)); 00704 else 00705 DLLExportedGlobals.push_back(getSymbol(&Alias)); 00706 } 00707 00708 // Output linker support code for dllexported globals on windows. 00709 if (!DLLExportedGlobals.empty() || !DLLExportedFns.empty()) { 00710 const TargetLoweringObjectFileCOFF &TLOFCOFF = 00711 static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering()); 00712 00713 OutStreamer.SwitchSection(TLOFCOFF.getDrectveSection()); 00714 00715 for (auto & Symbol : DLLExportedGlobals) 00716 GenerateExportDirective(Symbol, /*IsData=*/true); 00717 for (auto & Symbol : DLLExportedFns) 00718 GenerateExportDirective(Symbol, /*IsData=*/false); 00719 } 00720 } 00721 00722 if (Subtarget->isTargetELF()) { 00723 const TargetLoweringObjectFileELF &TLOFELF = 00724 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 00725 00726 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 00727 00728 // Output stubs for external and common global variables. 00729 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 00730 if (!Stubs.empty()) { 00731 OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 00732 const DataLayout *TD = TM.getSubtargetImpl()->getDataLayout(); 00733 00734 for (const auto &Stub : Stubs) { 00735 OutStreamer.EmitLabel(Stub.first); 00736 OutStreamer.EmitSymbolValue(Stub.second.getPointer(), 00737 TD->getPointerSize()); 00738 } 00739 Stubs.clear(); 00740 } 00741 00742 SM.serializeToStackMapSection(); 00743 } 00744 } 00745 00746 //===----------------------------------------------------------------------===// 00747 // Target Registry Stuff 00748 //===----------------------------------------------------------------------===// 00749 00750 // Force static initialization. 00751 extern "C" void LLVMInitializeX86AsmPrinter() { 00752 RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target); 00753 RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target); 00754 }