1 //===- MCWin64EH.h - Machine Code Win64 EH support --------------*- C++ -*-===// 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 declarations to support the Win64 Exception Handling 11 // scheme in MC. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_MC_MCWIN64EH_H 16 #define LLVM_MC_MCWIN64EH_H 17 18 #include "llvm/Support/Win64EH.h" 19 #include <cassert> 20 #include <vector> 21 22 namespace llvm { 23 class StringRef; 24 class MCStreamer; 25 class MCSymbol; 26 27 class MCWin64EHInstruction { 28 public: 29 typedef Win64EH::UnwindOpcodes OpType; 30 private: 31 OpType Operation; 32 MCSymbol *Label; 33 unsigned Offset; 34 unsigned Register; 35 public: MCWin64EHInstruction(OpType Op,MCSymbol * L,unsigned Reg)36 MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg) 37 : Operation(Op), Label(L), Offset(0), Register(Reg) { 38 assert(Op == Win64EH::UOP_PushNonVol); 39 } MCWin64EHInstruction(MCSymbol * L,unsigned Size)40 MCWin64EHInstruction(MCSymbol *L, unsigned Size) 41 : Operation(Size>128 ? Win64EH::UOP_AllocLarge : Win64EH::UOP_AllocSmall), 42 Label(L), Offset(Size) { } MCWin64EHInstruction(OpType Op,MCSymbol * L,unsigned Reg,unsigned Off)43 MCWin64EHInstruction(OpType Op, MCSymbol *L, unsigned Reg, unsigned Off) 44 : Operation(Op), Label(L), Offset(Off), Register(Reg) { 45 assert(Op == Win64EH::UOP_SetFPReg || 46 Op == Win64EH::UOP_SaveNonVol || 47 Op == Win64EH::UOP_SaveNonVolBig || 48 Op == Win64EH::UOP_SaveXMM128 || 49 Op == Win64EH::UOP_SaveXMM128Big); 50 } MCWin64EHInstruction(OpType Op,MCSymbol * L,bool Code)51 MCWin64EHInstruction(OpType Op, MCSymbol *L, bool Code) 52 : Operation(Op), Label(L), Offset(Code ? 1 : 0) { 53 assert(Op == Win64EH::UOP_PushMachFrame); 54 } getOperation()55 OpType getOperation() const { return Operation; } getLabel()56 MCSymbol *getLabel() const { return Label; } getOffset()57 unsigned getOffset() const { return Offset; } getSize()58 unsigned getSize() const { return Offset; } getRegister()59 unsigned getRegister() const { return Register; } isPushCodeFrame()60 bool isPushCodeFrame() const { return Offset == 1; } 61 }; 62 63 struct MCWin64EHUnwindInfo { MCWin64EHUnwindInfoMCWin64EHUnwindInfo64 MCWin64EHUnwindInfo() 65 : Begin(nullptr), End(nullptr),ExceptionHandler(nullptr), 66 Function(nullptr), PrologEnd(nullptr), Symbol(nullptr), 67 HandlesUnwind(false), HandlesExceptions(false), LastFrameInst(-1), 68 ChainedParent(nullptr), Instructions() {} 69 MCSymbol *Begin; 70 MCSymbol *End; 71 const MCSymbol *ExceptionHandler; 72 const MCSymbol *Function; 73 MCSymbol *PrologEnd; 74 MCSymbol *Symbol; 75 bool HandlesUnwind; 76 bool HandlesExceptions; 77 int LastFrameInst; 78 MCWin64EHUnwindInfo *ChainedParent; 79 std::vector<MCWin64EHInstruction> Instructions; 80 }; 81 82 class MCWin64EHUnwindEmitter { 83 public: 84 static StringRef GetSectionSuffix(const MCSymbol *func); 85 // 86 // This emits the unwind info sections (.pdata and .xdata in PE/COFF). 87 // 88 static void Emit(MCStreamer &streamer); 89 static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info); 90 }; 91 } // end namespace llvm 92 93 #endif 94