brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 6b8d08c Raw
156 lines · cpp
1//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//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// This file contains support for writing DWARF exception info into asm files.10//11//===----------------------------------------------------------------------===//12 13#include "DwarfException.h"14#include "llvm/BinaryFormat/Dwarf.h"15#include "llvm/CodeGen/AsmPrinter.h"16#include "llvm/CodeGen/MachineFunction.h"17#include "llvm/CodeGen/MachineModuleInfo.h"18#include "llvm/IR/Function.h"19#include "llvm/MC/MCAsmInfo.h"20#include "llvm/MC/MCContext.h"21#include "llvm/MC/MCStreamer.h"22#include "llvm/Target/TargetLoweringObjectFile.h"23#include "llvm/Target/TargetMachine.h"24#include "llvm/Target/TargetOptions.h"25using namespace llvm;26 27DwarfCFIException::DwarfCFIException(AsmPrinter *A) : EHStreamer(A) {}28 29DwarfCFIException::~DwarfCFIException() = default;30 31void DwarfCFIException::addPersonality(const GlobalValue *Personality) {32  if (!llvm::is_contained(Personalities, Personality))33    Personalities.push_back(Personality);34}35 36/// endModule - Emit all exception information that should come after the37/// content.38void DwarfCFIException::endModule() {39  // SjLj uses this pass and it doesn't need this info.40  if (!Asm->MAI->usesCFIForEH())41    return;42 43  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();44 45  unsigned PerEncoding = TLOF.getPersonalityEncoding();46 47  if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)48    return;49 50  // Emit indirect reference table for all used personality functions51  for (const GlobalValue *Personality : Personalities) {52    MCSymbol *Sym = Asm->getSymbol(Personality);53    TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym,54                              Asm->MMI);55  }56  Personalities.clear();57}58 59void DwarfCFIException::beginFunction(const MachineFunction *MF) {60  shouldEmitPersonality = shouldEmitLSDA = false;61  const Function &F = MF->getFunction();62 63  // If any landing pads survive, we need an EH table.64  bool hasLandingPads = !MF->getLandingPads().empty();65 66  // See if we need frame move info.67  bool shouldEmitMoves =68      Asm->getFunctionCFISectionType(*MF) != AsmPrinter::CFISection::None;69 70  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();71  unsigned PerEncoding = TLOF.getPersonalityEncoding();72  const GlobalValue *Per = nullptr;73  if (F.hasPersonalityFn())74    Per = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());75 76  // Emit a personality function even when there are no landing pads77  forceEmitPersonality =78      // ...if a personality function is explicitly specified79      F.hasPersonalityFn() &&80      // ... and it's not known to be a noop in the absence of invokes81      !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&82      // ... and we're not explicitly asked not to emit it83      F.needsUnwindTableEntry();84 85  shouldEmitPersonality =86      (forceEmitPersonality ||87       (hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&88      Per;89 90  unsigned LSDAEncoding = TLOF.getLSDAEncoding();91  shouldEmitLSDA = shouldEmitPersonality &&92    LSDAEncoding != dwarf::DW_EH_PE_omit;93 94  const MCAsmInfo &MAI = *MF->getContext().getAsmInfo();95  if (MAI.getExceptionHandlingType() != ExceptionHandling::None)96    shouldEmitCFI =97        MAI.usesCFIForEH() && (shouldEmitPersonality || shouldEmitMoves);98  else99    shouldEmitCFI = Asm->usesCFIWithoutEH() && shouldEmitMoves;100}101 102void DwarfCFIException::beginBasicBlockSection(const MachineBasicBlock &MBB) {103  if (!shouldEmitCFI)104    return;105 106  if (!hasEmittedCFISections) {107    AsmPrinter::CFISection CFISecType = Asm->getModuleCFISectionType();108    // If we don't say anything it implies `.cfi_sections .eh_frame`, so we109    // chose not to be verbose in that case. And with `ForceDwarfFrameSection`,110    // we should always emit .debug_frame.111    if (CFISecType == AsmPrinter::CFISection::Debug ||112        Asm->TM.Options.ForceDwarfFrameSection ||113        Asm->TM.Options.MCOptions.EmitSFrameUnwind)114      Asm->OutStreamer->emitCFISections(115          CFISecType == AsmPrinter::CFISection::EH, true,116          Asm->TM.Options.MCOptions.EmitSFrameUnwind);117    hasEmittedCFISections = true;118  }119 120  Asm->OutStreamer->emitCFIStartProc(/*IsSimple=*/false);121 122  // Indicate personality routine, if any.123  if (!shouldEmitPersonality)124    return;125 126  auto &F = MBB.getParent()->getFunction();127  auto *P = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());128  assert(P && "Expected personality function");129  // Record the personality function.130  addPersonality(P);131 132  const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();133  unsigned PerEncoding = TLOF.getPersonalityEncoding();134  const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);135  Asm->OutStreamer->emitCFIPersonality(Sym, PerEncoding);136 137  // Provide LSDA information.138  if (shouldEmitLSDA)139    Asm->OutStreamer->emitCFILsda(Asm->getMBBExceptionSym(MBB),140                                  TLOF.getLSDAEncoding());141}142 143void DwarfCFIException::endBasicBlockSection(const MachineBasicBlock &MBB) {144  if (shouldEmitCFI)145    Asm->OutStreamer->emitCFIEndProc();146}147 148/// endFunction - Gather and emit post-function exception information.149///150void DwarfCFIException::endFunction(const MachineFunction *MF) {151  if (!shouldEmitPersonality)152    return;153 154  emitExceptionTable();155}156