clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name EHStreamer.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/AMDGPU -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Analysis -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ASMParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/BinaryFormat -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitcode -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Bitstream -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /include/llvm/CodeGen -I /include/llvm/CodeGen/PBQP -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IR -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Coroutines -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData/Coverage -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/CodeView -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/DWARF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/MSF -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/PDB -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Demangle -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/JITLink -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ExecutionEngine/Orc -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenACC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Frontend/OpenMP -I /include/llvm/CodeGen/GlobalISel -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/IRReader -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/Transforms/InstCombine -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/LTO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Linker -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/MC/MCParser -I /include/llvm/CodeGen/MIRParser -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Object -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Option -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Passes -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ProfileData -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Scalar -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/ADT -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Support -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/DebugInfo/Symbolize -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Target -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Utils -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/Vectorize -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include/llvm/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/Target/X86 -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include/llvm/Transforms/IPO -I /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/libLLVM/../include -I /usr/src/gnu/usr.bin/clang/libLLVM/obj -I /usr/src/gnu/usr.bin/clang/libLLVM/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/libLLVM/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/libLLVM/../../../llvm/llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "EHStreamer.h" |
14 | #include "llvm/ADT/SmallVector.h" |
15 | #include "llvm/ADT/Twine.h" |
16 | #include "llvm/ADT/iterator_range.h" |
17 | #include "llvm/BinaryFormat/Dwarf.h" |
18 | #include "llvm/CodeGen/AsmPrinter.h" |
19 | #include "llvm/CodeGen/MachineFunction.h" |
20 | #include "llvm/CodeGen/MachineInstr.h" |
21 | #include "llvm/CodeGen/MachineOperand.h" |
22 | #include "llvm/IR/DataLayout.h" |
23 | #include "llvm/IR/Function.h" |
24 | #include "llvm/MC/MCAsmInfo.h" |
25 | #include "llvm/MC/MCContext.h" |
26 | #include "llvm/MC/MCStreamer.h" |
27 | #include "llvm/MC/MCSymbol.h" |
28 | #include "llvm/MC/MCTargetOptions.h" |
29 | #include "llvm/Support/Casting.h" |
30 | #include "llvm/Support/LEB128.h" |
31 | #include "llvm/Target/TargetLoweringObjectFile.h" |
32 | #include <algorithm> |
33 | #include <cassert> |
34 | #include <cstdint> |
35 | #include <vector> |
36 | |
37 | using namespace llvm; |
38 | |
39 | EHStreamer::EHStreamer(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} |
40 | |
41 | EHStreamer::~EHStreamer() = default; |
42 | |
43 | |
44 | unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L, |
45 | const LandingPadInfo *R) { |
46 | const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; |
47 | return std::mismatch(LIds.begin(), LIds.end(), RIds.begin(), RIds.end()) |
48 | .first - |
49 | LIds.begin(); |
50 | } |
51 | |
52 | |
53 | |
54 | void EHStreamer::computeActionsTable( |
55 | const SmallVectorImpl<const LandingPadInfo *> &LandingPads, |
56 | SmallVectorImpl<ActionEntry> &Actions, |
57 | SmallVectorImpl<unsigned> &FirstActions) { |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | const std::vector<unsigned> &FilterIds = Asm->MF->getFilterIds(); |
82 | SmallVector<int, 16> FilterOffsets; |
83 | FilterOffsets.reserve(FilterIds.size()); |
84 | int Offset = -1; |
85 | |
86 | for (unsigned FilterId : FilterIds) { |
87 | FilterOffsets.push_back(Offset); |
88 | Offset -= getULEB128Size(FilterId); |
89 | } |
90 | |
91 | FirstActions.reserve(LandingPads.size()); |
92 | |
93 | int FirstAction = 0; |
94 | unsigned SizeActions = 0; |
95 | const LandingPadInfo *PrevLPI = nullptr; |
96 | |
97 | for (const LandingPadInfo *LPI : LandingPads) { |
98 | const std::vector<int> &TypeIds = LPI->TypeIds; |
99 | unsigned NumShared = PrevLPI ? sharedTypeIDs(LPI, PrevLPI) : 0; |
100 | unsigned SizeSiteActions = 0; |
101 | |
102 | if (NumShared < TypeIds.size()) { |
103 | |
104 | unsigned SizeActionEntry = 0; |
105 | unsigned PrevAction = (unsigned)-1; |
106 | |
107 | if (NumShared) { |
108 | unsigned SizePrevIds = PrevLPI->TypeIds.size(); |
109 | assert(Actions.size()); |
110 | PrevAction = Actions.size() - 1; |
111 | SizeActionEntry = getSLEB128Size(Actions[PrevAction].NextAction) + |
112 | getSLEB128Size(Actions[PrevAction].ValueForTypeID); |
113 | |
114 | for (unsigned j = NumShared; j != SizePrevIds; ++j) { |
115 | assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!"); |
116 | SizeActionEntry -= getSLEB128Size(Actions[PrevAction].ValueForTypeID); |
117 | SizeActionEntry += -Actions[PrevAction].NextAction; |
118 | PrevAction = Actions[PrevAction].Previous; |
119 | } |
120 | } |
121 | |
122 | |
123 | for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { |
124 | int TypeID = TypeIds[J]; |
125 | assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); |
126 | int ValueForTypeID = |
127 | isFilterEHSelector(TypeID) ? FilterOffsets[-1 - TypeID] : TypeID; |
128 | unsigned SizeTypeID = getSLEB128Size(ValueForTypeID); |
129 | |
130 | int NextAction = SizeActionEntry ? -(SizeActionEntry + SizeTypeID) : 0; |
131 | SizeActionEntry = SizeTypeID + getSLEB128Size(NextAction); |
132 | SizeSiteActions += SizeActionEntry; |
133 | |
134 | ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; |
135 | Actions.push_back(Action); |
136 | PrevAction = Actions.size() - 1; |
137 | } |
138 | |
139 | |
140 | FirstAction = SizeActions + SizeSiteActions - SizeActionEntry + 1; |
141 | } |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | FirstActions.push_back(FirstAction); |
149 | |
150 | |
151 | SizeActions += SizeSiteActions; |
152 | |
153 | PrevLPI = LPI; |
154 | } |
155 | } |
156 | |
157 | |
158 | |
159 | bool EHStreamer::callToNoUnwindFunction(const MachineInstr *MI) { |
160 | assert(MI->isCall() && "This should be a call instruction!"); |
161 | |
162 | bool MarkedNoUnwind = false; |
163 | bool SawFunc = false; |
164 | |
165 | for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { |
166 | const MachineOperand &MO = MI->getOperand(I); |
167 | |
168 | if (!MO.isGlobal()) continue; |
169 | |
170 | const Function *F = dyn_cast<Function>(MO.getGlobal()); |
171 | if (!F) continue; |
172 | |
173 | if (SawFunc) { |
174 | |
175 | |
176 | |
177 | |
178 | |
179 | |
180 | MarkedNoUnwind = false; |
181 | break; |
182 | } |
183 | |
184 | MarkedNoUnwind = F->doesNotThrow(); |
185 | SawFunc = true; |
186 | } |
187 | |
188 | return MarkedNoUnwind; |
189 | } |
190 | |
191 | void EHStreamer::computePadMap( |
192 | const SmallVectorImpl<const LandingPadInfo *> &LandingPads, |
193 | RangeMapType &PadMap) { |
194 | |
195 | |
196 | |
197 | for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { |
198 | const LandingPadInfo *LandingPad = LandingPads[i]; |
199 | for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { |
200 | MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; |
201 | assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); |
202 | PadRange P = { i, j }; |
203 | PadMap[BeginLabel] = P; |
204 | } |
205 | } |
206 | } |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 | |
214 | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | |
224 | |
225 | |
226 | |
227 | |
228 | void EHStreamer::computeCallSiteTable( |
229 | SmallVectorImpl<CallSiteEntry> &CallSites, |
230 | SmallVectorImpl<CallSiteRange> &CallSiteRanges, |
231 | const SmallVectorImpl<const LandingPadInfo *> &LandingPads, |
232 | const SmallVectorImpl<unsigned> &FirstActions) { |
233 | RangeMapType PadMap; |
234 | computePadMap(LandingPads, PadMap); |
235 | |
236 | |
237 | MCSymbol *LastLabel = Asm->getFunctionBegin(); |
238 | |
239 | |
240 | |
241 | bool SawPotentiallyThrowing = false; |
242 | |
243 | |
244 | bool PreviousIsInvoke = false; |
245 | |
246 | bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; |
247 | |
248 | |
249 | for (const auto &MBB : *Asm->MF) { |
250 | if (&MBB == &Asm->MF->front() || MBB.isBeginSection()) { |
251 | |
252 | |
253 | CallSiteRanges.push_back( |
254 | {Asm->MBBSectionRanges[MBB.getSectionIDNum()].BeginLabel, |
255 | Asm->MBBSectionRanges[MBB.getSectionIDNum()].EndLabel, |
256 | Asm->getMBBExceptionSym(MBB), CallSites.size()}); |
257 | PreviousIsInvoke = false; |
258 | SawPotentiallyThrowing = false; |
259 | LastLabel = nullptr; |
260 | } |
261 | |
262 | if (MBB.isEHPad()) |
263 | CallSiteRanges.back().IsLPRange = true; |
264 | |
265 | for (const auto &MI : MBB) { |
266 | if (!MI.isEHLabel()) { |
267 | if (MI.isCall()) |
268 | SawPotentiallyThrowing |= !callToNoUnwindFunction(&MI); |
269 | continue; |
270 | } |
271 | |
272 | |
273 | MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol(); |
274 | if (BeginLabel == LastLabel) |
275 | SawPotentiallyThrowing = false; |
276 | |
277 | |
278 | RangeMapType::const_iterator L = PadMap.find(BeginLabel); |
279 | if (L == PadMap.end()) |
280 | |
281 | continue; |
282 | |
283 | const PadRange &P = L->second; |
284 | const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; |
285 | assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && |
286 | "Inconsistent landing pad map!"); |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | if (SawPotentiallyThrowing && |
293 | (Asm->MAI->usesCFIForEH() || |
294 | Asm->MAI->getExceptionHandlingType() == ExceptionHandling::AIX)) { |
295 | CallSites.push_back({LastLabel, BeginLabel, nullptr, 0}); |
296 | PreviousIsInvoke = false; |
297 | } |
298 | |
299 | LastLabel = LandingPad->EndLabels[P.RangeIndex]; |
300 | assert(BeginLabel && LastLabel && "Invalid landing pad!"); |
301 | |
302 | if (!LandingPad->LandingPadLabel) { |
303 | |
304 | PreviousIsInvoke = false; |
305 | } else { |
306 | |
307 | CallSiteEntry Site = { |
308 | BeginLabel, |
309 | LastLabel, |
310 | LandingPad, |
311 | FirstActions[P.PadIndex] |
312 | }; |
313 | |
314 | |
315 | if (PreviousIsInvoke && !IsSJLJ) { |
316 | CallSiteEntry &Prev = CallSites.back(); |
317 | if (Site.LPad == Prev.LPad && Site.Action == Prev.Action) { |
318 | |
319 | Prev.EndLabel = Site.EndLabel; |
320 | continue; |
321 | } |
322 | } |
323 | |
324 | |
325 | if (!IsSJLJ) |
326 | CallSites.push_back(Site); |
327 | else { |
328 | |
329 | |
330 | unsigned SiteNo = Asm->MF->getCallSiteBeginLabel(BeginLabel); |
331 | if (CallSites.size() < SiteNo) |
332 | CallSites.resize(SiteNo); |
333 | CallSites[SiteNo - 1] = Site; |
334 | } |
335 | PreviousIsInvoke = true; |
336 | } |
337 | } |
338 | |
339 | |
340 | |
341 | if (&MBB == &Asm->MF->back() || MBB.isEndSection()) { |
342 | |
343 | |
344 | |
345 | if (SawPotentiallyThrowing && !IsSJLJ) { |
346 | CallSiteEntry Site = {LastLabel, CallSiteRanges.back().FragmentEndLabel, |
347 | nullptr, 0}; |
348 | CallSites.push_back(Site); |
349 | SawPotentiallyThrowing = false; |
350 | } |
351 | CallSiteRanges.back().CallSiteEndIdx = CallSites.size(); |
352 | } |
353 | } |
354 | } |
355 | |
356 | |
357 | |
358 | |
359 | |
360 | |
361 | |
362 | |
363 | |
364 | |
365 | |
366 | |
367 | |
368 | |
369 | |
370 | |
371 | |
372 | |
373 | |
374 | |
375 | |
376 | |
377 | |
378 | MCSymbol *EHStreamer::emitExceptionTable() { |
379 | const MachineFunction *MF = Asm->MF; |
380 | const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos(); |
381 | const std::vector<unsigned> &FilterIds = MF->getFilterIds(); |
382 | const std::vector<LandingPadInfo> &PadInfos = MF->getLandingPads(); |
383 | |
384 | |
385 | |
386 | SmallVector<const LandingPadInfo *, 64> LandingPads; |
387 | LandingPads.reserve(PadInfos.size()); |
388 | |
389 | for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) |
| 1 | Assuming 'i' is equal to 'N' | |
|
| 2 | | Loop condition is false. Execution continues on line 393 | |
|
390 | LandingPads.push_back(&PadInfos[i]); |
391 | |
392 | |
393 | llvm::sort(LandingPads, [](const LandingPadInfo *L, const LandingPadInfo *R) { |
394 | return L->TypeIds < R->TypeIds; |
395 | }); |
396 | |
397 | |
398 | |
399 | SmallVector<ActionEntry, 32> Actions; |
400 | SmallVector<unsigned, 64> FirstActions; |
401 | computeActionsTable(LandingPads, Actions, FirstActions); |
402 | |
403 | |
404 | |
405 | |
406 | |
407 | SmallVector<CallSiteEntry, 64> CallSites; |
408 | SmallVector<CallSiteRange, 4> CallSiteRanges; |
409 | computeCallSiteTable(CallSites, CallSiteRanges, LandingPads, FirstActions); |
410 | |
411 | bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; |
| 3 | | Assuming the condition is false | |
|
412 | bool IsWasm = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Wasm; |
| 4 | | Assuming the condition is false | |
|
413 | bool HasLEB128Directives = Asm->MAI->hasLEB128Directives(); |
414 | unsigned CallSiteEncoding = |
415 | IsSJLJ ? static_cast<unsigned>(dwarf::DW_EH_PE_udata4) : |
| |
416 | Asm->getObjFileLowering().getCallSiteEncoding(); |
417 | bool HaveTTData = !TypeInfos.empty() || !FilterIds.empty(); |
| 6 | | Assuming the condition is false | |
|
| 7 | | Assuming the condition is false | |
|
418 | |
419 | |
420 | MCSection *LSDASection = Asm->getObjFileLowering().getSectionForLSDA( |
421 | MF->getFunction(), *Asm->CurrentFnSym, Asm->TM); |
422 | unsigned TTypeEncoding; |
423 | |
424 | if (!HaveTTData) { |
| |
425 | |
426 | |
427 | TTypeEncoding = dwarf::DW_EH_PE_omit; |
428 | } else { |
429 | |
430 | |
431 | |
432 | |
433 | |
434 | |
435 | |
436 | |
437 | |
438 | |
439 | |
440 | |
441 | |
442 | |
443 | |
444 | |
445 | |
446 | |
447 | |
448 | |
449 | |
450 | |
451 | |
452 | |
453 | |
454 | |
455 | |
456 | TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding(); |
457 | } |
458 | |
459 | |
460 | |
461 | |
462 | if (LSDASection) |
| 9 | | Assuming 'LSDASection' is null | |
|
| |
463 | Asm->OutStreamer->SwitchSection(LSDASection); |
464 | Asm->emitAlignment(Align(4)); |
465 | |
466 | |
467 | MCSymbol *GCCETSym = |
468 | Asm->OutContext.getOrCreateSymbol(Twine("GCC_except_table")+ |
469 | Twine(Asm->getFunctionNumber())); |
470 | Asm->OutStreamer->emitLabel(GCCETSym); |
471 | MCSymbol *CstEndLabel = Asm->createTempSymbol( |
472 | CallSiteRanges.size() > 1 ? "action_table_base" : "cst_end"); |
| 11 | | Assuming the condition is false | |
|
| |
473 | |
474 | MCSymbol *TTBaseLabel = nullptr; |
475 | if (HaveTTData) |
| |
476 | TTBaseLabel = Asm->createTempSymbol("ttbase"); |
477 | |
478 | const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); |
479 | |
480 | |
481 | |
482 | |
483 | |
484 | auto EmitTypeTableRefAndCallSiteTableEndRef = [&]() { |
485 | Asm->emitEncodingByte(TTypeEncoding, "@TType"); |
486 | if (HaveTTData) { |
487 | |
488 | |
489 | |
490 | |
491 | MCSymbol *TTBaseRefLabel = Asm->createTempSymbol("ttbaseref"); |
492 | Asm->emitLabelDifferenceAsULEB128(TTBaseLabel, TTBaseRefLabel); |
493 | Asm->OutStreamer->emitLabel(TTBaseRefLabel); |
494 | } |
495 | |
496 | |
497 | |
498 | |
499 | |
500 | MCSymbol *CstBeginLabel = Asm->createTempSymbol("cst_begin"); |
501 | Asm->emitEncodingByte(CallSiteEncoding, "Call site"); |
502 | Asm->emitLabelDifferenceAsULEB128(CstEndLabel, CstBeginLabel); |
503 | Asm->OutStreamer->emitLabel(CstBeginLabel); |
504 | }; |
505 | |
506 | |
507 | |
508 | |
509 | |
510 | |
511 | |
512 | auto EmitTypeTableOffsetAndCallSiteTableOffset = [&]() { |
513 | assert(CallSiteEncoding == dwarf::DW_EH_PE_udata4 && !HasLEB128Directives && |
514 | "Targets supporting .uleb128 do not need to take this path."); |
515 | if (CallSiteRanges.size() > 1) |
516 | report_fatal_error( |
517 | "-fbasic-block-sections is not yet supported on " |
518 | "platforms that do not have general LEB128 directive support."); |
519 | |
520 | uint64_t CallSiteTableSize = 0; |
521 | const CallSiteRange &CSRange = CallSiteRanges.back(); |
522 | for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx; |
523 | CallSiteIdx < CSRange.CallSiteEndIdx; ++CallSiteIdx) { |
524 | const CallSiteEntry &S = CallSites[CallSiteIdx]; |
525 | |
526 | |
527 | CallSiteTableSize += 12 + getULEB128Size(S.Action); |
528 | assert(isUInt<32>(CallSiteTableSize) && "CallSiteTableSize overflows."); |
529 | } |
530 | |
531 | Asm->emitEncodingByte(TTypeEncoding, "@TType"); |
532 | if (HaveTTData) { |
533 | const unsigned ByteSizeOfCallSiteOffset = |
534 | getULEB128Size(CallSiteTableSize); |
535 | uint64_t ActionTableSize = 0; |
536 | for (const ActionEntry &Action : Actions) { |
537 | |
538 | ActionTableSize += getSLEB128Size(Action.ValueForTypeID) + |
539 | getSLEB128Size(Action.NextAction); |
540 | assert(isUInt<32>(ActionTableSize) && "ActionTableSize overflows."); |
541 | } |
542 | |
543 | const unsigned TypeInfoSize = |
544 | Asm->GetSizeOfEncodedValue(TTypeEncoding) * MF->getTypeInfos().size(); |
545 | |
546 | const uint64_t LSDASizeBeforeAlign = |
547 | 1 |
548 | + ByteSizeOfCallSiteOffset |
549 | + CallSiteTableSize |
550 | + ActionTableSize; |
551 | |
552 | const uint64_t LSDASizeWithoutAlign = LSDASizeBeforeAlign + TypeInfoSize; |
553 | const unsigned ByteSizeOfLSDAWithoutAlign = |
554 | getULEB128Size(LSDASizeWithoutAlign); |
555 | const uint64_t DisplacementBeforeAlign = |
556 | 2 |
557 | + ByteSizeOfLSDAWithoutAlign + LSDASizeBeforeAlign; |
558 | |
559 | |
560 | const unsigned NeedAlignVal = (4 - DisplacementBeforeAlign % 4) % 4; |
561 | uint64_t LSDASizeWithAlign = LSDASizeWithoutAlign + NeedAlignVal; |
562 | const unsigned ByteSizeOfLSDAWithAlign = |
563 | getULEB128Size(LSDASizeWithAlign); |
564 | |
565 | |
566 | |
567 | |
568 | if (ByteSizeOfLSDAWithAlign > ByteSizeOfLSDAWithoutAlign) |
569 | LSDASizeWithAlign -= 1; |
570 | |
571 | Asm->OutStreamer->emitULEB128IntValue(LSDASizeWithAlign, |
572 | ByteSizeOfLSDAWithAlign); |
573 | } |
574 | |
575 | Asm->emitEncodingByte(CallSiteEncoding, "Call site"); |
576 | Asm->OutStreamer->emitULEB128IntValue(CallSiteTableSize); |
577 | }; |
578 | |
579 | |
580 | if (IsSJLJ || IsWasm) { |
| |
581 | Asm->OutStreamer->emitLabel(Asm->getMBBExceptionSym(Asm->MF->front())); |
582 | |
583 | |
584 | Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); |
585 | EmitTypeTableRefAndCallSiteTableEndRef(); |
586 | |
587 | unsigned idx = 0; |
588 | for (SmallVectorImpl<CallSiteEntry>::const_iterator |
589 | I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { |
590 | const CallSiteEntry &S = *I; |
591 | |
592 | |
593 | if (VerboseAsm) { |
594 | Asm->OutStreamer->AddComment(">> Call Site " + Twine(idx) + " <<"); |
595 | Asm->OutStreamer->AddComment(" On exception at call site "+Twine(idx)); |
596 | } |
597 | Asm->emitULEB128(idx); |
598 | |
599 | |
600 | |
601 | |
602 | if (VerboseAsm) { |
603 | if (S.Action == 0) |
604 | Asm->OutStreamer->AddComment(" Action: cleanup"); |
605 | else |
606 | Asm->OutStreamer->AddComment(" Action: " + |
607 | Twine((S.Action - 1) / 2 + 1)); |
608 | } |
609 | Asm->emitULEB128(S.Action); |
610 | } |
611 | Asm->OutStreamer->emitLabel(CstEndLabel); |
612 | } else { |
613 | |
614 | |
615 | |
616 | |
617 | |
618 | |
619 | |
620 | |
621 | |
622 | |
623 | |
624 | |
625 | |
626 | |
627 | |
628 | |
629 | |
630 | |
631 | |
632 | |
633 | assert(CallSiteRanges.size() != 0 && "No call-site ranges!"); |
634 | |
635 | |
636 | |
637 | const CallSiteRange *LandingPadRange = nullptr; |
| 15 | | 'LandingPadRange' initialized to a null pointer value | |
|
638 | for (const CallSiteRange &CSRange : CallSiteRanges) { |
| 16 | | Assuming '__begin2' is equal to '__end2' | |
|
639 | if (CSRange.IsLPRange) { |
640 | assert(LandingPadRange == nullptr && |
641 | "All landing pads must be in a single callsite range."); |
642 | LandingPadRange = &CSRange; |
643 | } |
644 | } |
645 | |
646 | |
647 | |
648 | |
649 | |
650 | |
651 | |
652 | |
653 | |
654 | |
655 | |
656 | |
657 | |
658 | |
659 | unsigned Entry = 0; |
660 | for (const CallSiteRange &CSRange : CallSiteRanges) { |
| 17 | | Assuming '__begin2' is not equal to '__end2' | |
|
661 | if (CSRange.CallSiteBeginIdx != 0) { |
| 18 | | Assuming field 'CallSiteBeginIdx' is equal to 0 | |
|
| |
662 | |
663 | |
664 | Asm->emitAlignment(Align(4)); |
665 | } |
666 | Asm->OutStreamer->emitLabel(CSRange.ExceptionLabel); |
667 | |
668 | |
669 | |
670 | |
671 | if (CallSiteRanges.size() == 1) { |
| 20 | | Assuming the condition is false | |
|
| |
672 | Asm->emitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); |
673 | } else if (!Asm->isPositionIndependent()) { |
| 22 | | Assuming the condition is false | |
|
| |
674 | |
675 | |
676 | |
677 | Asm->emitEncodingByte(dwarf::DW_EH_PE_absptr, "@LPStart"); |
678 | Asm->OutStreamer->emitSymbolValue(LandingPadRange->FragmentBeginLabel, |
679 | Asm->MAI->getCodePointerSize()); |
680 | } else { |
681 | |
682 | Asm->emitEncodingByte(dwarf::DW_EH_PE_pcrel, "@LPStart"); |
683 | MCContext &Context = Asm->OutStreamer->getContext(); |
684 | MCSymbol *Dot = Context.createTempSymbol(); |
685 | Asm->OutStreamer->emitLabel(Dot); |
686 | Asm->OutStreamer->emitValue( |
687 | MCBinaryExpr::createSub( |
688 | MCSymbolRefExpr::create(LandingPadRange->FragmentBeginLabel, |
| 24 | | Access to field 'FragmentBeginLabel' results in a dereference of a null pointer (loaded from variable 'LandingPadRange') |
|
689 | Context), |
690 | MCSymbolRefExpr::create(Dot, Context), Context), |
691 | Asm->MAI->getCodePointerSize()); |
692 | } |
693 | |
694 | if (HasLEB128Directives) |
695 | EmitTypeTableRefAndCallSiteTableEndRef(); |
696 | else |
697 | EmitTypeTableOffsetAndCallSiteTableOffset(); |
698 | |
699 | for (size_t CallSiteIdx = CSRange.CallSiteBeginIdx; |
700 | CallSiteIdx != CSRange.CallSiteEndIdx; ++CallSiteIdx) { |
701 | const CallSiteEntry &S = CallSites[CallSiteIdx]; |
702 | |
703 | MCSymbol *EHFuncBeginSym = CSRange.FragmentBeginLabel; |
704 | MCSymbol *EHFuncEndSym = CSRange.FragmentEndLabel; |
705 | |
706 | MCSymbol *BeginLabel = S.BeginLabel; |
707 | if (!BeginLabel) |
708 | BeginLabel = EHFuncBeginSym; |
709 | MCSymbol *EndLabel = S.EndLabel; |
710 | if (!EndLabel) |
711 | EndLabel = EHFuncEndSym; |
712 | |
713 | |
714 | if (VerboseAsm) |
715 | Asm->OutStreamer->AddComment(">> Call Site " + Twine(++Entry) + |
716 | " <<"); |
717 | Asm->emitCallSiteOffset(BeginLabel, EHFuncBeginSym, CallSiteEncoding); |
718 | if (VerboseAsm) |
719 | Asm->OutStreamer->AddComment(Twine(" Call between ") + |
720 | BeginLabel->getName() + " and " + |
721 | EndLabel->getName()); |
722 | Asm->emitCallSiteOffset(EndLabel, BeginLabel, CallSiteEncoding); |
723 | |
724 | |
725 | |
726 | if (!S.LPad) { |
727 | if (VerboseAsm) |
728 | Asm->OutStreamer->AddComment(" has no landing pad"); |
729 | Asm->emitCallSiteValue(0, CallSiteEncoding); |
730 | } else { |
731 | if (VerboseAsm) |
732 | Asm->OutStreamer->AddComment(Twine(" jumps to ") + |
733 | S.LPad->LandingPadLabel->getName()); |
734 | Asm->emitCallSiteOffset(S.LPad->LandingPadLabel, |
735 | LandingPadRange->FragmentBeginLabel, |
736 | CallSiteEncoding); |
737 | } |
738 | |
739 | |
740 | |
741 | |
742 | if (VerboseAsm) { |
743 | if (S.Action == 0) |
744 | Asm->OutStreamer->AddComment(" On action: cleanup"); |
745 | else |
746 | Asm->OutStreamer->AddComment(" On action: " + |
747 | Twine((S.Action - 1) / 2 + 1)); |
748 | } |
749 | Asm->emitULEB128(S.Action); |
750 | } |
751 | } |
752 | Asm->OutStreamer->emitLabel(CstEndLabel); |
753 | } |
754 | |
755 | |
756 | int Entry = 0; |
757 | for (const ActionEntry &Action : Actions) { |
758 | if (VerboseAsm) { |
759 | |
760 | Asm->OutStreamer->AddComment(">> Action Record " + Twine(++Entry) + " <<"); |
761 | } |
762 | |
763 | |
764 | |
765 | |
766 | |
767 | if (VerboseAsm) { |
768 | if (Action.ValueForTypeID > 0) |
769 | Asm->OutStreamer->AddComment(" Catch TypeInfo " + |
770 | Twine(Action.ValueForTypeID)); |
771 | else if (Action.ValueForTypeID < 0) |
772 | Asm->OutStreamer->AddComment(" Filter TypeInfo " + |
773 | Twine(Action.ValueForTypeID)); |
774 | else |
775 | Asm->OutStreamer->AddComment(" Cleanup"); |
776 | } |
777 | Asm->emitSLEB128(Action.ValueForTypeID); |
778 | |
779 | |
780 | if (VerboseAsm) { |
781 | if (Action.Previous == unsigned(-1)) { |
782 | Asm->OutStreamer->AddComment(" No further actions"); |
783 | } else { |
784 | Asm->OutStreamer->AddComment(" Continue to action " + |
785 | Twine(Action.Previous + 1)); |
786 | } |
787 | } |
788 | Asm->emitSLEB128(Action.NextAction); |
789 | } |
790 | |
791 | if (HaveTTData) { |
792 | Asm->emitAlignment(Align(4)); |
793 | emitTypeInfos(TTypeEncoding, TTBaseLabel); |
794 | } |
795 | |
796 | Asm->emitAlignment(Align(4)); |
797 | return GCCETSym; |
798 | } |
799 | |
800 | void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) { |
801 | const MachineFunction *MF = Asm->MF; |
802 | const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos(); |
803 | const std::vector<unsigned> &FilterIds = MF->getFilterIds(); |
804 | |
805 | const bool VerboseAsm = Asm->OutStreamer->isVerboseAsm(); |
806 | |
807 | int Entry = 0; |
808 | |
809 | if (VerboseAsm && !TypeInfos.empty()) { |
810 | Asm->OutStreamer->AddComment(">> Catch TypeInfos <<"); |
811 | Asm->OutStreamer->AddBlankLine(); |
812 | Entry = TypeInfos.size(); |
813 | } |
814 | |
815 | for (const GlobalValue *GV : make_range(TypeInfos.rbegin(), |
816 | TypeInfos.rend())) { |
817 | if (VerboseAsm) |
818 | Asm->OutStreamer->AddComment("TypeInfo " + Twine(Entry--)); |
819 | Asm->emitTTypeReference(GV, TTypeEncoding); |
820 | } |
821 | |
822 | Asm->OutStreamer->emitLabel(TTBaseLabel); |
823 | |
824 | |
825 | if (VerboseAsm && !FilterIds.empty()) { |
826 | Asm->OutStreamer->AddComment(">> Filter TypeInfos <<"); |
827 | Asm->OutStreamer->AddBlankLine(); |
828 | Entry = 0; |
829 | } |
830 | for (std::vector<unsigned>::const_iterator |
831 | I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { |
832 | unsigned TypeID = *I; |
833 | if (VerboseAsm) { |
834 | --Entry; |
835 | if (isFilterEHSelector(TypeID)) |
836 | Asm->OutStreamer->AddComment("FilterInfo " + Twine(Entry)); |
837 | } |
838 | |
839 | Asm->emitULEB128(TypeID); |
840 | } |
841 | } |