Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
35271 views
//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//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//===----------------------------------------------------------------------===//7//8// This file contains support for writing DWARF exception info into asm files.9//10//===----------------------------------------------------------------------===//1112#include "DwarfException.h"13#include "llvm/BinaryFormat/Dwarf.h"14#include "llvm/CodeGen/AsmPrinter.h"15#include "llvm/CodeGen/MachineFunction.h"16#include "llvm/CodeGen/MachineModuleInfo.h"17#include "llvm/IR/Function.h"18#include "llvm/MC/MCAsmInfo.h"19#include "llvm/MC/MCContext.h"20#include "llvm/MC/MCStreamer.h"21#include "llvm/Target/TargetLoweringObjectFile.h"22#include "llvm/Target/TargetMachine.h"23#include "llvm/Target/TargetOptions.h"24using namespace llvm;2526DwarfCFIException::DwarfCFIException(AsmPrinter *A) : EHStreamer(A) {}2728DwarfCFIException::~DwarfCFIException() = default;2930void DwarfCFIException::addPersonality(const GlobalValue *Personality) {31if (!llvm::is_contained(Personalities, Personality))32Personalities.push_back(Personality);33}3435/// endModule - Emit all exception information that should come after the36/// content.37void DwarfCFIException::endModule() {38// SjLj uses this pass and it doesn't need this info.39if (!Asm->MAI->usesCFIForEH())40return;4142const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();4344unsigned PerEncoding = TLOF.getPersonalityEncoding();4546if ((PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)47return;4849// Emit indirect reference table for all used personality functions50for (const GlobalValue *Personality : Personalities) {51MCSymbol *Sym = Asm->getSymbol(Personality);52TLOF.emitPersonalityValue(*Asm->OutStreamer, Asm->getDataLayout(), Sym);53}54Personalities.clear();55}5657void DwarfCFIException::beginFunction(const MachineFunction *MF) {58shouldEmitPersonality = shouldEmitLSDA = false;59const Function &F = MF->getFunction();6061// If any landing pads survive, we need an EH table.62bool hasLandingPads = !MF->getLandingPads().empty();6364// See if we need frame move info.65bool shouldEmitMoves =66Asm->getFunctionCFISectionType(*MF) != AsmPrinter::CFISection::None;6768const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();69unsigned PerEncoding = TLOF.getPersonalityEncoding();70const GlobalValue *Per = nullptr;71if (F.hasPersonalityFn())72Per = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());7374// Emit a personality function even when there are no landing pads75forceEmitPersonality =76// ...if a personality function is explicitly specified77F.hasPersonalityFn() &&78// ... and it's not known to be a noop in the absence of invokes79!isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&80// ... and we're not explicitly asked not to emit it81F.needsUnwindTableEntry();8283shouldEmitPersonality =84(forceEmitPersonality ||85(hasLandingPads && PerEncoding != dwarf::DW_EH_PE_omit)) &&86Per;8788unsigned LSDAEncoding = TLOF.getLSDAEncoding();89shouldEmitLSDA = shouldEmitPersonality &&90LSDAEncoding != dwarf::DW_EH_PE_omit;9192const MCAsmInfo &MAI = *MF->getContext().getAsmInfo();93if (MAI.getExceptionHandlingType() != ExceptionHandling::None)94shouldEmitCFI =95MAI.usesCFIForEH() && (shouldEmitPersonality || shouldEmitMoves);96else97shouldEmitCFI = Asm->usesCFIWithoutEH() && shouldEmitMoves;98}99100void DwarfCFIException::beginBasicBlockSection(const MachineBasicBlock &MBB) {101if (!shouldEmitCFI)102return;103104if (!hasEmittedCFISections) {105AsmPrinter::CFISection CFISecType = Asm->getModuleCFISectionType();106// If we don't say anything it implies `.cfi_sections .eh_frame`, so we107// chose not to be verbose in that case. And with `ForceDwarfFrameSection`,108// we should always emit .debug_frame.109if (CFISecType == AsmPrinter::CFISection::Debug ||110Asm->TM.Options.ForceDwarfFrameSection)111Asm->OutStreamer->emitCFISections(112CFISecType == AsmPrinter::CFISection::EH, true);113hasEmittedCFISections = true;114}115116Asm->OutStreamer->emitCFIStartProc(/*IsSimple=*/false);117118// Indicate personality routine, if any.119if (!shouldEmitPersonality)120return;121122auto &F = MBB.getParent()->getFunction();123auto *P = dyn_cast<GlobalValue>(F.getPersonalityFn()->stripPointerCasts());124assert(P && "Expected personality function");125// Record the personality function.126addPersonality(P);127128const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();129unsigned PerEncoding = TLOF.getPersonalityEncoding();130const MCSymbol *Sym = TLOF.getCFIPersonalitySymbol(P, Asm->TM, MMI);131Asm->OutStreamer->emitCFIPersonality(Sym, PerEncoding);132133// Provide LSDA information.134if (shouldEmitLSDA)135Asm->OutStreamer->emitCFILsda(Asm->getMBBExceptionSym(MBB),136TLOF.getLSDAEncoding());137}138139void DwarfCFIException::endBasicBlockSection(const MachineBasicBlock &MBB) {140if (shouldEmitCFI)141Asm->OutStreamer->emitCFIEndProc();142}143144/// endFunction - Gather and emit post-function exception information.145///146void DwarfCFIException::endFunction(const MachineFunction *MF) {147if (!shouldEmitPersonality)148return;149150emitExceptionTable();151}152153154