diff options
author | Bill Wendling <isanbard@gmail.com> | 2009-05-15 01:12:28 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2009-05-15 01:12:28 +0000 |
commit | eb9072195ca7d777a71194dcaaaa369d82f24f53 (patch) | |
tree | e491a2e76a9c7f13ea296ead1b35a1ef86a582aa /lib/CodeGen/AsmPrinter/DwarfWriter.cpp | |
parent | 88423eecd0f16d3cfa89bdf92abdb72a5dc0616a (diff) |
Split out the DwarfException class into its own file. No functionality change,
though the classes have been marked with "VISIBILITY_HIDDEN".
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71827 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfWriter.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 776 |
1 files changed, 7 insertions, 769 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 83275fb92e..71f73a59f5 100644 --- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -13,6 +13,7 @@ #include "llvm/CodeGen/DwarfWriter.h" #include "DIE.h" +#include "DwarfException.h" #include "DwarfPrinter.h" #include "llvm/Module.h" #include "llvm/DerivedTypes.h" @@ -68,7 +69,7 @@ static const unsigned InitValuesSetSize = 9; // log2(512) //===----------------------------------------------------------------------===// /// CompileUnit - This dwarf writer support class manages information associate /// with a source file. -class CompileUnit { +class VISIBILITY_HIDDEN CompileUnit { /// ID - File identifier for source. /// unsigned ID; @@ -153,7 +154,7 @@ public: //===----------------------------------------------------------------------===// /// SrcLineInfo - This class is used to record source line correspondence. /// -class SrcLineInfo { +class VISIBILITY_HIDDEN SrcLineInfo { unsigned Line; // Source line number. unsigned Column; // Source column. unsigned SourceID; // Source ID number. @@ -172,7 +173,7 @@ public: //===----------------------------------------------------------------------===// /// DbgVariable - This class is used to track local variable information. /// -class DbgVariable { +class VISIBILITY_HIDDEN DbgVariable { DIVariable Var; // Variable Descriptor. unsigned FrameIndex; // Variable frame index. public: @@ -187,7 +188,7 @@ public: /// DbgScope - This class is used to track scope information. /// class DbgConcreteScope; -class DbgScope { +class VISIBILITY_HIDDEN DbgScope { DbgScope *Parent; // Parent to this scope. DIDescriptor Desc; // Debug info descriptor for scope. // Either subprogram or block. @@ -251,7 +252,7 @@ void DbgScope::dump() const { /// DbgConcreteScope - This class is used to track a scope that holds concrete /// instance information. /// -class DbgConcreteScope : public DbgScope { +class VISIBILITY_HIDDEN DbgConcreteScope : public DbgScope { CompileUnit *Unit; DIE *Die; // Debug info for this concrete scope. public: @@ -274,7 +275,7 @@ DbgScope::~DbgScope() { //===----------------------------------------------------------------------===// /// DwarfDebug - Emits Dwarf debug directives. /// -class DwarfDebug : public Dwarf { +class VISIBILITY_HIDDEN DwarfDebug : public Dwarf { //===--------------------------------------------------------------------===// // Attributes used to construct specific Dwarf sections. // @@ -2813,769 +2814,6 @@ public: } }; -//===----------------------------------------------------------------------===// -/// DwarfException - Emits Dwarf exception handling directives. -/// -class DwarfException : public Dwarf { - struct FunctionEHFrameInfo { - std::string FnName; - unsigned Number; - unsigned PersonalityIndex; - bool hasCalls; - bool hasLandingPads; - std::vector<MachineMove> Moves; - const Function * function; - - FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P, - bool hC, bool hL, - const std::vector<MachineMove> &M, - const Function *f): - FnName(FN), Number(Num), PersonalityIndex(P), - hasCalls(hC), hasLandingPads(hL), Moves(M), function (f) { } - }; - - std::vector<FunctionEHFrameInfo> EHFrames; - - /// shouldEmitTable - Per-function flag to indicate if EH tables should - /// be emitted. - bool shouldEmitTable; - - /// shouldEmitMoves - Per-function flag to indicate if frame moves info - /// should be emitted. - bool shouldEmitMoves; - - /// shouldEmitTableModule - Per-module flag to indicate if EH tables - /// should be emitted. - bool shouldEmitTableModule; - - /// shouldEmitFrameModule - Per-module flag to indicate if frame moves - /// should be emitted. - bool shouldEmitMovesModule; - - /// ExceptionTimer - Timer for the Dwarf exception writer. - Timer *ExceptionTimer; - - /// EmitCommonEHFrame - Emit the common eh unwind frame. - /// - void EmitCommonEHFrame(const Function *Personality, unsigned Index) { - // Size and sign of stack growth. - int stackGrowth = - Asm->TM.getFrameInfo()->getStackGrowthDirection() == - TargetFrameInfo::StackGrowsUp ? - TD->getPointerSize() : -TD->getPointerSize(); - - // Begin eh frame section. - Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); - - if (!TAI->doesRequireNonLocalEHFrameLabel()) - O << TAI->getEHGlobalPrefix(); - O << "EH_frame" << Index << ":\n"; - EmitLabel("section_eh_frame", Index); - - // Define base labels. - EmitLabel("eh_frame_common", Index); - - // Define the eh frame length. - EmitDifference("eh_frame_common_end", Index, - "eh_frame_common_begin", Index, true); - Asm->EOL("Length of Common Information Entry"); - - // EH frame header. - EmitLabel("eh_frame_common_begin", Index); - Asm->EmitInt32((int)0); - Asm->EOL("CIE Identifier Tag"); - Asm->EmitInt8(DW_CIE_VERSION); - Asm->EOL("CIE Version"); - - // The personality presence indicates that language specific information - // will show up in the eh frame. - Asm->EmitString(Personality ? "zPLR" : "zR"); - Asm->EOL("CIE Augmentation"); - - // Round out reader. - Asm->EmitULEB128Bytes(1); - Asm->EOL("CIE Code Alignment Factor"); - Asm->EmitSLEB128Bytes(stackGrowth); - Asm->EOL("CIE Data Alignment Factor"); - Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); - Asm->EOL("CIE Return Address Column"); - - // If there is a personality, we need to indicate the functions location. - if (Personality) { - Asm->EmitULEB128Bytes(7); - Asm->EOL("Augmentation Size"); - - if (TAI->getNeedsIndirectEncoding()) { - Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4 | DW_EH_PE_indirect); - Asm->EOL("Personality (pcrel sdata4 indirect)"); - } else { - Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); - Asm->EOL("Personality (pcrel sdata4)"); - } - - PrintRelDirective(true); - O << TAI->getPersonalityPrefix(); - Asm->EmitExternalGlobal((const GlobalVariable *)(Personality)); - O << TAI->getPersonalitySuffix(); - if (strcmp(TAI->getPersonalitySuffix(), "+4@GOTPCREL")) - O << "-" << TAI->getPCSymbol(); - Asm->EOL("Personality"); - - Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); - Asm->EOL("LSDA Encoding (pcrel sdata4)"); - - Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); - Asm->EOL("FDE Encoding (pcrel sdata4)"); - } else { - Asm->EmitULEB128Bytes(1); - Asm->EOL("Augmentation Size"); - - Asm->EmitInt8(DW_EH_PE_pcrel | DW_EH_PE_sdata4); - Asm->EOL("FDE Encoding (pcrel sdata4)"); - } - - // Indicate locations of general callee saved registers in frame. - std::vector<MachineMove> Moves; - RI->getInitialFrameState(Moves); - EmitFrameMoves(NULL, 0, Moves, true); - - // On Darwin the linker honors the alignment of eh_frame, which means it - // must be 8-byte on 64-bit targets to match what gcc does. Otherwise - // you get holes which confuse readers of eh_frame. - Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, - 0, 0, false); - EmitLabel("eh_frame_common_end", Index); - - Asm->EOL(); - } - - /// EmitEHFrame - Emit function exception frame information. - /// - void EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) { - Function::LinkageTypes linkage = EHFrameInfo.function->getLinkage(); - - assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() && - "Should not emit 'available externally' functions at all"); - - Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection()); - - // Externally visible entry into the functions eh frame info. - // If the corresponding function is static, this should not be - // externally visible. - if (linkage != Function::InternalLinkage && - linkage != Function::PrivateLinkage) { - if (const char *GlobalEHDirective = TAI->getGlobalEHDirective()) - O << GlobalEHDirective << EHFrameInfo.FnName << "\n"; - } - - // If corresponding function is weak definition, this should be too. - if ((linkage == Function::WeakAnyLinkage || - linkage == Function::WeakODRLinkage || - linkage == Function::LinkOnceAnyLinkage || - linkage == Function::LinkOnceODRLinkage) && - TAI->getWeakDefDirective()) - O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; - - // If there are no calls then you can't unwind. This may mean we can - // omit the EH Frame, but some environments do not handle weak absolute - // symbols. - // If UnwindTablesMandatory is set we cannot do this optimization; the - // unwind info is to be available for non-EH uses. - if (!EHFrameInfo.hasCalls && - !UnwindTablesMandatory && - ((linkage != Function::WeakAnyLinkage && - linkage != Function::WeakODRLinkage && - linkage != Function::LinkOnceAnyLinkage && - linkage != Function::LinkOnceODRLinkage) || - !TAI->getWeakDefDirective() || - TAI->getSupportsWeakOmittedEHFrame())) - { - O << EHFrameInfo.FnName << " = 0\n"; - // This name has no connection to the function, so it might get - // dead-stripped when the function is not, erroneously. Prohibit - // dead-stripping unconditionally. - if (const char *UsedDirective = TAI->getUsedDirective()) - O << UsedDirective << EHFrameInfo.FnName << "\n\n"; - } else { - O << EHFrameInfo.FnName << ":\n"; - - // EH frame header. - EmitDifference("eh_frame_end", EHFrameInfo.Number, - "eh_frame_begin", EHFrameInfo.Number, true); - Asm->EOL("Length of Frame Information Entry"); - - EmitLabel("eh_frame_begin", EHFrameInfo.Number); - - if (TAI->doesRequireNonLocalEHFrameLabel()) { - PrintRelDirective(true, true); - PrintLabelName("eh_frame_begin", EHFrameInfo.Number); - - if (!TAI->isAbsoluteEHSectionOffsets()) - O << "-EH_frame" << EHFrameInfo.PersonalityIndex; - } else { - EmitSectionOffset("eh_frame_begin", "eh_frame_common", - EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, - true, true, false); - } - - Asm->EOL("FDE CIE offset"); - - EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); - Asm->EOL("FDE initial location"); - EmitDifference("eh_func_end", EHFrameInfo.Number, - "eh_func_begin", EHFrameInfo.Number, true); - Asm->EOL("FDE address range"); - - // If there is a personality and landing pads then point to the language - // specific data area in the exception table. - if (EHFrameInfo.PersonalityIndex) { - Asm->EmitULEB128Bytes(4); - Asm->EOL("Augmentation size"); - - if (EHFrameInfo.hasLandingPads) - EmitReference("exception", EHFrameInfo.Number, true, true); - else - Asm->EmitInt32((int)0); - Asm->EOL("Language Specific Data Area"); - } else { - Asm->EmitULEB128Bytes(0); - Asm->EOL("Augmentation size"); - } - - // Indicate locations of function specific callee saved registers in - // frame. - EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, - true); - - // On Darwin the linker honors the alignment of eh_frame, which means it - // must be 8-byte on 64-bit targets to match what gcc does. Otherwise - // you get holes which confuse readers of eh_frame. - Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, - 0, 0, false); - EmitLabel("eh_frame_end", EHFrameInfo.Number); - - // If the function is marked used, this table should be also. We cannot - // make the mark unconditional in this case, since retaining the table - // also retains the function in this case, and there is code around - // that depends on unused functions (calling undefined externals) being - // dead-stripped to link correctly. Yes, there really is. - if (MMI->getUsedFunctions().count(EHFrameInfo.function)) - if (const char *UsedDirective = TAI->getUsedDirective()) - O << UsedDirective << EHFrameInfo.FnName << "\n\n"; - } - } - - /// EmitExceptionTable - Emit landing pads and actions. - /// - /// The general organization of the table is complex, but the basic concepts - /// are easy. First there is a header which describes the location and - /// organization of the three components that follow. - /// 1. The landing pad site information describes the range of code covered - /// by the try. In our case it's an accumulation of the ranges covered - /// by the invokes in the try. There is also a reference to the landing - /// pad that handles the exception once processed. Finally an index into - /// the actions table. - /// 2. The action table, in our case, is composed of pairs of type ids - /// and next action offset. Starting with the action index from the - /// landing pad site, each type Id is checked for a match to the current - /// exception. If it matches then the exception and type id are passed - /// on to the landing pad. Otherwise the next action is looked up. This - /// chain is terminated with a next action of zero. If no type id is - /// found the the frame is unwound and handling continues. - /// 3. Type id table contains references to all the C++ typeinfo for all - /// catches in the function. This tables is reversed indexed base 1. - - /// SharedTypeIds - How many leading type ids two landing pads have in common. - static unsigned SharedTypeIds(const LandingPadInfo *L, - const LandingPadInfo *R) { - const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; - unsigned LSize = LIds.size(), RSize = RIds.size(); - unsigned MinSize = LSize < RSize ? LSize : RSize; - unsigned Count = 0; - - for (; Count != MinSize; ++Count) - if (LIds[Count] != RIds[Count]) - return Count; - - return Count; - } - - /// PadLT - Order landing pads lexicographically by type id. - static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { - const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; - unsigned LSize = LIds.size(), RSize = RIds.size(); - unsigned MinSize = LSize < RSize ? LSize : RSize; - - for (unsigned i = 0; i != MinSize; ++i) - if (LIds[i] != RIds[i]) - return LIds[i] < RIds[i]; - - return LSize < RSize; - } - - struct KeyInfo { - static inline unsigned getEmptyKey() { return -1U; } - static inline unsigned getTombstoneKey() { return -2U; } - static unsigned getHashValue(const unsigned &Key) { return Key; } - static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; } - static bool isPod() { return true; } - }; - - /// ActionEntry - Structure describing an entry in the actions table. - struct ActionEntry { - int ValueForTypeID; // The value to write - may not be equal to the type id. - int NextAction; - struct ActionEntry *Previous; - }; - - /// PadRange - Structure holding a try-range and the associated landing pad. - struct PadRange { - // The index of the landing pad. - unsigned PadIndex; - // The index of the begin and end labels in the landing pad's label lists. - unsigned RangeIndex; - }; - - typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType; - - /// CallSiteEntry - Structure describing an entry in the call-site table. - struct CallSiteEntry { - // The 'try-range' is BeginLabel .. EndLabel. - unsigned BeginLabel; // zero indicates the start of the function. - unsigned EndLabel; // zero indicates the end of the function. - // The landing pad starts at PadLabel. - unsigned PadLabel; // zero indicates that there is no landing pad. - unsigned Action; - }; - - void EmitExceptionTable() { - const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); - const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); - const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); - if (PadInfos.empty()) return; - - // Sort the landing pads in order of their type ids. This is used to fold - // duplicate actions. - SmallVector<const LandingPadInfo *, 64> LandingPads; - LandingPads.reserve(PadInfos.size()); - for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) - LandingPads.push_back(&PadInfos[i]); - std::sort(LandingPads.begin(), LandingPads.end(), PadLT); - - // Negative type ids index into FilterIds, positive type ids index into - // TypeInfos. The value written for a positive type id is just the type - // id itself. For a negative type id, however, the value written is the - // (negative) byte offset of the corresponding FilterIds entry. The byte - // offset is usually equal to the type id, because the FilterIds entries - // are written using a variable width encoding which outputs one byte per - // entry as long as the value written is not too large, but can differ. - // This kind of complication does not occur for positive type ids because - // type infos are output using a fixed width encoding. - // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i]. - SmallVector<int, 16> FilterOffsets; - FilterOffsets.reserve(FilterIds.size()); - int Offset = -1; - for(std::vector<unsigned>::const_iterator I = FilterIds.begin(), - E = FilterIds.end(); I != E; ++I) { - FilterOffsets.push_back(Offset); - Offset -= TargetAsmInfo::getULEB128Size(*I); - } - - // Compute the actions table and gather the first action index for each - // landing pad site. - SmallVector<ActionEntry, 32> Actions; - SmallVector<unsigned, 64> FirstActions; - FirstActions.reserve(LandingPads.size()); - - int FirstAction = 0; - unsigned SizeActions = 0; - for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { - const LandingPadInfo *LP = LandingPads[i]; - const std::vector<int> &TypeIds = LP->TypeIds; - const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0; - unsigned SizeSiteActions = 0; - - if (NumShared < TypeIds.size()) { - unsigned SizeAction = 0; - ActionEntry *PrevAction = 0; - - if (NumShared) { - const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size(); - assert(Actions.size()); - PrevAction = &Actions.back(); - SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) + - TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); - for (unsigned j = NumShared; j != SizePrevIds; ++j) { - SizeAction -= - TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); - SizeAction += -PrevAction->NextAction; - PrevAction = PrevAction->Previous; - } - } - - // Compute the actions. - for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) { - int TypeID = TypeIds[I]; - assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); - int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; - unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID); - - int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; - SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction); - SizeSiteActions += SizeAction; - - ActionEntry Action = {ValueForTypeID, NextAction, PrevAction}; - Actions.push_back(Action); - - PrevAction = &Actions.back(); - } - - // Record the first action of the landing pad site. - FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; - } // else identical - re-use previous FirstAction - - FirstActions.push_back(FirstAction); - - // Compute this sites contribution to size. - SizeActions += SizeSiteActions; - } - - // Compute the call-site table. The entry for an invoke has a try-range - // containing the call, a non-zero landing pad and an appropriate action. - // The entry for an ordinary call has a try-range containing the call and - // zero for the landing pad and the action. Calls marked 'nounwind' have - // no entry and must not be contained in the try-range of any entry - they - // form gaps in the table. Entries must be ordered by try-range address. - SmallVector<CallSiteEntry, 64> CallSites; - - RangeMapType PadMap; - // Invokes and nounwind calls have entries in PadMap (due to being bracketed - // by try-range labels when lowered). Ordinary calls do not, so appropriate - // try-ranges for them need be deduced. - for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { - const LandingPadInfo *LandingPad = LandingPads[i]; - for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { - unsigned BeginLabel = LandingPad->BeginLabels[j]; - assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); - PadRange P = { i, j }; - PadMap[BeginLabel] = P; - } - } - - // The end label of the previous invoke or nounwind try-range. - unsigned LastLabel = 0; - - // Whether there is a potentially throwing instruction (currently this means - // an ordinary call) between the end of the previous try-range and now. - bool SawPotentiallyThrowing = false; - - // Whether the last callsite entry was for an invoke. - bool PreviousIsInvoke = false; - - // Visit all instructions in order of address. - for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); - I != E; ++I) { - for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); - MI != E; ++MI) { - if (!MI->isLabel()) { - SawPotentiallyThrowing |= MI->getDesc().isCall(); - continue; - } - - unsigned BeginLabel = MI->getOperand(0).getImm(); - assert(BeginLabel && "Invalid label!"); - - // End of the previous try-range? - if (BeginLabel == LastLabel) - SawPotentiallyThrowing = false; - - // Beginning of a new try-range? - RangeMapType::iterator L = PadMap.find(BeginLabel); - if (L == PadMap.end()) - // Nope, it was just some random label. - continue; - - PadRange P = L->second; - const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; - - assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && - "Inconsistent landing pad map!"); - - // If some instruction between the previous try-range and this one may - // throw, create a call-site entry with no landing pad for the region - // between the try-ranges. - if (SawPotentiallyThrowing) { - CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0}; - CallSites.push_back(Site); - PreviousIsInvoke = false; - } - - LastLabel = LandingPad->EndLabels[P.RangeIndex]; - assert(BeginLabel && LastLabel && "Invalid landing pad!"); - - if (LandingPad->LandingPadLabel) { - // This try-range is for an invoke. - CallSiteEntry Site = {BeginLabel, LastLabel, - LandingPad->LandingPadLabel, FirstActions[P.PadIndex]}; - - // Try to merge with the previous call-site. - if (PreviousIsInvoke) { - CallSiteEntry &Prev = CallSites.back(); - if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { - // Extend the range of the previous entry. - Prev.EndLabel = Site.EndLabel; - continue; - } - } - - // Otherwise, create a new call-site. - CallSites.push_back(Site); - PreviousIsInvoke = true; - } else { - // Create a gap. - PreviousIsInvoke = false; - } - } - } - // If some instruction between the previous try-range and the end of the - // function may throw, create a call-site entry with no landing pad for the - // region following the try-range. - if (SawPotentiallyThrowing) { - CallSiteEntry Site = {LastLabel, 0, 0, 0}; - CallSites.push_back(Site); - } - - // Final tallies. - - // Call sites. - const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4 - const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4 - const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4 - unsigned SizeSites = CallSites.size() * (SiteStartSize + - SiteLengthSize + - LandingPadSize); - for (unsigned i = 0, e = CallSites.size(); i < e; ++i) - SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action); - - // Type infos. - const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr - unsigned SizeTypes = TypeInfos.size() * TypeInfoSize; - - unsigned TypeOffset = sizeof(int8_t) + // Call site format - TargetAsmInfo::getULEB128Size(SizeSites) + // Call-site table length - SizeSites + SizeActions + SizeTypes; - - unsigned TotalSize = sizeof(int8_t) + // LPStart format - sizeof(int8_t) + // TType format - TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset - TypeOffset; - - unsigned SizeAlign = (4 - TotalSize) & 3; - - // Begin the exception table. - Asm->SwitchToDataSection(TAI->getDwarfExceptionSection()); - Asm->EmitAlignment(2, 0, 0, false); - O << "GCC_except_table" << SubprogramCount << ":\n"; - for (unsigned i = 0; i != SizeAlign; ++i) { - Asm->EmitInt8(0); - Asm->EOL("Padding"); - } - EmitLabel("exception", SubprogramCount); - - // Emit the header. - Asm->EmitInt8(DW_EH_PE_omit); - Asm->EOL("LPStart format (DW_EH_PE_omit)"); - Asm->EmitInt8(DW_EH_PE_absptr); - Asm->EOL("TType format (DW_EH_PE_absptr)"); - Asm->EmitULEB128Bytes(TypeOffset); - Asm->EOL("TType base offset"); - Asm->EmitInt8(DW_EH_PE_udata4); - Asm->EOL("Call site format (DW_EH_PE_udata4)"); - Asm->EmitULEB128Bytes(SizeSites); - Asm->EOL("Call-site table length"); - - // Emit the landing pad site information. - for (unsigned i = 0; i < CallSites.size(); ++i) { - CallSiteEntry &S = CallSites[i]; - const char *BeginTag; - unsigned BeginNumber; - - if (!S.BeginLabel) { - BeginTag = "eh_func_begin"; - BeginNumber = SubprogramCount; - } else { - BeginTag = "label"; - BeginNumber = S.BeginLabel; - } - - EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, - true, true); - Asm->EOL("Region start"); - - if (!S.EndLabel) { - EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, - true); - } else { - EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); - } - Asm->EOL("Region length"); - - if (!S.PadLabel) - Asm->EmitInt32(0); - else - EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, - true, true); - Asm->EOL("Landing pad"); - - Asm->EmitULEB128Bytes(S.Action); - Asm->EOL("Action"); - } - - // Emit the actions. - for (unsigned I = 0, N = Actions.size(); I != N; ++I) { - ActionEntry &Action = Actions[I]; - - Asm->EmitSLEB128Bytes(Action.ValueForTypeID); - Asm->EOL("TypeInfo index"); - Asm->EmitSLEB128Bytes(Action.NextAction); - Asm->EOL("Next action"); - } - - // Emit the type ids. - for (unsigned M = TypeInfos.size(); M; --M) { - GlobalVariable *GV = TypeInfos[M - 1]; - - PrintRelDirective(); - - if (GV) { - std::string GLN; - O << Asm->getGlobalLinkName(GV, GLN); - } else { - O << "0"; - } - - Asm->EOL("TypeInfo"); - } - - // Emit the filter typeids. - for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) { - unsigned TypeID = FilterIds[j]; - Asm->EmitULEB128Bytes(TypeID); - Asm->EOL("Filter TypeInfo index"); - } - - Asm->EmitAlignment(2, 0, 0, false); - } - -public: - //===--------------------------------------------------------------------===// - // Main entry points. - // - DwarfException(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T) - : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false), - shouldEmitTableModule(false), shouldEmitMovesModule(false), - ExceptionTimer(0) { - if (TimePassesIsEnabled) - ExceptionTimer = new Timer("Dwarf Exception Writer", - getDwarfTimerGroup()); - } - - virtual ~DwarfException() { - delete ExceptionTimer; - } - - /// SetModuleInfo - Set machine module information when it's known that pass - /// manager has created it. Set by the target AsmPrinter. - void SetModuleInfo(MachineModuleInfo *mmi) { - MMI = mmi; - } - - /// BeginModule - Emit all exception information that should come prior to the - /// content. - void BeginModule(Module *M) { - this->M = M; - } - - /// EndModule - Emit all exception information that should come after the - /// content. - void EndModule() { - if (TimePassesIsEnabled) - ExceptionTimer->startTimer(); - - if (shouldEmitMovesModule || shouldEmitTableModule) { - const std::vector<Function *> Personalities = MMI->getPersonalities(); - for (unsigned i = 0; i < Personalities.size(); ++i) - EmitCommonEHFrame(Personalities[i], i); - - for (std::vector<FunctionEHFrameInfo>::iterator I = EHFrames.begin(), - E = EHFrames.end(); I != E; ++I) - EmitEHFrame(*I); - } - - if (TimePassesIsEnabled) - ExceptionTimer->stopTimer(); - } - - /// BeginFunction - Gather pre-function exception information. Assumes being - /// emitted immediately after the function entry point. - void BeginFunction(MachineFunction *MF) { - if (TimePassesIsEnabled) - ExceptionTimer->startTimer(); - - this->MF = MF; - shouldEmitTable = shouldEmitMoves = false; - - if (MMI && TAI->doesSupportExceptionHandling()) { - // Map all labels and get rid of any dead landing pads. - MMI->TidyLandingPads(); - - // If any landing pads survive, we need an EH table. - if (MMI->getLandingPads().size()) - shouldEmitTable = true; - - // See if we need frame move info. - if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) - shouldEmitMoves = true; - - if (shouldEmitMoves || shouldEmitTable) - // Assumes in correct section after the entry point. - EmitLabel("eh_func_begin", ++SubprogramCount); - } - - shouldEmitTableModule |= shouldEmitTable; - shouldEmitMovesModule |= shouldEmitMoves; - - if (TimePassesIsEnabled) - ExceptionTimer->stopTimer(); - } - - /// EndFunction - Gather and emit post-function exception information. - /// - void EndFunction() { - if (TimePassesIsEnabled) - ExceptionTimer->startTimer(); - - if (shouldEmitMoves || shouldEmitTable) { - EmitLabel("eh_func_end", SubprogramCount); - EmitExceptionTable(); - - // Save EH frame information - std::string Name; - EHFrames.push_back( - FunctionEHFrameInfo(getAsm()->getCurrentFunctionEHName(MF, Name), - SubprogramCount, - MMI->getPersonalityIndex(), - MF->getFrameInfo()->hasCalls(), - !MMI->getLandingPads().empty(), - MMI->getFrameMoves(), - MF->getFunction())); - } - - if (TimePassesIsEnabled) - ExceptionTimer->stopTimer(); - } -}; - } // End of namespace llvm //===----------------------------------------------------------------------===// |