brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · e02b556 Raw
202 lines · c
1//===-- X86AsmPrinter.h - X86 implementation of AsmPrinter ------*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIB_TARGET_X86_X86ASMPRINTER_H10#define LLVM_LIB_TARGET_X86_X86ASMPRINTER_H11 12#include "llvm/CodeGen/AsmPrinter.h"13#include "llvm/CodeGen/FaultMaps.h"14#include "llvm/CodeGen/StackMaps.h"15 16// Implemented in X86MCInstLower.cpp17namespace {18  class X86MCInstLower;19}20 21namespace llvm {22class MCCodeEmitter;23class MCStreamer;24class X86Subtarget;25class TargetMachine;26 27class LLVM_LIBRARY_VISIBILITY X86AsmPrinter : public AsmPrinter {28public:29  static char ID;30 31private:32  const X86Subtarget *Subtarget = nullptr;33  FaultMaps FM;34  std::unique_ptr<MCCodeEmitter> CodeEmitter;35  bool EmitFPOData = false;36  bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false;37  bool IndCSPrefix = false;38  bool EnableImportCallOptimization = false;39 40  enum ImportCallKind : unsigned {41    IMAGE_RETPOLINE_AMD64_IMPORT_BR = 0x02,42    IMAGE_RETPOLINE_AMD64_IMPORT_CALL = 0x03,43    IMAGE_RETPOLINE_AMD64_INDIR_BR = 0x04,44    IMAGE_RETPOLINE_AMD64_INDIR_CALL = 0x05,45    IMAGE_RETPOLINE_AMD64_INDIR_BR_REX = 0x06,46    IMAGE_RETPOLINE_AMD64_CFG_BR = 0x08,47    IMAGE_RETPOLINE_AMD64_CFG_CALL = 0x09,48    IMAGE_RETPOLINE_AMD64_CFG_BR_REX = 0x0A,49    IMAGE_RETPOLINE_AMD64_SWITCHTABLE_FIRST = 0x010,50    IMAGE_RETPOLINE_AMD64_SWITCHTABLE_LAST = 0x01F,51  };52  struct ImportCallInfo {53    MCSymbol *CalleeSymbol;54    ImportCallKind Kind;55  };56  DenseMap<MCSection *, std::vector<ImportCallInfo>>57      SectionToImportedFunctionCalls;58 59  // This utility class tracks the length of a stackmap instruction's 'shadow'.60  // It is used by the X86AsmPrinter to ensure that the stackmap shadow61  // invariants (i.e. no other stackmaps, patchpoints, or control flow within62  // the shadow) are met, while outputting a minimal number of NOPs for padding.63  //64  // To minimise the number of NOPs used, the shadow tracker counts the number65  // of instruction bytes output since the last stackmap. Only if there are too66  // few instruction bytes to cover the shadow are NOPs used for padding.67  class StackMapShadowTracker {68  public:69    void startFunction(MachineFunction &MF) {70      this->MF = &MF;71    }72    void count(const MCInst &Inst, const MCSubtargetInfo &STI,73               MCCodeEmitter *CodeEmitter);74 75    // Called to signal the start of a shadow of RequiredSize bytes.76    void reset(unsigned RequiredSize) {77      RequiredShadowSize = RequiredSize;78      CurrentShadowSize = 0;79      InShadow = true;80    }81 82    // Called before every stackmap/patchpoint, and at the end of basic blocks,83    // to emit any necessary padding-NOPs.84    void emitShadowPadding(MCStreamer &OutStreamer, const MCSubtargetInfo &STI);85  private:86    const MachineFunction *MF = nullptr;87    bool InShadow = false;88 89    // RequiredShadowSize holds the length of the shadow specified in the most90    // recently encountered STACKMAP instruction.91    // CurrentShadowSize counts the number of bytes encoded since the most92    // recently encountered STACKMAP, stopping when that number is greater than93    // or equal to RequiredShadowSize.94    unsigned RequiredShadowSize = 0, CurrentShadowSize = 0;95  };96 97  StackMapShadowTracker SMShadowTracker;98 99  // All instructions emitted by the X86AsmPrinter should use this helper100  // method.101  //102  // This helper function invokes the SMShadowTracker on each instruction before103  // outputting it to the OutStream. This allows the shadow tracker to minimise104  // the number of NOPs used for stackmap padding.105  void EmitAndCountInstruction(MCInst &Inst);106  void LowerSTACKMAP(const MachineInstr &MI);107  void LowerPATCHPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);108  void LowerSTATEPOINT(const MachineInstr &MI, X86MCInstLower &MCIL);109  void LowerFAULTING_OP(const MachineInstr &MI, X86MCInstLower &MCIL);110  void LowerPATCHABLE_OP(const MachineInstr &MI, X86MCInstLower &MCIL);111 112  void LowerTlsAddr(X86MCInstLower &MCInstLowering, const MachineInstr &MI);113 114  // XRay-specific lowering for X86.115  void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI,116                                     X86MCInstLower &MCIL);117  void LowerPATCHABLE_RET(const MachineInstr &MI, X86MCInstLower &MCIL);118  void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);119  void LowerPATCHABLE_EVENT_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);120  void LowerPATCHABLE_TYPED_EVENT_CALL(const MachineInstr &MI,121                                       X86MCInstLower &MCIL);122 123  void LowerFENTRY_CALL(const MachineInstr &MI, X86MCInstLower &MCIL);124 125  // KCFI specific lowering for X86.126  uint32_t MaskKCFIType(uint32_t Value);127  void EmitKCFITypePadding(const MachineFunction &MF, bool HasType = true);128  void LowerKCFI_CHECK(const MachineInstr &MI);129 130  // Address sanitizer specific lowering for X86.131  void LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI);132 133  // Choose between emitting .seh_ directives and .cv_fpo_ directives.134  void EmitSEHInstruction(const MachineInstr *MI);135 136  void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;137  void PrintOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);138  void PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,139                            raw_ostream &O, StringRef Modifier = {});140  void PrintPCRelImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);141  void PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,142                            raw_ostream &O, StringRef Modifier = {});143  void PrintMemReference(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,144                         StringRef Modifier = {});145  void PrintIntelMemReference(const MachineInstr *MI, unsigned OpNo,146                              raw_ostream &O, StringRef Modifier = {});147  const MCSubtargetInfo *getIFuncMCSubtargetInfo() const override;148  void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI,149                              MCSymbol *LazyPointer) override;150  void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI,151                                    MCSymbol *LazyPointer) override;152 153  void emitCallInstruction(const llvm::MCInst &MCI);154  void maybeEmitNopAfterCallForWindowsEH(const MachineInstr *MI);155 156  // Emits a label to mark the next instruction as being relevant to Import Call157  // Optimization.158  void emitLabelAndRecordForImportCallOptimization(ImportCallKind Kind);159 160public:161  X86AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);162 163  StringRef getPassName() const override {164    return "X86 Assembly Printer";165  }166 167  const X86Subtarget &getSubtarget() const { return *Subtarget; }168 169  void emitStartOfAsmFile(Module &M) override;170 171  void emitEndOfAsmFile(Module &M) override;172 173  void emitInstruction(const MachineInstr *MI) override;174 175  void emitBasicBlockEnd(const MachineBasicBlock &MBB) override;176 177  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,178                       const char *ExtraCode, raw_ostream &O) override;179  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,180                             const char *ExtraCode, raw_ostream &O) override;181 182  bool doInitialization(Module &M) override {183    SMShadowTracker.reset(0);184    SM.reset();185    FM.reset();186    return AsmPrinter::doInitialization(M);187  }188 189  bool runOnMachineFunction(MachineFunction &MF) override;190  void emitFunctionBodyStart() override;191  void emitFunctionBodyEnd() override;192  void emitKCFITypeId(const MachineFunction &MF) override;193 194  bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override {195    return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;196  }197};198 199} // end namespace llvm200 201#endif202