Home | History | Annotate | Download | only in AsmPrinter
      1 //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains support for writing DWARF exception info into asm files.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "DwarfException.h"
     15 #include "llvm/ADT/SmallString.h"
     16 #include "llvm/ADT/StringExtras.h"
     17 #include "llvm/ADT/Twine.h"
     18 #include "llvm/CodeGen/AsmPrinter.h"
     19 #include "llvm/CodeGen/MachineFrameInfo.h"
     20 #include "llvm/CodeGen/MachineFunction.h"
     21 #include "llvm/CodeGen/MachineModuleInfo.h"
     22 #include "llvm/IR/DataLayout.h"
     23 #include "llvm/IR/Module.h"
     24 #include "llvm/MC/MCAsmInfo.h"
     25 #include "llvm/MC/MCContext.h"
     26 #include "llvm/MC/MCExpr.h"
     27 #include "llvm/MC/MCSection.h"
     28 #include "llvm/MC/MCStreamer.h"
     29 #include "llvm/MC/MCSymbol.h"
     30 #include "llvm/Support/CommandLine.h"
     31 #include "llvm/Support/Dwarf.h"
     32 #include "llvm/Support/FormattedStream.h"
     33 #include "llvm/Target/Mangler.h"
     34 #include "llvm/Target/TargetFrameLowering.h"
     35 #include "llvm/Target/TargetOptions.h"
     36 #include "llvm/Target/TargetRegisterInfo.h"
     37 using namespace llvm;
     38 
     39 static cl::opt<bool>
     40 EnableARMEHABIDescriptors("arm-enable-ehabi-descriptors", cl::Hidden,
     41   cl::desc("Generate ARM EHABI tables with unwinding descriptors"),
     42   cl::init(false));
     43 
     44 
     45 ARMException::ARMException(AsmPrinter *A)
     46   : DwarfException(A) {}
     47 
     48 ARMException::~ARMException() {}
     49 
     50 void ARMException::EndModule() {
     51 }
     52 
     53 /// BeginFunction - Gather pre-function exception information. Assumes it's
     54 /// being emitted immediately after the function entry point.
     55 void ARMException::BeginFunction(const MachineFunction *MF) {
     56   Asm->OutStreamer.EmitFnStart();
     57   if (Asm->MF->getFunction()->needsUnwindTableEntry())
     58     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
     59                                                   Asm->getFunctionNumber()));
     60 }
     61 
     62 /// EndFunction - Gather and emit post-function exception information.
     63 ///
     64 void ARMException::EndFunction() {
     65   if (!Asm->MF->getFunction()->needsUnwindTableEntry())
     66     Asm->OutStreamer.EmitCantUnwind();
     67   else {
     68     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
     69                                                   Asm->getFunctionNumber()));
     70 
     71     if (EnableARMEHABIDescriptors) {
     72       // Map all labels and get rid of any dead landing pads.
     73       MMI->TidyLandingPads();
     74 
     75       if (!MMI->getLandingPads().empty()) {
     76         // Emit references to personality.
     77         if (const Function * Personality =
     78             MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
     79           MCSymbol *PerSym = Asm->Mang->getSymbol(Personality);
     80           Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
     81           Asm->OutStreamer.EmitPersonality(PerSym);
     82         }
     83 
     84         // Emit .handlerdata directive.
     85         Asm->OutStreamer.EmitHandlerData();
     86 
     87         // Emit actual exception table
     88         EmitExceptionTable();
     89       }
     90     }
     91   }
     92 
     93   Asm->OutStreamer.EmitFnEnd();
     94 }
     95 
     96 void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
     97   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
     98   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
     99 
    100   bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
    101 
    102   int Entry = 0;
    103   // Emit the Catch TypeInfos.
    104   if (VerboseAsm && !TypeInfos.empty()) {
    105     Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
    106     Asm->OutStreamer.AddBlankLine();
    107     Entry = TypeInfos.size();
    108   }
    109 
    110   for (std::vector<const GlobalVariable *>::const_reverse_iterator
    111          I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
    112     const GlobalVariable *GV = *I;
    113     if (VerboseAsm)
    114       Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
    115     Asm->EmitTTypeReference(GV, TTypeEncoding);
    116   }
    117 
    118   // Emit the Exception Specifications.
    119   if (VerboseAsm && !FilterIds.empty()) {
    120     Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
    121     Asm->OutStreamer.AddBlankLine();
    122     Entry = 0;
    123   }
    124   for (std::vector<unsigned>::const_iterator
    125          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
    126     unsigned TypeID = *I;
    127     if (VerboseAsm) {
    128       --Entry;
    129       if (TypeID != 0)
    130         Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
    131     }
    132 
    133     Asm->EmitTTypeReference((TypeID == 0 ? 0 : TypeInfos[TypeID - 1]),
    134                             TTypeEncoding);
    135   }
    136 }
    137