summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2023-01-04 12:14:22 +0100
committerStephan Bergmann <sbergman@redhat.com>2023-01-04 13:49:58 +0000
commitef533553559fe09b4afab651fc692885d1acf4ed (patch)
treebbd17cba9c5253ddbe62250efa63c3d169156180
parent146eb1aa750a7612deb9d3e1825a7a2e1256bd4d (diff)
Rudimentary support for dynamic_cast on UNO proxy objects
<https://gerrit.libreoffice.org/c/core/+/144139> "New loplugin:unocast" had argued that uses of dynamic_cast from a UNO interface type are broken in general (because if the source object is a proxy from the C*+ UNO bridge, its vtable's RTTI slot will normally not be set up, which can cause a crash), and should be replaced with uses of XUnoTunnel. Which the various recent "loplugin:unocast (...)" commits started to do. However, it became clear that that is not the most ideal way forward: For one, getting more and more implementations of XUnoTunnel::getSomething into existing class hierarchies is error prone, as each such implementation must manually delegate to all its base class implementations. For another, uses of comphelper::getFromUnoTunnel (which often needs to do a queryInterface to XUnoTunnel first) are easily more expensive than uses of dynamic_cast. Thanks to Noel, the insight here is that for the use case of a dynamic_cast from a UNO interface type to a local C++ class type, and if the source object is a proxy, it is sufficient that the dynamic_cast will not crash. It will necessarily always return null (as the proxy will never be the implementation of a local C++ class type), so it is sufficient to fill the RTTI slots of the proxies' vtables with dummy values. That avoids having to set up proper RTTI for those potentially multiple-inheritance proxy types. (And with this in place, all those recent "loplugin:unocast (...)" commits can be reverted again in a next step.) I verified the changes for the gcc3_linux_aarch64 (on macOS), gcc3_linux_intel, gcc3_linux_x86-64, gcc3_macosx_x86-64, msvc_win32_intel, and msvc_win32_x86-64 bridges. The changes for all the other bridges were done blindly. (For gcc3_linux_x86-64, which already conditionally supported proper RTTI for UBSan, setting the offset-to-top slot to non-zero had to be made conditional too, as the dummy ProxyRtti will always pretend to be a full class rather than a potential base class that could have a non-zero offset-to-top value. For msvc_win32_*, it turned out that the existing code to set up dummy XInterface RTTI (which was there for reasons lost to history) was broken.) Change-Id: Iec4b8067d26b14b6fb02c2fdd15e1eee20919590 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145038 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r--bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx15
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx9
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx14
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx14
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips64/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx14
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx14
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc64/cpp2uno.cxx14
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx17
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx11
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx14
-rw-r--r--bridges/source/cpp_uno/msvc_win32_arm64/cpp2uno.cxx113
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx79
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx89
-rw-r--r--testtools/source/bridgetest/bridgetest.cxx4
27 files changed, 487 insertions, 77 deletions
diff --git a/bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx
index 2e6fdd11a820..92068152245c 100644
--- a/bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx
@@ -30,6 +30,7 @@
#include "share.hxx"
#include <string.h>
+#include <typeinfo>
using namespace ::com::sun::star::uno;
@@ -571,7 +572,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bp
__asm__ volatile ("isync" : : : "memory");
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -585,6 +586,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -592,7 +599,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
index 21de11b5ea36..9ba5af012443 100644
--- a/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
@@ -16,6 +16,11 @@
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+
+#include <sal/config.h>
+
+#include <typeinfo>
+
#include <com/sun/star/uno/RuntimeException.hpp>
#include <sal/log.hxx>
#include <uno/data.h>
@@ -457,7 +462,7 @@ namespace
}
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -471,6 +476,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot);
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -478,7 +489,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
index 775a4aff6962..669c4443c5f0 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
@@ -24,6 +24,7 @@
#include <cstddef>
#include <cstdlib>
#include <cstring>
+#include <typeinfo>
#include <dlfcn.h>
@@ -502,7 +503,7 @@ unsigned char * generateCodeSnippet(
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) {
@@ -515,6 +516,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -522,7 +529,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = nullptr;
- slots[-1].fn = nullptr;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx
index bd0be3981d7c..98709f4c5e90 100644
--- a/bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx
@@ -30,6 +30,7 @@
#include "share.hxx"
#include <stdio.h>
+#include <typeinfo>
//Calling Standards:
// "Calling Standard for Alpha Systems"
@@ -585,7 +586,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, u
__asm__ __volatile__("call_pal 0x86");
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -599,6 +600,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -606,7 +613,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx
index 103f2b492e3a..f476cf7df10b 100644
--- a/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx
@@ -18,6 +18,7 @@
*/
#include <malloc.h>
+#include <typeinfo>
#include <rtl/alloc.h>
#include <sal/log.hxx>
@@ -484,7 +485,7 @@ namespace
}
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -498,6 +499,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -505,7 +512,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = nullptr;
- slots[-1].fn = nullptr;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx
index 5491e0153b7e..7e8524d1c726 100644
--- a/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx
@@ -18,6 +18,7 @@
*/
#include <malloc.h>
+#include <typeinfo>
#include <rtl/alloc.h>
@@ -629,7 +630,7 @@ namespace
}
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -643,6 +644,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -650,7 +657,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx
index ddcd40818036..0d8303861c28 100644
--- a/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx
@@ -30,6 +30,7 @@
#include "share.hxx"
#include <stdio.h>
+#include <typeinfo>
extern "C" { extern void (*privateSnippetExecutor)(); }
@@ -607,10 +608,16 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot* bridges::cpp_uno::shared::VtableFactory::initializeBlock(void * block, sal_Int32 slotCount, sal_Int32, typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
- slots[-1] = {0,0};
+ slots[-1] = {0,reinterpret_cast<sal_uInt64>(&typeid(ProxyRtti))};
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
index 70c6091ec207..5dd6e1aa90f1 100644
--- a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
@@ -18,6 +18,10 @@
*/
+#include <sal/config.h>
+
+#include <typeinfo>
+
#include <com/sun/star/uno/genfunc.hxx>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <sal/log.hxx>
@@ -438,7 +442,7 @@ unsigned char * codeSnippet(
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) {
@@ -451,6 +455,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -458,7 +468,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = nullptr;
- slots[-1].fn = nullptr;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
index 0273b39da4e3..d0c1ce900501 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
@@ -31,6 +31,7 @@
#include <stdio.h>
#include <string.h>
+#include <typeinfo>
using namespace com::sun::star::uno;
@@ -480,7 +481,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const* bpt
struct bridges::cpp_uno::shared::VtableFactory::Slot
{
- void* fn;
+ void const* fn;
};
bridges::cpp_uno::shared::VtableFactory::Slot*
@@ -494,6 +495,15 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(sal_Int32 slot
return (slotCount + 2) * sizeof(Slot) + slotCount * codeSnippetSize;
}
+namespace
+{
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti
+{
+};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot*
bridges::cpp_uno::shared::VtableFactory::initializeBlock(void* block, sal_Int32 slotCount,
sal_Int32,
@@ -501,7 +511,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(void* block, sal_Int32
{
Slot* slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
- slots[-1].fn = 0; //destructor
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx
index c293f3ce6b64..ac375e052bf6 100644
--- a/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx
@@ -18,6 +18,7 @@
*/
#include <malloc.h>
+#include <typeinfo>
#include <rtl/alloc.h>
#include <sal/log.hxx>
@@ -441,7 +442,7 @@ namespace
}
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -455,6 +456,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -462,7 +469,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx
index 35e1f231d770..21ec313942ac 100644
--- a/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <string.h>
+#include <typeinfo>
using namespace com::sun::star::uno;
@@ -719,7 +720,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bpt
#endif
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -734,6 +735,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -741,7 +748,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
- slots[-1].fn = 0; //destructor
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_mips64/cpp2uno.cxx
index ebde9821eab2..7dbf0022e963 100644
--- a/bridges/source/cpp_uno/gcc3_linux_mips64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_mips64/cpp2uno.cxx
@@ -30,6 +30,7 @@
#include <stdio.h>
#include <string.h>
+#include <typeinfo>
using namespace com::sun::star::uno;
@@ -616,7 +617,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bpt
#endif
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -631,6 +632,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -638,7 +645,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
- slots[-1].fn = 0; //destructor
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
index 521dccd6dae1..328fb7a17e38 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
@@ -19,6 +19,7 @@
#include <string.h>
+#include <typeinfo>
#include <com/sun/star/uno/genfunc.hxx>
#include <sal/log.hxx>
@@ -702,7 +703,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bp
__asm__ volatile ("isync" : : : "memory");
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -716,6 +717,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -723,7 +730,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
index ab3fbd4c76b3..d1a5ee6f4e76 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
@@ -31,6 +31,7 @@
#include "share.hxx"
#include <stdio.h>
#include <string.h>
+#include <typeinfo>
#ifdef OSL_BIGENDIAN
#define IS_BIG_ENDIAN 1
@@ -664,7 +665,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bp
__asm__ volatile ("isync" : : : "memory");
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -678,6 +679,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -685,7 +692,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
index 6af52e9e471a..16f6ba27c0f4 100644
--- a/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_riscv64/cpp2uno.cxx
@@ -32,6 +32,7 @@
#include <stdio.h>
//#include <string.h>
#include <cstring>
+#include <typeinfo>
using namespace com::sun::star::uno;
@@ -709,7 +710,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const* bpt
struct bridges::cpp_uno::shared::VtableFactory::Slot
{
- void* fn;
+ void const* fn;
};
bridges::cpp_uno::shared::VtableFactory::Slot*
@@ -723,6 +724,15 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(sal_Int32 slot
return (slotCount + 2) * sizeof(Slot) + slotCount * codeSnippetSize;
}
+namespace
+{
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti
+{
+};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot*
bridges::cpp_uno::shared::VtableFactory::initializeBlock(void* block, sal_Int32 slotCount,
sal_Int32,
@@ -730,7 +740,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(void* block, sal_Int32
{
Slot* slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
- slots[-1].fn = 0; //destructor
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx
index b9e61b148304..aca33d1ae511 100644
--- a/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx
@@ -31,6 +31,7 @@
#include "share.hxx"
#include <stdio.h>
#include <string.h>
+#include <typeinfo>
using namespace ::com::sun::star::uno;
@@ -602,7 +603,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, u
{
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -616,6 +617,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -623,7 +630,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx
index ed48be648bca..285d1241a2d5 100644
--- a/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx
@@ -30,6 +30,7 @@
#include "share.hxx"
#include <stdio.h>
+#include <typeinfo>
using namespace ::com::sun::star::uno;
@@ -565,7 +566,7 @@ void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, u
{
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -579,6 +580,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -586,7 +593,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
index 8afbd04a7161..950d644df106 100644
--- a/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <typeinfo>
+
#include <com/sun/star/uno/genfunc.hxx>
#include <sal/log.hxx>
#include <typelib/typedescription.hxx>
@@ -477,7 +481,7 @@ unsigned char * codeSnippet(
} //end of namespace
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -491,6 +495,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -498,7 +508,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
- slots[-1].fn = 0; //destructor
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc64/cpp2uno.cxx
index 9b157f082120..f455be45dc88 100644
--- a/bridges/source/cpp_uno/gcc3_linux_sparc64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc64/cpp2uno.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <typeinfo>
+
#include <com/sun/star/uno/genfunc.hxx>
#include <sal/log.hxx>
#include <typelib/typedescription.hxx>
@@ -650,7 +654,7 @@ unsigned char * codeSnippet(
} //end of namespace
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -664,6 +668,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -671,7 +681,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
- slots[-1].fn = 0; //destructor
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
index f400c766a2e6..7466d0e225bc 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <typeinfo>
#include <rtl/alloc.h>
#include <sal/log.hxx>
@@ -445,7 +446,7 @@ static unsigned char * codeSnippet( unsigned char * code,
return code + codeSnippetSize;
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -459,17 +460,27 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+#if ENABLE_RUNTIME_OPTIMIZATIONS
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+#endif
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
typelib_InterfaceTypeDescription * type)
{
Slot * slots = mapBlockToVtable(block);
- slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
#if ENABLE_RUNTIME_OPTIMIZATIONS
- slots[-1].fn = nullptr;
+ slots[-2].fn = nullptr;
+ slots[-1].fn = &typeid(ProxyRtti);
+ (void)vtableNumber;
(void)type;
#else
+ slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
slots[-1].fn = x86_64::getRtti(type->aBase);
#endif
return slots + slotCount;
diff --git a/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
index efdf211d8a6e..11426e9475b2 100644
--- a/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_macosx_x86-64/cpp2uno.cxx
@@ -20,6 +20,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <typeinfo>
#include <rtl/alloc.h>
#include <sal/log.hxx>
@@ -453,7 +454,7 @@ static unsigned char * codeSnippet( unsigned char * code,
return code + codeSnippetSize;
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -467,6 +468,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -474,7 +481,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = nullptr;
- slots[-1].fn = nullptr;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx
index 5609bd6dc839..33687f1d0a02 100644
--- a/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx
@@ -20,6 +20,7 @@
#include <sal/alloca.h>
#include <strings.h>
+#include <typeinfo>
#include <com/sun/star/uno/genfunc.hxx>
#include "com/sun/star/uno/RuntimeException.hpp"
@@ -431,7 +432,7 @@ unsigned char * codeSnippet(
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -445,6 +446,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -452,7 +459,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx
index 639b8da3dc88..55c1360f844e 100644
--- a/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx
@@ -17,6 +17,10 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <typeinfo>
+
#include <com/sun/star/uno/genfunc.hxx>
#include <sal/log.hxx>
#include <typelib/typedescription.hxx>
@@ -475,7 +479,7 @@ unsigned char * codeSnippet(
} //end of namespace
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
@@ -489,6 +493,12 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
@@ -496,7 +506,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
{
Slot * slots = mapBlockToVtable(block);
slots[-2].fn = 0; //null
- slots[-1].fn = 0; //destructor
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/msvc_win32_arm64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_arm64/cpp2uno.cxx
index cfefa60e748a..fc956121dc07 100644
--- a/bridges/source/cpp_uno/msvc_win32_arm64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_arm64/cpp2uno.cxx
@@ -24,6 +24,8 @@
#include <cstddef>
#include <cstdlib>
#include <cstring>
+#include <limits>
+#include <typeinfo>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/uno/genfunc.hxx>
@@ -42,6 +44,8 @@
#include "abi.hxx"
+extern "C" IMAGE_DOS_HEADER const __ImageBase;
+
extern "C" void vtableSlotCall();
using namespace ::com::sun::star;
@@ -357,27 +361,110 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(sal_Int32 slot
return (slotCount + 1) * sizeof(Slot) + slotCount * codeSnippetSize;
}
+static sal_uInt32 imageRelative(void const* p)
+{
+ assert(reinterpret_cast<sal_uIntPtr>(p) >= reinterpret_cast<sal_uIntPtr>(&__ImageBase)
+ && reinterpret_cast<sal_uIntPtr>(p) - reinterpret_cast<sal_uIntPtr>(&__ImageBase)
+ <= std::numeric_limits<sal_uInt32>::max());
+ return reinterpret_cast<sal_uIntPtr>(p) - reinterpret_cast<sal_uIntPtr>(&__ImageBase);
+}
+
+namespace
+{
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti
+{
+};
+
+// The following vtable RTTI data is based on how the code at
+// <https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/MicrosoftCXXABI.cpp> computes
+// such data, and on how <https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483>
+// "Accessing the current module’s HINSTANCE from a static library" obtians __ImageBase:
+
+struct RttiClassHierarchyDescriptor;
+
+#pragma warning(push)
+#pragma warning(disable : 4324) // "structure was padded due to alignment specifier"
+
+struct alignas(16) RttiBaseClassDescriptor
+{
+ sal_uInt32 n0 = imageRelative(&typeid(ProxyRtti));
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = 0xFFFFFFFF;
+ sal_uInt32 n4 = 0;
+ sal_uInt32 n5 = 0x40;
+ sal_uInt32 n6;
+ RttiBaseClassDescriptor(RttiClassHierarchyDescriptor const* chd)
+ : n6(imageRelative(chd))
+ {
+ }
+};
+
+struct alignas(4) RttiBaseClassArray
+{
+ sal_uInt32 n0;
+ sal_uInt32 n1 = 0;
+ RttiBaseClassArray(RttiBaseClassDescriptor const* bcd)
+ : n0(imageRelative(bcd))
+ {
+ }
+};
+
+struct alignas(8) RttiClassHierarchyDescriptor
+{
+ sal_uInt32 n0 = 0;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 1;
+ sal_uInt32 n3;
+ RttiClassHierarchyDescriptor(RttiBaseClassArray const* bca)
+ : n3(imageRelative(bca))
+ {
+ }
+};
+
+struct alignas(16) RttiCompleteObjectLocator
+{
+ sal_uInt32 n0 = 1;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = imageRelative(&typeid(ProxyRtti));
+ sal_uInt32 n4;
+ sal_uInt32 n5 = imageRelative(this);
+ RttiCompleteObjectLocator(RttiClassHierarchyDescriptor const* chd)
+ : n4(imageRelative(chd))
+ {
+ }
+};
+
+struct Rtti
+{
+ RttiBaseClassDescriptor bcd;
+ RttiBaseClassArray bca;
+ RttiClassHierarchyDescriptor chd;
+ RttiCompleteObjectLocator col;
+ Rtti()
+ : bcd(&chd)
+ , bca(&bcd)
+ , chd(&bca)
+ , col(&chd)
+ {
+ }
+};
+
+#pragma warning(pop)
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot*
bridges::cpp_uno::shared::VtableFactory::initializeBlock(void* block, sal_Int32 slotCount,
sal_Int32,
typelib_InterfaceTypeDescription*)
{
- struct Rtti
- {
- sal_Int32 n0, n1, n2;
- type_info* rtti;
- Rtti()
- : n0(0)
- , n1(0)
- , n2(0)
- , rtti(RTTInfos::get("com.sun.star.uno.XInterface"))
- {
- }
- };
static Rtti rtti;
Slot* slots = mapBlockToVtable(block);
- slots[-1].fn = &rtti;
+ slots[-1].fn = &rtti.col;
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
index 0908c7666b50..577c318c5767 100644
--- a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
@@ -18,6 +18,10 @@
*/
+#include <sal/config.h>
+
+#include <typeinfo>
+
#include <malloc.h>
#include <com/sun/star/uno/genfunc.hxx>
@@ -124,23 +128,80 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+
+// The following vtable RTTI data is based on how the code at
+// <https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/MicrosoftCXXABI.cpp> computes
+// such data:
+
+struct RttiClassHierarchyDescriptor;
+
+#pragma warning (push)
+#pragma warning (disable: 4324) // "structure was padded due to alignment specifier"
+
+struct alignas(16) RttiBaseClassDescriptor {
+ sal_uInt32 n0 = reinterpret_cast<sal_uInt32>(&typeid(ProxyRtti));
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = 0xFFFFFFFF;
+ sal_uInt32 n4 = 0;
+ sal_uInt32 n5 = 0x40;
+ sal_uInt32 n6;
+ RttiBaseClassDescriptor(RttiClassHierarchyDescriptor const * chd):
+ n6(reinterpret_cast<sal_uInt32>(chd)) {}
+};
+
+struct alignas(4) RttiBaseClassArray {
+ sal_uInt32 n0;
+ sal_uInt32 n1 = 0;
+ RttiBaseClassArray(RttiBaseClassDescriptor const * bcd): n0(reinterpret_cast<sal_uInt32>(bcd))
+ {}
+};
+
+struct alignas(4) RttiClassHierarchyDescriptor {
+ sal_uInt32 n0 = 0;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 1;
+ sal_uInt32 n3;
+ RttiClassHierarchyDescriptor(RttiBaseClassArray const * bca):
+ n3(reinterpret_cast<sal_uInt32>(bca)) {}
+};
+
+struct alignas(16) RttiCompleteObjectLocator {
+ sal_uInt32 n0 = 0;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = reinterpret_cast<sal_uInt32>(&typeid(ProxyRtti));
+ sal_uInt32 n4;
+ RttiCompleteObjectLocator(RttiClassHierarchyDescriptor const * chd):
+ n4(reinterpret_cast<sal_uInt32>(chd)) {}
+};
+
+struct Rtti {
+ RttiBaseClassDescriptor bcd;
+ RttiBaseClassArray bca;
+ RttiClassHierarchyDescriptor chd;
+ RttiCompleteObjectLocator col;
+ Rtti(): bcd(&chd), bca(&bcd), chd(&bca), col(&chd) {}
+};
+
+#pragma warning (pop)
+
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
- struct Rtti {
- sal_Int32 n0, n1, n2;
- type_info * rtti;
- Rtti():
- n0(0), n1(0), n2(0),
- rtti(RTTInfos::get("com.sun.star.uno.XInterface"))
- {}
- };
static Rtti rtti;
Slot * slots = mapBlockToVtable(block);
- slots[-1].fn = &rtti;
+ slots[-1].fn = &rtti.col;
return slots + slotCount;
}
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
index 159eb99a4756..974a4a94d48b 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
@@ -18,6 +18,12 @@
*/
+#include <sal/config.h>
+
+#include <cassert>
+#include <limits>
+#include <typeinfo>
+
#include <malloc.h>
#include <com/sun/star/uno/genfunc.hxx>
@@ -34,6 +40,8 @@
#include <msvc/cpp2uno.hxx>
#include <msvc/amd64.hxx>
+extern "C" IMAGE_DOS_HEADER const __ImageBase;
+
using namespace ::com::sun::star;
extern "C" typelib_TypeClass cpp_vtable_call(sal_Int64 nOffsetAndIndex, void ** pCallStack)
@@ -141,24 +149,87 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+static sal_uInt32 imageRelative(void const * p) {
+ assert(
+ reinterpret_cast<sal_uIntPtr>(p) >= reinterpret_cast<sal_uIntPtr>(&__ImageBase)
+ && reinterpret_cast<sal_uIntPtr>(p) - reinterpret_cast<sal_uIntPtr>(&__ImageBase)
+ <= std::numeric_limits<sal_uInt32>::max());
+ return reinterpret_cast<sal_uIntPtr>(p) - reinterpret_cast<sal_uIntPtr>(&__ImageBase);
+}
+
+namespace {
+
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+
+// The following vtable RTTI data is based on how the code at
+// <https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/MicrosoftCXXABI.cpp> computes
+// such data, and on how <https://devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483>
+// "Accessing the current module’s HINSTANCE from a static library" obtians __ImageBase:
+
+struct RttiClassHierarchyDescriptor;
+
+#pragma warning (push)
+#pragma warning (disable: 4324) // "structure was padded due to alignment specifier"
+
+struct alignas(16) RttiBaseClassDescriptor {
+ sal_uInt32 n0 = imageRelative(&typeid(ProxyRtti));
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = 0xFFFFFFFF;
+ sal_uInt32 n4 = 0;
+ sal_uInt32 n5 = 0x40;
+ sal_uInt32 n6;
+ RttiBaseClassDescriptor(RttiClassHierarchyDescriptor const * chd): n6(imageRelative(chd)) {}
+};
+
+struct alignas(4) RttiBaseClassArray {
+ sal_uInt32 n0;
+ sal_uInt32 n1 = 0;
+ RttiBaseClassArray(RttiBaseClassDescriptor const * bcd): n0(imageRelative(bcd)) {}
+};
+
+struct alignas(8) RttiClassHierarchyDescriptor {
+ sal_uInt32 n0 = 0;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 1;
+ sal_uInt32 n3;
+ RttiClassHierarchyDescriptor(RttiBaseClassArray const * bca): n3(imageRelative(bca)) {}
+};
+
+struct alignas(16) RttiCompleteObjectLocator {
+ sal_uInt32 n0 = 1;
+ sal_uInt32 n1 = 0;
+ sal_uInt32 n2 = 0;
+ sal_uInt32 n3 = imageRelative(&typeid(ProxyRtti));
+ sal_uInt32 n4;
+ sal_uInt32 n5 = imageRelative(this);
+ RttiCompleteObjectLocator(RttiClassHierarchyDescriptor const * chd): n4(imageRelative(chd)) {}
+};
+
+struct Rtti {
+ RttiBaseClassDescriptor bcd;
+ RttiBaseClassArray bca;
+ RttiClassHierarchyDescriptor chd;
+ RttiCompleteObjectLocator col;
+ Rtti(): bcd(&chd), bca(&bcd), chd(&bca), col(&chd) {}
+};
+
+#pragma warning (pop)
+
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block,
sal_Int32 slotCount,
sal_Int32, typelib_InterfaceTypeDescription *)
{
- struct Rtti {
- sal_Int32 n0, n1, n2;
- type_info * rtti;
- Rtti():
- n0(0), n1(0), n2(0),
- rtti(RTTInfos::get("com.sun.star.uno.XInterface"))
- {}
- };
static Rtti rtti;
Slot * slots = mapBlockToVtable(block);
- slots[-1].fn = &rtti;
+ slots[-1].fn = &rtti.col;
return slots + slotCount;
}
diff --git a/testtools/source/bridgetest/bridgetest.cxx b/testtools/source/bridgetest/bridgetest.cxx
index 78bcdc6f0d3a..6067e3a5235a 100644
--- a/testtools/source/bridgetest/bridgetest.cxx
+++ b/testtools/source/bridgetest/bridgetest.cxx
@@ -1263,6 +1263,10 @@ sal_Int32 TestBridgeImpl::run( const Sequence< OUString > & rArgs )
bRet = check( raiseException( xLBT ) , "exception test" )&& bRet;
bRet = check( raiseOnewayException( xLBT ),
"oneway exception test" ) && bRet;
+ // Check that a dynamic_cast from what is potentially a proxy object does not cause a crash
+ // (and the choice of TestBridgeImpl as target is rather arbitrary, it is just some type for
+ // which the dynamic_cast is known to be null):
+ bRet = (dynamic_cast<TestBridgeImpl *>(xOriginal.get()) == nullptr) && bRet;
if (! bRet)
{
throw RuntimeException( "error: test failed!" );