Path: blob/main/contrib/llvm-project/llvm/lib/DWARFCFIChecker/DWARFCFIFunctionFrameStreamer.cpp
213766 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/DWARFCFIChecker/DWARFCFIFunctionFrameStreamer.h"9#include "llvm/ADT/ArrayRef.h"10#include "llvm/MC/MCContext.h"11#include "llvm/MC/MCDwarf.h"12#include "llvm/MC/MCInst.h"13#include "llvm/MC/MCInstrInfo.h"14#include "llvm/MC/MCStreamer.h"15#include <optional>1617using namespace llvm;1819void CFIFunctionFrameStreamer::updateReceiver(20const std::optional<MCInst> &NewInst) {21assert(hasUnfinishedDwarfFrameInfo() &&22"should have an unfinished DWARF frame here");23assert(!FrameIndices.empty() &&24"there should be an index available for the current frame");25assert(FrameIndices.size() == LastInstructions.size());26assert(LastInstructions.size() == LastDirectiveIndices.size());2728auto Frames = getDwarfFrameInfos();29assert(FrameIndices.back() < Frames.size());30unsigned LastDirectiveIndex = LastDirectiveIndices.back();31unsigned CurrentDirectiveIndex =32Frames[FrameIndices.back()].Instructions.size();33assert(CurrentDirectiveIndex >= LastDirectiveIndex);3435const MCDwarfFrameInfo *LastFrame = &Frames[FrameIndices.back()];36ArrayRef<MCCFIInstruction> Directives;37if (LastDirectiveIndex < CurrentDirectiveIndex) {38Directives = ArrayRef<MCCFIInstruction>(LastFrame->Instructions);39Directives =40Directives.drop_front(LastDirectiveIndex)41.drop_back(LastFrame->Instructions.size() - CurrentDirectiveIndex);42}4344auto MaybeLastInstruction = LastInstructions.back();45if (MaybeLastInstruction)46// The directives are associated with an instruction.47Receiver->emitInstructionAndDirectives(*MaybeLastInstruction, Directives);48else49// The directives are the prologue directives.50Receiver->startFunctionFrame(false /* TODO: should put isEH here */,51Directives);5253// Update the internal state for the top frame.54LastInstructions.back() = NewInst;55LastDirectiveIndices.back() = CurrentDirectiveIndex;56}5758void CFIFunctionFrameStreamer::emitInstruction(const MCInst &Inst,59const MCSubtargetInfo &STI) {60if (hasUnfinishedDwarfFrameInfo())61// Send the last instruction with the unsent directives already in the frame62// to the receiver.63updateReceiver(Inst);64}6566void CFIFunctionFrameStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {67LastInstructions.push_back(std::nullopt);68LastDirectiveIndices.push_back(0);69FrameIndices.push_back(getNumFrameInfos());7071MCStreamer::emitCFIStartProcImpl(Frame);72}7374void CFIFunctionFrameStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame) {75// Send the last instruction with the final directives of the current frame to76// the receiver.77updateReceiver(std::nullopt);7879assert(!FrameIndices.empty() && "There should be at least one frame to pop");80LastDirectiveIndices.pop_back();81LastInstructions.pop_back();82FrameIndices.pop_back();8384Receiver->finishFunctionFrame();8586MCStreamer::emitCFIEndProcImpl(CurFrame);87}888990