X86AsmPrinter.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file contains a printer that converts from our internal representation
  10. // of machine-dependent LLVM code to X86 machine code.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "X86AsmPrinter.h"
  14. #include "MCTargetDesc/X86ATTInstPrinter.h"
  15. #include "MCTargetDesc/X86BaseInfo.h"
  16. #include "MCTargetDesc/X86TargetStreamer.h"
  17. #include "TargetInfo/X86TargetInfo.h"
  18. #include "X86InstrInfo.h"
  19. #include "X86MachineFunctionInfo.h"
  20. #include "X86Subtarget.h"
  21. #include "llvm/BinaryFormat/COFF.h"
  22. #include "llvm/BinaryFormat/ELF.h"
  23. #include "llvm/CodeGen/MachineConstantPool.h"
  24. #include "llvm/CodeGen/MachineModuleInfoImpls.h"
  25. #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
  26. #include "llvm/IR/DerivedTypes.h"
  27. #include "llvm/IR/InlineAsm.h"
  28. #include "llvm/IR/Mangler.h"
  29. #include "llvm/IR/Module.h"
  30. #include "llvm/IR/Type.h"
  31. #include "llvm/MC/MCAsmInfo.h"
  32. #include "llvm/MC/MCCodeEmitter.h"
  33. #include "llvm/MC/MCContext.h"
  34. #include "llvm/MC/MCExpr.h"
  35. #include "llvm/MC/MCInstBuilder.h"
  36. #include "llvm/MC/MCSectionCOFF.h"
  37. #include "llvm/MC/MCSectionELF.h"
  38. #include "llvm/MC/MCSectionMachO.h"
  39. #include "llvm/MC/MCStreamer.h"
  40. #include "llvm/MC/MCSymbol.h"
  41. #include "llvm/MC/TargetRegistry.h"
  42. #include "llvm/Support/Debug.h"
  43. #include "llvm/Support/ErrorHandling.h"
  44. #include "llvm/Support/MachineValueType.h"
  45. #include "llvm/Target/TargetMachine.h"
  46. using namespace llvm;
  47. X86AsmPrinter::X86AsmPrinter(TargetMachine &TM,
  48. std::unique_ptr<MCStreamer> Streamer)
  49. : AsmPrinter(TM, std::move(Streamer)), FM(*this) {}
  50. //===----------------------------------------------------------------------===//
  51. // Primitive Helper Functions.
  52. //===----------------------------------------------------------------------===//
  53. /// runOnMachineFunction - Emit the function body.
  54. ///
  55. bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
  56. Subtarget = &MF.getSubtarget<X86Subtarget>();
  57. SMShadowTracker.startFunction(MF);
  58. CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(
  59. *Subtarget->getInstrInfo(), MF.getContext()));
  60. EmitFPOData =
  61. Subtarget->isTargetWin32() && MF.getMMI().getModule()->getCodeViewFlag();
  62. IndCSPrefix =
  63. MF.getMMI().getModule()->getModuleFlag("indirect_branch_cs_prefix");
  64. SetupMachineFunction(MF);
  65. if (Subtarget->isTargetCOFF()) {
  66. bool Local = MF.getFunction().hasLocalLinkage();
  67. OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
  68. OutStreamer->emitCOFFSymbolStorageClass(
  69. Local ? COFF::IMAGE_SYM_CLASS_STATIC : COFF::IMAGE_SYM_CLASS_EXTERNAL);
  70. OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
  71. << COFF::SCT_COMPLEX_TYPE_SHIFT);
  72. OutStreamer->endCOFFSymbolDef();
  73. }
  74. // Emit the rest of the function body.
  75. emitFunctionBody();
  76. // Emit the XRay table for this function.
  77. emitXRayTable();
  78. EmitFPOData = false;
  79. IndCSPrefix = false;
  80. // We didn't modify anything.
  81. return false;
  82. }
  83. void X86AsmPrinter::emitFunctionBodyStart() {
  84. if (EmitFPOData) {
  85. auto *XTS =
  86. static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
  87. XTS->emitFPOProc(
  88. CurrentFnSym,
  89. MF->getInfo<X86MachineFunctionInfo>()->getArgumentStackSize());
  90. }
  91. }
  92. void X86AsmPrinter::emitFunctionBodyEnd() {
  93. if (EmitFPOData) {
  94. auto *XTS =
  95. static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
  96. XTS->emitFPOEndProc();
  97. }
  98. }
  99. uint32_t X86AsmPrinter::MaskKCFIType(uint32_t Value) {
  100. // If the type hash matches an invalid pattern, mask the value.
  101. const uint32_t InvalidValues[] = {
  102. 0xFA1E0FF3, /* ENDBR64 */
  103. 0xFB1E0FF3, /* ENDBR32 */
  104. };
  105. for (uint32_t N : InvalidValues) {
  106. // LowerKCFI_CHECK emits -Value for indirect call checks, so we must also
  107. // mask that. Note that -(Value + 1) == ~Value.
  108. if (N == Value || -N == Value)
  109. return Value + 1;
  110. }
  111. return Value;
  112. }
  113. void X86AsmPrinter::EmitKCFITypePadding(const MachineFunction &MF,
  114. bool HasType) {
  115. // Keep the function entry aligned, taking patchable-function-prefix into
  116. // account if set.
  117. int64_t PrefixBytes = 0;
  118. (void)MF.getFunction()
  119. .getFnAttribute("patchable-function-prefix")
  120. .getValueAsString()
  121. .getAsInteger(10, PrefixBytes);
  122. // Also take the type identifier into account if we're emitting
  123. // one. Otherwise, just pad with nops. The X86::MOV32ri instruction emitted
  124. // in X86AsmPrinter::emitKCFITypeId is 5 bytes long.
  125. if (HasType)
  126. PrefixBytes += 5;
  127. emitNops(offsetToAlignment(PrefixBytes, MF.getAlignment()));
  128. }
  129. /// emitKCFITypeId - Emit the KCFI type information in architecture specific
  130. /// format.
  131. void X86AsmPrinter::emitKCFITypeId(const MachineFunction &MF) {
  132. const Function &F = MF.getFunction();
  133. if (!F.getParent()->getModuleFlag("kcfi"))
  134. return;
  135. ConstantInt *Type = nullptr;
  136. if (const MDNode *MD = F.getMetadata(LLVMContext::MD_kcfi_type))
  137. Type = mdconst::extract<ConstantInt>(MD->getOperand(0));
  138. // If we don't have a type to emit, just emit padding if needed to maintain
  139. // the same alignment for all functions.
  140. if (!Type) {
  141. EmitKCFITypePadding(MF, /*HasType=*/false);
  142. return;
  143. }
  144. // Emit a function symbol for the type data to avoid unreachable instruction
  145. // warnings from binary validation tools, and use the same linkage as the
  146. // parent function. Note that using local linkage would result in duplicate
  147. // symbols for weak parent functions.
  148. MCSymbol *FnSym = OutContext.getOrCreateSymbol("__cfi_" + MF.getName());
  149. emitLinkage(&MF.getFunction(), FnSym);
  150. if (MAI->hasDotTypeDotSizeDirective())
  151. OutStreamer->emitSymbolAttribute(FnSym, MCSA_ELF_TypeFunction);
  152. OutStreamer->emitLabel(FnSym);
  153. // Embed the type hash in the X86::MOV32ri instruction to avoid special
  154. // casing object file parsers.
  155. EmitKCFITypePadding(MF);
  156. EmitAndCountInstruction(MCInstBuilder(X86::MOV32ri)
  157. .addReg(X86::EAX)
  158. .addImm(MaskKCFIType(Type->getZExtValue())));
  159. if (MAI->hasDotTypeDotSizeDirective()) {
  160. MCSymbol *EndSym = OutContext.createTempSymbol("cfi_func_end");
  161. OutStreamer->emitLabel(EndSym);
  162. const MCExpr *SizeExp = MCBinaryExpr::createSub(
  163. MCSymbolRefExpr::create(EndSym, OutContext),
  164. MCSymbolRefExpr::create(FnSym, OutContext), OutContext);
  165. OutStreamer->emitELFSize(FnSym, SizeExp);
  166. }
  167. }
  168. /// PrintSymbolOperand - Print a raw symbol reference operand. This handles
  169. /// jump tables, constant pools, global address and external symbols, all of
  170. /// which print to a label with various suffixes for relocation types etc.
  171. void X86AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
  172. raw_ostream &O) {
  173. switch (MO.getType()) {
  174. default: llvm_unreachable("unknown symbol type!");
  175. case MachineOperand::MO_ConstantPoolIndex:
  176. GetCPISymbol(MO.getIndex())->print(O, MAI);
  177. printOffset(MO.getOffset(), O);
  178. break;
  179. case MachineOperand::MO_GlobalAddress: {
  180. const GlobalValue *GV = MO.getGlobal();
  181. MCSymbol *GVSym;
  182. if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
  183. MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
  184. GVSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
  185. else
  186. GVSym = getSymbolPreferLocal(*GV);
  187. // Handle dllimport linkage.
  188. if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
  189. GVSym = OutContext.getOrCreateSymbol(Twine("__imp_") + GVSym->getName());
  190. else if (MO.getTargetFlags() == X86II::MO_COFFSTUB)
  191. GVSym =
  192. OutContext.getOrCreateSymbol(Twine(".refptr.") + GVSym->getName());
  193. if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
  194. MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
  195. MCSymbol *Sym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
  196. MachineModuleInfoImpl::StubValueTy &StubSym =
  197. MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
  198. if (!StubSym.getPointer())
  199. StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
  200. !GV->hasInternalLinkage());
  201. }
  202. // If the name begins with a dollar-sign, enclose it in parens. We do this
  203. // to avoid having it look like an integer immediate to the assembler.
  204. if (GVSym->getName()[0] != '$')
  205. GVSym->print(O, MAI);
  206. else {
  207. O << '(';
  208. GVSym->print(O, MAI);
  209. O << ')';
  210. }
  211. printOffset(MO.getOffset(), O);
  212. break;
  213. }
  214. }
  215. switch (MO.getTargetFlags()) {
  216. default:
  217. llvm_unreachable("Unknown target flag on GV operand");
  218. case X86II::MO_NO_FLAG: // No flag.
  219. break;
  220. case X86II::MO_DARWIN_NONLAZY:
  221. case X86II::MO_DLLIMPORT:
  222. case X86II::MO_COFFSTUB:
  223. // These affect the name of the symbol, not any suffix.
  224. break;
  225. case X86II::MO_GOT_ABSOLUTE_ADDRESS:
  226. O << " + [.-";
  227. MF->getPICBaseSymbol()->print(O, MAI);
  228. O << ']';
  229. break;
  230. case X86II::MO_PIC_BASE_OFFSET:
  231. case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
  232. O << '-';
  233. MF->getPICBaseSymbol()->print(O, MAI);
  234. break;
  235. case X86II::MO_TLSGD: O << "@TLSGD"; break;
  236. case X86II::MO_TLSLD: O << "@TLSLD"; break;
  237. case X86II::MO_TLSLDM: O << "@TLSLDM"; break;
  238. case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break;
  239. case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
  240. case X86II::MO_TPOFF: O << "@TPOFF"; break;
  241. case X86II::MO_DTPOFF: O << "@DTPOFF"; break;
  242. case X86II::MO_NTPOFF: O << "@NTPOFF"; break;
  243. case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break;
  244. case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break;
  245. case X86II::MO_GOTPCREL_NORELAX: O << "@GOTPCREL_NORELAX"; break;
  246. case X86II::MO_GOT: O << "@GOT"; break;
  247. case X86II::MO_GOTOFF: O << "@GOTOFF"; break;
  248. case X86II::MO_PLT: O << "@PLT"; break;
  249. case X86II::MO_TLVP: O << "@TLVP"; break;
  250. case X86II::MO_TLVP_PIC_BASE:
  251. O << "@TLVP" << '-';
  252. MF->getPICBaseSymbol()->print(O, MAI);
  253. break;
  254. case X86II::MO_SECREL: O << "@SECREL32"; break;
  255. }
  256. }
  257. void X86AsmPrinter::PrintOperand(const MachineInstr *MI, unsigned OpNo,
  258. raw_ostream &O) {
  259. const MachineOperand &MO = MI->getOperand(OpNo);
  260. const bool IsATT = MI->getInlineAsmDialect() == InlineAsm::AD_ATT;
  261. switch (MO.getType()) {
  262. default: llvm_unreachable("unknown operand type!");
  263. case MachineOperand::MO_Register: {
  264. if (IsATT)
  265. O << '%';
  266. O << X86ATTInstPrinter::getRegisterName(MO.getReg());
  267. return;
  268. }
  269. case MachineOperand::MO_Immediate:
  270. if (IsATT)
  271. O << '$';
  272. O << MO.getImm();
  273. return;
  274. case MachineOperand::MO_ConstantPoolIndex:
  275. case MachineOperand::MO_GlobalAddress: {
  276. switch (MI->getInlineAsmDialect()) {
  277. case InlineAsm::AD_ATT:
  278. O << '$';
  279. break;
  280. case InlineAsm::AD_Intel:
  281. O << "offset ";
  282. break;
  283. }
  284. PrintSymbolOperand(MO, O);
  285. break;
  286. }
  287. case MachineOperand::MO_BlockAddress: {
  288. MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
  289. Sym->print(O, MAI);
  290. break;
  291. }
  292. }
  293. }
  294. /// PrintModifiedOperand - Print subregisters based on supplied modifier,
  295. /// deferring to PrintOperand() if no modifier was supplied or if operand is not
  296. /// a register.
  297. void X86AsmPrinter::PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
  298. raw_ostream &O, const char *Modifier) {
  299. const MachineOperand &MO = MI->getOperand(OpNo);
  300. if (!Modifier || !MO.isReg())
  301. return PrintOperand(MI, OpNo, O);
  302. if (MI->getInlineAsmDialect() == InlineAsm::AD_ATT)
  303. O << '%';
  304. Register Reg = MO.getReg();
  305. if (strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
  306. unsigned Size = (strcmp(Modifier+6,"64") == 0) ? 64 :
  307. (strcmp(Modifier+6,"32") == 0) ? 32 :
  308. (strcmp(Modifier+6,"16") == 0) ? 16 : 8;
  309. Reg = getX86SubSuperRegister(Reg, Size);
  310. }
  311. O << X86ATTInstPrinter::getRegisterName(Reg);
  312. }
  313. /// PrintPCRelImm - This is used to print an immediate value that ends up
  314. /// being encoded as a pc-relative value. These print slightly differently, for
  315. /// example, a $ is not emitted.
  316. void X86AsmPrinter::PrintPCRelImm(const MachineInstr *MI, unsigned OpNo,
  317. raw_ostream &O) {
  318. const MachineOperand &MO = MI->getOperand(OpNo);
  319. switch (MO.getType()) {
  320. default: llvm_unreachable("Unknown pcrel immediate operand");
  321. case MachineOperand::MO_Register:
  322. // pc-relativeness was handled when computing the value in the reg.
  323. PrintOperand(MI, OpNo, O);
  324. return;
  325. case MachineOperand::MO_Immediate:
  326. O << MO.getImm();
  327. return;
  328. case MachineOperand::MO_GlobalAddress:
  329. PrintSymbolOperand(MO, O);
  330. return;
  331. }
  332. }
  333. void X86AsmPrinter::PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
  334. raw_ostream &O, const char *Modifier) {
  335. const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
  336. const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
  337. const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
  338. // If we really don't want to print out (rip), don't.
  339. bool HasBaseReg = BaseReg.getReg() != 0;
  340. if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
  341. BaseReg.getReg() == X86::RIP)
  342. HasBaseReg = false;
  343. // HasParenPart - True if we will print out the () part of the mem ref.
  344. bool HasParenPart = IndexReg.getReg() || HasBaseReg;
  345. switch (DispSpec.getType()) {
  346. default:
  347. llvm_unreachable("unknown operand type!");
  348. case MachineOperand::MO_Immediate: {
  349. int DispVal = DispSpec.getImm();
  350. if (DispVal || !HasParenPart)
  351. O << DispVal;
  352. break;
  353. }
  354. case MachineOperand::MO_GlobalAddress:
  355. case MachineOperand::MO_ConstantPoolIndex:
  356. PrintSymbolOperand(DispSpec, O);
  357. break;
  358. }
  359. if (Modifier && strcmp(Modifier, "H") == 0)
  360. O << "+8";
  361. if (HasParenPart) {
  362. assert(IndexReg.getReg() != X86::ESP &&
  363. "X86 doesn't allow scaling by ESP");
  364. O << '(';
  365. if (HasBaseReg)
  366. PrintModifiedOperand(MI, OpNo + X86::AddrBaseReg, O, Modifier);
  367. if (IndexReg.getReg()) {
  368. O << ',';
  369. PrintModifiedOperand(MI, OpNo + X86::AddrIndexReg, O, Modifier);
  370. unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
  371. if (ScaleVal != 1)
  372. O << ',' << ScaleVal;
  373. }
  374. O << ')';
  375. }
  376. }
  377. static bool isSimpleReturn(const MachineInstr &MI) {
  378. // We exclude all tail calls here which set both isReturn and isCall.
  379. return MI.getDesc().isReturn() && !MI.getDesc().isCall();
  380. }
  381. static bool isIndirectBranchOrTailCall(const MachineInstr &MI) {
  382. unsigned Opc = MI.getOpcode();
  383. return MI.getDesc().isIndirectBranch() /*Make below code in a good shape*/ ||
  384. Opc == X86::TAILJMPr || Opc == X86::TAILJMPm ||
  385. Opc == X86::TAILJMPr64 || Opc == X86::TAILJMPm64 ||
  386. Opc == X86::TCRETURNri || Opc == X86::TCRETURNmi ||
  387. Opc == X86::TCRETURNri64 || Opc == X86::TCRETURNmi64 ||
  388. Opc == X86::TAILJMPr64_REX || Opc == X86::TAILJMPm64_REX;
  389. }
  390. void X86AsmPrinter::emitBasicBlockEnd(const MachineBasicBlock &MBB) {
  391. if (Subtarget->hardenSlsRet() || Subtarget->hardenSlsIJmp()) {
  392. auto I = MBB.getLastNonDebugInstr();
  393. if (I != MBB.end()) {
  394. if ((Subtarget->hardenSlsRet() && isSimpleReturn(*I)) ||
  395. (Subtarget->hardenSlsIJmp() && isIndirectBranchOrTailCall(*I))) {
  396. MCInst TmpInst;
  397. TmpInst.setOpcode(X86::INT3);
  398. EmitToStreamer(*OutStreamer, TmpInst);
  399. }
  400. }
  401. }
  402. AsmPrinter::emitBasicBlockEnd(MBB);
  403. SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
  404. }
  405. void X86AsmPrinter::PrintMemReference(const MachineInstr *MI, unsigned OpNo,
  406. raw_ostream &O, const char *Modifier) {
  407. assert(isMem(*MI, OpNo) && "Invalid memory reference!");
  408. const MachineOperand &Segment = MI->getOperand(OpNo + X86::AddrSegmentReg);
  409. if (Segment.getReg()) {
  410. PrintModifiedOperand(MI, OpNo + X86::AddrSegmentReg, O, Modifier);
  411. O << ':';
  412. }
  413. PrintLeaMemReference(MI, OpNo, O, Modifier);
  414. }
  415. void X86AsmPrinter::PrintIntelMemReference(const MachineInstr *MI,
  416. unsigned OpNo, raw_ostream &O,
  417. const char *Modifier) {
  418. const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
  419. unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
  420. const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
  421. const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
  422. const MachineOperand &SegReg = MI->getOperand(OpNo + X86::AddrSegmentReg);
  423. // If we really don't want to print out (rip), don't.
  424. bool HasBaseReg = BaseReg.getReg() != 0;
  425. if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
  426. BaseReg.getReg() == X86::RIP)
  427. HasBaseReg = false;
  428. // If we really just want to print out displacement.
  429. if (Modifier && (DispSpec.isGlobal() || DispSpec.isSymbol()) &&
  430. !strcmp(Modifier, "disp-only")) {
  431. HasBaseReg = false;
  432. }
  433. // If this has a segment register, print it.
  434. if (SegReg.getReg()) {
  435. PrintOperand(MI, OpNo + X86::AddrSegmentReg, O);
  436. O << ':';
  437. }
  438. O << '[';
  439. bool NeedPlus = false;
  440. if (HasBaseReg) {
  441. PrintOperand(MI, OpNo + X86::AddrBaseReg, O);
  442. NeedPlus = true;
  443. }
  444. if (IndexReg.getReg()) {
  445. if (NeedPlus) O << " + ";
  446. if (ScaleVal != 1)
  447. O << ScaleVal << '*';
  448. PrintOperand(MI, OpNo + X86::AddrIndexReg, O);
  449. NeedPlus = true;
  450. }
  451. if (!DispSpec.isImm()) {
  452. if (NeedPlus) O << " + ";
  453. PrintOperand(MI, OpNo + X86::AddrDisp, O);
  454. } else {
  455. int64_t DispVal = DispSpec.getImm();
  456. if (DispVal || (!IndexReg.getReg() && !HasBaseReg)) {
  457. if (NeedPlus) {
  458. if (DispVal > 0)
  459. O << " + ";
  460. else {
  461. O << " - ";
  462. DispVal = -DispVal;
  463. }
  464. }
  465. O << DispVal;
  466. }
  467. }
  468. O << ']';
  469. }
  470. static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO,
  471. char Mode, raw_ostream &O) {
  472. Register Reg = MO.getReg();
  473. bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
  474. if (!X86::GR8RegClass.contains(Reg) &&
  475. !X86::GR16RegClass.contains(Reg) &&
  476. !X86::GR32RegClass.contains(Reg) &&
  477. !X86::GR64RegClass.contains(Reg))
  478. return true;
  479. switch (Mode) {
  480. default: return true; // Unknown mode.
  481. case 'b': // Print QImode register
  482. Reg = getX86SubSuperRegister(Reg, 8);
  483. break;
  484. case 'h': // Print QImode high register
  485. Reg = getX86SubSuperRegister(Reg, 8, true);
  486. break;
  487. case 'w': // Print HImode register
  488. Reg = getX86SubSuperRegister(Reg, 16);
  489. break;
  490. case 'k': // Print SImode register
  491. Reg = getX86SubSuperRegister(Reg, 32);
  492. break;
  493. case 'V':
  494. EmitPercent = false;
  495. [[fallthrough]];
  496. case 'q':
  497. // Print 64-bit register names if 64-bit integer registers are available.
  498. // Otherwise, print 32-bit register names.
  499. Reg = getX86SubSuperRegister(Reg, P.getSubtarget().is64Bit() ? 64 : 32);
  500. break;
  501. }
  502. if (EmitPercent)
  503. O << '%';
  504. O << X86ATTInstPrinter::getRegisterName(Reg);
  505. return false;
  506. }
  507. static bool printAsmVRegister(const MachineOperand &MO, char Mode,
  508. raw_ostream &O) {
  509. Register Reg = MO.getReg();
  510. bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
  511. unsigned Index;
  512. if (X86::VR128XRegClass.contains(Reg))
  513. Index = Reg - X86::XMM0;
  514. else if (X86::VR256XRegClass.contains(Reg))
  515. Index = Reg - X86::YMM0;
  516. else if (X86::VR512RegClass.contains(Reg))
  517. Index = Reg - X86::ZMM0;
  518. else
  519. return true;
  520. switch (Mode) {
  521. default: // Unknown mode.
  522. return true;
  523. case 'x': // Print V4SFmode register
  524. Reg = X86::XMM0 + Index;
  525. break;
  526. case 't': // Print V8SFmode register
  527. Reg = X86::YMM0 + Index;
  528. break;
  529. case 'g': // Print V16SFmode register
  530. Reg = X86::ZMM0 + Index;
  531. break;
  532. }
  533. if (EmitPercent)
  534. O << '%';
  535. O << X86ATTInstPrinter::getRegisterName(Reg);
  536. return false;
  537. }
  538. /// PrintAsmOperand - Print out an operand for an inline asm expression.
  539. ///
  540. bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
  541. const char *ExtraCode, raw_ostream &O) {
  542. // Does this asm operand have a single letter operand modifier?
  543. if (ExtraCode && ExtraCode[0]) {
  544. if (ExtraCode[1] != 0) return true; // Unknown modifier.
  545. const MachineOperand &MO = MI->getOperand(OpNo);
  546. switch (ExtraCode[0]) {
  547. default:
  548. // See if this is a generic print operand
  549. return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
  550. case 'a': // This is an address. Currently only 'i' and 'r' are expected.
  551. switch (MO.getType()) {
  552. default:
  553. return true;
  554. case MachineOperand::MO_Immediate:
  555. O << MO.getImm();
  556. return false;
  557. case MachineOperand::MO_ConstantPoolIndex:
  558. case MachineOperand::MO_JumpTableIndex:
  559. case MachineOperand::MO_ExternalSymbol:
  560. llvm_unreachable("unexpected operand type!");
  561. case MachineOperand::MO_GlobalAddress:
  562. PrintSymbolOperand(MO, O);
  563. if (Subtarget->isPICStyleRIPRel())
  564. O << "(%rip)";
  565. return false;
  566. case MachineOperand::MO_Register:
  567. O << '(';
  568. PrintOperand(MI, OpNo, O);
  569. O << ')';
  570. return false;
  571. }
  572. case 'c': // Don't print "$" before a global var name or constant.
  573. switch (MO.getType()) {
  574. default:
  575. PrintOperand(MI, OpNo, O);
  576. break;
  577. case MachineOperand::MO_Immediate:
  578. O << MO.getImm();
  579. break;
  580. case MachineOperand::MO_ConstantPoolIndex:
  581. case MachineOperand::MO_JumpTableIndex:
  582. case MachineOperand::MO_ExternalSymbol:
  583. llvm_unreachable("unexpected operand type!");
  584. case MachineOperand::MO_GlobalAddress:
  585. PrintSymbolOperand(MO, O);
  586. break;
  587. }
  588. return false;
  589. case 'A': // Print '*' before a register (it must be a register)
  590. if (MO.isReg()) {
  591. O << '*';
  592. PrintOperand(MI, OpNo, O);
  593. return false;
  594. }
  595. return true;
  596. case 'b': // Print QImode register
  597. case 'h': // Print QImode high register
  598. case 'w': // Print HImode register
  599. case 'k': // Print SImode register
  600. case 'q': // Print DImode register
  601. case 'V': // Print native register without '%'
  602. if (MO.isReg())
  603. return printAsmMRegister(*this, MO, ExtraCode[0], O);
  604. PrintOperand(MI, OpNo, O);
  605. return false;
  606. case 'x': // Print V4SFmode register
  607. case 't': // Print V8SFmode register
  608. case 'g': // Print V16SFmode register
  609. if (MO.isReg())
  610. return printAsmVRegister(MO, ExtraCode[0], O);
  611. PrintOperand(MI, OpNo, O);
  612. return false;
  613. case 'P': // This is the operand of a call, treat specially.
  614. PrintPCRelImm(MI, OpNo, O);
  615. return false;
  616. case 'n': // Negate the immediate or print a '-' before the operand.
  617. // Note: this is a temporary solution. It should be handled target
  618. // independently as part of the 'MC' work.
  619. if (MO.isImm()) {
  620. O << -MO.getImm();
  621. return false;
  622. }
  623. O << '-';
  624. }
  625. }
  626. PrintOperand(MI, OpNo, O);
  627. return false;
  628. }
  629. bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
  630. const char *ExtraCode,
  631. raw_ostream &O) {
  632. if (ExtraCode && ExtraCode[0]) {
  633. if (ExtraCode[1] != 0) return true; // Unknown modifier.
  634. switch (ExtraCode[0]) {
  635. default: return true; // Unknown modifier.
  636. case 'b': // Print QImode register
  637. case 'h': // Print QImode high register
  638. case 'w': // Print HImode register
  639. case 'k': // Print SImode register
  640. case 'q': // Print SImode register
  641. // These only apply to registers, ignore on mem.
  642. break;
  643. case 'H':
  644. if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
  645. return true; // Unsupported modifier in Intel inline assembly.
  646. } else {
  647. PrintMemReference(MI, OpNo, O, "H");
  648. }
  649. return false;
  650. // Print memory only with displacement. The Modifer 'P' is used in inline
  651. // asm to present a call symbol or a global symbol which can not use base
  652. // reg or index reg.
  653. case 'P':
  654. if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
  655. PrintIntelMemReference(MI, OpNo, O, "disp-only");
  656. } else {
  657. PrintMemReference(MI, OpNo, O, "disp-only");
  658. }
  659. return false;
  660. }
  661. }
  662. if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
  663. PrintIntelMemReference(MI, OpNo, O, nullptr);
  664. } else {
  665. PrintMemReference(MI, OpNo, O, nullptr);
  666. }
  667. return false;
  668. }
  669. void X86AsmPrinter::emitStartOfAsmFile(Module &M) {
  670. const Triple &TT = TM.getTargetTriple();
  671. if (TT.isOSBinFormatELF()) {
  672. // Assemble feature flags that may require creation of a note section.
  673. unsigned FeatureFlagsAnd = 0;
  674. if (M.getModuleFlag("cf-protection-branch"))
  675. FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_IBT;
  676. if (M.getModuleFlag("cf-protection-return"))
  677. FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_SHSTK;
  678. if (FeatureFlagsAnd) {
  679. // Emit a .note.gnu.property section with the flags.
  680. if (!TT.isArch32Bit() && !TT.isArch64Bit())
  681. llvm_unreachable("CFProtection used on invalid architecture!");
  682. MCSection *Cur = OutStreamer->getCurrentSectionOnly();
  683. MCSection *Nt = MMI->getContext().getELFSection(
  684. ".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
  685. OutStreamer->switchSection(Nt);
  686. // Emitting note header.
  687. const int WordSize = TT.isArch64Bit() && !TT.isX32() ? 8 : 4;
  688. emitAlignment(WordSize == 4 ? Align(4) : Align(8));
  689. OutStreamer->emitIntValue(4, 4 /*size*/); // data size for "GNU\0"
  690. OutStreamer->emitIntValue(8 + WordSize, 4 /*size*/); // Elf_Prop size
  691. OutStreamer->emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4 /*size*/);
  692. OutStreamer->emitBytes(StringRef("GNU", 4)); // note name
  693. // Emitting an Elf_Prop for the CET properties.
  694. OutStreamer->emitInt32(ELF::GNU_PROPERTY_X86_FEATURE_1_AND);
  695. OutStreamer->emitInt32(4); // data size
  696. OutStreamer->emitInt32(FeatureFlagsAnd); // data
  697. emitAlignment(WordSize == 4 ? Align(4) : Align(8)); // padding
  698. OutStreamer->endSection(Nt);
  699. OutStreamer->switchSection(Cur);
  700. }
  701. }
  702. if (TT.isOSBinFormatMachO())
  703. OutStreamer->switchSection(getObjFileLowering().getTextSection());
  704. if (TT.isOSBinFormatCOFF()) {
  705. // Emit an absolute @feat.00 symbol.
  706. MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
  707. OutStreamer->beginCOFFSymbolDef(S);
  708. OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
  709. OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
  710. OutStreamer->endCOFFSymbolDef();
  711. int64_t Feat00Value = 0;
  712. if (TT.getArch() == Triple::x86) {
  713. // According to the PE-COFF spec, the LSB of this value marks the object
  714. // for "registered SEH". This means that all SEH handler entry points
  715. // must be registered in .sxdata. Use of any unregistered handlers will
  716. // cause the process to terminate immediately. LLVM does not know how to
  717. // register any SEH handlers, so its object files should be safe.
  718. Feat00Value |= COFF::Feat00Flags::SafeSEH;
  719. }
  720. if (M.getModuleFlag("cfguard")) {
  721. // Object is CFG-aware.
  722. Feat00Value |= COFF::Feat00Flags::GuardCF;
  723. }
  724. if (M.getModuleFlag("ehcontguard")) {
  725. // Object also has EHCont.
  726. Feat00Value |= COFF::Feat00Flags::GuardEHCont;
  727. }
  728. if (M.getModuleFlag("ms-kernel")) {
  729. // Object is compiled with /kernel.
  730. Feat00Value |= COFF::Feat00Flags::Kernel;
  731. }
  732. OutStreamer->emitSymbolAttribute(S, MCSA_Global);
  733. OutStreamer->emitAssignment(
  734. S, MCConstantExpr::create(Feat00Value, MMI->getContext()));
  735. }
  736. OutStreamer->emitSyntaxDirective();
  737. // If this is not inline asm and we're in 16-bit
  738. // mode prefix assembly with .code16.
  739. bool is16 = TT.getEnvironment() == Triple::CODE16;
  740. if (M.getModuleInlineAsm().empty() && is16)
  741. OutStreamer->emitAssemblerFlag(MCAF_Code16);
  742. }
  743. static void
  744. emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
  745. MachineModuleInfoImpl::StubValueTy &MCSym) {
  746. // L_foo$stub:
  747. OutStreamer.emitLabel(StubLabel);
  748. // .indirect_symbol _foo
  749. OutStreamer.emitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
  750. if (MCSym.getInt())
  751. // External to current translation unit.
  752. OutStreamer.emitIntValue(0, 4/*size*/);
  753. else
  754. // Internal to current translation unit.
  755. //
  756. // When we place the LSDA into the TEXT section, the type info
  757. // pointers need to be indirect and pc-rel. We accomplish this by
  758. // using NLPs; however, sometimes the types are local to the file.
  759. // We need to fill in the value for the NLP in those cases.
  760. OutStreamer.emitValue(
  761. MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
  762. 4 /*size*/);
  763. }
  764. static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
  765. MachineModuleInfoMachO &MMIMacho =
  766. MMI->getObjFileInfo<MachineModuleInfoMachO>();
  767. // Output stubs for dynamically-linked functions.
  768. MachineModuleInfoMachO::SymbolListTy Stubs;
  769. // Output stubs for external and common global variables.
  770. Stubs = MMIMacho.GetGVStubList();
  771. if (!Stubs.empty()) {
  772. OutStreamer.switchSection(MMI->getContext().getMachOSection(
  773. "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
  774. SectionKind::getMetadata()));
  775. for (auto &Stub : Stubs)
  776. emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
  777. Stubs.clear();
  778. OutStreamer.addBlankLine();
  779. }
  780. }
  781. void X86AsmPrinter::emitEndOfAsmFile(Module &M) {
  782. const Triple &TT = TM.getTargetTriple();
  783. if (TT.isOSBinFormatMachO()) {
  784. // Mach-O uses non-lazy symbol stubs to encode per-TU information into
  785. // global table for symbol lookup.
  786. emitNonLazyStubs(MMI, *OutStreamer);
  787. // Emit fault map information.
  788. FM.serializeToFaultMapSection();
  789. // This flag tells the linker that no global symbols contain code that fall
  790. // through to other global symbols (e.g. an implementation of multiple entry
  791. // points). If this doesn't occur, the linker can safely perform dead code
  792. // stripping. Since LLVM never generates code that does this, it is always
  793. // safe to set.
  794. OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
  795. } else if (TT.isOSBinFormatCOFF()) {
  796. if (MMI->usesMSVCFloatingPoint()) {
  797. // In Windows' libcmt.lib, there is a file which is linked in only if the
  798. // symbol _fltused is referenced. Linking this in causes some
  799. // side-effects:
  800. //
  801. // 1. For x86-32, it will set the x87 rounding mode to 53-bit instead of
  802. // 64-bit mantissas at program start.
  803. //
  804. // 2. It links in support routines for floating-point in scanf and printf.
  805. //
  806. // MSVC emits an undefined reference to _fltused when there are any
  807. // floating point operations in the program (including calls). A program
  808. // that only has: `scanf("%f", &global_float);` may fail to trigger this,
  809. // but oh well...that's a documented issue.
  810. StringRef SymbolName =
  811. (TT.getArch() == Triple::x86) ? "__fltused" : "_fltused";
  812. MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
  813. OutStreamer->emitSymbolAttribute(S, MCSA_Global);
  814. return;
  815. }
  816. } else if (TT.isOSBinFormatELF()) {
  817. FM.serializeToFaultMapSection();
  818. }
  819. // Emit __morestack address if needed for indirect calls.
  820. if (TT.getArch() == Triple::x86_64 && TM.getCodeModel() == CodeModel::Large) {
  821. if (MCSymbol *AddrSymbol = OutContext.lookupSymbol("__morestack_addr")) {
  822. Align Alignment(1);
  823. MCSection *ReadOnlySection = getObjFileLowering().getSectionForConstant(
  824. getDataLayout(), SectionKind::getReadOnly(),
  825. /*C=*/nullptr, Alignment);
  826. OutStreamer->switchSection(ReadOnlySection);
  827. OutStreamer->emitLabel(AddrSymbol);
  828. unsigned PtrSize = MAI->getCodePointerSize();
  829. OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("__morestack"),
  830. PtrSize);
  831. }
  832. }
  833. }
  834. //===----------------------------------------------------------------------===//
  835. // Target Registry Stuff
  836. //===----------------------------------------------------------------------===//
  837. // Force static initialization.
  838. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86AsmPrinter() {
  839. RegisterAsmPrinter<X86AsmPrinter> X(getTheX86_32Target());
  840. RegisterAsmPrinter<X86AsmPrinter> Y(getTheX86_64Target());
  841. }