LLVM  12.0.0git
DwarfCFIException.cpp
Go to the documentation of this file.
1 //===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//
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 support for writing DWARF exception info into asm files.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "DwarfException.h"
14 #include "llvm/ADT/Twine.h"
19 #include "llvm/IR/DataLayout.h"
20 #include "llvm/IR/Mangler.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/MC/MCAsmInfo.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCExpr.h"
25 #include "llvm/MC/MCSection.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSymbol.h"
34 using namespace llvm;
35 
37  : EHStreamer(A), shouldEmitCFI(false), hasEmittedCFISections(false) {}
38 
40  endFragment();
41 
42  // Map all labels and get rid of any dead landing pads.
43  if (!Asm->MF->getLandingPads().empty()) {
44  MachineFunction *NonConstMF = const_cast<MachineFunction*>(Asm->MF);
45  NonConstMF->tidyLandingPads();
46  }
47 }
48 
50  if (shouldEmitCFI && !Asm->MF->hasBBSections())
51  Asm->OutStreamer->emitCFIEndProc();
52 }
53 
55  : DwarfCFIExceptionBase(A), shouldEmitPersonality(false),
56  forceEmitPersonality(false), shouldEmitLSDA(false),
57  shouldEmitMoves(false) {}
58 
60 
61 /// endModule - Emit all exception information that should come after the
62 /// content.
64  // SjLj uses this pass and it doesn't need this info.
65  if (!Asm->MAI->usesCFIForEH())
66  return;
67 
69 
70  unsigned PerEncoding = TLOF.getPersonalityEncoding();
71 
72  if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)
73  return;
74 
75  // Emit references to all used personality functions
76  for (const Function *Personality : MMI->getPersonalities()) {
77  if (!Personality)
78  continue;
79  MCSymbol *Sym = Asm->getSymbol(Personality);
81  }
82 }
83 
85  const MachineBasicBlock *MBB) {
86  return Asm->getMBBExceptionSym(*MBB);
87 }
88 
90  shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
91  const Function &F = MF->getFunction();
92 
93  // If any landing pads survive, we need an EH table.
94  bool hasLandingPads = !MF->getLandingPads().empty();
95 
96  // See if we need frame move info.
98 
99  shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None;
100 
102  unsigned PerEncoding = TLOF.getPersonalityEncoding();
103  const Function *Per = nullptr;
104  if (F.hasPersonalityFn())
105  Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
106 
107  // Emit a personality function even when there are no landing pads
108  forceEmitPersonality =
109  // ...if a personality function is explicitly specified
110  F.hasPersonalityFn() &&
111  // ... and it's not known to be a noop in the absence of invokes
113  // ... and we're not explicitly asked not to emit it
114  F.needsUnwindTableEntry();
115 
116  shouldEmitPersonality =
117  (forceEmitPersonality ||
118  (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
119  Per;
120 
121  unsigned LSDAEncoding = TLOF.getLSDAEncoding();
122  shouldEmitLSDA = shouldEmitPersonality &&
123  LSDAEncoding != dwarf::DW_EH_PE_omit;
124 
126  (shouldEmitPersonality || shouldEmitMoves);
128 }
129 
132  if (!shouldEmitCFI)
133  return;
134 
135  if (!hasEmittedCFISections) {
137  Asm->OutStreamer->emitCFISections(false, true);
139  Asm->OutStreamer->emitCFISections(true, true);
140  hasEmittedCFISections = true;
141  }
142 
143  Asm->OutStreamer->emitCFIStartProc(/*IsSimple=*/false);
144 
145  // Indicate personality routine, if any.
146  if (!shouldEmitPersonality)
147  return;
148 
149  auto &F = MBB->getParent()->getFunction();
150  auto *P = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
151  assert(P && "Expected personality function");
152 
153  // If we are forced to emit this personality, make sure to record
154  // it because it might not appear in any landingpad
155  if (forceEmitPersonality)
156  MMI->addPersonality(P);
157 
159  unsigned PerEncoding = TLOF.getPersonalityEncoding();
160  const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);
161  Asm->OutStreamer->emitCFIPersonality(Sym, PerEncoding);
162 
163  // Provide LSDA information.
164  if (shouldEmitLSDA)
165  Asm->OutStreamer->emitCFILsda(ESP(Asm, MBB), TLOF.getLSDAEncoding());
166 }
167 
168 /// endFunction - Gather and emit post-function exception information.
169 ///
171  if (!shouldEmitPersonality)
172  return;
173 
175 }
176 
179 }
180 
182  if (shouldEmitCFI)
183  Asm->OutStreamer->emitCFIEndProc();
184 }
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:368
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:222
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:97
This class represents lattice values for constants.
Definition: AllocatorList.h:23
virtual void emitPersonalityValue(MCStreamer &Streamer, const DataLayout &TM, const MCSymbol *Sym) const
static MCSymbol * getExceptionSym(AsmPrinter *Asm, const MachineBasicBlock *MBB)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
bool needsOnlyDebugCFIMoves() const
Returns false if needsCFIMoves() == CFI_M_EH for any function in the module.
Definition: AsmPrinter.h:377
CFIMoveType needsCFIMoves() const
void beginFragment(const MachineBasicBlock *MBB, ExceptionSymbolProvider ESP) override
bool shouldEmitCFI
Per-function flag to indicate if frame CFI info should be emitted.
F(f)
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:100
MachineModuleInfo & getMMI() const
void endBasicBlock(const MachineBasicBlock &MBB) override
Process end of a basic block during basic block sections.
DwarfCFIException(AsmPrinter *A)
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineBasicBlock & MBB
MachineModuleInfo * MMI
Collected machine module information.
Definition: EHStreamer.h:36
MCSymbol * ExceptionSymbolProvider(AsmPrinter *Asm, const MachineBasicBlock *MBB)
Emits exception handling directives.
Definition: EHStreamer.h:30
void endFunction(const MachineFunction *) override
Gather and emit post-function exception information.
bool hasBBSections() const
Returns true if this function has basic block sections enabled.
void tidyLandingPads(DenseMap< MCSymbol *, uintptr_t > *LPMap=nullptr, bool TidyIfNoBeginLabels=true)
Remap landing pad labels and remove any deleted landing pads.
const MCContext & getContext() const
void beginBasicBlock(const MachineBasicBlock &MBB) override
Process beginning of a basic block during basic block sections.
void beginFunction(const MachineFunction *MF) override
Gather pre-function exception information.
#define P(N)
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:88
void addPersonality(const Function *Personality)
Provide the personality function for the exception information.
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:85
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:82
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
unsigned ForceDwarfFrameSection
Emit DWARF debug frame section.
AsmPrinter * Asm
Target of directive emission.
Definition: EHStreamer.h:33
bool hasEmittedCFISections
Per-module flag to indicate if .cfi_section has beeen emitted.
const std::vector< LandingPadInfo > & getLandingPads() const
Return a reference to the landing pad info for the current function.
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:472
Module.h This file contains the declarations for the Module class.
bool usesCFIForEH() const
Returns true if the exception handling method for the platform uses call frame information to unwind.
Definition: MCAsmInfo.h:648
This file contains constants used for implementing Dwarf debug support.
void endModule() override
Emit all exception information that should come after the content.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
TargetOptions Options
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCSymbol * emitExceptionTable()
Emit landing pads and actions.
Definition: EHStreamer.cpp:381
const std::vector< const Function * > & getPersonalities() const
Return array of personality functions ever seen.
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:226
virtual MCSymbol * getCFIPersonalitySymbol(const GlobalValue *GV, const TargetMachine &TM, MachineModuleInfo *MMI) const
bool isNoOpWithoutInvoke(EHPersonality Pers)
Return true if this personality may be safely removed if there are no invoke instructions remaining i...