summaryrefslogtreecommitdiffstats
path: root/salhelper
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /salhelper
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'salhelper')
-rw-r--r--salhelper/CppunitTest_salhelper_testapi.mk29
-rw-r--r--salhelper/IwyuFilter_salhelper.yaml2
-rw-r--r--salhelper/Library_salhelper.mk38
-rw-r--r--salhelper/Makefile7
-rw-r--r--salhelper/Module_salhelper.mk23
-rw-r--r--salhelper/README1
-rw-r--r--salhelper/qa/test_api.cxx248
-rw-r--r--salhelper/source/condition.cxx131
-rw-r--r--salhelper/source/dynload.cxx112
-rw-r--r--salhelper/source/gcc3.map139
-rw-r--r--salhelper/source/simplereferenceobject.cxx62
-rw-r--r--salhelper/source/thread.cxx51
-rw-r--r--salhelper/source/timer.cxx415
-rw-r--r--salhelper/test/Symbols/loader.cxx56
-rw-r--r--salhelper/test/Symbols/makefile.mk85
-rw-r--r--salhelper/test/Symbols/samplelib.cxx53
-rw-r--r--salhelper/test/Symbols/samplelib.hxx43
-rw-r--r--salhelper/test/dynamicloader/loader.cxx57
-rw-r--r--salhelper/test/dynamicloader/makefile.mk99
-rw-r--r--salhelper/test/dynamicloader/samplelib.cxx53
-rw-r--r--salhelper/test/dynamicloader/samplelib.hxx43
-rw-r--r--salhelper/test/rtti/exports.dxp6
-rw-r--r--salhelper/test/rtti/makefile.mk92
-rw-r--r--salhelper/test/rtti/rttitest.cxx38
-rw-r--r--salhelper/test/rtti/samplelibrtti.cxx51
-rw-r--r--salhelper/test/rtti/samplelibrtti.hxx44
-rw-r--r--salhelper/test/rtti/sols.map48
27 files changed, 2026 insertions, 0 deletions
diff --git a/salhelper/CppunitTest_salhelper_testapi.mk b/salhelper/CppunitTest_salhelper_testapi.mk
new file mode 100644
index 000000000..f3d98aa43
--- /dev/null
+++ b/salhelper/CppunitTest_salhelper_testapi.mk
@@ -0,0 +1,29 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# Major Contributor(s):
+# Copyright (C) 2012 Radu Ioan <ioan.radu.g@gmail.com> (initial developer)
+#
+# All Rights Reserved.
+#
+# For minor contributions see the git repository.
+
+$(eval $(call gb_CppunitTest_CppunitTest,salhelper_testapi))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,salhelper_testapi,\
+ salhelper/qa/test_api \
+))
+
+$(eval $(call gb_CppunitTest_use_external,salhelper_testapi,boost_headers))
+
+$(eval $(call gb_CppunitTest_use_libraries,salhelper_testapi,\
+ salhelper \
+ sal \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/salhelper/IwyuFilter_salhelper.yaml b/salhelper/IwyuFilter_salhelper.yaml
new file mode 100644
index 000000000..f017243be
--- /dev/null
+++ b/salhelper/IwyuFilter_salhelper.yaml
@@ -0,0 +1,2 @@
+---
+assumeFilename: salhelper/source/dynload.cxx
diff --git a/salhelper/Library_salhelper.mk b/salhelper/Library_salhelper.mk
new file mode 100644
index 000000000..a97666daf
--- /dev/null
+++ b/salhelper/Library_salhelper.mk
@@ -0,0 +1,38 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Library_Library,salhelper))
+
+$(eval $(call gb_Library_add_defs,salhelper,\
+ -DSALHELPER_DLLIMPLEMENTATION \
+))
+
+$(eval $(call gb_Library_use_libraries,salhelper,\
+ sal \
+))
+
+$(eval $(call gb_Library_add_exception_objects,salhelper,\
+ salhelper/source/condition \
+ salhelper/source/dynload \
+ salhelper/source/simplereferenceobject \
+ salhelper/source/thread \
+ salhelper/source/timer \
+))
+
+# At least on Linux, for backwards compatibility the salhelper library needs a
+# specific soname and symbol versioning. The symbols in the gcc3.map should be
+# those not already filtered out due to hidden visibility, so combining the
+# visibility feature with the version map file feature works well.
+# Solaris would need something like this, too. Its backwards compatibility is
+# broken for now:
+
+$(eval $(call gb_Library_set_soversion_script,salhelper,$(SRCDIR)/salhelper/source/gcc3.map))
+
+# vim: set noet sw=4 ts=4:
diff --git a/salhelper/Makefile b/salhelper/Makefile
new file mode 100644
index 000000000..ccb1c85a0
--- /dev/null
+++ b/salhelper/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/salhelper/Module_salhelper.mk b/salhelper/Module_salhelper.mk
new file mode 100644
index 000000000..e10508b55
--- /dev/null
+++ b/salhelper/Module_salhelper.mk
@@ -0,0 +1,23 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,salhelper))
+
+$(eval $(call gb_Module_add_targets,salhelper,\
+ Library_salhelper \
+))
+
+ifneq ($(OS),iOS)
+$(eval $(call gb_Module_add_check_targets,salhelper,\
+ CppunitTest_salhelper_testapi \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/salhelper/README b/salhelper/README
new file mode 100644
index 000000000..019a562df
--- /dev/null
+++ b/salhelper/README
@@ -0,0 +1 @@
+C++ helpers to make use of sal easier.
diff --git a/salhelper/qa/test_api.cxx b/salhelper/qa/test_api.cxx
new file mode 100644
index 000000000..dd45f4c73
--- /dev/null
+++ b/salhelper/qa/test_api.cxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * 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 <osl/mutex.hxx>
+#include <salhelper/condition.hxx>
+#include <salhelper/dynload.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+#include <memory>
+
+namespace {
+
+std::type_info const & getConditionTypeInfo()
+{ return typeid (salhelper::Condition *); }
+
+std::type_info const & getConditionModifierTypeInfo()
+{ return typeid (salhelper::ConditionModifier *); }
+
+std::type_info const & getConditionWaiterTypeInfo()
+{ return typeid (salhelper::ConditionWaiter *); }
+
+std::type_info const & getORealDynamicLoaderTypeInfo()
+{ return typeid (salhelper::ORealDynamicLoader *); }
+
+std::type_info const & getSimpleReferenceObjectTypeInfo()
+{ return typeid (salhelper::SimpleReferenceObject *); }
+
+}
+
+namespace {
+
+class DerivedCondition: public salhelper::Condition {
+public:
+ explicit DerivedCondition(osl::Mutex & mutex): Condition(mutex) {}
+
+protected:
+ virtual bool applies() const override { return false; }
+};
+
+class DerivedConditionWaiterTimedout:
+ public salhelper::ConditionWaiter::timedout
+{};
+
+class DerivedSimpleReferenceObject: public salhelper::SimpleReferenceObject {};
+
+class Test: public CppUnit::TestFixture {
+public:
+ void testCondition();
+
+ void testConditionModifier();
+
+ void testConditionWaiter();
+
+ void testConditionWaiterTimedout();
+
+ void testORealDynamicLoader();
+
+ void testSimpleReferenceObject();
+
+ void testDerivedCondition();
+
+ void testDerivedConditionWaiterTimedout();
+
+ void testDerivedSimpleReferenceObject();
+
+ CPPUNIT_TEST_SUITE(Test);
+ CPPUNIT_TEST(testCondition);
+ CPPUNIT_TEST(testConditionModifier);
+ CPPUNIT_TEST(testConditionWaiter);
+ CPPUNIT_TEST(testConditionWaiterTimedout);
+ CPPUNIT_TEST(testORealDynamicLoader);
+ CPPUNIT_TEST(testSimpleReferenceObject);
+ CPPUNIT_TEST(testDerivedCondition);
+ CPPUNIT_TEST(testDerivedConditionWaiterTimedout);
+ CPPUNIT_TEST(testDerivedSimpleReferenceObject);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void Test::testCondition() {
+ osl::Mutex mutex;
+ std::unique_ptr< salhelper::Condition > p(new DerivedCondition(mutex));
+ CPPUNIT_ASSERT(typeid(*p) != typeid(salhelper::Condition));
+ CPPUNIT_ASSERT(bool(typeid (p.get()) == typeid (salhelper::Condition *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::Condition const * >(p.get()))
+ == typeid (salhelper::Condition const *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::Condition volatile * >(p.get()))
+ == typeid (salhelper::Condition volatile *)));
+ CPPUNIT_ASSERT(bool(typeid (salhelper::Condition *) == getConditionTypeInfo()));
+}
+
+#ifdef _MSC_VER
+#pragma warning (push)
+#pragma warning (disable: 4189) // 'p': local variable is initialized but not referenced
+#endif
+
+
+void Test::testConditionModifier() {
+ salhelper::ConditionModifier * p = nullptr;
+ CPPUNIT_ASSERT(bool(typeid (*p) == typeid (salhelper::ConditionModifier)));
+ CPPUNIT_ASSERT(bool(typeid (p) == typeid (salhelper::ConditionModifier *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::ConditionModifier const * >(p))
+ == typeid (salhelper::ConditionModifier const *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::ConditionModifier volatile * >(p))
+ == typeid (salhelper::ConditionModifier volatile *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (salhelper::ConditionModifier *)
+ == getConditionModifierTypeInfo()));
+}
+
+void Test::testConditionWaiter() {
+ salhelper::ConditionWaiter * p = nullptr;
+ CPPUNIT_ASSERT(bool(typeid (*p) == typeid (salhelper::ConditionWaiter)));
+ CPPUNIT_ASSERT(bool(typeid (p) == typeid (salhelper::ConditionWaiter *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::ConditionWaiter const * >(p))
+ == typeid (salhelper::ConditionWaiter const *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::ConditionWaiter volatile * >(p))
+ == typeid (salhelper::ConditionWaiter volatile *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (salhelper::ConditionWaiter *) == getConditionWaiterTypeInfo()));
+}
+
+void Test::testConditionWaiterTimedout() {
+ salhelper::ConditionWaiter::timedout x;
+ CPPUNIT_ASSERT(bool(typeid (x) == typeid (salhelper::ConditionWaiter::timedout)));
+ CPPUNIT_ASSERT(bool(
+ typeid (&x) == typeid (salhelper::ConditionWaiter::timedout *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::ConditionWaiter::timedout const * >(&x))
+ == typeid (salhelper::ConditionWaiter::timedout const *)));
+ CPPUNIT_ASSERT(bool(
+ (typeid
+ (const_cast< salhelper::ConditionWaiter::timedout volatile * >(&x)))
+ == typeid (salhelper::ConditionWaiter::timedout volatile *)));
+ try {
+ throw salhelper::ConditionWaiter::timedout();
+ } catch (salhelper::ConditionWaiter::timedout &) {
+ } catch (...) {
+ CPPUNIT_FAIL("not caught");
+ }
+}
+
+void Test::testORealDynamicLoader() {
+ salhelper::ORealDynamicLoader * p = nullptr;
+ CPPUNIT_ASSERT(typeid (p) != typeid (salhelper::ORealDynamicLoader));
+ CPPUNIT_ASSERT(bool(typeid (p) == typeid (salhelper::ORealDynamicLoader *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::ORealDynamicLoader const * >(p))
+ == typeid (salhelper::ORealDynamicLoader const *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::ORealDynamicLoader volatile * >(p))
+ == typeid (salhelper::ORealDynamicLoader volatile *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (salhelper::ORealDynamicLoader *)
+ == getORealDynamicLoaderTypeInfo()));
+}
+
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+void Test::testSimpleReferenceObject() {
+ salhelper::SimpleReferenceObject * p = new DerivedSimpleReferenceObject;
+ try {
+ CPPUNIT_ASSERT(
+ typeid (*p) != typeid (salhelper::SimpleReferenceObject));
+ CPPUNIT_ASSERT(bool(
+ typeid (p) == typeid (salhelper::SimpleReferenceObject *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (const_cast< salhelper::SimpleReferenceObject const * >(p))
+ == typeid (salhelper::SimpleReferenceObject const *)));
+ CPPUNIT_ASSERT(bool(
+ (typeid
+ (const_cast< salhelper::SimpleReferenceObject volatile * >(p)))
+ == typeid (salhelper::SimpleReferenceObject volatile *)));
+ CPPUNIT_ASSERT(bool(
+ typeid (salhelper::SimpleReferenceObject *)
+ == getSimpleReferenceObjectTypeInfo()));
+ } catch (...) {
+ delete static_cast< DerivedSimpleReferenceObject * >(p);
+ throw;
+ }
+ delete static_cast< DerivedSimpleReferenceObject * >(p);
+}
+
+void Test::testDerivedCondition() {
+ osl::Mutex mutex;
+ // Next line tests that new doesn't throw
+ std::unique_ptr< salhelper::Condition > p(new DerivedCondition(mutex));
+}
+
+void Test::testDerivedConditionWaiterTimedout() {
+ // Next line tests that new doesn't throw
+ std::unique_ptr< salhelper::ConditionWaiter::timedout > p(
+ new DerivedConditionWaiterTimedout);
+ try {
+ throw DerivedConditionWaiterTimedout();
+ } catch (salhelper::ConditionWaiter::timedout &) {
+ } catch (...) {
+ CPPUNIT_FAIL("not caught");
+ }
+}
+
+void Test::testDerivedSimpleReferenceObject() {
+ salhelper::SimpleReferenceObject * p = new DerivedSimpleReferenceObject;
+ try {
+ CPPUNIT_ASSERT(dynamic_cast< DerivedSimpleReferenceObject * >(p) != nullptr);
+ } catch (...) {
+ delete static_cast< DerivedSimpleReferenceObject * >(p);
+ throw;
+ }
+ delete static_cast< DerivedSimpleReferenceObject * >(p);
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(Test);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/source/condition.cxx b/salhelper/source/condition.cxx
new file mode 100644
index 000000000..a83cc753e
--- /dev/null
+++ b/salhelper/source/condition.cxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+
+#include <salhelper/condition.hxx>
+#include <osl/time.h>
+#include <osl/mutex.hxx>
+
+using namespace salhelper;
+
+
+/******************************************************************
+ * *
+ * Condition *
+ * *
+ ******************************************************************/
+
+Condition::Condition(osl::Mutex& aMutex)
+ : m_aMutex(aMutex),
+ m_aCondition()
+{
+}
+
+
+Condition::~Condition()
+{
+}
+
+
+/******************************************************************
+ * *
+ * ConditionModifier *
+ * *
+ ******************************************************************/
+
+ConditionModifier::ConditionModifier(Condition& aCond)
+ : m_aCond(aCond)
+{
+ m_aCond.m_aMutex.acquire();
+}
+
+
+ConditionModifier::~ConditionModifier()
+{
+ if(m_aCond.applies())
+ m_aCond.m_aCondition.set();
+
+ m_aCond.m_aMutex.release();
+}
+
+
+/******************************************************************
+ * *
+ * ConditionWaiter *
+ * *
+ ******************************************************************/
+
+ConditionWaiter::timedout::timedout() {}
+
+ConditionWaiter::timedout::timedout(timedout const &) {}
+
+ConditionWaiter::timedout::~timedout() {}
+
+ConditionWaiter::timedout &
+ConditionWaiter::timedout::operator =(timedout const &) { return *this; }
+
+ConditionWaiter::ConditionWaiter(Condition& aCond)
+ : m_aCond(aCond)
+{
+ while(true) {
+ m_aCond.m_aCondition.wait();
+ m_aCond.m_aMutex.acquire();
+
+ if(m_aCond.applies())
+ break;
+ else {
+ m_aCond.m_aCondition.reset();
+ m_aCond.m_aMutex.release();
+ }
+ }
+}
+
+
+ConditionWaiter::ConditionWaiter(Condition& aCond,sal_uInt32 milliSec)
+ : m_aCond(aCond)
+{
+ TimeValue aTime;
+ aTime.Seconds = milliSec / 1000;
+ aTime.Nanosec = 1000000 * ( milliSec % 1000 );
+
+ while(true) {
+ if( m_aCond.m_aCondition.wait(&aTime) ==
+ osl::Condition::result_timeout )
+ throw timedout();
+
+ m_aCond.m_aMutex.acquire();
+
+ if(m_aCond.applies())
+ break;
+ else {
+ m_aCond.m_aCondition.reset();
+ m_aCond.m_aMutex.release();
+ }
+ }
+}
+
+
+ConditionWaiter::~ConditionWaiter()
+{
+ if(! m_aCond.applies())
+ m_aCond.m_aCondition.reset();
+ m_aCond.m_aMutex.release();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/source/dynload.cxx b/salhelper/source/dynload.cxx
new file mode 100644
index 000000000..d3b8e70fb
--- /dev/null
+++ b/salhelper/source/dynload.cxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <salhelper/dynload.hxx>
+
+namespace salhelper
+{
+
+typedef void* (*ApiInitFunction) ();
+
+ORealDynamicLoader::ORealDynamicLoader(ORealDynamicLoader ** ppSetToZeroInDestructor_,
+ const OUString& moduleName,
+ const OUString& initFunction,
+ void* pApi,
+ oslModule pModule)
+ : m_pApi(pApi)
+ , m_refCount(1)
+ , m_pModule(pModule)
+ , m_strModuleName(moduleName)
+ , m_strInitFunction(initFunction)
+ , ppSetToZeroInDestructor( ppSetToZeroInDestructor_ )
+{
+}
+
+ORealDynamicLoader* ORealDynamicLoader::newInstance(ORealDynamicLoader ** ppSetToZeroInDestructor,
+ const OUString& moduleName,
+ const OUString& initFunction)
+{
+#ifdef DISABLE_DYNLOADING
+ (void) ppSetToZeroInDestructor;
+ (void) moduleName;
+ (void) initFunction;
+
+ return NULL;
+#else
+ ApiInitFunction initFunc;
+ oslModule pModule = osl_loadModule(moduleName.pData, SAL_LOADMODULE_DEFAULT);
+
+ if ( !pModule )
+ {
+ return nullptr;
+ }
+
+ initFunc = reinterpret_cast<ApiInitFunction>(osl_getFunctionSymbol(
+ pModule, initFunction.pData));
+
+ if ( !initFunc )
+ {
+ osl_unloadModule(pModule);
+ return nullptr;
+ }
+
+ return(new ORealDynamicLoader(ppSetToZeroInDestructor, moduleName,
+ initFunction,
+ initFunc(),
+ pModule));
+#endif
+}
+
+ORealDynamicLoader::~ORealDynamicLoader()
+{
+ // set the address to zero
+ if( ppSetToZeroInDestructor )
+ *ppSetToZeroInDestructor = nullptr;
+
+ if (m_pModule)
+ {
+#ifndef DISABLE_DYNLOADING
+ osl_unloadModule(m_pModule);
+#endif
+ m_pModule = nullptr;
+ }
+}
+
+sal_uInt32 ORealDynamicLoader::acquire()
+{
+ return ++m_refCount;
+}
+
+sal_uInt32 ORealDynamicLoader::release()
+{
+ sal_uInt32 nRet = --m_refCount;
+ if( nRet == 0 )
+ delete this;
+ return nRet;
+}
+
+
+void* ORealDynamicLoader::getApi() const
+{
+ return m_pApi;
+}
+
+} // namespace salhelper
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/source/gcc3.map b/salhelper/source/gcc3.map
new file mode 100644
index 000000000..3d0d90d4a
--- /dev/null
+++ b/salhelper/source/gcc3.map
@@ -0,0 +1,139 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+UDK_3_0_0 { # should have been UDK_3.0
+ global:
+ _ZTI*; _ZTS*; # weak RTTI symbols for C++ exceptions
+
+ _ZN9salhelper18ORealDynamicLoader11newInstanceEPPS0_RKN3rtl8OUStringES6_;
+ _ZN9salhelper18ORealDynamicLoader7acquireEv;
+ _ZN9salhelper18ORealDynamicLoader7releaseEv;
+ _ZN9salhelper18ORealDynamicLoaderC1EPPS0_RKN3rtl8OUStringES6_PvS7_;
+ _ZN9salhelper18ORealDynamicLoaderC2EPPS0_RKN3rtl8OUStringES6_PvS7_;
+ _ZN9salhelper18ORealDynamicLoaderD0Ev;
+ _ZN9salhelper18ORealDynamicLoaderD1Ev;
+ _ZN9salhelper18ORealDynamicLoaderD2Ev;
+ _ZN9salhelper21SimpleReferenceObjectD0Ev;
+ _ZN9salhelper21SimpleReferenceObjectD1Ev;
+ _ZN9salhelper21SimpleReferenceObjectD2Ev;
+ _ZN9salhelper21SimpleReferenceObjectdlEPv;
+
+ # Introducing a question mark at the end because of
+ # marginal type discrepancy there is a difference in the
+ # mangled name between Linux and macOS, see #i69351#
+ _ZN9salhelper21SimpleReferenceObjectnwE?; # salhelper::SimpleReferenceObject::operator new (std::size_t)
+
+ _ZNK9salhelper18ORealDynamicLoader6getApiEv;
+ # _ZTIN9salhelper18ORealDynamicLoaderE;
+ # _ZTSN9salhelper18ORealDynamicLoaderE;
+ _ZTVN9salhelper18ORealDynamicLoaderE;
+ # _ZTIN9salhelper21SimpleReferenceObjectE;
+ # _ZTSN9salhelper21SimpleReferenceObjectE;
+ _ZTVN9salhelper21SimpleReferenceObjectE;
+
+ local:
+ *;
+};
+
+UDK_3.1 {
+ global:
+ _ZN9salhelper21SimpleReferenceObjectdlEPvRKSt9nothrow_t;
+
+ # Introducing a wildcard right in the middle because due to
+ # marginal type discrepancy there is a difference in the
+ # mangled name between Linux and macOS see #i69351#
+ _ZN9salhelper21SimpleReferenceObjectnwE?RKSt9nothrow_t; # salhelper::SimpleReferenceObject::operator new (std::size_t, std::nothrow_t const&)
+
+ _ZN9salhelper9ConditionC1ERN3osl5MutexE;
+ _ZN9salhelper9ConditionC2ERN3osl5MutexE;
+ _ZN9salhelper9ConditionD0Ev;
+ _ZN9salhelper9ConditionD1Ev;
+ _ZN9salhelper9ConditionD2Ev;
+ # _ZTIN9salhelper9ConditionE;
+ # _ZTIS9salhelper9ConditionE;
+
+ _ZN9salhelper17ConditionModifierC1ERNS_9ConditionE;
+ _ZN9salhelper17ConditionModifierC2ERNS_9ConditionE;
+ _ZN9salhelper17ConditionModifierD1Ev;
+ _ZN9salhelper17ConditionModifierD2Ev;
+
+ _ZN9salhelper15ConditionWaiterC1ERNS_9ConditionE;
+ _ZN9salhelper15ConditionWaiterC1ERNS_9ConditionE?;
+ _ZN9salhelper15ConditionWaiterC2ERNS_9ConditionE;
+ _ZN9salhelper15ConditionWaiterC2ERNS_9ConditionE?;
+ _ZN9salhelper15ConditionWaiterD1Ev;
+ _ZN9salhelper15ConditionWaiterD2Ev;
+
+ _ZN9salhelper15ConditionWaiter8timedoutaSERKS1_;
+ _ZN9salhelper15ConditionWaiter8timedoutC1ERKS1_;
+ _ZN9salhelper15ConditionWaiter8timedoutC1Ev;
+ _ZN9salhelper15ConditionWaiter8timedoutC2ERKS1_;
+ _ZN9salhelper15ConditionWaiter8timedoutC2Ev;
+ _ZN9salhelper15ConditionWaiter8timedoutD0Ev;
+ _ZN9salhelper15ConditionWaiter8timedoutD1Ev;
+ _ZN9salhelper15ConditionWaiter8timedoutD2Ev;
+ # _ZTIN9salhelper15ConditionWaiter8timedoutE;
+ # _ZTSN9salhelper15ConditionWaiter8timedoutE;
+
+
+ _ZN9salhelper5TimerC1ERKNS_10TTimeValueE;
+ _ZN9salhelper5TimerC1ERKNS_10TTimeValueES3_;
+ _ZN9salhelper5TimerC1Ev;
+ _ZN9salhelper5TimerC2ERKNS_10TTimeValueE;
+ _ZN9salhelper5TimerC2ERKNS_10TTimeValueES3_;
+ _ZN9salhelper5TimerC2Ev;
+ _ZN9salhelper5TimerD0Ev;
+ _ZN9salhelper5TimerD1Ev;
+ _ZN9salhelper5TimerD2Ev;
+ _ZN9salhelper5Timer5startEv;
+ _ZN9salhelper5Timer4stopEv;
+ _ZNK9salhelper5Timer9isTickingEv;
+ _ZNK9salhelper5Timer9isExpiredEv;
+ _ZNK9salhelper5Timer13expiresBeforeEPKS0_;
+ _ZN9salhelper5Timer15setAbsoluteTimeERKNS_10TTimeValueE;
+ _ZN9salhelper5Timer16setRemainingTimeERKNS_10TTimeValueE;
+ _ZN9salhelper5Timer16setRemainingTimeERKNS_10TTimeValueES3_;
+ _ZN9salhelper5Timer7addTimeERKNS_10TTimeValueE;
+ _ZNK9salhelper5Timer16getRemainingTimeEv;
+
+
+} UDK_3_0_0;
+
+LIBO_UDK_3.6 { # symbols available in >= LibO 3.6
+ global:
+ _ZN9salhelper6Thread12onTerminatedEv;
+ # salhelper::Thread::onTerminated()
+ _ZN9salhelper6Thread3runEv; # salhelper::Thread::run()
+ _ZN9salhelper6Thread6launchEv; # salhelper::Thread::launch()
+ _ZN9salhelper6ThreadC1EPKc; # salhelper::Thread::Thread(char const*)
+ _ZN9salhelper6ThreadC2EPKc; # salhelper::Thread::Thread(char const*)
+ _ZN9salhelper6ThreadD0Ev; # salhelper::Thread::~Thread()
+ _ZN9salhelper6ThreadD1Ev; # salhelper::Thread::~Thread()
+ _ZN9salhelper6ThreadD2Ev; # salhelper::Thread::~Thread()
+ _ZTVN9salhelper6ThreadE; # vtable for salhelper::Thread
+ _ZThn*_N9salhelper6Thread12onTerminatedEv;
+ # non-virtual thunk to salhelper::Thread::onTerminated()
+ _ZThn*_N9salhelper6Thread3runEv;
+ # non-virtual thunk to salhelper::Thread::run()
+} UDK_3.1;
+
+# Unique libstdc++ symbols:
+GLIBCXX_3.4 {
+ global:
+ _ZGVNSt7num_put*; _ZNSt7num_put*;
+ _ZNSs4_Rep20_S_empty_rep_storageE;
+};
diff --git a/salhelper/source/simplereferenceobject.cxx b/salhelper/source/simplereferenceobject.cxx
new file mode 100644
index 000000000..d57e7f0cd
--- /dev/null
+++ b/salhelper/source/simplereferenceobject.cxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <salhelper/simplereferenceobject.hxx>
+
+#include <cassert>
+#include <new>
+
+using salhelper::SimpleReferenceObject;
+
+SimpleReferenceObject::~SimpleReferenceObject()
+{
+ assert(m_nCount == 0);
+}
+
+void *SimpleReferenceObject::operator new(std::size_t nSize)
+{
+ return ::operator new(nSize);
+}
+
+void *SimpleReferenceObject::operator new(std::size_t nSize,
+ std::nothrow_t const &)
+{
+#if defined(_WIN32)
+ return ::operator new(nSize);
+ // WNT lacks a global nothrow operator new...
+#else // _WIN32
+ return ::operator new(nSize, std::nothrow);
+#endif // _WIN32
+}
+
+void SimpleReferenceObject::operator delete(void * pPtr)
+{
+ ::operator delete(pPtr);
+}
+
+void SimpleReferenceObject::operator delete(void * pPtr, std::nothrow_t const &)
+{
+#if defined(_WIN32)
+ ::operator delete(pPtr); // WNT lacks a global nothrow operator delete...
+#else // _WIN32
+ ::operator delete(pPtr, std::nothrow);
+#endif // _WIN32
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/source/thread.cxx b/salhelper/source/thread.cxx
new file mode 100644
index 000000000..1a06bf3b2
--- /dev/null
+++ b/salhelper/source/thread.cxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <stdexcept>
+#include <string>
+
+#include <sal/log.hxx>
+#include <salhelper/thread.hxx>
+
+salhelper::Thread::Thread(char const * name): name_(name) {}
+
+void salhelper::Thread::launch() {
+ SAL_INFO("salhelper.thread", "launch " << name_);
+ // Assumption is that osl::Thread::create returns normally with a true
+ // return value iff it causes osl::Thread::run to start executing:
+ acquire();
+ try {
+ if (!create()) {
+ throw std::runtime_error("osl::Thread::create failed");
+ }
+ } catch (...) {
+ release();
+ throw;
+ }
+}
+
+salhelper::Thread::~Thread() {}
+
+void salhelper::Thread::run() {
+ try {
+ setName(name_);
+ execute();
+ } catch (...) {
+ // Work around the problem that onTerminated is not called if run throws
+ // an exception:
+ onTerminated();
+ throw;
+ }
+}
+
+void salhelper::Thread::onTerminated() { release(); }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/source/timer.cxx b/salhelper/source/timer.cxx
new file mode 100644
index 000000000..8101b2387
--- /dev/null
+++ b/salhelper/source/timer.cxx
@@ -0,0 +1,415 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#include <salhelper/timer.hxx>
+
+#include <osl/thread.hxx>
+#include <osl/conditn.hxx>
+#include <osl/mutex.hxx>
+#include <rtl/instance.hxx>
+
+using namespace salhelper;
+
+class salhelper::TimerManager : public osl::Thread
+{
+public:
+ TimerManager();
+
+ virtual ~TimerManager() override;
+
+ /// register timer
+ void registerTimer(salhelper::Timer* pTimer);
+
+ /// unregister timer
+ void unregisterTimer(salhelper::Timer const * pTimer);
+
+ /// lookup timer
+ bool lookupTimer(const salhelper::Timer* pTimer);
+
+ /// retrieves the "Singleton" TimerManager Instance
+ static TimerManager* getTimerManager();
+
+protected:
+ /// worker-function of thread
+ virtual void SAL_CALL run() override;
+
+ /// Checking and triggering of a timer event
+ void checkForTimeout();
+
+ /// cleanup Method
+ virtual void SAL_CALL onTerminated() override;
+
+ /// sorted-queue data
+ salhelper::Timer* m_pHead;
+ /// List Protection
+ osl::Mutex m_Lock;
+ /// Signal the insertion of a timer
+ osl::Condition m_notEmpty;
+
+ /// "Singleton Pattern"
+ static salhelper::TimerManager* m_pManager;
+
+};
+
+Timer::Timer()
+ : m_aTimeOut(0),
+ m_aExpired(0),
+ m_aRepeatDelta(0),
+ m_pNext(nullptr)
+{
+}
+
+Timer::Timer(const TTimeValue& rTime)
+ : m_aTimeOut(rTime),
+ m_aExpired(0),
+ m_aRepeatDelta(0),
+ m_pNext(nullptr)
+{
+}
+
+Timer::Timer(const TTimeValue& rTime, const TTimeValue& Repeat)
+ : m_aTimeOut(rTime),
+ m_aExpired(0),
+ m_aRepeatDelta(Repeat),
+ m_pNext(nullptr)
+{
+}
+
+Timer::~Timer()
+{
+ stop();
+}
+
+void Timer::start()
+{
+ if (!isTicking())
+ {
+ if (!m_aTimeOut.isEmpty())
+ setRemainingTime(m_aTimeOut);
+
+ TimerManager *pManager = TimerManager::getTimerManager();
+
+ if (pManager)
+ pManager->registerTimer(this);
+ }
+}
+
+void Timer::stop()
+{
+ TimerManager *pManager = TimerManager::getTimerManager();
+
+ if (pManager)
+ pManager->unregisterTimer(this);
+}
+
+sal_Bool Timer::isTicking() const
+{
+ TimerManager *pManager = TimerManager::getTimerManager();
+
+ if (pManager)
+ return pManager->lookupTimer(this);
+ else
+ return false;
+}
+
+sal_Bool Timer::isExpired() const
+{
+ TTimeValue Now;
+
+ osl_getSystemTime(&Now);
+
+ return !(Now < m_aExpired);
+}
+
+sal_Bool Timer::expiresBefore(const Timer* pTimer) const
+{
+ if (pTimer)
+ return m_aExpired < pTimer->m_aExpired;
+ else
+ return false;
+}
+
+void Timer::setAbsoluteTime(const TTimeValue& Time)
+{
+ m_aTimeOut = 0;
+ m_aExpired = Time;
+ m_aRepeatDelta = 0;
+
+ m_aExpired.normalize();
+}
+
+void Timer::setRemainingTime(const TTimeValue& Remaining)
+{
+ osl_getSystemTime(&m_aExpired);
+
+ m_aExpired.addTime(Remaining);
+}
+
+void Timer::setRemainingTime(const TTimeValue& Remaining, const TTimeValue& Repeat)
+{
+ osl_getSystemTime(&m_aExpired);
+
+ m_aExpired.addTime(Remaining);
+
+ m_aRepeatDelta = Repeat;
+}
+
+void Timer::addTime(const TTimeValue& Delta)
+{
+ m_aExpired.addTime(Delta);
+}
+
+TTimeValue Timer::getRemainingTime() const
+{
+ TTimeValue Now;
+
+ osl_getSystemTime(&Now);
+
+ sal_Int32 secs = m_aExpired.Seconds - Now.Seconds;
+
+ if (secs < 0)
+ return TTimeValue(0, 0);
+
+ sal_Int32 nsecs = m_aExpired.Nanosec - Now.Nanosec;
+
+ if (nsecs < 0)
+ {
+ if (secs > 0)
+ {
+ secs -= 1;
+ nsecs += 1000000000;
+ }
+ else
+ return TTimeValue(0, 0);
+ }
+
+ return TTimeValue(secs, nsecs);
+}
+
+namespace
+{
+ // Synchronize access to TimerManager
+ struct theTimerManagerMutex : public rtl::Static< osl::Mutex, theTimerManagerMutex> {};
+}
+
+TimerManager* salhelper::TimerManager::m_pManager = nullptr;
+
+/** The timer manager cleanup has been removed (no thread is killed anymore),
+ so the thread leaks.
+
+ This will result in a GPF in case the salhelper-library gets unloaded before
+ process termination.
+
+ @TODO : rewrite this file, so that the timerManager thread gets destroyed,
+ when there are no timers anymore !
+**/
+
+TimerManager::TimerManager()
+{
+ osl::MutexGuard Guard(theTimerManagerMutex::get());
+
+ assert(m_pManager == nullptr);
+
+ m_pManager = this;
+ m_pHead= nullptr;
+ m_notEmpty.reset();
+
+ // start thread
+ create();
+}
+
+TimerManager::~TimerManager()
+{
+ osl::MutexGuard Guard(theTimerManagerMutex::get());
+
+ if (m_pManager == this)
+ m_pManager = nullptr;
+}
+
+void TimerManager::onTerminated()
+{
+ delete this; // FIXME
+}
+
+TimerManager* TimerManager::getTimerManager()
+{
+ osl::MutexGuard Guard(theTimerManagerMutex::get());
+
+ if (! m_pManager)
+ new TimerManager;
+
+ return m_pManager;
+}
+
+void TimerManager::registerTimer(Timer* pTimer)
+{
+ if (!pTimer)
+ return;
+
+ osl::MutexGuard Guard(m_Lock);
+
+ // try to find one with equal or lower remaining time.
+ Timer** ppIter = &m_pHead;
+
+ while (*ppIter)
+ {
+ if (pTimer->expiresBefore(*ppIter))
+ {
+ // next element has higher remaining time,
+ // => insert new timer before
+ break;
+ }
+ ppIter= &((*ppIter)->m_pNext);
+ }
+
+ // next element has higher remaining time,
+ // => insert new timer before
+ pTimer->m_pNext= *ppIter;
+ *ppIter = pTimer;
+
+
+ if (pTimer == m_pHead)
+ {
+ // it was inserted as new head
+ // signal it to TimerManager Thread
+ m_notEmpty.set();
+ }
+}
+
+void TimerManager::unregisterTimer(Timer const * pTimer)
+{
+ if (!pTimer)
+ return;
+
+ // lock access
+ osl::MutexGuard Guard(m_Lock);
+
+ Timer** ppIter = &m_pHead;
+
+ while (*ppIter)
+ {
+ if (pTimer == (*ppIter))
+ {
+ // remove timer from list
+ *ppIter = (*ppIter)->m_pNext;
+ return;
+ }
+ ppIter= &((*ppIter)->m_pNext);
+ }
+}
+
+bool TimerManager::lookupTimer(const Timer* pTimer)
+{
+ if (!pTimer)
+ return false;
+
+ // lock access
+ osl::MutexGuard Guard(m_Lock);
+
+ // check the list
+ for (Timer* pIter = m_pHead; pIter != nullptr; pIter= pIter->m_pNext)
+ {
+ if (pIter == pTimer)
+ return true;
+ }
+
+ return false;
+}
+
+void TimerManager::checkForTimeout()
+{
+ m_Lock.acquire();
+
+ if (!m_pHead)
+ {
+ m_Lock.release();
+ return;
+ }
+
+ Timer* pTimer = m_pHead;
+
+ if (pTimer->isExpired())
+ {
+ // remove expired timer
+ m_pHead = pTimer->m_pNext;
+
+ pTimer->acquire();
+
+ m_Lock.release();
+
+ pTimer->onShot();
+
+ // restart timer if specified
+ if (!pTimer->m_aRepeatDelta.isEmpty())
+ {
+ TTimeValue Now;
+
+ osl_getSystemTime(&Now);
+
+ Now.Seconds += pTimer->m_aRepeatDelta.Seconds;
+ Now.Nanosec += pTimer->m_aRepeatDelta.Nanosec;
+
+ pTimer->m_aExpired = Now;
+
+ registerTimer(pTimer);
+ }
+ pTimer->release();
+ }
+ else
+ {
+ m_Lock.release();
+ }
+}
+
+void TimerManager::run()
+{
+ osl_setThreadName("salhelper::TimerManager");
+
+ setPriority( osl_Thread_PriorityBelowNormal );
+
+ while (schedule())
+ {
+ TTimeValue delay;
+ TTimeValue* pDelay=nullptr;
+
+ m_Lock.acquire();
+
+ if (m_pHead != nullptr)
+ {
+ delay = m_pHead->getRemainingTime();
+ pDelay=&delay;
+ }
+ else
+ {
+ pDelay=nullptr;
+ }
+
+
+ m_notEmpty.reset();
+
+ m_Lock.release();
+
+
+ m_notEmpty.wait(pDelay);
+
+ checkForTimeout();
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/Symbols/loader.cxx b/salhelper/test/Symbols/loader.cxx
new file mode 100644
index 000000000..a0bfc50fa
--- /dev/null
+++ b/salhelper/test/Symbols/loader.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <salhelper/dynload.hxx>
+#include <rtl/ustring>
+#include "samplelib.hxx"
+
+using namespace salhelper;
+
+using OUString;
+
+
+class SampleLibLoader
+ : public ::salhelper::ODynamicLoader<SampleLib_Api>
+{
+public:
+ SampleLibLoader():
+ ::salhelper::ODynamicLoader<SampleLib_Api>
+ (OUString( SAL_MODULENAME( "samplelib") ),
+ OUString( SAMPLELIB_INIT_FUNCTION_NAME ))
+ {}
+
+};
+
+
+int main( int argc, char *argv[ ], char *envp[ ] )
+{
+ SampleLibLoader Loader;
+ SampleLibLoader Loader2;
+ Loader= Loader2;
+ SampleLib_Api *pApi= Loader.getApi();
+
+ sal_Int32 retint= pApi->funcA( 10);
+ double retdouble= pApi->funcB( 3.14);
+
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/Symbols/makefile.mk b/salhelper/test/Symbols/makefile.mk
new file mode 100644
index 000000000..acfa20d92
--- /dev/null
+++ b/salhelper/test/Symbols/makefile.mk
@@ -0,0 +1,85 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+PRJ=..$/..$/
+
+PRJNAME=salhelper
+TARGET=dynloader
+TARGET1=samplelib
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+
+# --- Files ---
+
+#RTTI on
+.IF "$(OS)" == "WNT"
+CFLAGS+= -GR
+.ENDIF
+
+
+#---------------------------------------------------------------------------
+# Build the test library which is loaded by the
+# RealDynamicLoader
+
+SLOFILES= $(SLO)$/samplelib.obj
+
+LIB1TARGET= $(SLB)$/$(TARGET1).lib
+LIB1OBJFILES= $(SLOFILES)
+
+
+SHL1TARGET= $(TARGET1)
+
+SHL1STDLIBS= \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET1)
+SHL1LIBS= $(SLB)$/$(TARGET1).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+DEFLIB1NAME= $(TARGET1)
+DEF1DEPN= $(MISC)$/$(SHL1TARGET).flt
+
+# ------------------------------------------------------------------------------
+
+OBJFILES= $(OBJ)$/loader.obj
+
+APP1TARGET= $(TARGET)
+APP1OBJS= $(OBJFILES)
+
+APP1STDLIBS= \
+ $(SALHELPERLIB) \
+ $(SALLIB)
+
+APP1DEF= $(MISC)\$(APP1TARGET).def
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo __CT>>$@
diff --git a/salhelper/test/Symbols/samplelib.cxx b/salhelper/test/Symbols/samplelib.cxx
new file mode 100644
index 000000000..f904d43eb
--- /dev/null
+++ b/salhelper/test/Symbols/samplelib.cxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "samplelib.hxx"
+#include <sal/types.h>
+
+extern "C"
+SampleLib_Api* SAL_CALL initSampleLibApi()
+{
+ static SampleLib_Api aApi= {0,0};
+ if (!aApi.funcA)
+ {
+ aApi.funcA= &funcA;
+ aApi.funcB= &funcB;
+ return (&aApi);
+ }
+ else
+ {
+ return (&aApi);
+ }
+
+}
+
+
+sal_Int32 SAL_CALL funcA( sal_Int32 a)
+{
+ return a;
+}
+
+
+double SAL_CALL funcB( double a)
+{
+ return a;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/Symbols/samplelib.hxx b/salhelper/test/Symbols/samplelib.hxx
new file mode 100644
index 000000000..d1213f6de
--- /dev/null
+++ b/salhelper/test/Symbols/samplelib.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SALHELPER_TEST_SYMBOLS_SAMPLELIB_HXX
+#define INCLUDED_SALHELPER_TEST_SYMBOLS_SAMPLELIB_HXX
+
+#include <sal/types.h>
+
+struct SampleLib_Api
+{
+ sal_Int32 (*funcA)( sal_Int32 );
+ double (*funcB)( double );
+};
+
+
+typedef SampleLib_Api* (*InitSampleLib_Api)(void);
+
+#define SAMPLELIB_INIT_FUNCTION_NAME "initSampleLibApi"
+
+
+sal_Int32 funcA( sal_Int32 a);
+double funcB( double a);
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/dynamicloader/loader.cxx b/salhelper/test/dynamicloader/loader.cxx
new file mode 100644
index 000000000..7d7bed793
--- /dev/null
+++ b/salhelper/test/dynamicloader/loader.cxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <salhelper/dynload.hxx>
+#include <rtl/ustring>
+#include "samplelib.hxx"
+
+
+using namespace salhelper;
+
+using OUString;
+
+
+class SampleLibLoader
+ : public ::salhelper::ODynamicLoader<SampleLib_Api>
+{
+public:
+ SampleLibLoader():
+ ::salhelper::ODynamicLoader<SampleLib_Api>
+ (OUString( SAL_MODULENAME( "samplelib") ),
+ OUString( SAMPLELIB_INIT_FUNCTION_NAME) )
+ {}
+
+};
+
+
+int main( int argc, char *argv[ ], char *envp[ ] )
+{
+ SampleLibLoader Loader;
+ SampleLibLoader Loader2;
+ Loader= Loader2;
+ SampleLib_Api *pApi= Loader.getApi();
+
+ sal_Int32 retint= pApi->funcA( 10);
+ double retdouble= pApi->funcB( 3.14);
+
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/dynamicloader/makefile.mk b/salhelper/test/dynamicloader/makefile.mk
new file mode 100644
index 000000000..aca574384
--- /dev/null
+++ b/salhelper/test/dynamicloader/makefile.mk
@@ -0,0 +1,99 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+
+PRJ=..$/..$/
+
+PRJNAME=salhelper
+TARGET=dynloader
+TARGET1=samplelib
+TARGETTYPE=CUI
+LIBTARGET=NO
+
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=FALSE
+
+# --- Settings ---
+
+.INCLUDE : settings.mk
+
+# --- Files ---
+
+#RTTI on
+.IF "$(OS)" == "WNT"
+CFLAGS+= -GR
+.ENDIF
+
+#---------------------------------------------------------------------------
+# Build the test library which is loaded by the
+# RealDynamicLoader
+
+SLOFILES= \
+ $(SLO)$/samplelib.obj
+
+LIB1TARGET=$(SLB)$/$(TARGET1).lib
+LIB1OBJFILES= \
+ $(SLO)$/samplelib.obj
+
+
+SHL1TARGET= $(TARGET1)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET1)
+SHL1LIBS= $(SLB)$/$(TARGET1).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+DEFLIB1NAME =$(TARGET1)
+DEF1DEPN= $(MISC)$/$(SHL1TARGET).flt
+
+# ------------------------------------------------------------------------------
+
+APP1NOSAL=TRUE
+
+APP1TARGET= $(TARGET)
+
+APP1OBJS= $(OBJ)$/loader.obj
+
+APP1STDLIBS= \
+ $(SALLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB)
+
+.IF "$(OS)" == "WNT"
+APP1STDLIBS+= $(LB)$/isalhelper.lib
+.ELSE
+APP1STDLIBS+= -lsalhelper$(UDK_MAJOR)$(COM)
+.ENDIF
+
+APP1DEF= $(MISC)\$(APP1TARGET).def
+
+# --- Targets ---
+
+.INCLUDE : target.mk
+
+
+$(MISC)$/$(SHL1TARGET).flt: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo __CT>>$@
+
diff --git a/salhelper/test/dynamicloader/samplelib.cxx b/salhelper/test/dynamicloader/samplelib.cxx
new file mode 100644
index 000000000..f904d43eb
--- /dev/null
+++ b/salhelper/test/dynamicloader/samplelib.cxx
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "samplelib.hxx"
+#include <sal/types.h>
+
+extern "C"
+SampleLib_Api* SAL_CALL initSampleLibApi()
+{
+ static SampleLib_Api aApi= {0,0};
+ if (!aApi.funcA)
+ {
+ aApi.funcA= &funcA;
+ aApi.funcB= &funcB;
+ return (&aApi);
+ }
+ else
+ {
+ return (&aApi);
+ }
+
+}
+
+
+sal_Int32 SAL_CALL funcA( sal_Int32 a)
+{
+ return a;
+}
+
+
+double SAL_CALL funcB( double a)
+{
+ return a;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/dynamicloader/samplelib.hxx b/salhelper/test/dynamicloader/samplelib.hxx
new file mode 100644
index 000000000..7b65a0ceb
--- /dev/null
+++ b/salhelper/test/dynamicloader/samplelib.hxx
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SALHELPER_TEST_DYNAMICLOADER_SAMPLELIB_HXX
+#define INCLUDED_SALHELPER_TEST_DYNAMICLOADER_SAMPLELIB_HXX
+
+#include <sal/types.h>
+
+struct SampleLib_Api
+{
+ sal_Int32 (*funcA)( sal_Int32 );
+ double (*funcB)( double );
+};
+
+
+typedef SampleLib_Api* (*InitSampleLib_Api)(void);
+
+#define SAMPLELIB_INIT_FUNCTION_NAME "initSampleLibApi"
+
+
+sal_Int32 SAL_CALL funcA( sal_Int32 a);
+double SAL_CALL funcB( double a);
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/rtti/exports.dxp b/salhelper/test/rtti/exports.dxp
new file mode 100644
index 000000000..beafa6a1c
--- /dev/null
+++ b/salhelper/test/rtti/exports.dxp
@@ -0,0 +1,6 @@
+?funcA@MyClassA@@UAEXXZ
+?funcB@MyClassA@@UAEXXZ
+?funcC@MyClassA@@MAEXXZ
+?funcA@MyClassB@@UAEXXZ
+?funcB@MyClassB@@UAEXXZ
+?funcC@MyClassB@@MAEXXZ
diff --git a/salhelper/test/rtti/makefile.mk b/salhelper/test/rtti/makefile.mk
new file mode 100644
index 000000000..dd811d531
--- /dev/null
+++ b/salhelper/test/rtti/makefile.mk
@@ -0,0 +1,92 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+PRJ=..$/..
+
+PRJNAME= salhelper
+TARGET= rtti
+TARGET1=samplelibrtti
+LIBTARGET=NO
+TARGETTYPE=CUI
+
+
+ENABLE_EXCEPTIONS=TRUE
+
+USE_DEFFILE= TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+#RTTI on
+.IF "$(OS)" == "WNT"
+CFLAGS+= -GR
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/samplelibrtti.obj
+
+LIB1TARGET=$(SLB)$/$(TARGET1).lib
+LIB1OBJFILES= \
+ $(SLO)$/samplelibrtti.obj
+
+SHL1TARGET= $(TARGET1)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET1)
+SHL1LIBS= $(SLB)$/$(TARGET1).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+DEF1EXPORTFILE= exports.dxp
+
+DEF1NAME= $(SHL1TARGET)
+
+.IF "$(OS)$(CPUNAME)"=="SOLARISSPARC"
+SHL1VERSIONMAP= sols.map
+.ENDIF
+
+
+# ------------------------------------------------------------------
+
+APP1NOSAL=TRUE
+
+APP1TARGET= $(TARGET)
+
+APP1OBJS= $(OBJ)$/rttitest.obj
+
+APP1STDLIBS= \
+ $(SALLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB)
+
+.IF "$(OS)" == "WNT"
+APP1STDLIBS+= $(LB)$/isamplelibrtti.lib
+.ELSE
+APP1STDLIBS+= -lsamplelibrtti
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/salhelper/test/rtti/rttitest.cxx b/salhelper/test/rtti/rttitest.cxx
new file mode 100644
index 000000000..7e753d3a6
--- /dev/null
+++ b/salhelper/test/rtti/rttitest.cxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdio.h>
+#include <typeinfo>
+
+int main()
+{
+ MyClassB b;
+ MyClassA* pA= &b;
+ // test the virtual function
+ pA->funcA();
+
+ if( typeid( b) == typeid( pA))
+ printf("\nsame types");
+
+ MyClassB* pB= dynamic_cast<MyClassB* >( pA);
+ pB->funcA();
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/rtti/samplelibrtti.cxx b/salhelper/test/rtti/samplelibrtti.cxx
new file mode 100644
index 000000000..c148eb69b
--- /dev/null
+++ b/salhelper/test/rtti/samplelibrtti.cxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdio.h>
+
+// MyClassA =============================================================
+void MyClassA::funcA()
+{
+ printf("MyClassA::funcA \n");
+}
+
+void MyClassA::funcB()
+{
+}
+
+void MyClassA::funcC()
+{
+}
+
+// MyClassB ===============================================================
+void MyClassB::funcA()
+{
+
+ printf("MyClassA::funcB \n");
+}
+
+void MyClassB::funcB()
+{
+}
+
+void MyClassB::funcC()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/rtti/samplelibrtti.hxx b/salhelper/test/rtti/samplelibrtti.hxx
new file mode 100644
index 000000000..ae7e984a9
--- /dev/null
+++ b/salhelper/test/rtti/samplelibrtti.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SALHELPER_TEST_RTTI_SAMPLELIBRTTI_HXX
+#define INCLUDED_SALHELPER_TEST_RTTI_SAMPLELIBRTTI_HXX
+
+class MyClassA
+{
+public:
+ virtual void funcA();
+ virtual void funcB();
+protected:
+ virtual void funcC();
+};
+
+
+class MyClassB: public MyClassA
+{
+public:
+ virtual void funcA();
+ virtual void funcB();
+protected:
+ virtual void funcC();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/salhelper/test/rtti/sols.map b/salhelper/test/rtti/sols.map
new file mode 100644
index 000000000..b4b9cf95a
--- /dev/null
+++ b/salhelper/test/rtti/sols.map
@@ -0,0 +1,48 @@
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+UDK_3_0_0 {
+ global:
+_fini;
+_init;
+
+__1cIMyClassAFfuncA6M_v_;
+__1cIMyClassAFfuncB6M_v_;
+__1cIMyClassAFfuncC6M_v_;
+__1cIMyClassAG__vtbl_;
+__1cIMyClassBFfuncA6M_v_;
+__1cIMyClassBFfuncB6M_v_;
+__1cIMyClassBFfuncC6M_v_;
+__1cIMyClassBG__vtbl_;
+__RTTI__1CpknIMyClassA_;
+__RTTI__1CpknIMyClassB_;
+__RTTI__1CpnIMyClassA_;
+__RTTI__1CpnIMyClassB_;
+__RTTI__1nIMyClassA_;
+__RTTI__1nIMyClassB_;
+
+local:
+ *;
+};
+
+
+
+
+
+
+
+