summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@novell.com>2011-02-02 13:23:50 +0200
committerTor Lillqvist <tlillqvist@novell.com>2011-02-02 13:29:43 +0200
commit8a91eee9c3a42917584f74ac62a46336488811c9 (patch)
tree22451bbb029c9b569ce9417fbdc44bbd7de6a5c4 /bridges
parent1a6617cf054891b89a330c44e60d9d31bf034d6e (diff)
More work on except.cxx, intermediate commit
Now I have some understanding what it is the code here should do, and have found 3rd-party documentation (in source code form even) for the exception-related data structures. It still crashes, but I hope that is just because of thinkos that need to be fixed by debugging, or reading the code. There are some horrible code with quite complex casts in places, I need to introduce some macros or inline functions instead to make the casting from RVAs to real pointers and back cleaner. Also maybe just use DWORD instead of sal_uInt32 for terseness, and use a specific typedef name for DWORDs that actually are RVAs for clarity?
Diffstat (limited to 'bridges')
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx514
1 files changed, 331 insertions, 183 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
index 03e9dee50ff0..df724232cfaf 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
@@ -26,6 +26,150 @@
*
************************************************************************/
+// Interesting info can be found in:
+
+// MSDN, obviously
+
+// http://www.osronline.com/article.cfm?article=469
+
+// ONTL, "Open NT Native Template Library", a C++ STL-like library
+// that can be used even when writing Windows drivers. This is some
+// quite badass code. The author has done impressive heavy spelunking
+// of MSVCR structures. http://code.google.com/p/ontl/
+
+// Geoff Chappell's pages:
+// http://members.ozemail.com.au/~geoffch/samples/programming/msvc/language/index.html
+
+// The below is from ONTL's ntl/nt/exception.hxx, cleaned up to keep just the _M_X64 parts:
+
+#if 0
+
+/* This information until the corresponding '#endif // 0' is covered
+ * by ONTL's license, which is said to be the "zlib/libgng license"
+ * below, which as far as I see is permissive enough to allow this
+ * information to be included here in this source file. Note that no
+ * actual code from ONTL below gets compiled into the object file.
+ */
+
+/*
+ * Copyright (c) 2011 <copyright holders> (The ONTL main
+ * developer(s) don't tell their real name(s) on the ONTL site.)
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+typedef uint32_t rva_t;
+
+///\note the calling convention should not matter since this has no arguments
+typedef void generic_function_t();
+
+ struct ptrtomember // _PMD
+ {
+ typedef __w64 int32_t mdiff_t;
+ mdiff_t member_offset;
+ mdiff_t vbtable_offset; // -1 if not a virtual base
+ mdiff_t vdisp_offset; // offset to the displacement value inside the vbtable
+
+ template<typename T>
+ T * operator()(T * const thisptr) const
+ {
+ uintptr_t tp = reinterpret_cast<uintptr_t>(thisptr);
+ uintptr_t ptr = tp + member_offset;
+ if ( vbtable_offset != -1 ) // !(vbtable_offset < 0)
+ {
+ ptr += *reinterpret_cast<mdiff_t*>( static_cast<intptr_t>(vdisp_offset + *reinterpret_cast<mdiff_t*>(tp + vbtable_offset)) )
+ + vbtable_offset;
+ }
+ return reinterpret_cast<T*>(ptr);
+ }
+ };
+
+struct catchabletype
+{
+ /** is simple type */
+ uint32_t memmoveable : 1;
+ /** catchable as reference only */
+ uint32_t refonly : 1;
+ /** class with virtual base */
+ uint32_t hasvirtbase : 1;
+ /** offset to the type descriptor */
+ rva_t typeinfo;
+
+ /** catch type instance location within a thrown object */
+ ptrtomember thiscast;
+ /** size of the simple type or offset into buffer of \c this pointer for catch object */
+ uint32_t object_size;
+
+ union
+ {
+ rva_t copyctor;
+ rva_t copyctor2;
+ };
+ };
+
+#pragma pack(push, 4)
+ struct catchabletypearray
+ {
+ uint32_t size;
+ rva_t type[1];
+ };
+#pragma pack(pop)
+
+#pragma pack(push, 4)
+ struct throwinfo
+ {
+ typedef exception_disposition __cdecl forwardcompathandler_t(...);
+
+ /* 0x00 */ uint32_t econst : 1;
+ /* 0x00 */ uint32_t evolatile : 1;
+ /* 0x00 */ uint32_t : 1;
+ /* 0x00 */ uint32_t e8 : 1;
+ /* 0x04 */ rva_t exception_dtor;
+ /* 0x08 */ rva_t forwardcompathandler;
+ /* 0x0C */ rva_t catchabletypearray; ///< types able to catch the exception.
+ };
+#pragma pack(pop)
+
+ /// This type represents the catch clause
+ struct ehandler
+ {
+ // union { uint32_t adjectives; void * ptr; };
+ uint32_t isconst : 1;
+ uint32_t isvolatile : 1;
+ uint32_t isunaligned : 1;// guess it is not used on x86
+ uint32_t isreference : 1;
+
+ uint32_t :27;
+ uint32_t ishz : 1;
+
+ /** offset to the type descriptor of this catch object */
+ /*0x04*/ rva_t typeinfo; // dispType
+ /*0x08*/ int eobject_bpoffset; // dispCatchObj
+ /** offset to the catch clause funclet */
+ /*0x0C*/ rva_t handler; // dispOfHandler
+ /*0x10*/ uint32_t frame; // dispFrame
+ }
+
+#endif // 0
+
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_bridges.hxx"
@@ -181,202 +325,185 @@ RTTInfos::~RTTInfos() throw ()
}
}
-struct ObjectFunction
-{
- char somecode[12];
- typelib_TypeDescription * _pTypeDescr; // type of object
-
- inline static void * operator new ( size_t nSize );
- inline static void operator delete ( void * pMem );
-
- ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ();
- ~ObjectFunction() throw ();
-};
-
-inline void * ObjectFunction::operator new(
- size_t nSize )
-{
- void * pMem = rtl_allocateMemory( nSize );
- if (pMem != 0)
- {
- DWORD old_protect;
-#if OSL_DEBUG_LEVEL > 0
- BOOL success =
-#endif
- VirtualProtect( pMem, nSize, PAGE_EXECUTE_READWRITE, &old_protect );
- OSL_ENSURE( success, "VirtualProtect() failed!" );
- }
- return pMem;
-}
-
-inline void ObjectFunction::operator delete(
- void * pMem )
-{
- rtl_freeMemory( pMem );
-}
-
-ObjectFunction::ObjectFunction(
- typelib_TypeDescription * pTypeDescr,
- void * fpFunc ) throw ()
- : _pTypeDescr( pTypeDescr )
-{
- ::typelib_typedescription_acquire( _pTypeDescr );
-
- unsigned char * pCode = (unsigned char *)somecode;
- // a must be!
- OSL_ENSURE( (void *)this == (void *)pCode, "### unexpected!" );
-
- // push ObjectFunction this
- *pCode++ = 0x68;
- *(void **)pCode = this;
- pCode += sizeof(void *);
- // jmp rel64 fpFunc
- *pCode++ = 0xe9;
- *(sal_Int64 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int64);
-}
-
-ObjectFunction::~ObjectFunction() throw ()
-{
- ::typelib_typedescription_release( _pTypeDescr );
-}
-
-
-void * __cdecl __copyConstruct(
+void * __cdecl copyConstruct(
void * pExcThis,
void * pSource,
- ObjectFunction * pThis )
- throw ()
+ typelib_TypeDescription * pTD ) throw ()
{
- ::uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire );
+ ::uno_copyData( pExcThis, pSource, pTD, cpp_acquire );
return pExcThis;
}
-void * __cdecl __destruct(
+void * __cdecl destruct(
void * pExcThis,
- ObjectFunction * pThis )
- throw ()
+ typelib_TypeDescription * pTD ) throw ()
{
- ::uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release );
+ ::uno_destructData( pExcThis, pTD, cpp_release );
return pExcThis;
}
-#if 0
-
-// These are machine code snippets in asmbits.asm
+const int codeSnippetSize = 40;
-extern void *copyConstruct;
-extern void *destruct;
-
-#else
-
-static void whatthefuck_copyctor(sal_Int64 i, ...)
+void GenerateConstructorTrampoline(
+ sal_uChar * pCode,
+ typelib_TypeDescription * pTD ) throw ()
{
- MessageBoxA (NULL, "Shit!", "whatthefuck_copyctor in except.cxx", MB_OK);
+ // push typelib_TypeDescription pTD
+ *pCode++ = 0x68;
+ *(void **)pCode = pTD;
+ pCode += sizeof(void *);
+ // jmp rel64 fpFunc
+ *pCode++ = 0xe9;
+ *(sal_Int64 *)pCode = (sal_uChar *)&copyConstruct - pCode - sizeof(sal_Int64);
}
-static void whatthefuck_dtor(sal_Int64 i, ...)
+void GenerateDestructorTrampoline(
+ sal_uChar * pCode,
+ typelib_TypeDescription * pTD ) throw ()
{
- MessageBoxA (NULL, "Shit!", "whatthefuck_dtor in except.cxx", MB_OK);
+ // mov rdx, pTD
+ *pCode++ = 0x68;
+ *(void **)pCode = pTD;
+ pCode += sizeof(void *);
+ // jmp rel64 fpFunc
+ *pCode++ = 0xe9;
+ *(sal_Int64 *)pCode = (sal_uChar *)destruct - pCode - sizeof(sal_Int64);
}
-#endif
+// This looks like it is the struct catchabletype above
struct ExceptionType
{
- sal_Int32 _n0;
- type_info * _pTypeInfo;
- sal_Int32 _n1, _n2, _n3, _n4;
- ObjectFunction * _pCopyCtor;
- sal_Int32 _n5;
-
- inline ExceptionType( typelib_TypeDescription * pTypeDescr ) throw ()
+ sal_Int32 _n0; // flags
+ sal_uInt32 _pTypeInfo; // typeinfo
+ sal_Int32 _n1, _n2, _n3; // thiscast
+ sal_Int32 _n4; // object_size
+ sal_uInt32 _pCopyCtor; // copyctor
+
+ inline ExceptionType(
+ sal_uChar * pCode,
+ sal_uInt64 pCodeBase,
+ typelib_TypeDescription * pTD ) throw ()
: _n0( 0 )
, _n1( 0 )
, _n2( -1 )
, _n3( 0 )
- , _n4( pTypeDescr->nSize )
-#if 0
- , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) )
-#else
- , _pCopyCtor( (ObjectFunction*) whatthefuck_copyctor )
-#endif
- , _n5( 0 )
- { _pTypeInfo = mscx_getRTTI( pTypeDescr->pTypeName ); }
+ , _n4( pTD->nSize )
+ {
+ _pTypeInfo = (sal_uInt32) ((sal_uInt64) mscx_getRTTI( pTD->pTypeName ) - pCodeBase);
+ GenerateConstructorTrampoline( pCode, pTD );
+ _pCopyCtor = (sal_uInt32) ((sal_uInt64) pCode - pCodeBase);
+ }
inline ~ExceptionType() throw ()
- { delete _pCopyCtor; }
+ {
+ }
};
+struct RaiseInfo;
+
+class ExceptionInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRaiseInfos;
+
+public:
+ static RaiseInfo * getRaiseInfo( typelib_TypeDescription * pTD ) throw ();
+
+ static DWORD allocationGranularity;
+
+ ExceptionInfos() throw ();
+ ~ExceptionInfos() throw ();
+};
+
+DWORD ExceptionInfos::allocationGranularity = 0;
+
+// This corresponds to the struct throwinfo described above.
+
struct RaiseInfo
{
sal_Int32 _n0;
- ObjectFunction * _pDtor;
+ sal_uInt32 _pDtor;
sal_Int32 _n2;
- void * _types;
- sal_Int32 _n3, _n4;
+ sal_uInt32 _types;
+
+ // Additional fields
+ typelib_TypeDescription * _pTD;
+ sal_uChar * _code;
+ sal_uInt64 _codeBase;
+
+ RaiseInfo( typelib_TypeDescription * pTD ) throw ();
- RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
~RaiseInfo() throw ();
};
-RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
+RaiseInfo::RaiseInfo( typelib_TypeDescription * pTD )throw ()
: _n0( 0 )
-#if 0
- , _pDtor( new ObjectFunction( pTypeDescr, destruct ) )
-#else
- , _pDtor( (ObjectFunction*) whatthefuck_dtor )
-#endif
, _n2( 0 )
- , _n3( 0 )
- , _n4( 0 )
+ , _pTD( pTD )
{
- typelib_CompoundTypeDescription * pCompTypeDescr;
+ typelib_CompoundTypeDescription * pCompTD;
+
+ // Count how many trampolines we need
+ int codeSize = codeSnippetSize;
- // info count
- sal_Int32 nLen = 0;
- for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
- pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ // Info count
+ int nLen = 0;
+ for ( pCompTD = (typelib_CompoundTypeDescription*)pTD;
+ pCompTD; pCompTD = pCompTD->pBaseTypeDescription )
{
++nLen;
+ codeSize += codeSnippetSize;
}
- // info count accompanied by type info ptrs: type, base type, base base type, ...
- _types = ::rtl_allocateMemory( sizeof(sal_Int64) + (sizeof(ExceptionType *) * nLen) );
- *(sal_Int64 *)_types = nLen;
+ sal_uChar * pCode = _code = (sal_uChar *)::rtl_allocateMemory( codeSize );
+
+ _codeBase = (sal_uInt64)pCode & ~(ExceptionInfos::allocationGranularity-1);
+
+ DWORD old_protect;
+#if OSL_DEBUG_LEVEL > 0
+ BOOL success =
+#endif
+ VirtualProtect( pCode, codeSize, PAGE_EXECUTE_READWRITE, &old_protect );
+ OSL_ENSURE( success, "VirtualProtect() failed!" );
+
+ ::typelib_typedescription_acquire( pTD );
- ExceptionType ** ppTypes = (ExceptionType **)((sal_Int64 *)_types + 1);
+ GenerateDestructorTrampoline( pCode, pTD );
+ _pDtor = (sal_Int32)((sal_uInt64)pCode - _codeBase);
+ pCode += codeSnippetSize;
- sal_Int32 nPos = 0;
- for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
- pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ // Info count accompanied by type info ptrs: type, base type, base base type, ...
+ _types = (sal_Int32)((sal_uInt64)::rtl_allocateMemory( 4 + 4* nLen) - _codeBase);
+ *(sal_Int32 *)_types = nLen;
+
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+
+ int nPos = 0;
+ for ( pCompTD = (typelib_CompoundTypeDescription*)pTD;
+ pCompTD; pCompTD = pCompTD->pBaseTypeDescription )
{
- ppTypes[nPos++] = new ExceptionType( (typelib_TypeDescription *)pCompTypeDescr );
+ ppTypes[nPos++] =
+ new ExceptionType( pCode, _codeBase,
+ (typelib_TypeDescription *)pCompTD );
+ pCode += codeSnippetSize;
}
}
RaiseInfo::~RaiseInfo() throw ()
{
- ExceptionType ** ppTypes = (ExceptionType **)((sal_Int64 *)_types + 1);
- for ( sal_Int32 nTypes = *(sal_Int64 *)_types; nTypes--; )
+ sal_uInt32 * pTypes =
+ (sal_uInt32 *)(_codeBase + _types) + 1;
+
+ for ( int nTypes = *(sal_uInt32 *)(_codeBase + _types); nTypes--; )
{
- delete ppTypes[nTypes];
+ delete (ExceptionType *) (_codeBase + pTypes[nTypes]);
}
- ::rtl_freeMemory( _types );
+ ::rtl_freeMemory( (void*)(_codeBase +_types) );
+ ::rtl_freeMemory( _code );
- delete _pDtor;
+ ::typelib_typedescription_release( _pTD );
}
-class ExceptionInfos
-{
- Mutex _aMutex;
- t_string2PtrMap _allRaiseInfos;
-
-public:
- static void * getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
-
- ExceptionInfos() throw ();
- ~ExceptionInfos() throw ();
-};
-
ExceptionInfos::ExceptionInfos() throw ()
{
}
@@ -394,8 +521,8 @@ ExceptionInfos::~ExceptionInfos() throw ()
delete (RaiseInfo *)iPos->second;
}
}
-void * ExceptionInfos::getRaiseInfo(
- typelib_TypeDescription * pTypeDescr ) throw ()
+
+RaiseInfo * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTD ) throw ()
{
static ExceptionInfos * s_pInfos = 0;
if (! s_pInfos)
@@ -403,6 +530,10 @@ void * ExceptionInfos::getRaiseInfo(
MutexGuard aGuard( Mutex::getGlobalMutex() );
if (! s_pInfos)
{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo( &systemInfo );
+ allocationGranularity = systemInfo.dwAllocationGranularity;
+
#ifdef LEAK_STATIC_DATA
s_pInfos = new ExceptionInfos();
#else
@@ -412,28 +543,29 @@ void * ExceptionInfos::getRaiseInfo(
}
}
- OSL_ASSERT( pTypeDescr &&
- (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
- pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION) );
+ OSL_ASSERT( pTD &&
+ (pTD->eTypeClass == typelib_TypeClass_STRUCT ||
+ pTD->eTypeClass == typelib_TypeClass_EXCEPTION) );
- void * pRaiseInfo;
+ RaiseInfo * pRaiseInfo;
- OUString const & rTypeName = *reinterpret_cast< OUString * >( &pTypeDescr->pTypeName );
+ OUString const & rTypeName = *reinterpret_cast< OUString * >( &pTD->pTypeName );
MutexGuard aGuard( s_pInfos->_aMutex );
t_string2PtrMap::const_iterator const iFind(
s_pInfos->_allRaiseInfos.find( rTypeName ) );
if (iFind == s_pInfos->_allRaiseInfos.end())
{
- pRaiseInfo = new RaiseInfo( pTypeDescr );
- // put into map
+ pRaiseInfo = new RaiseInfo( pTD );
+
+ // Put into map
pair< t_string2PtrMap::iterator, bool > insertion(
- s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, pRaiseInfo ) ) );
+ s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, (void *)pRaiseInfo ) ) );
OSL_ENSURE( insertion.second, "### raise info insertion failed?!" );
}
else
{
- // reuse existing info
- pRaiseInfo = iFind->second;
+ // Reuse existing info
+ pRaiseInfo = (RaiseInfo *)iFind->second;
}
return pRaiseInfo;
@@ -464,24 +596,25 @@ void mscx_raiseException(
uno_Mapping * pUno2Cpp )
{
// no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
- // thus this obj file will be compiled without opt, so no inling of
+ // thus this obj file will be compiled without opt, so no inlining of
// ExceptionInfos::getRaiseInfo()
// construct cpp exception object
- typelib_TypeDescription * pTypeDescr = 0;
- TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ typelib_TypeDescription * pTD = NULL;
+ TYPELIB_DANGER_GET( &pTD, pUnoExc->pType );
- void * pCppExc = alloca( pTypeDescr->nSize );
- ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+ void * pCppExc = alloca( pTD->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTD, pUno2Cpp );
- ULONG_PTR arFilterArgs[3];
+ ULONG_PTR arFilterArgs[4];
arFilterArgs[0] = MSVC_magic_number;
arFilterArgs[1] = (ULONG_PTR)pCppExc;
- arFilterArgs[2] = (ULONG_PTR)ExceptionInfos::getRaiseInfo( pTypeDescr );
+ arFilterArgs[2] = (ULONG_PTR)ExceptionInfos::getRaiseInfo( pTD );
+ arFilterArgs[3] = ((RaiseInfo *)arFilterArgs[2])->_codeBase;
- // destruct uno exception
+ // Destruct uno exception
::uno_any_destruct( pUnoExc, 0 );
- TYPELIB_DANGER_RELEASE( pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTD );
// last point to release anything not affected by stack unwinding
RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs );
@@ -494,8 +627,10 @@ int mscx_filterCppException(
{
if (pPointers == 0)
return EXCEPTION_CONTINUE_SEARCH;
+
EXCEPTION_RECORD * pRecord = pPointers->ExceptionRecord;
- // handle only C++ exceptions:
+
+ // Handle only C++ exceptions:
if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
return EXCEPTION_CONTINUE_SEARCH;
@@ -504,13 +639,13 @@ int mscx_filterCppException(
if (rethrow && pRecord == pPointers->ExceptionRecord)
{
- // hack to get msvcrt internal _curexception field:
+ // Hack to get msvcrt internal _curexception field:
pRecord = *reinterpret_cast< EXCEPTION_RECORD ** >(
reinterpret_cast< char * >( __pxcptinfoptrs() ) +
- // as long as we don't demand msvcr source as build prerequisite
- // (->platform sdk), we have to code those offsets here.
+ // As long as we don't demand MSVCR source as build prerequisite,
+ // we have to code those offsets here.
//
- // crt\src\mtdll.h:
+ // MSVS9/crt/src/mtdll.h:
// offsetof (_tiddata, _curexception) -
// offsetof (_tiddata, _tpxcptinfoptrs):
#if _MSC_VER < 1500
@@ -522,34 +657,47 @@ int mscx_filterCppException(
#endif
);
}
- // rethrow: handle only C++ exceptions:
+
+ // Rethrow: handle only C++ exceptions:
if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
return EXCEPTION_CONTINUE_SEARCH;
- if (pRecord->NumberParameters == 3 &&
-// pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
- pRecord->ExceptionInformation[ 1 ] != 0 &&
- pRecord->ExceptionInformation[ 2 ] != 0)
+ if (pRecord->NumberParameters == 4 &&
+ pRecord->ExceptionInformation[0] == MSVC_magic_number &&
+ pRecord->ExceptionInformation[1] != 0 &&
+ pRecord->ExceptionInformation[2] != 0 &&
+ pRecord->ExceptionInformation[3] != 0)
{
- void * types = reinterpret_cast< RaiseInfo * >(
- pRecord->ExceptionInformation[ 2 ] )->_types;
- if (types != 0 && *reinterpret_cast< DWORD * >( types ) > 0) // count
+ // ExceptionInformation[1] is the address of the thrown object
+ // (or the address of a pointer to it, in most cases when it
+ // is a C++ class, obviously).
+
+ // [2] is the throwinfo pointer
+
+ // [3] is the image base address which is added the 32-bit
+ // rva_t fields in throwinfo to get actual 64-bit addresses
+
+ void * types =
+ (void *) (pRecord->ExceptionInformation[3] +
+ ((RaiseInfo *)pRecord->ExceptionInformation[2])->_types);
+
+ if (types != 0 && *(DWORD *)types > 0)
{
- ExceptionType * pType = *reinterpret_cast< ExceptionType ** >(
- reinterpret_cast< DWORD * >( types ) + 1 );
- if (pType != 0 && pType->_pTypeInfo != 0)
+ DWORD pType = *((DWORD *)types + 1);
+ if (pType != 0 &&
+ ((ExceptionType *)(pRecord->ExceptionInformation[3]+pType))->_pTypeInfo != 0)
{
OUString aRTTIname(
OStringToOUString(
reinterpret_cast< __type_info * >(
- pType->_pTypeInfo )->_m_d_name,
+ ((ExceptionType *)(pRecord->ExceptionInformation[3]+pType))->_pTypeInfo )->_m_d_name,
RTL_TEXTENCODING_ASCII_US ) );
OUString aUNOname( toUNOname( aRTTIname ) );
- typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_TypeDescription * pExcTD = 0;
typelib_typedescription_getByName(
- &pExcTypeDescr, aUNOname.pData );
- if (pExcTypeDescr == 0)
+ &pExcTD, aUNOname.pData );
+ if (pExcTD == NULL)
{
OUStringBuffer buf;
buf.appendAscii(
@@ -578,16 +726,16 @@ int mscx_filterCppException(
// construct uno exception any
uno_any_constructAndConvert(
pUnoExc, (void *) pRecord->ExceptionInformation[1],
- pExcTypeDescr, pCpp2Uno );
+ pExcTD, pCpp2Uno );
#if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
if (! rethrow)
{
uno_destructData(
(void *) pRecord->ExceptionInformation[1],
- pExcTypeDescr, cpp_release );
+ pExcTD, cpp_release );
}
#endif
- typelib_typedescription_release( pExcTypeDescr );
+ typelib_typedescription_release( pExcTD );
}
return EXCEPTION_EXECUTE_HANDLER;