Kaydet (Commit) 222cea83 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Fix getRTTI for Android x86

First, make sure existing compiler-generated RTTI from liblo-native-code.so is
found (so that catching bridge-synthesized exceptions in native code works with
libc++abi, which checks type equivalence by address instead of string
comparsion), by using the dlsym(RTLD_DEFAULT,...) mechanism as in the ANDROID
gcc3_linux_arm bridge case.  And second, if that should fail, synthesize the
type_info even if the included cxxabi.h doesn't provide the relevant type
declarations, by using copies from the ABI specification, as also done on other
platforms.

Instead of always having getRTTI fail and raiseException throw a non-synthesized
css::uno::RuntimeException("no rtti for type ...").  Which explains the mystery
discussed in the commit message of 312eeeee
"Switch Android armeabi-v7a to libc++/libc++abi/libunwind too", why the observed
misbehavior on x86 was so different from that on armeabi-v7a.

Change-Id: I9308654c5c2b88b4d27e0e8e9edda1849133a161
Reviewed-on: https://gerrit.libreoffice.org/65070
Tested-by: Jenkins
Reviewed-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst 11526808
...@@ -90,7 +90,9 @@ class RTTI ...@@ -90,7 +90,9 @@ class RTTI
t_rtti_map m_rttis; t_rtti_map m_rttis;
t_rtti_map m_generatedRttis; t_rtti_map m_generatedRttis;
#if defined ANDROID
void * m_hApp; void * m_hApp;
#endif
public: public:
RTTI(); RTTI();
...@@ -100,13 +102,17 @@ public: ...@@ -100,13 +102,17 @@ public:
}; };
RTTI::RTTI() RTTI::RTTI()
#if !defined ANDROID
: m_hApp( dlopen(nullptr, RTLD_LAZY) ) : m_hApp( dlopen(nullptr, RTLD_LAZY) )
#endif
{ {
} }
RTTI::~RTTI() RTTI::~RTTI()
{ {
#if !defined ANDROID
dlclose( m_hApp ); dlclose( m_hApp );
#endif
} }
...@@ -135,7 +141,11 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) ...@@ -135,7 +141,11 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr )
buf.append( 'E' ); buf.append( 'E' );
OString symName( buf.makeStringAndClear() ); OString symName( buf.makeStringAndClear() );
#if !defined ANDROID
rtti = static_cast<type_info *>(dlsym( m_hApp, symName.getStr() )); rtti = static_cast<type_info *>(dlsym( m_hApp, symName.getStr() ));
#else
rtti = static_cast<type_info *>(dlsym( RTLD_DEFAULT, symName.getStr() ));
#endif
if (rtti) if (rtti)
{ {
...@@ -156,9 +166,6 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) ...@@ -156,9 +166,6 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr )
#if OSL_DEBUG_LEVEL > 1 #if OSL_DEBUG_LEVEL > 1
fprintf( stderr,"generated rtti for %s\n", rttiName ); fprintf( stderr,"generated rtti for %s\n", rttiName );
#endif #endif
// TODO: incompatible with llvm-c++ in ndk16 - no __si_class_type_info or __class_type_info
// either do as iOS one and inline thing or find another way
#if !defined(ANDROID)
if (pTypeDescr->pBaseTypeDescription) if (pTypeDescr->pBaseTypeDescription)
{ {
// ensure availability of base // ensure availability of base
...@@ -176,9 +183,6 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) ...@@ -176,9 +183,6 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr )
pair< t_rtti_map::iterator, bool > insertion( pair< t_rtti_map::iterator, bool > insertion(
m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
SAL_WARN_IF( !insertion.second, "bridges", "### inserting new generated rtti failed?!" ); SAL_WARN_IF( !insertion.second, "bridges", "### inserting new generated rtti failed?!" );
#else
(void) rttiName; // silence -Wunused-variable
#endif
} }
else // taking already generated rtti else // taking already generated rtti
{ {
...@@ -244,9 +248,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) ...@@ -244,9 +248,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
static RTTI rtti_data; static RTTI rtti_data;
rtti = rtti_data.getRTTI(reinterpret_cast<typelib_CompoundTypeDescription*>(pTypeDescr)); rtti = rtti_data.getRTTI(reinterpret_cast<typelib_CompoundTypeDescription*>(pTypeDescr));
TYPELIB_DANGER_RELEASE( pTypeDescr ); TYPELIB_DANGER_RELEASE( pTypeDescr );
#if !defined(ANDROID) // see TODO above
assert(rtti && "### no rtti for throwing exception!"); assert(rtti && "### no rtti for throwing exception!");
#endif
if (! rtti) if (! rtti)
{ {
throw RuntimeException( throw RuntimeException(
......
...@@ -33,6 +33,33 @@ ...@@ -33,6 +33,33 @@
#include <uno/any2.h> #include <uno/any2.h>
#include <uno/mapping.h> #include <uno/mapping.h>
#if !HAVE_CXXABI_H_CLASS_TYPE_INFO
// <https://mentorembedded.github.io/cxx-abi/abi.html>,
// libstdc++-v3/libsupc++/cxxabi.h:
namespace __cxxabiv1 {
class __class_type_info: public std::type_info {
public:
explicit __class_type_info(char const * n): type_info(n) {}
~__class_type_info() override;
};
}
#endif
#if !HAVE_CXXABI_H_SI_CLASS_TYPE_INFO
// <https://mentorembedded.github.io/cxx-abi/abi.html>,
// libstdc++-v3/libsupc++/cxxabi.h:
namespace __cxxabiv1 {
class __si_class_type_info: public __class_type_info {
public:
__class_type_info const * __base_type;
explicit __si_class_type_info(
char const * n, __class_type_info const *base):
__class_type_info(n), __base_type(base) {}
~__si_class_type_info() override;
};
}
#endif
namespace CPPU_CURRENT_NAMESPACE namespace CPPU_CURRENT_NAMESPACE
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment