119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===// 219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The LLVM Compiler Infrastructure 419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source 619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details. 719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file contains support for writing DWARF exception info into asm files. 1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "DwarfException.h" 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Module.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/AsmPrinter.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineModuleInfo.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFrameInfo.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFunction.h" 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAsmInfo.h" 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCContext.h" 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCExpr.h" 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCSection.h" 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCStreamer.h" 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCSymbol.h" 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/Mangler.h" 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetData.h" 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetFrameLowering.h" 2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetLoweringObjectFile.h" 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetMachine.h" 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetOptions.h" 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetRegisterInfo.h" 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Dwarf.h" 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/FormattedStream.h" 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/SmallString.h" 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringExtras.h" 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Twine.h" 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm; 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDwarfException::DwarfException(AsmPrinter *A) 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : Asm(A), MMI(Asm->MMI) {} 4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDwarfException::~DwarfException() {} 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// SharedTypeIds - How many leading type ids two landing pads have in common. 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned DwarfException::SharedTypeIds(const LandingPadInfo *L, 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const LandingPadInfo *R) { 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned LSize = LIds.size(), RSize = RIds.size(); 5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MinSize = LSize < RSize ? LSize : RSize; 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Count = 0; 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (; Count != MinSize; ++Count) 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (LIds[Count] != RIds[Count]) 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Count; 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Count; 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// PadLT - Order landing pads lexicographically by type id. 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned LSize = LIds.size(), RSize = RIds.size(); 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MinSize = LSize < RSize ? LSize : RSize; 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != MinSize; ++i) 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (LIds[i] != RIds[i]) 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return LIds[i] < RIds[i]; 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return LSize < RSize; 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ComputeActionsTable - Compute the actions table and gather the first action 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// index for each landing pad site. 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned DwarfException:: 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads, 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVectorImpl<ActionEntry> &Actions, 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVectorImpl<unsigned> &FirstActions) { 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The action table follows the call-site table in the LSDA. The individual 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // records are of two types: 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * Catch clause 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * Exception specification 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The two record kinds have the same format, with only small differences. 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // They are distinguished by the "switch value" field: Catch clauses 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // (TypeInfos) have strictly positive switch values, and exception 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // specifications (FilterIds) have strictly negative switch values. Value 0 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // indicates a catch-all clause. 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Negative type IDs index into FilterIds. Positive type IDs index into 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // TypeInfos. The value written for a positive type ID is just the type ID 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // itself. For a negative type ID, however, the value written is the 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // (negative) byte offset of the corresponding FilterIds entry. The byte 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // offset is usually equal to the type ID (because the FilterIds entries are 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // written using a variable width encoding, which outputs one byte per entry 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // as long as the value written is not too large) but can differ. This kind 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // of complication does not occur for positive type IDs because type infos are 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // output using a fixed width encoding. FilterOffsets[i] holds the byte 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // offset corresponding to FilterIds[i]. 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<int, 16> FilterOffsets; 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FilterOffsets.reserve(FilterIds.size()); 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int Offset = -1; 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (std::vector<unsigned>::const_iterator 10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) { 11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FilterOffsets.push_back(Offset); 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset -= MCAsmInfo::getULEB128Size(*I); 11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FirstActions.reserve(LandingPads.size()); 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FirstAction = 0; 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeActions = 0; 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const LandingPadInfo *PrevLPI = 0; 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (SmallVectorImpl<const LandingPadInfo *>::const_iterator 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) { 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const LandingPadInfo *LPI = *I; 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<int> &TypeIds = LPI->TypeIds; 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0; 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeSiteActions = 0; 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (NumShared < TypeIds.size()) { 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeAction = 0; 12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned PrevAction = (unsigned)-1; 13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (NumShared) { 13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizePrevIds = PrevLPI->TypeIds.size(); 13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Actions.size()); 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PrevAction = Actions.size() - 1; 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeAction = 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) + 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned j = NumShared; j != SizePrevIds; ++j) { 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!"); 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeAction -= 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID); 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeAction += -Actions[PrevAction].NextAction; 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PrevAction = Actions[PrevAction].Previous; 14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Compute the actions. 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) { 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int TypeID = TypeIds[J]; 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID); 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction); 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeSiteActions += SizeAction; 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ActionEntry Action = { ValueForTypeID, NextAction, PrevAction }; 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Actions.push_back(Action); 16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PrevAction = Actions.size() - 1; 16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Record the first action of the landing pad site. 16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } // else identical - re-use previous FirstAction 16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Information used when created the call-site table. The action record 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // field of the call site record is the offset of the first associated 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // action record, relative to the start of the actions table. This value is 17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // biased by 1 (1 indicating the start of the actions table), and 0 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // indicates that there are no actions. 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FirstActions.push_back(FirstAction); 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Compute this sites contribution to size. 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeActions += SizeSiteActions; 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PrevLPI = LPI; 17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SizeActions; 18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// CallToNoUnwindFunction - Return `true' if this is a call to a function 18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// marked `nounwind'. Return `false' otherwise. 18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool DwarfException::CallToNoUnwindFunction(const MachineInstr *MI) { 18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(MI->getDesc().isCall() && "This should be a call instruction!"); 18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool MarkedNoUnwind = false; 19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool SawFunc = false; 19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MachineOperand &MO = MI->getOperand(I); 19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!MO.isGlobal()) continue; 19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const Function *F = dyn_cast<Function>(MO.getGlobal()); 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (F == 0) continue; 19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SawFunc) { 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Be conservative. If we have more than one function operand for this 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // call, then we can't make the assumption that it's the callee and 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // not a parameter to the call. 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: Determine if there's a way to say that `F' is the callee or 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // parameter. 20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MarkedNoUnwind = false; 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MarkedNoUnwind = F->doesNotThrow(); 21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SawFunc = true; 21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return MarkedNoUnwind; 21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ComputeCallSiteTable - Compute the call-site table. The entry for an invoke 21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// has a try-range containing the call, a non-zero landing pad, and an 22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// appropriate action. The entry for an ordinary call has a try-range 22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// containing the call and zero for the landing pad and the action. Calls 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// marked 'nounwind' have no entry and must not be contained in the try-range 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// of any entry - they form gaps in the table. Entries must be ordered by 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// try-range address. 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DwarfException:: 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const RangeMapType &PadMap, 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const SmallVectorImpl<const LandingPadInfo *> &LandingPads, 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const SmallVectorImpl<unsigned> &FirstActions) { 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The end label of the previous invoke or nounwind try-range. 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *LastLabel = 0; 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Whether there is a potentially throwing instruction (currently this means 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // an ordinary call) between the end of the previous try-range and now. 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool SawPotentiallyThrowing = false; 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Whether the last CallSite entry was for an invoke. 23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool PreviousIsInvoke = false; 23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Visit all instructions in order of address. 24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end(); 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I != E; ++I) { 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MI != E; ++MI) { 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!MI->isLabel()) { 24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (MI->getDesc().isCall()) 24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SawPotentiallyThrowing |= !CallToNoUnwindFunction(MI); 24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // End of the previous try-range? 25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol(); 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (BeginLabel == LastLabel) 25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SawPotentiallyThrowing = false; 25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Beginning of a new try-range? 25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RangeMapType::const_iterator L = PadMap.find(BeginLabel); 25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (L == PadMap.end()) 25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Nope, it was just some random label. 26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const PadRange &P = L->second; 26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Inconsistent landing pad map!"); 26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // For Dwarf exception handling (SjLj handling doesn't use this). If some 26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // instruction between the previous try-range and this one may throw, 26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // create a call-site entry with no landing pad for the region between the 27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // try-ranges. 27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) { 27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 }; 27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSites.push_back(Site); 27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PreviousIsInvoke = false; 27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LastLabel = LandingPad->EndLabels[P.RangeIndex]; 27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(BeginLabel && LastLabel && "Invalid landing pad!"); 27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!LandingPad->LandingPadLabel) { 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Create a gap. 28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PreviousIsInvoke = false; 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This try-range is for an invoke. 28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteEntry Site = { 28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BeginLabel, 28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LastLabel, 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LandingPad->LandingPadLabel, 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FirstActions[P.PadIndex] 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Try to merge with the previous call-site. SJLJ doesn't do this 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (PreviousIsInvoke && Asm->MAI->isExceptionHandlingDwarf()) { 29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteEntry &Prev = CallSites.back(); 29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Extend the range of the previous entry. 29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Prev.EndLabel = Site.EndLabel; 29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Otherwise, create a new call-site. 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Asm->MAI->isExceptionHandlingDwarf()) 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSites.push_back(Site); 30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else { 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // SjLj EH must maintain the call sites in the order assigned 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // to them by the SjLjPrepare pass. 30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel); 30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (CallSites.size() < SiteNo) 31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSites.resize(SiteNo); 31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSites[SiteNo - 1] = Site; 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PreviousIsInvoke = true; 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If some instruction between the previous try-range and the end of the 31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // function may throw, create a call-site entry with no landing pad for the 32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // region following the try-range. 32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) { 32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteEntry Site = { LastLabel, 0, 0, 0 }; 32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSites.push_back(Site); 32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// EmitExceptionTable - Emit landing pads and actions. 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// The general organization of the table is complex, but the basic concepts are 33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// easy. First there is a header which describes the location and organization 33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// of the three components that follow. 33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 1. The landing pad site information describes the range of code covered by 33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// the try. In our case it's an accumulation of the ranges covered by the 33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// invokes in the try. There is also a reference to the landing pad that 33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// handles the exception once processed. Finally an index into the actions 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// table. 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 2. The action table, in our case, is composed of pairs of type IDs and next 33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// action offset. Starting with the action index from the landing pad 34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// site, each type ID is checked for a match to the current exception. If 34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// it matches then the exception and type id are passed on to the landing 34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// pad. Otherwise the next action is looked up. This chain is terminated 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// with a next action of zero. If no type id is found then the frame is 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// unwound and handling continues. 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 3. Type ID table contains references to all the C++ typeinfo for all 34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// catches in the function. This tables is reverse indexed base 1. 34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DwarfException::EmitExceptionTable() { 34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Sort the landing pads in order of their type ids. This is used to fold 35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // duplicate actions. 35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<const LandingPadInfo *, 64> LandingPads; 35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LandingPads.reserve(PadInfos.size()); 35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LandingPads.push_back(&PadInfos[i]); 35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Compute the actions table and gather the first action index for each 36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // landing pad site. 36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<ActionEntry, 32> Actions; 36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<unsigned, 64> FirstActions; 36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions); 36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Invokes and nounwind calls have entries in PadMap (due to being bracketed 36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // by try-range labels when lowered). Ordinary calls do not, so appropriate 37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // try-ranges for them need be deduced when using DWARF exception handling. 37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RangeMapType PadMap; 37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const LandingPadInfo *LandingPad = LandingPads[i]; 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; 37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PadRange P = { i, j }; 37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PadMap[BeginLabel] = P; 37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Compute the call-site table. 38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<CallSiteEntry, 64> CallSites; 38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions); 38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Final tallies. 38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Call sites. 38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj; 39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true; 39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned CallSiteTableLength; 39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (IsSJLJ) 39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteTableLength = 0; 39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else { 39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SiteStartSize = 4; // dwarf::DW_EH_PE_udata4 39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4 39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4 39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteTableLength = 40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize); 40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = CallSites.size(); i < e; ++i) { 40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action); 40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (IsSJLJ) 40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteTableLength += MCAsmInfo::getULEB128Size(i); 40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Type infos. 41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection(); 41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TTypeEncoding; 41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TypeFormatSize; 41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!HaveTTData) { 41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say 41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // that we're omitting that bit. 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TTypeEncoding = dwarf::DW_EH_PE_omit; 41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // dwarf::DW_EH_PE_absptr 41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeFormatSize = Asm->getTargetData().getPointerSize(); 42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Okay, we have actual filters or typeinfos to emit. As such, we need to 42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // pick a type encoding for them. We're about to emit a list of pointers to 42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // typeinfo objects at the end of the LSDA. However, unless we're in static 42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // mode, this reference will require a relocation by the dynamic linker. 42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Because of this, we have a couple of options: 42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 1) If we are in -static mode, we can always use an absolute reference 42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // from the LSDA, because the static linker will resolve it. 43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 2) Otherwise, if the LSDA section is writable, we can output the direct 43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // reference to the typeinfo and allow the dynamic linker to relocate 43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // it. Since it is in a writable section, the dynamic linker won't 43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // have a problem. 43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 3) Finally, if we're in PIC mode and the LDSA section isn't writable, 43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // we need to use some form of indirection. For example, on Darwin, 43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // we can output a statically-relocatable reference to a dyld stub. The 43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // offset to the stub is constant, but the contents are in a section 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // that is updated by the dynamic linker. This is easy enough, but we 44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // need to tell the personality function of the unwinder to indirect 44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // through the dyld stub. 44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: When (3) is actually implemented, we'll have to emit the stubs 44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // somewhere. This predicate should be moved to a shared location that is 44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // in target-independent code. 44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding(); 44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding); 45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Begin the exception table. 45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Sometimes we want not to emit the data into separate section (e.g. ARM 45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // EHABI). In this case LSDASection will be NULL. 45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (LSDASection) 45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.SwitchSection(LSDASection); 45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitAlignment(2); 45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit the LSDA. 46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *GCCETSym = 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+ 46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Twine(Asm->getFunctionNumber())); 46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.EmitLabel(GCCETSym); 46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("exception", 46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->getFunctionNumber())); 46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (IsSJLJ) 46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("_LSDA_", 46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->getFunctionNumber())); 47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit the LSDA header. 47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); 47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitEncodingByte(TTypeEncoding, "@TType"); 47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The type infos need to be aligned. GCC does this by inserting padding just 47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // before the type infos. However, this changes the size of the exception 47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // table, so you need to take this into account when you output the exception 47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // table size. However, the size is output using a variable length encoding. 47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // So by increasing the size by inserting padding, you may increase the number 48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // of bytes used for writing the size. If it increases, say by one byte, then 48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // you now need to output one less byte of padding to get the type infos 48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // aligned. However this decreases the size of the exception table. This 48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // changes the value you have to output for the exception table size. Due to 48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the variable length encoding, the number of bytes used for writing the 48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // length may decrease. If so, you then have to increase the amount of 48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // padding. And so on. If you look carefully at the GCC code you will see that 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // it indeed does this in a loop, going on and on until the values stabilize. 48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We chose another solution: don't output padding inside the table like GCC 48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // does, instead output it before the table. 49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeTypes = TypeInfos.size() * TypeFormatSize; 49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned CallSiteTableLengthSize = 49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCAsmInfo::getULEB128Size(CallSiteTableLength); 49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TTypeBaseOffset = 49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sizeof(int8_t) + // Call site format 49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteTableLengthSize + // Call site table length size 49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CallSiteTableLength + // Call site table length 49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeActions + // Actions size 49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeTypes; 49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TTypeBaseOffsetSize = MCAsmInfo::getULEB128Size(TTypeBaseOffset); 50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TotalSize = 50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sizeof(int8_t) + // LPStart format 50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman sizeof(int8_t) + // TType format 50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size 50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TTypeBaseOffset; // TType base offset 50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeAlign = (4 - TotalSize) & 3; 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (HaveTTData) { 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Account for any extra padding that will be added to the call site table 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // length. 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign); 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeAlign = 0; 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool VerboseAsm = Asm->OutStreamer.isVerboseAsm(); 51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // SjLj Exception handling 51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (IsSJLJ) { 51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add extra padding if it wasn't added to the TType base offset. 52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit the landing pad site information. 52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned idx = 0; 52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (SmallVectorImpl<CallSiteEntry>::const_iterator 52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) { 52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CallSiteEntry &S = *I; 52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Offset of the landing pad, counted in 16-byte bundles relative to the 53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // @LPStart address. 53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) { 53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(">> Call Site ") + 53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::utostr(idx) + " <<"); 53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" On exception at call site ") + 53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::utostr(idx)); 53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitULEB128(idx); 53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Offset of the first associated action record, relative to the start of 54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the action table. This value is biased by 1 (1 indicates the start of 54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the action table), and 0 indicates that there are no actions. 54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) { 54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (S.Action == 0) 54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(" Action: cleanup"); 54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" Action: ") + 54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::utostr((S.Action - 1) / 2 + 1)); 54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitULEB128(S.Action); 55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // DWARF Exception handling 55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Asm->MAI->isExceptionHandlingDwarf()); 55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The call-site table is a list of all call sites that may throw an 55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // exception (including C++ 'throw' statements) in the procedure 55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // fragment. It immediately follows the LSDA header. Each entry indicates, 55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // for a given call, the first corresponding action record and corresponding 55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // landing pad. 56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The table begins with the number of bytes, stored as an LEB128 56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // compressed, unsigned integer. The records immediately follow the record 56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // count. They are sorted in increasing call-site address. Each record 56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // indicates: 56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * The position of the call-site. 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * The position of the landing pad. 56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // * The first action record for that call site. 56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // A missing entry in the call-site table indicates that a call is not 57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // supposed to throw. 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit the landing pad call site table. 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add extra padding if it wasn't added to the TType base offset. 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign); 57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Entry = 0; 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (SmallVectorImpl<CallSiteEntry>::const_iterator 58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CallSiteEntry &S = *I; 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *EHFuncBeginSym = 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber()); 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *BeginLabel = S.BeginLabel; 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (BeginLabel == 0) 58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BeginLabel = EHFuncBeginSym; 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *EndLabel = S.EndLabel; 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (EndLabel == 0) 59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Offset of the call site relative to the previous call site, counted in 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // number of 16-byte bundles. The first call site is counted relative to 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the start of the procedure fragment. 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) 59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(">> Call Site ") + 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::utostr(++Entry) + " <<"); 60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4); 60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) 60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" Call between ") + 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BeginLabel->getName() + " and " + 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EndLabel->getName()); 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitLabelDifference(EndLabel, BeginLabel, 4); 60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Offset of the landing pad, counted in 16-byte bundles relative to the 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // @LPStart address. 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!S.PadLabel) { 61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) 61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(" has no landing pad"); 61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); 61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" jumps to ") + 61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman S.PadLabel->getName()); 61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4); 61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Offset of the first associated action record, relative to the start of 62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the action table. This value is biased by 1 (1 indicates the start of 62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the action table), and 0 indicates that there are no actions. 62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) { 62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (S.Action == 0) 62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(" On action: cleanup"); 62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" On action: ") + 62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::utostr((S.Action - 1) / 2 + 1)); 63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitULEB128(S.Action); 63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit the Action Table. 63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int Entry = 0; 63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (SmallVectorImpl<ActionEntry>::const_iterator 63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = Actions.begin(), E = Actions.end(); I != E; ++I) { 63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const ActionEntry &Action = *I; 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) { 64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit comments that decode the action table. 64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(">> Action Record ") + 64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::utostr(++Entry) + " <<"); 64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Type Filter 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Used by the runtime to match the type of the thrown exception to the 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // type of the catch clauses or the types in the exception specification. 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) { 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Action.ValueForTypeID > 0) 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" Catch TypeInfo ") + 65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::itostr(Action.ValueForTypeID)); 65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (Action.ValueForTypeID < 0) 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" Filter TypeInfo ") + 65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::itostr(Action.ValueForTypeID)); 65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(" Cleanup"); 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitSLEB128(Action.ValueForTypeID); 66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Action Record 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // 66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Self-relative signed displacement in bytes of the next action record, 66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // or 0 if there is no next action record. 66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) { 66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Action.NextAction == 0) { 66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(" No further actions"); 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NextAction = Entry + (Action.NextAction + 1) / 2; 67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine(" Continue to action ") + 67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman llvm::utostr(NextAction)); 67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitSLEB128(Action.NextAction); 67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit the Catch TypeInfos. 68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm && !TypeInfos.empty()) { 68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(">> Catch TypeInfos <<"); 68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddBlankLine(); 68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry = TypeInfos.size(); 68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (std::vector<const GlobalVariable *>::const_reverse_iterator 68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { 68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const GlobalVariable *GV = *I; 68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) 69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine("TypeInfo ") + llvm::utostr(Entry--)); 69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (GV) 69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitReference(GV, TTypeEncoding); 69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding), 69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 0); 69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Emit the Exception Specifications. 69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm && !FilterIds.empty()) { 70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(">> Filter TypeInfos <<"); 70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddBlankLine(); 70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry = 0; 70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (std::vector<unsigned>::const_iterator 70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { 70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned TypeID = *I; 70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (VerboseAsm) { 70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman --Entry; 70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TypeID != 0) 71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->OutStreamer.AddComment(Twine("FilterInfo ") + llvm::itostr(Entry)); 71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitULEB128(TypeID); 71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Asm->EmitAlignment(2); 71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// EndModule - Emit all exception information that should come after the 72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// content. 72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DwarfException::EndModule() { 72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(0 && "Should be implemented"); 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// BeginFunction - Gather pre-function exception information. Assumes it's 72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// being emitted immediately after the function entry point. 72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DwarfException::BeginFunction(const MachineFunction *MF) { 72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(0 && "Should be implemented"); 72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// EndFunction - Gather and emit post-function exception information. 73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid DwarfException::EndFunction() { 73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(0 && "Should be implemented"); 73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 736