DwarfException.cpp revision e2cf37b88c089a71727b3ecd466856f0cd638813
1eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===// 2eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 3eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// The LLVM Compiler Infrastructure 4eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 5eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// This file is distributed under the University of Illinois Open Source 6eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// License. See LICENSE.TXT for details. 7eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 8eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===----------------------------------------------------------------------===// 9eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 10eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// This file contains support for writing dwarf exception info into asm files. 11eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// 12eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===----------------------------------------------------------------------===// 13eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 14eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "DwarfException.h" 15eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Module.h" 16eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineModuleInfo.h" 17eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineFrameInfo.h" 18eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineLocation.h" 19eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Support/Dwarf.h" 20eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Support/Timer.h" 21eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Support/raw_ostream.h" 22eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetAsmInfo.h" 23eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetRegisterInfo.h" 24eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetData.h" 25eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetFrameInfo.h" 26eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetOptions.h" 27eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/ADT/StringExtras.h" 28eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingusing namespace llvm; 29eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 30eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingstatic TimerGroup &getDwarfTimerGroup() { 31eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling static TimerGroup DwarfTimerGroup("Dwarf Exception"); 32eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return DwarfTimerGroup; 33eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 34eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 35bc0d23afae781c45f92865c1c27bed0ce51fe545Bill WendlingDwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A, 36bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling const TargetAsmInfo *T) 37bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false), 38bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling shouldEmitTableModule(false), shouldEmitMovesModule(false), 39bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling ExceptionTimer(0) { 40bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling if (TimePassesIsEnabled) 41bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling ExceptionTimer = new Timer("Dwarf Exception Writer", 42bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling getDwarfTimerGroup()); 43bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling} 44bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 45bc0d23afae781c45f92865c1c27bed0ce51fe545Bill WendlingDwarfException::~DwarfException() { 46bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling delete ExceptionTimer; 47bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling} 48bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling 49eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EmitCommonEHFrame(const Function *Personality, 50eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned Index) { 51eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Size and sign of stack growth. 52eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int stackGrowth = 53eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->TM.getFrameInfo()->getStackGrowthDirection() == 54eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TargetFrameInfo::StackGrowsUp ? 55eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TD->getPointerSize() : -TD->getPointerSize(); 56eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 57eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Begin eh frame section. 58eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); 59eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 60e2cf37b88c089a71727b3ecd466856f0cd638813Chris Lattner if (TAI->is_EHSymbolPrivate()) 61e2cf37b88c089a71727b3ecd466856f0cd638813Chris Lattner O << TAI->getPrivateGlobalPrefix(); 62eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 63eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "EH_frame" << Index << ":\n"; 64eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("section_eh_frame", Index); 65eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 66eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Define base labels. 67eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_common", Index); 68eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 69eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Define the eh frame length. 70eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("eh_frame_common_end", Index, 71eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "eh_frame_common_begin", Index, true); 72eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Length of Common Information Entry"); 73eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 74eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // EH frame header. 75eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_common_begin", Index); 76eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt32((int)0); 77eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Identifier Tag"); 78eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_CIE_VERSION); 79eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Version"); 80eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 81eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // The personality presence indicates that language specific information will 82eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // show up in the eh frame. 83eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitString(Personality ? "zPLR" : "zR"); 84eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Augmentation"); 85eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 86eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Round out reader. 87eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(1); 88eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Code Alignment Factor"); 89eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitSLEB128Bytes(stackGrowth); 90eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Data Alignment Factor"); 91eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); 92eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("CIE Return Address Column"); 93eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 94eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If there is a personality, we need to indicate the functions location. 95eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (Personality) { 96eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(7); 97eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation Size"); 98eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 99eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TAI->getNeedsIndirectEncoding()) { 100eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4 | 101eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling dwarf::DW_EH_PE_indirect); 102eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Personality (pcrel sdata4 indirect)"); 103eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 104eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 105eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Personality (pcrel sdata4)"); 106eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 107eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 108eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrintRelDirective(true); 109eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << TAI->getPersonalityPrefix(); 110eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); 111eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << TAI->getPersonalitySuffix(); 112eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (strcmp(TAI->getPersonalitySuffix(), "+4@GOTPCREL")) 113eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "-" << TAI->getPCSymbol(); 114eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Personality"); 115eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 116eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 117eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("LSDA Encoding (pcrel sdata4)"); 118eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 119eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 120eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE Encoding (pcrel sdata4)"); 121eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 122eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(1); 123eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation Size"); 124eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 125eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 126eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE Encoding (pcrel sdata4)"); 127eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 128eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 129eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Indicate locations of general callee saved registers in frame. 130eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling std::vector<MachineMove> Moves; 131eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling RI->getInitialFrameState(Moves); 132eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitFrameMoves(NULL, 0, Moves, true); 133eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 134eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // On Darwin the linker honors the alignment of eh_frame, which means it must 135eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get 136eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // holes which confuse readers of eh_frame. 137eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 138eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 0, 0, false); 139eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_common_end", Index); 140eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 141eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL(); 142eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 143eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 144eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EmitEHFrame - Emit function exception frame information. 145eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 146eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) { 147eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() && 148eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "Should not emit 'available externally' functions at all"); 149eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 150eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Function::LinkageTypes linkage = EHFrameInfo.function->getLinkage(); 151eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); 152eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 153eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Externally visible entry into the functions eh frame info. If the 154eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // corresponding function is static, this should not be externally visible. 155eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (linkage != Function::InternalLinkage && 156eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling linkage != Function::PrivateLinkage) { 157eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (const char *GlobalEHDirective = TAI->getGlobalEHDirective()) 158eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; 159eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 160eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 161eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If corresponding function is weak definition, this should be too. 162eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if ((linkage == Function::WeakAnyLinkage || 163eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling linkage == Function::WeakODRLinkage || 164eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling linkage == Function::LinkOnceAnyLinkage || 165eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling linkage == Function::LinkOnceODRLinkage) && 166eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TAI->getWeakDefDirective()) 167eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; 168eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 169eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If there are no calls then you can't unwind. This may mean we can omit the 170eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // EH Frame, but some environments do not handle weak absolute symbols. If 171eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // UnwindTablesMandatory is set we cannot do this optimization; the unwind 172eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // info is to be available for non-EH uses. 173eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!EHFrameInfo.hasCalls && 174eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling !UnwindTablesMandatory && 175eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ((linkage != Function::WeakAnyLinkage && 176eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling linkage != Function::WeakODRLinkage && 177eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling linkage != Function::LinkOnceAnyLinkage && 178eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling linkage != Function::LinkOnceODRLinkage) || 179eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling !TAI->getWeakDefDirective() || 180eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TAI->getSupportsWeakOmittedEHFrame())) { 181eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << EHFrameInfo.FnName << " = 0\n"; 182eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // This name has no connection to the function, so it might get 183eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // dead-stripped when the function is not, erroneously. Prohibit 184eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // dead-stripping unconditionally. 185eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (const char *UsedDirective = TAI->getUsedDirective()) 186eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 187eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 188eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << EHFrameInfo.FnName << ":\n"; 189eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 190eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // EH frame header. 191eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("eh_frame_end", EHFrameInfo.Number, 192eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "eh_frame_begin", EHFrameInfo.Number, true); 193eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Length of Frame Information Entry"); 194eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 195eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_begin", EHFrameInfo.Number); 196eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 197e2cf37b88c089a71727b3ecd466856f0cd638813Chris Lattner if (!TAI->is_EHSymbolPrivate()) { 198e2cf37b88c089a71727b3ecd466856f0cd638813Chris Lattner// FIXME: HOW ARE THESE TWO ARMS DIFFERENT?? EH_frame vs eh_frame_common? 199eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrintRelDirective(true, true); 200eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrintLabelName("eh_frame_begin", EHFrameInfo.Number); 201eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 202eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!TAI->isAbsoluteEHSectionOffsets()) 203eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "-EH_frame" << EHFrameInfo.PersonalityIndex; 204eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 205eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitSectionOffset("eh_frame_begin", "eh_frame_common", 206eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, 207eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling true, true, false); 208eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 209eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 210eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE CIE offset"); 211eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 212eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); 213eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE initial location"); 214eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("eh_func_end", EHFrameInfo.Number, 215eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "eh_func_begin", EHFrameInfo.Number, true); 216eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("FDE address range"); 217eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 218eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If there is a personality and landing pads then point to the language 219eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // specific data area in the exception table. 220eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (EHFrameInfo.PersonalityIndex) { 221eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(4); 222eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation size"); 223eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 224eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (EHFrameInfo.hasLandingPads) 225eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitReference("exception", EHFrameInfo.Number, true, true); 226eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling else 227eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt32((int)0); 228eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Language Specific Data Area"); 229eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 230eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(0); 231eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Augmentation size"); 232eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 233eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 234eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Indicate locations of function specific callee saved registers in frame. 235eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, 236eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling true); 237eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 238eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // On Darwin the linker honors the alignment of eh_frame, which means it 239eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you 240eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // get holes which confuse readers of eh_frame. 241eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 242eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 0, 0, false); 243eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_frame_end", EHFrameInfo.Number); 244eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 245eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If the function is marked used, this table should be also. We cannot 246eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // make the mark unconditional in this case, since retaining the table also 247eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // retains the function in this case, and there is code around that depends 248eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // on unused functions (calling undefined externals) being dead-stripped to 249eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // link correctly. Yes, there really is. 250eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (MMI->getUsedFunctions().count(EHFrameInfo.function)) 251eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (const char *UsedDirective = TAI->getUsedDirective()) 252eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << UsedDirective << EHFrameInfo.FnName << "\n\n"; 253eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 254eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 255eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 256eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EmitExceptionTable - Emit landing pads and actions. 257eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 258eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// The general organization of the table is complex, but the basic concepts are 259eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// easy. First there is a header which describes the location and organization 260eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// of the three components that follow. 261eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 262eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 1. The landing pad site information describes the range of code covered by 263eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// the try. In our case it's an accumulation of the ranges covered by the 264eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// invokes in the try. There is also a reference to the landing pad that 265eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// handles the exception once processed. Finally an index into the actions 266eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// table. 267eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 2. The action table, in our case, is composed of pairs of type ids and next 268eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// action offset. Starting with the action index from the landing pad 269eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// site, each type Id is checked for a match to the current exception. If 270eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// it matches then the exception and type id are passed on to the landing 271eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// pad. Otherwise the next action is looked up. This chain is terminated 272eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// with a next action of zero. If no type id is found the the frame is 273eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// unwound and handling continues. 274eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 3. Type id table contains references to all the C++ typeinfo for all 275eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// catches in the function. This tables is reversed indexed base 1. 276eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 277eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// SharedTypeIds - How many leading type ids two landing pads have in common. 278eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingunsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 279eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *R) { 280eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 281eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 282eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 283eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned Count = 0; 284eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 285eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (; Count != MinSize; ++Count) 286eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[Count] != RIds[Count]) 287eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 288eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 289eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return Count; 290eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 291eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 292eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// PadLT - Order landing pads lexicographically by type id. 293eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingbool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 294eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 295eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LSize = LIds.size(), RSize = RIds.size(); 296eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned MinSize = LSize < RSize ? LSize : RSize; 297eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 298eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i != MinSize; ++i) 299eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LIds[i] != RIds[i]) 300eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LIds[i] < RIds[i]; 301eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 302eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling return LSize < RSize; 303eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 304eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 305eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EmitExceptionTable() { 306eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 307eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 308eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 309eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (PadInfos.empty()) return; 310eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 311eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Sort the landing pads in order of their type ids. This is used to fold 312eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // duplicate actions. 313eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<const LandingPadInfo *, 64> LandingPads; 314eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LandingPads.reserve(PadInfos.size()); 315eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 316eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LandingPads.push_back(&PadInfos[i]); 317eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 318eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 319eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Negative type ids index into FilterIds, positive type ids index into 320eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // TypeInfos. The value written for a positive type id is just the type id 321eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // itself. For a negative type id, however, the value written is the 322eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // (negative) byte offset of the corresponding FilterIds entry. The byte 323eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // offset is usually equal to the type id, because the FilterIds entries are 324eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // written using a variable width encoding which outputs one byte per entry as 325eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // long as the value written is not too large, but can differ. This kind of 326eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // complication does not occur for positive type ids because type infos are 327eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // output using a fixed width encoding. FilterOffsets[i] holds the byte 328eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // offset corresponding to FilterIds[i]. 329eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<int, 16> FilterOffsets; 330eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.reserve(FilterIds.size()); 331eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int Offset = -1; 332eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for(std::vector<unsigned>::const_iterator I = FilterIds.begin(), 333eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling E = FilterIds.end(); I != E; ++I) { 334eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FilterOffsets.push_back(Offset); 335eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Offset -= TargetAsmInfo::getULEB128Size(*I); 336eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 337eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 338eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute the actions table and gather the first action index for each 339eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // landing pad site. 340eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<ActionEntry, 32> Actions; 341eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<unsigned, 64> FirstActions; 342eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.reserve(LandingPads.size()); 343eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 344eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int FirstAction = 0; 345eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeActions = 0; 346eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 347eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *LP = LandingPads[i]; 348eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<int> &TypeIds = LP->TypeIds; 349eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0; 350eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeSiteActions = 0; 351eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 352eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared < TypeIds.size()) { 353eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeAction = 0; 354eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ActionEntry *PrevAction = 0; 355eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 356eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (NumShared) { 357eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size(); 358eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(Actions.size()); 359eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrevAction = &Actions.back(); 360eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) + 361eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 362eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 363eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned j = NumShared; j != SizePrevIds; ++j) { 364eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction -= 365eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 366eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction += -PrevAction->NextAction; 367eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrevAction = PrevAction->Previous; 368eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 369eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 370eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 371eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute the actions. 372eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) { 373eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int TypeID = TypeIds[I]; 374eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 375eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 376eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID); 377eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 378eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 379eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction); 380eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSiteActions += SizeAction; 381eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 382eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ActionEntry Action = {ValueForTypeID, NextAction, PrevAction}; 383eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Actions.push_back(Action); 384eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 385eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrevAction = &Actions.back(); 386eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 387eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 388eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Record the first action of the landing pad site. 389eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 390eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } // else identical - re-use previous FirstAction 391eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 392eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions.push_back(FirstAction); 393eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 394eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute this sites contribution to size. 395eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeActions += SizeSiteActions; 396eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 397eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 398eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Compute the call-site table. The entry for an invoke has a try-range 399eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // containing the call, a non-zero landing pad and an appropriate action. The 400eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // entry for an ordinary call has a try-range containing the call and zero for 401eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // the landing pad and the action. Calls marked 'nounwind' have no entry and 402eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // must not be contained in the try-range of any entry - they form gaps in the 403eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // table. Entries must be ordered by try-range address. 404eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SmallVector<CallSiteEntry, 64> CallSites; 405eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 406eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling RangeMapType PadMap; 407eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 408eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Invokes and nounwind calls have entries in PadMap (due to being bracketed 409eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // by try-range labels when lowered). Ordinary calls do not, so appropriate 410eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // try-ranges for them need be deduced. 411eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 412eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *LandingPad = LandingPads[i]; 413eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 414eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned BeginLabel = LandingPad->BeginLabels[j]; 415eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 416eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PadRange P = { i, j }; 417eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PadMap[BeginLabel] = P; 418eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 419eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 420eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 421eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // The end label of the previous invoke or nounwind try-range. 422eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned LastLabel = 0; 423eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 424eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Whether there is a potentially throwing instruction (currently this means 425eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // an ordinary call) between the end of the previous try-range and now. 426eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool SawPotentiallyThrowing = false; 427eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 428eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Whether the last callsite entry was for an invoke. 429eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling bool PreviousIsInvoke = false; 430eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 431eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Visit all instructions in order of address. 432eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 433eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling I != E; ++I) { 434eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 435eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MI != E; ++MI) { 436eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!MI->isLabel()) { 437eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SawPotentiallyThrowing |= MI->getDesc().isCall(); 438eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 439eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 440eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 441eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned BeginLabel = MI->getOperand(0).getImm(); 442eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel && "Invalid label!"); 443eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 444eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // End of the previous try-range? 445eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (BeginLabel == LastLabel) 446eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SawPotentiallyThrowing = false; 447eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 448eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Beginning of a new try-range? 449eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling RangeMapType::iterator L = PadMap.find(BeginLabel); 450eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (L == PadMap.end()) 451eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Nope, it was just some random label. 452eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 453eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 454eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PadRange P = L->second; 455eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 456eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 457eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 458eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling "Inconsistent landing pad map!"); 459eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 460eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If some instruction between the previous try-range and this one may 461eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // throw, create a call-site entry with no landing pad for the region 462eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // between the try-ranges. 463eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (SawPotentiallyThrowing) { 464eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0}; 465eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 466eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = false; 467eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 468eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 469eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LastLabel = LandingPad->EndLabels[P.RangeIndex]; 470eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling assert(BeginLabel && LastLabel && "Invalid landing pad!"); 471eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 472eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (LandingPad->LandingPadLabel) { 473eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // This try-range is for an invoke. 474eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry Site = {BeginLabel, LastLabel, 475eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LandingPad->LandingPadLabel, 476eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling FirstActions[P.PadIndex]}; 477eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 478eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Try to merge with the previous call-site. 479eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (PreviousIsInvoke) { 480eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry &Prev = CallSites.back(); 481eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 482eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Extend the range of the previous entry. 483eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Prev.EndLabel = Site.EndLabel; 484eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling continue; 485eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 486eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 487eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 488eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Otherwise, create a new call-site. 489eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 490eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = true; 491eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 492eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Create a gap. 493eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PreviousIsInvoke = false; 494eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 495eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 496eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 497eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 498eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If some instruction between the previous try-range and the end of the 499eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // function may throw, create a call-site entry with no landing pad for the 500eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // region following the try-range. 501eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (SawPotentiallyThrowing) { 502eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry Site = {LastLabel, 0, 0, 0}; 503eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSites.push_back(Site); 504eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 505eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 506eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Final tallies. 507eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 508eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Call sites. 509eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4 510eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4 511eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4 512eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeSites = CallSites.size() * (SiteStartSize + 513eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SiteLengthSize + 514eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling LandingPadSize); 515eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0, e = CallSites.size(); i < e; ++i) 516eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action); 517eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 518eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Type infos. 519eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr 520eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeTypes = TypeInfos.size() * TypeInfoSize; 521eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 522eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned TypeOffset = sizeof(int8_t) + // Call site format 523eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TargetAsmInfo::getULEB128Size(SizeSites) + // Call-site table length 524eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SizeSites + SizeActions + SizeTypes; 525eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 526eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned TotalSize = sizeof(int8_t) + // LPStart format 527eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling sizeof(int8_t) + // TType format 528eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset 529eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling TypeOffset; 530eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 531eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned SizeAlign = (4 - TotalSize) & 3; 532eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 533eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Begin the exception table. 534eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->SwitchToDataSection(TAI->getDwarfExceptionSection()); 535eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(2, 0, 0, false); 536eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "GCC_except_table" << SubprogramCount << ":\n"; 537eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 538eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i != SizeAlign; ++i) { 539eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(0); 540eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Padding"); 541eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 542eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 543eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("exception", SubprogramCount); 544eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 545eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Emit the header. 546eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_omit); 547eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("LPStart format (DW_EH_PE_omit)"); 548eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_absptr); 549eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("TType format (DW_EH_PE_absptr)"); 550eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(TypeOffset); 551eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("TType base offset"); 552eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt8(dwarf::DW_EH_PE_udata4); 553eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Call site format (DW_EH_PE_udata4)"); 554eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(SizeSites); 555eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Call-site table length"); 556eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 557eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Emit the landing pad site information. 558eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i < CallSites.size(); ++i) { 559eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling CallSiteEntry &S = CallSites[i]; 560eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const char *BeginTag; 561eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned BeginNumber; 562eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 563eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!S.BeginLabel) { 564eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling BeginTag = "eh_func_begin"; 565eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling BeginNumber = SubprogramCount; 566eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 567eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling BeginTag = "label"; 568eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling BeginNumber = S.BeginLabel; 569eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 570eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 571eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, 572eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling true, true); 573eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Region start"); 574eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 575eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!S.EndLabel) 576eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, 577eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling true); 578eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling else 579eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); 580eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 581eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Region length"); 582eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 583eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!S.PadLabel) 584eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitInt32(0); 585eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling else 586eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, 587eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling true, true); 588eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 589eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Landing pad"); 590eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 591eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(S.Action); 592eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Action"); 593eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 594eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 595eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Emit the actions. 596eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned I = 0, N = Actions.size(); I != N; ++I) { 597eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ActionEntry &Action = Actions[I]; 598eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 599eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitSLEB128Bytes(Action.ValueForTypeID); 600eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("TypeInfo index"); 601eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitSLEB128Bytes(Action.NextAction); 602eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Next action"); 603eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 604eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 605eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Emit the type ids. 606eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned M = TypeInfos.size(); M; --M) { 607eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling GlobalVariable *GV = TypeInfos[M - 1]; 608eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling PrintRelDirective(); 609eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 610eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (GV) { 611eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling std::string GLN; 612eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << Asm->getGlobalLinkName(GV, GLN); 613eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } else { 614eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling O << "0"; 615eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 616eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 617eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("TypeInfo"); 618eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 619eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 620eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Emit the filter typeids. 621eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) { 622eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling unsigned TypeID = FilterIds[j]; 623eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitULEB128Bytes(TypeID); 624eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EOL("Filter TypeInfo index"); 625eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 626eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 627eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling Asm->EmitAlignment(2, 0, 0, false); 628eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 629eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 630eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndModule - Emit all exception information that should come after the 631eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// content. 632eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndModule() { 633eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 634eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->startTimer(); 635eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 636eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (shouldEmitMovesModule || shouldEmitTableModule) { 637eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling const std::vector<Function *> Personalities = MMI->getPersonalities(); 638eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (unsigned i = 0; i < Personalities.size(); ++i) 639eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitCommonEHFrame(Personalities[i], i); 640eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 641eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(), 642eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling E = EHFrames.end(); I != E; ++I) 643eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitEHFrame(*I); 644eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 645eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 646eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 647eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->stopTimer(); 648eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 649eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 650eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// BeginFunction - Gather pre-function exception information. Assumes being 651eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// emitted immediately after the function entry point. 652eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::BeginFunction(MachineFunction *MF) { 653eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 654eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->startTimer(); 655eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 656eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling this->MF = MF; 657eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitTable = shouldEmitMoves = false; 658eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 659eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (MMI && TAI->doesSupportExceptionHandling()) { 660eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Map all labels and get rid of any dead landing pads. 661eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MMI->TidyLandingPads(); 662eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 663eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // If any landing pads survive, we need an EH table. 664eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (MMI->getLandingPads().size()) 665eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitTable = true; 666eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 667eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // See if we need frame move info. 668eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) 669eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitMoves = true; 670eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 671eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (shouldEmitMoves || shouldEmitTable) 672eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Assumes in correct section after the entry point. 673eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_func_begin", ++SubprogramCount); 674eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 675eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 676eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitTableModule |= shouldEmitTable; 677eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling shouldEmitMovesModule |= shouldEmitMoves; 678eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 679eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 680eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->stopTimer(); 681eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 682eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 683eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndFunction - Gather and emit post-function exception information. 684eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// 685eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndFunction() { 686eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 687eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->startTimer(); 688eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 689eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (shouldEmitMoves || shouldEmitTable) { 690eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitLabel("eh_func_end", SubprogramCount); 691eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EmitExceptionTable(); 692eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 693eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling // Save EH frame information 694eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling EHFrames.push_back( 695e2cf37b88c089a71727b3ecd466856f0cd638813Chris Lattner FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF), 696eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling SubprogramCount, 697eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MMI->getPersonalityIndex(), 698eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MF->getFrameInfo()->hasCalls(), 699eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling !MMI->getLandingPads().empty(), 700eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MMI->getFrameMoves(), 701eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling MF->getFunction())); 702eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling } 703eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling 704eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling if (TimePassesIsEnabled) 705eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling ExceptionTimer->stopTimer(); 706eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling} 707