llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfException.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

109 lines
3.6 KiB
C
Raw Normal View History

//===-- DwarfException.h - Dwarf Exception Framework -----------*- C++ -*--===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains support for writing dwarf exception info into asm files.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
#include "EHStreamer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCDwarf.h"
namespace llvm {
class MachineFunction;
class ARMTargetStreamer;
class LLVM_LIBRARY_VISIBILITY DwarfCFIExceptionBase : public EHStreamer {
protected:
DwarfCFIExceptionBase(AsmPrinter *A);
/// Per-function flag to indicate if frame CFI info should be emitted.
bool shouldEmitCFI;
/// Per-module flag to indicate if .cfi_section has beeen emitted.
bool hasEmittedCFISections;
void markFunctionEnd() override;
void endFragment() override;
};
class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public DwarfCFIExceptionBase {
/// Per-function flag to indicate if .cfi_personality should be emitted.
bool shouldEmitPersonality;
/// Per-function flag to indicate if .cfi_personality must be emitted.
bool forceEmitPersonality;
/// Per-function flag to indicate if .cfi_lsda should be emitted.
bool shouldEmitLSDA;
public:
//===--------------------------------------------------------------------===//
// Main entry points.
//
DwarfCFIException(AsmPrinter *A);
~DwarfCFIException() override;
/// Emit all exception information that should come after the content.
void endModule() override;
/// Gather pre-function exception information. Assumes being emitted
/// immediately after the function entry point.
void beginFunction(const MachineFunction *MF) override;
/// Gather and emit post-function exception information.
void endFunction(const MachineFunction *) override;
void beginFragment(const MachineBasicBlock *MBB,
ExceptionSymbolProvider ESP) override;
Call Frame Information (CFI) Handling for Basic Block Sections This patch handles CFI with basic block sections, which unlike DebugInfo does not support ranges. The DWARF standard explicitly requires emitting separate CFI Frame Descriptor Entries for each contiguous fragment of a function. Thus, the CFI information for all callee-saved registers (possibly including the frame pointer, if necessary) have to be emitted along with redefining the Call Frame Address (CFA), viz. where the current frame starts. CFI directives are emitted in FDE’s in the object file with a low_pc, high_pc specification. So, a single FDE must point to a contiguous code region unlike debug info which has the support for ranges. This is what complicates CFI for basic block sections. Now, what happens when we start placing individual basic blocks in unique sections: * Basic block sections allow the linker to randomly reorder basic blocks in the address space such that a given basic block can become non-contiguous with the original function. * The different basic block sections can no longer share the cfi_startproc and cfi_endproc directives. So, each basic block section should emit this independently. * Each (cfi_startproc, cfi_endproc) directive will result in a new FDE that caters to that basic block section. * Now, this basic block section needs to duplicate the information from the entry block to compute the CFA as it is an independent entity. It cannot refer to the FDE of the original function and hence must duplicate all the stuff that is needed to compute the CFA on its own. * We are working on a de-duplication patch that can share common information in FDEs in a CIE (Common Information Entry) and we will present this as a follow up patch. This can significantly reduce the duplication overhead and is particularly useful when several basic block sections are created. * The CFI directives are emitted similarly for registers that are pushed onto the stack, like callee saved registers in the prologue. There are cfi directives that emit how to retrieve the value of the register at that point when the push happened. This has to be duplicated too in a basic block that is floated as a separate section. Differential Revision: https://reviews.llvm.org/D79978
2020-07-15 02:55:41 +08:00
void beginBasicBlock(const MachineBasicBlock &MBB) override;
void endBasicBlock(const MachineBasicBlock &MBB) override;
};
class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase {
void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) override;
ARMTargetStreamer &getTargetStreamer();
public:
//===--------------------------------------------------------------------===//
// Main entry points.
//
ARMException(AsmPrinter *A);
~ARMException() override;
/// Emit all exception information that should come after the content.
void endModule() override {}
/// Gather pre-function exception information. Assumes being emitted
/// immediately after the function entry point.
void beginFunction(const MachineFunction *MF) override;
/// Gather and emit post-function exception information.
void endFunction(const MachineFunction *) override;
};
class LLVM_LIBRARY_VISIBILITY AIXException : public DwarfCFIExceptionBase {
/// This is AIX's compat unwind section, which unwinder would use
/// to find the location of LSDA area and personality rountine.
void emitExceptionInfoTable(const MCSymbol *LSDA, const MCSymbol *PerSym);
public:
AIXException(AsmPrinter *A);
void endModule() override {}
void beginFunction(const MachineFunction *MF) override {}
void endFunction(const MachineFunction *MF) override;
};
} // End of namespace llvm
#endif