Win64Exception.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//===-- CodeGen/AsmPrinter/Win64Exception.cpp - Dwarf Exception Impl ------===//
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//                     The LLVM Compiler Infrastructure
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// License. See LICENSE.TXT for details.
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//===----------------------------------------------------------------------===//
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This file contains support for writing Win64 exception info into asm files.
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//===----------------------------------------------------------------------===//
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "DwarfException.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/ADT/SmallString.h"
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/ADT/StringExtras.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/ADT/Twine.h"
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/CodeGen/AsmPrinter.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/CodeGen/MachineFrameInfo.h"
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/CodeGen/MachineFunction.h"
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/CodeGen/MachineModuleInfo.h"
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/IR/DataLayout.h"
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/IR/Mangler.h"
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/IR/Module.h"
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/MC/MCAsmInfo.h"
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/MC/MCContext.h"
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/MC/MCExpr.h"
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/MC/MCSection.h"
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/MC/MCStreamer.h"
30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/MC/MCSymbol.h"
31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/Support/Dwarf.h"
32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/Support/ErrorHandling.h"
33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/Support/FormattedStream.h"
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/Target/TargetFrameLowering.h"
35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/Target/TargetLoweringObjectFile.h"
36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/Target/TargetOptions.h"
37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "llvm/Target/TargetRegisterInfo.h"
38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)using namespace llvm;
39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Win64Exception::Win64Exception(AsmPrinter *A)
41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  : DwarfException(A),
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    shouldEmitPersonality(false), shouldEmitLSDA(false), shouldEmitMoves(false)
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    {}
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)Win64Exception::~Win64Exception() {}
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/// endModule - Emit all exception information that should come after the
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/// content.
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void Win64Exception::endModule() {
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/// beginFunction - Gather pre-function exception information. Assumes it's
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/// being emitted immediately after the function entry point.
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void Win64Exception::beginFunction(const MachineFunction *MF) {
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // If any landing pads survive, we need an EH table.
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool hasLandingPads = !MMI->getLandingPads().empty();
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  shouldEmitMoves = Asm->needsSEHMoves();
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  unsigned PerEncoding = TLOF.getPersonalityEncoding();
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()];
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  shouldEmitPersonality = hasLandingPads &&
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    PerEncoding != dwarf::DW_EH_PE_omit && Per;
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  unsigned LSDAEncoding = TLOF.getLSDAEncoding();
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  shouldEmitLSDA = shouldEmitPersonality &&
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    LSDAEncoding != dwarf::DW_EH_PE_omit;
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!shouldEmitPersonality && !shouldEmitMoves)
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Asm->OutStreamer.EmitWin64EHStartProc(Asm->CurrentFnSym);
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!shouldEmitPersonality)
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MCSymbol *GCCHandlerSym =
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Asm->GetExternalSymbolSymbol("_GCC_specific_handler");
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Asm->OutStreamer.EmitWin64EHHandler(GCCHandlerSym, true, true);
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                Asm->getFunctionNumber()));
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/// endFunction - Gather and emit post-function exception information.
90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)///
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void Win64Exception::endFunction(const MachineFunction *) {
92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!shouldEmitPersonality && !shouldEmitMoves)
93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                                Asm->getFunctionNumber()));
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Map all labels and get rid of any dead landing pads.
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  MMI->TidyLandingPads();
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (shouldEmitPersonality) {
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()];
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    const MCSymbol *Sym =
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Asm->OutStreamer.PushSection();
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Asm->OutStreamer.EmitWin64EHHandlerData();
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Asm->OutStreamer.EmitValue(MCSymbolRefExpr::Create(Sym, Asm->OutContext),
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                               4);
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EmitExceptionTable();
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    Asm->OutStreamer.PopSection();
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Asm->OutStreamer.EmitWin64EHEndProc();
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)