brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 1b77584 Raw
89 lines · cpp
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-exception6//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 18using namespace llvm;19 20void 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  else50    // 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 59void CFIFunctionFrameStreamer::emitInstruction(const MCInst &Inst,60                                               const MCSubtargetInfo &STI) {61  if (hasUnfinishedDwarfFrameInfo())62    // Send the last instruction with the unsent directives already in the frame63    // to the receiver.64    updateReceiver(Inst);65}66 67void 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 75void CFIFunctionFrameStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame) {76  // Send the last instruction with the final directives of the current frame to77  // 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