//===- CodeGen/AsmPrinter/EHStreamer.cpp - Exception Directive Streamer ---===// // // 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 exception info into assembly files. // //===----------------------------------------------------------------------===// #include "EHStreamer.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/IR/Function.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/Support/Casting.h" #include "llvm/Support/LEB128.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include <algorithm> #include <cassert> #include <cstdint> #include <vector> usingnamespacellvm; EHStreamer::EHStreamer(AsmPrinter *A) : … { … } EHStreamer::~EHStreamer() = default; /// How many leading type ids two landing pads have in common. unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L, const LandingPadInfo *R) { … } /// Compute the actions table and gather the first action index for each landing /// pad site. void EHStreamer::computeActionsTable( const SmallVectorImpl<const LandingPadInfo *> &LandingPads, SmallVectorImpl<ActionEntry> &Actions, SmallVectorImpl<unsigned> &FirstActions) { … } /// Return `true' if this is a call to a function marked `nounwind'. Return /// `false' otherwise. bool EHStreamer::callToNoUnwindFunction(const MachineInstr *MI) { … } void EHStreamer::computePadMap( const SmallVectorImpl<const LandingPadInfo *> &LandingPads, RangeMapType &PadMap) { … } /// Compute the call-site table. The entry for an invoke has a try-range /// containing the call, a non-zero landing pad, and an appropriate action. The /// entry for an ordinary call has a try-range containing the call and zero for /// the landing pad and the action. Calls marked 'nounwind' have no entry and /// must not be contained in the try-range of any entry - they form gaps in the /// table. Entries must be ordered by try-range address. /// /// Call-sites are split into one or more call-site ranges associated with /// different sections of the function. /// /// - Without -basic-block-sections, all call-sites are grouped into one /// call-site-range corresponding to the function section. /// /// - With -basic-block-sections, one call-site range is created for each /// section, with its FragmentBeginLabel and FragmentEndLabel respectively // set to the beginning and ending of the corresponding section and its // ExceptionLabel set to the exception symbol dedicated for this section. // Later, one LSDA header will be emitted for each call-site range with its // call-sites following. The action table and type info table will be // shared across all ranges. void EHStreamer::computeCallSiteTable( SmallVectorImpl<CallSiteEntry> &CallSites, SmallVectorImpl<CallSiteRange> &CallSiteRanges, const SmallVectorImpl<const LandingPadInfo *> &LandingPads, const SmallVectorImpl<unsigned> &FirstActions) { … } /// Emit landing pads and actions. /// /// The general organization of the table is complex, but the basic concepts are /// easy. First there is a header which describes the location and organization /// of the three components that follow. /// /// 1. The landing pad site information describes the range of code covered by /// the try. In our case it's an accumulation of the ranges covered by the /// invokes in the try. There is also a reference to the landing pad that /// handles the exception once processed. Finally an index into the actions /// table. /// 2. The action table, in our case, is composed of pairs of type IDs and next /// action offset. Starting with the action index from the landing pad /// site, each type ID is checked for a match to the current exception. If /// it matches then the exception and type id are passed on to the landing /// pad. Otherwise the next action is looked up. This chain is terminated /// with a next action of zero. If no type id is found then the frame is /// unwound and handling continues. /// 3. Type ID table contains references to all the C++ typeinfo for all /// catches in the function. This tables is reverse indexed base 1. /// /// Returns the starting symbol of an exception table. MCSymbol *EHStreamer::emitExceptionTable() { … } void EHStreamer::emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) { … }