Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DWARFCFIChecker/DWARFCFIFunctionFrameStreamer.cpp
213766 views
1
//===----------------------------------------------------------------------===//
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
#include "llvm/DWARFCFIChecker/DWARFCFIFunctionFrameStreamer.h"
10
#include "llvm/ADT/ArrayRef.h"
11
#include "llvm/MC/MCContext.h"
12
#include "llvm/MC/MCDwarf.h"
13
#include "llvm/MC/MCInst.h"
14
#include "llvm/MC/MCInstrInfo.h"
15
#include "llvm/MC/MCStreamer.h"
16
#include <optional>
17
18
using namespace llvm;
19
20
void CFIFunctionFrameStreamer::updateReceiver(
21
const std::optional<MCInst> &NewInst) {
22
assert(hasUnfinishedDwarfFrameInfo() &&
23
"should have an unfinished DWARF frame here");
24
assert(!FrameIndices.empty() &&
25
"there should be an index available for the current frame");
26
assert(FrameIndices.size() == LastInstructions.size());
27
assert(LastInstructions.size() == LastDirectiveIndices.size());
28
29
auto Frames = getDwarfFrameInfos();
30
assert(FrameIndices.back() < Frames.size());
31
unsigned LastDirectiveIndex = LastDirectiveIndices.back();
32
unsigned CurrentDirectiveIndex =
33
Frames[FrameIndices.back()].Instructions.size();
34
assert(CurrentDirectiveIndex >= LastDirectiveIndex);
35
36
const MCDwarfFrameInfo *LastFrame = &Frames[FrameIndices.back()];
37
ArrayRef<MCCFIInstruction> Directives;
38
if (LastDirectiveIndex < CurrentDirectiveIndex) {
39
Directives = ArrayRef<MCCFIInstruction>(LastFrame->Instructions);
40
Directives =
41
Directives.drop_front(LastDirectiveIndex)
42
.drop_back(LastFrame->Instructions.size() - CurrentDirectiveIndex);
43
}
44
45
auto MaybeLastInstruction = LastInstructions.back();
46
if (MaybeLastInstruction)
47
// The directives are associated with an instruction.
48
Receiver->emitInstructionAndDirectives(*MaybeLastInstruction, Directives);
49
else
50
// The directives are the prologue directives.
51
Receiver->startFunctionFrame(false /* TODO: should put isEH here */,
52
Directives);
53
54
// Update the internal state for the top frame.
55
LastInstructions.back() = NewInst;
56
LastDirectiveIndices.back() = CurrentDirectiveIndex;
57
}
58
59
void CFIFunctionFrameStreamer::emitInstruction(const MCInst &Inst,
60
const MCSubtargetInfo &STI) {
61
if (hasUnfinishedDwarfFrameInfo())
62
// Send the last instruction with the unsent directives already in the frame
63
// to the receiver.
64
updateReceiver(Inst);
65
}
66
67
void CFIFunctionFrameStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
68
LastInstructions.push_back(std::nullopt);
69
LastDirectiveIndices.push_back(0);
70
FrameIndices.push_back(getNumFrameInfos());
71
72
MCStreamer::emitCFIStartProcImpl(Frame);
73
}
74
75
void CFIFunctionFrameStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame) {
76
// Send the last instruction with the final directives of the current frame to
77
// the receiver.
78
updateReceiver(std::nullopt);
79
80
assert(!FrameIndices.empty() && "There should be at least one frame to pop");
81
LastDirectiveIndices.pop_back();
82
LastInstructions.pop_back();
83
FrameIndices.pop_back();
84
85
Receiver->finishFunctionFrame();
86
87
MCStreamer::emitCFIEndProcImpl(CurFrame);
88
}
89
90