Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
35271 views
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/BinaryFormat/Dwarf.h"
15
#include "llvm/CodeGen/AsmPrinter.h"
16
#include "llvm/CodeGen/MachineFunction.h"
17
#include "llvm/CodeGen/MachineModuleInfo.h"
18
#include "llvm/IR/Function.h"
19
#include "llvm/MC/MCAsmInfo.h"
20
#include "llvm/MC/MCContext.h"
21
#include "llvm/MC/MCStreamer.h"
22
#include "llvm/Target/TargetLoweringObjectFile.h"
23
#include "llvm/Target/TargetMachine.h"
24
#include "llvm/Target/TargetOptions.h"
25
using namespace llvm;
26
27
DwarfCFIException::DwarfCFIException(AsmPrinter *A) : EHStreamer(A) {}
28
29
DwarfCFIException::~DwarfCFIException() = default;
30
31
void DwarfCFIException::addPersonality(const GlobalValue *Personality) {
32
if (!llvm::is_contained(Personalities, Personality))
33
Personalities.push_back(Personality);
34
}
35
36
/// endModule - Emit all exception information that should come after the
37
/// content.
38
void DwarfCFIException::endModule() {
39
// SjLj uses this pass and it doesn't need this info.
40
if (!Asm->MAI->usesCFIForEH())
41
return;
42
43
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
44
45
unsigned PerEncoding = TLOF.getPersonalityEncoding();
46
47
if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)
48
return;
49
50
// Emit indirect reference table for all used personality functions
51
for (const GlobalValue *Personality : Personalities) {
52
MCSymbol *Sym = Asm->getSymbol(Personality);
53
TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym);
54
}
55
Personalities.clear();
56
}
57
58
void DwarfCFIException::beginFunction(const MachineFunction *MF) {
59
shouldEmitPersonality = shouldEmitLSDA = false;
60
const Function &F = MF->getFunction();
61
62
// If any landing pads survive, we need an EH table.
63
bool hasLandingPads = !MF->getLandingPads().empty();
64
65
// See if we need frame move info.
66
bool shouldEmitMoves =
67
Asm->getFunctionCFISectionType(*MF) != AsmPrinter::CFISection::None;
68
69
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
70
unsigned PerEncoding = TLOF.getPersonalityEncoding();
71
const GlobalValue *Per = nullptr;
72
if (F.hasPersonalityFn())
73
Per = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
74
75
// Emit a personality function even when there are no landing pads
76
forceEmitPersonality =
77
// ...if a personality function is explicitly specified
78
F.hasPersonalityFn() &&
79
// ... and it's not known to be a noop in the absence of invokes
80
!isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
81
// ... and we're not explicitly asked not to emit it
82
F.needsUnwindTableEntry();
83
84
shouldEmitPersonality =
85
(forceEmitPersonality ||
86
(hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&
87
Per;
88
89
unsigned LSDAEncoding = TLOF.getLSDAEncoding();
90
shouldEmitLSDA = shouldEmitPersonality &&
91
LSDAEncoding != dwarf::DW_EH_PE_omit;
92
93
const MCAsmInfo &MAI = *MF->getContext().getAsmInfo();
94
if (MAI.getExceptionHandlingType() != ExceptionHandling::None)
95
shouldEmitCFI =
96
MAI.usesCFIForEH() && (shouldEmitPersonality || shouldEmitMoves);
97
else
98
shouldEmitCFI = Asm->usesCFIWithoutEH() && shouldEmitMoves;
99
}
100
101
void DwarfCFIException::beginBasicBlockSection(const MachineBasicBlock &MBB) {
102
if (!shouldEmitCFI)
103
return;
104
105
if (!hasEmittedCFISections) {
106
AsmPrinter::CFISection CFISecType = Asm->getModuleCFISectionType();
107
// If we don't say anything it implies `.cfi_sections .eh_frame`, so we
108
// chose not to be verbose in that case. And with `ForceDwarfFrameSection`,
109
// we should always emit .debug_frame.
110
if (CFISecType == AsmPrinter::CFISection::Debug ||
111
Asm->TM.Options.ForceDwarfFrameSection)
112
Asm->OutStreamer->emitCFISections(
113
CFISecType == AsmPrinter::CFISection::EH, true);
114
hasEmittedCFISections = true;
115
}
116
117
Asm->OutStreamer->emitCFIStartProc(/*IsSimple=*/false);
118
119
// Indicate personality routine, if any.
120
if (!shouldEmitPersonality)
121
return;
122
123
auto &F = MBB.getParent()->getFunction();
124
auto *P = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());
125
assert(P && "Expected personality function");
126
// Record the personality function.
127
addPersonality(P);
128
129
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
130
unsigned PerEncoding = TLOF.getPersonalityEncoding();
131
const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);
132
Asm->OutStreamer->emitCFIPersonality(Sym, PerEncoding);
133
134
// Provide LSDA information.
135
if (shouldEmitLSDA)
136
Asm->OutStreamer->emitCFILsda(Asm->getMBBExceptionSym(MBB),
137
TLOF.getLSDAEncoding());
138
}
139
140
void DwarfCFIException::endBasicBlockSection(const MachineBasicBlock &MBB) {
141
if (shouldEmitCFI)
142
Asm->OutStreamer->emitCFIEndProc();
143
}
144
145
/// endFunction - Gather and emit post-function exception information.
146
///
147
void DwarfCFIException::endFunction(const MachineFunction *MF) {
148
if (!shouldEmitPersonality)
149
return;
150
151
emitExceptionTable();
152
}
153
154