From fccf0a2b25da833b115648e1dc10119444a924d5 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 6 Jul 2007 12:46:24 +0000 Subject: [PATCH] Indexes into the list of filter ids cannot be output directly: they need to be turned into byte offsets (often the same, but may not be if there are many type infos). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37942 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/DwarfWriter.cpp | 74 +++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp index 6bfbacd7136..f86c4d5d76a 100644 --- a/lib/CodeGen/DwarfWriter.cpp +++ b/lib/CodeGen/DwarfWriter.cpp @@ -2894,6 +2894,26 @@ private: O << UsedDirective << EHFrameInfo.FnName << ".eh\n\n"; } + /// EmitExceptionTable - Emit landpads 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) { @@ -2922,26 +2942,6 @@ private: return LSize < RSize; } - /// EmitExceptionTable - Emit landpads 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. - struct KeyInfo { static inline unsigned getEmptyKey() { return -1U; } static inline unsigned getTombstoneKey() { return -2U; } @@ -2957,7 +2957,7 @@ private: typedef DenseMap PadMapType; struct ActionEntry { - int TypeID; + int ValueForTypeID; // The value to write - may not be equal to the type id. int NextAction; struct ActionEntry *Previous; }; @@ -2974,7 +2974,6 @@ private: // Sort the landing pads in order of their type ids. This is used to fold // duplicate actions. SmallVector LandingPads; - LandingPads.reserve(PadInfos.size()); for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) LandingPads.push_back(&PadInfos[i]); @@ -2987,6 +2986,25 @@ private: // The actions table. SmallVector Actions; + // 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 FilterOffsets; + FilterOffsets.reserve(FilterIds.size()); + int Offset = -1; + for(std::vector::const_iterator I = FilterIds.begin(), + E = FilterIds.end(); I != E; ++I) { + FilterOffsets.push_back(Offset); + Offset -= Asm->SizeSLEB128(*I); + } + // Compute sizes for exception table. unsigned SizeSites = 0; unsigned SizeActions = 0; @@ -3010,9 +3028,9 @@ private: assert(Actions.size()); PrevAction = &Actions.back(); SizeAction = Asm->SizeSLEB128(PrevAction->NextAction) + - Asm->SizeSLEB128(PrevAction->TypeID); + Asm->SizeSLEB128(PrevAction->ValueForTypeID); for (unsigned j = NumShared; j != SizePrevIds; ++j) { - SizeAction -= Asm->SizeSLEB128(PrevAction->TypeID); + SizeAction -= Asm->SizeSLEB128(PrevAction->ValueForTypeID); SizeAction += -PrevAction->NextAction; PrevAction = PrevAction->Previous; } @@ -3021,13 +3039,15 @@ private: // Compute the actions. for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) { int TypeID = TypeIds[I]; - unsigned SizeTypeID = Asm->SizeSLEB128(TypeID); + assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); + int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; + unsigned SizeTypeID = Asm->SizeSLEB128(ValueForTypeID); int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; SizeAction = SizeTypeID + Asm->SizeSLEB128(NextAction); SizeSiteActions += SizeAction; - ActionEntry Action = {TypeID, NextAction, PrevAction}; + ActionEntry Action = {ValueForTypeID, NextAction, PrevAction}; Actions.push_back(Action); PrevAction = &Actions.back(); @@ -3145,7 +3165,7 @@ private: for (unsigned I = 0, N = Actions.size(); I != N; ++I) { ActionEntry &Action = Actions[I]; - Asm->EmitSLEB128Bytes(Action.TypeID); + Asm->EmitSLEB128Bytes(Action.ValueForTypeID); Asm->EOL("TypeInfo index"); Asm->EmitSLEB128Bytes(Action.NextAction); Asm->EOL("Next action");