summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx')
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx667
1 files changed, 447 insertions, 220 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 bb5c5b1922b8..2157568ad915 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
@@ -26,11 +26,227 @@
*
************************************************************************/
+// 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 eobject
+{
+ typedef void (* dtor_ptr )(eobject*);
+ typedef void (* ctor_ptr )(eobject*, eobject*);
+ typedef void (* ctor_ptr2)(eobject*, eobject*, int);
+};
+
+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
+}
+
+// ___BuildCatchObject
+/// 15.3/16 When the exception-declaration specifies a class type, a copy
+/// constructor is used to initialize either the object declared
+/// in the exception-declaration or,
+/// if the exception-declaration does not specify a name,
+/// a temporary object of that type.
+///\note This is the question may we optimize out the last case.
+///\warning If the copy constructor throws an exception, std::unexpected would be called
+void
+ constructcatchobject(
+ cxxregistration * cxxreg,
+ const ehandler * const catchblock,
+ catchabletype * const convertable,
+ const dispatcher_context* const dispatch
+ )
+ const
+{
+ _EH_TRACE_ENTER();
+ // build helper
+ __try {
+ struct typeinfo_t { void* vtbl; void* spare; char name[1]; };
+ enum catchable_info { cidefault, cicomplex, civirtual } cinfo = cidefault;
+
+ const typeinfo_t* ti = catchblock->typeinfo ? dispatch->va<typeinfo_t*>(catchblock->typeinfo) : NULL;
+ if(ti && *ti->name && (catchblock->eobject_bpoffset || catchblock->ishz)){
+ eobject** objplace = catchblock->ishz
+ ? reinterpret_cast<eobject**>(cxxreg)
+ : reinterpret_cast<eobject**>(catchblock->eobject_bpoffset + cxxreg->fp.FramePointers);
+ if(catchblock->isreference){
+ // just ref/pointer
+ *objplace = adjust_pointer(get_object(), convertable);
+ }else if(convertable->memmoveable){
+ // POD
+ std::memcpy(objplace, get_object(), convertable->object_size);
+ if(convertable->object_size == sizeof(void*) && *objplace)
+ *objplace = adjust_pointer((void*)*objplace, convertable);
+ }else{
+ // if copy ctor exists, call it; binary copy otherwise
+ if(convertable->copyctor){
+ cinfo = convertable->hasvirtbase ? civirtual : cicomplex;
+ }else{
+ std::memcpy(objplace, (const void*)adjust_pointer(get_object(), convertable), convertable->object_size);
+ }
+ }
+ }
+ // end of build helper
+ if(cinfo != cidefault){
+ eobject* objthis = catchblock->ishz
+ ? reinterpret_cast<eobject*>(cxxreg)
+ : reinterpret_cast<eobject*>(catchblock->eobject_bpoffset + cxxreg->fp.FramePointers);
+ void* copyctor = thrown_va(convertable->copyctor);
+ eobject* copyarg = adjust_pointer(get_object(), convertable);
+ if(cinfo == cicomplex)
+ (eobject::ctor_ptr (copyctor))(objthis, copyarg);
+ else
+ (eobject::ctor_ptr2(copyctor))(objthis, copyarg, 1);
+ }
+ }
+ __except(cxxregistration::unwindfilter(static_cast<nt::ntstatus>(_exception_code())))
+ {
+ nt::exception::inconsistency();
+ }
+ _EH_TRACE_LEAVE();
+}
+
+#endif // 0
+
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_bridges.hxx"
#pragma warning( disable : 4237 )
-#include <hash_map>
+#include <boost/unordered_map.hpp>
#include <sal/config.h>
#include <malloc.h>
#include <new.h>
@@ -45,7 +261,6 @@
#include "mscx.hxx"
-
#pragma pack(push, 8)
using namespace ::com::sun::star::uno;
@@ -56,8 +271,9 @@ using namespace ::rtl;
namespace CPPU_CURRENT_NAMESPACE
{
-//==================================================================================================
-static inline OUString toUNOname( OUString const & rRTTIname ) throw ()
+static inline OUString toUNOname(
+ OUString const & rRTTIname )
+ throw ()
{
OUStringBuffer aRet( 64 );
OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
@@ -74,8 +290,10 @@ static inline OUString toUNOname( OUString const & rRTTIname ) throw ()
}
return aRet.makeStringAndClear();
}
-//==================================================================================================
-static inline OUString toRTTIname( OUString const & rUNOname ) throw ()
+
+static inline OUString toRTTIname(
+ OUString const & rUNOname )
+ throw ()
{
OUStringBuffer aRet( 64 );
aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU"
@@ -91,15 +309,10 @@ static inline OUString toRTTIname( OUString const & rUNOname ) throw ()
return aRet.makeStringAndClear();
}
+//RTTI simulation
-//##################################################################################################
-//#### RTTI simulation #############################################################################
-//##################################################################################################
-
-
-typedef hash_map< OUString, void *, OUStringHash, equal_to< OUString > > t_string2PtrMap;
+typedef boost::unordered_map< OUString, void *, OUStringHash, equal_to< OUString > > t_string2PtrMap;
-//==================================================================================================
class RTTInfos
{
Mutex _aMutex;
@@ -113,7 +326,6 @@ public:
~RTTInfos();
};
-//==================================================================================================
class __type_info
{
friend type_info * RTTInfos::getRTTI( OUString const & ) throw ();
@@ -131,11 +343,11 @@ private:
void * _m_data;
char _m_d_name[1];
};
-//__________________________________________________________________________________________________
+
__type_info::~__type_info() throw ()
{
}
-//__________________________________________________________________________________________________
+
type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
{
// a must be
@@ -164,11 +376,11 @@ type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
return (type_info *)iFind->second;
}
}
-//__________________________________________________________________________________________________
+
RTTInfos::RTTInfos() throw ()
{
}
-//__________________________________________________________________________________________________
+
RTTInfos::~RTTInfos() throw ()
{
#if OSL_DEBUG_LEVEL > 1
@@ -185,208 +397,206 @@ RTTInfos::~RTTInfos() throw ()
}
}
-
-//##################################################################################################
-//#### Exception raising ###########################################################################
-//##################################################################################################
-
-
-//==================================================================================================
-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 * pExcThis, void * pSource, ObjectFunction * pThis )
- throw ()
+void * __cdecl copyConstruct(
+ void * pExcThis,
+ void * pSource,
+ 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 * pExcThis, ObjectFunction * pThis )
- throw ()
+
+void * __cdecl destruct(
+ void * pExcThis,
+ typelib_TypeDescription * pTD ) throw ()
{
- ::uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release );
+ ::uno_destructData( pExcThis, pTD, cpp_release );
return pExcThis;
}
+const int codeSnippetSize = 40;
-#if 0
+void GenerateConstructorTrampoline(
+ unsigned char * code,
+ typelib_TypeDescription * pTD ) throw ()
+{
+ unsigned char *p = code;
-// These are machine code snippets in asmbits.asm
+ // mov r8, pTD
+ *p++ = 0x49; *p++ = 0xB8;
+ *((void **)p) = pTD; p += 8;
-extern void *copyConstruct;
-extern void *destruct;
+ // mov r11, copyConstruct
+ *p++ = 0x49; *p++ = 0xBB;
+ *((void **)p) = &copyConstruct; p += 8;
-#else
+ // jmp r11
+ *p++ = 0x41; *p++ = 0xFF; *p++ = 0xE3;
-static void whatthefuck_copyctor(sal_Int64 i, ...)
-{
- MessageBoxA (NULL, "Shit!", "whatthefuck_copyctor in except.cxx", MB_OK);
+ OSL_ASSERT( p < code + codeSnippetSize );
}
-static void whatthefuck_dtor(sal_Int64 i, ...)
+void GenerateDestructorTrampoline(
+ unsigned char * code,
+ typelib_TypeDescription * pTD ) throw ()
{
- MessageBoxA (NULL, "Shit!", "whatthefuck_dtor in except.cxx", MB_OK);
+ unsigned char *p = code;
+
+ // mov rdx, pTD
+ *p++ = 0x48; *p++ = 0xBA;
+ *((void **)p) = pTD; p += 8;
+
+ // mov r11, destruct
+ *p++ = 0x49; *p++ = 0xBB;
+ *((void **)p) = &destruct; p += 8;
+
+ // jmp r11
+ *p++ = 0x41; *p++ = 0xFF; *p++ = 0xE3;
+
+ OSL_ASSERT( p < code + codeSnippetSize );
}
-#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 )
+ {
+ // As _n0 is always initialized to zero, that means the
+ // hasvirtbase flag (see the ONTL catchabletype struct) is
+ // off, and thus the copyctor is of the ctor_ptr kind.
+ _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 );
+
+ GenerateDestructorTrampoline( pCode, pTD );
+ _pDtor = (sal_Int32)((sal_uInt64)pCode - _codeBase);
+ pCode += codeSnippetSize;
+
+ // 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_Int64 *)_types + 1);
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
- sal_Int32 nPos = 0;
- for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
- pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ 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 ()
{
}
-//__________________________________________________________________________________________________
+
ExceptionInfos::~ExceptionInfos() throw ()
{
#if OSL_DEBUG_LEVEL > 1
@@ -400,8 +610,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)
@@ -409,6 +619,10 @@ void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) thro
MutexGuard aGuard( Mutex::getGlobalMutex() );
if (! s_pInfos)
{
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo( &systemInfo );
+ allocationGranularity = systemInfo.dwAllocationGranularity;
+
#ifdef LEAK_STATIC_DATA
s_pInfos = new ExceptionInfos();
#else
@@ -418,41 +632,36 @@ void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) thro
}
}
- 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;
}
-
-//##################################################################################################
-//#### exported ####################################################################################
-//##################################################################################################
-
-
-//##################################################################################################
-type_info * mscx_getRTTI( OUString const & rUNOname )
+type_info * mscx_getRTTI(
+ OUString const & rUNOname )
{
static RTTInfos * s_pRTTIs = 0;
if (! s_pRTTIs)
@@ -471,41 +680,46 @@ type_info * mscx_getRTTI( OUString const & rUNOname )
return s_pRTTIs->getRTTI( rUNOname );
}
-//##################################################################################################
-void mscx_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+void mscx_raiseException(
+ uno_Any * pUnoExc,
+ 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 );
}
-//##############################################################################
int mscx_filterCppException(
- EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+ EXCEPTION_POINTERS * pPointers,
+ uno_Any * pUnoExc,
+ uno_Mapping * pCpp2Uno )
{
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;
@@ -514,13 +728,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
@@ -532,34 +746,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(
@@ -588,16 +815,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;