summaryrefslogtreecommitdiffstats
path: root/external/firebird
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 /external/firebird
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 '')
-rw-r--r--external/firebird/0001-Avoid-hangup-in-SS-when-error-happens-at-system-atta.patch.151
-rw-r--r--external/firebird/0001-Fix-warning-on-Win64-build-231.patch.137
-rw-r--r--external/firebird/0001-Make-comparison-operator-member-functions-const.patch.149
-rw-r--r--external/firebird/0002-Backported-fix-for-CORE-5452-Segfault-when-engine-s-.patch.11013
-rw-r--r--external/firebird/ExternalPackage_firebird.mk28
-rw-r--r--external/firebird/ExternalProject_firebird.mk116
-rw-r--r--external/firebird/Makefile7
-rw-r--r--external/firebird/Module_firebird.mk18
-rw-r--r--external/firebird/README3
-rw-r--r--external/firebird/UnpackedTarball_firebird.mk63
-rw-r--r--external/firebird/asan.patch252
-rw-r--r--external/firebird/c++17.patch301
-rw-r--r--external/firebird/firebird-Engine12.patch16
-rw-r--r--external/firebird/firebird-cloop-compiler.patch.112
-rw-r--r--external/firebird/firebird-configure-x86-64-macosx.patch.120
-rw-r--r--external/firebird/firebird-cygwin-msvc.patch654
-rw-r--r--external/firebird/firebird-gcc6.patch.119
-rw-r--r--external/firebird/firebird-macosx.patch.1132
-rw-r--r--external/firebird/firebird-rpath.patch.011
-rw-r--r--external/firebird/firebird-tdf125284.patch.127
-rw-r--r--external/firebird/firebird-vs2017.patch.111
-rw-r--r--external/firebird/firebird.disable-ib-util-not-found.patch.117
-rw-r--r--external/firebird/libc++.patch11
-rw-r--r--external/firebird/macosx-elcapitan-dyld.patch58
-rw-r--r--external/firebird/sanitizer.patch80
-rw-r--r--external/firebird/ubsan.patch287
-rw-r--r--external/firebird/wnt-dbgutil.patch63
27 files changed, 3356 insertions, 0 deletions
diff --git a/external/firebird/0001-Avoid-hangup-in-SS-when-error-happens-at-system-atta.patch.1 b/external/firebird/0001-Avoid-hangup-in-SS-when-error-happens-at-system-atta.patch.1
new file mode 100644
index 000000000..e569fccdc
--- /dev/null
+++ b/external/firebird/0001-Avoid-hangup-in-SS-when-error-happens-at-system-atta.patch.1
@@ -0,0 +1,51 @@
+From 36a7a2634669075be3294a1d075524a0b6f80962 Mon Sep 17 00:00:00 2001
+From: hvlad <hvlad@users.sourceforge.net>
+Date: Wed, 17 Aug 2016 15:45:30 +0300
+Subject: [PATCH] Avoid hangup in SS when error happens at system attachment
+ initialization time
+
+---
+ src/jrd/cch.cpp | 7 ++++++-
+ src/jrd/vio.cpp | 5 +++++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp
+index 35ea096..643cf4d 100644
+--- a/src/jrd/cch.cpp
++++ b/src/jrd/cch.cpp
+@@ -2963,10 +2963,15 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
+ iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
+ }
+
+- bcb->bcb_flags &= ~(BCB_cache_writer | BCB_writer_start);
++ bcb->bcb_flags &= ~BCB_cache_writer;
+
+ try
+ {
++ if (bcb->bcb_flags & BCB_writer_start)
++ {
++ bcb->bcb_flags &= ~BCB_writer_start;
++ bcb->bcb_writer_init.release();
++ }
+ bcb->bcb_writer_fini.release();
+ }
+ catch (const Firebird::Exception& ex)
+diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp
+index a8cf0fc..3d35a27 100644
+--- a/src/jrd/vio.cpp
++++ b/src/jrd/vio.cpp
+@@ -4988,6 +4988,11 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
+ try
+ {
+ // Notify the finalization caller that we're finishing.
++ if (dbb->dbb_flags & DBB_gc_starting)
++ {
++ dbb->dbb_flags &= ~DBB_gc_starting;
++ dbb->dbb_gc_init.release();
++ }
+ dbb->dbb_gc_fini.release();
+ }
+ catch (const Firebird::Exception& ex)
+--
+2.9.3
+
diff --git a/external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1 b/external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1
new file mode 100644
index 000000000..0e21f9e27
--- /dev/null
+++ b/external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1
@@ -0,0 +1,37 @@
+From 60cb8e07b17ad8533d7d13f52435aa11e48f4659 Mon Sep 17 00:00:00 2001
+From: Dimitry Sibiryakov <sd@ibphoenix.com>
+Date: Tue, 12 Nov 2019 13:42:49 +0100
+Subject: [PATCH] Fix warning on Win64 build (#231)
+
+---
+ src/common/ThreadStart.cpp | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/common/ThreadStart.cpp b/src/common/ThreadStart.cpp
+index 184c93a32b..758056432f 100644
+--- a/src/common/ThreadStart.cpp
++++ b/src/common/ThreadStart.cpp
+@@ -309,13 +309,16 @@ Thread Thread::start(ThreadEntryPoint* routine, void* arg, int priority_arg, Han
+ * Advanced Windows by Richter pg. # 109. */
+
+ unsigned thread_id;
+- unsigned long real_handle =
+- _beginthreadex(NULL, 0, THREAD_ENTRYPOINT, THREAD_ARG, CREATE_SUSPENDED, &thread_id);
+- if (!real_handle)
++ HANDLE handle =
++ reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0, THREAD_ENTRYPOINT, THREAD_ARG, CREATE_SUSPENDED, &thread_id));
++ if (!handle)
+ {
++ // Though MSDN says that _beginthreadex() returns error in errno,
++ // GetLastError() still works because RTL call no other system
++ // functions after CreateThread() in the case of error.
++ // Watch out if it is ever changed.
+ Firebird::system_call_failed::raise("_beginthreadex", GetLastError());
+ }
+- HANDLE handle = reinterpret_cast<HANDLE>(real_handle);
+
+ SetThreadPriority(handle, priority);
+
+--
+2.20.1
+
diff --git a/external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1 b/external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1
new file mode 100644
index 000000000..42c677f7e
--- /dev/null
+++ b/external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1
@@ -0,0 +1,49 @@
+From 15390d75ee6ca429dbbe15ea04214df8a30fbd48 Mon Sep 17 00:00:00 2001
+From: Stephan Bergmann <sbergman@redhat.com>
+Date: Mon, 21 Oct 2019 17:54:18 +0200
+Subject: [PATCH] Make comparison operator member functions const
+
+...which avoids overload resolution ambiguities in C++20, when a synthesized
+candidate of operator == for a reversed-argument rewrite conflicts with the
+actual operator ==, due to the asymmetric const-ness of the implicit object
+parameter and the RHS parameter. (As observed with recent Clang 10 trunk with
+-std=c++2a when building firebird as part of LibreOffice:
+
+> workdir/UnpackedTarball/firebird/src/jrd/inf.cpp:1139:62: error: use of overloaded operator '!=' is ambiguous (with operand types 'RuntimeStatistics::Iterator' and 'Jrd::RuntimeStatistics::Iterator')
+> for (RuntimeStatistics::Iterator iter = stats.begin(); iter != stats.end(); ++iter)
+> ~~~~ ^ ~~~~~~~~~~~
+> workdir/UnpackedTarball/firebird/src/jrd/../dsql/../jrd/RuntimeStatistics.h:283:8: note: candidate function
+> bool operator!=(const Iterator& other)
+> ^
+> workdir/UnpackedTarball/firebird/src/jrd/../dsql/../jrd/RuntimeStatistics.h:278:8: note: candidate function
+> bool operator==(const Iterator& other)
+> ^
+> workdir/UnpackedTarball/firebird/src/jrd/../dsql/../jrd/RuntimeStatistics.h:278:8: note: candidate function (with reversed parameter order)
+
+)
+---
+ src/jrd/RuntimeStatistics.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/jrd/RuntimeStatistics.h b/src/jrd/RuntimeStatistics.h
+index 74a03de2ad..fab286ad1a 100644
+--- a/src/jrd/RuntimeStatistics.h
++++ b/src/jrd/RuntimeStatistics.h
+@@ -290,12 +290,12 @@ public:
+ {}
+
+ public:
+- bool operator==(const Iterator& other)
++ bool operator==(const Iterator& other) const
+ {
+ return (m_counts == other.m_counts);
+ }
+
+- bool operator!=(const Iterator& other)
++ bool operator!=(const Iterator& other) const
+ {
+ return (m_counts != other.m_counts);
+ }
+--
+2.21.0
+
diff --git a/external/firebird/0002-Backported-fix-for-CORE-5452-Segfault-when-engine-s-.patch.1 b/external/firebird/0002-Backported-fix-for-CORE-5452-Segfault-when-engine-s-.patch.1
new file mode 100644
index 000000000..c55df4d0a
--- /dev/null
+++ b/external/firebird/0002-Backported-fix-for-CORE-5452-Segfault-when-engine-s-.patch.1
@@ -0,0 +1,1013 @@
+From 40f782ae3e918c4f3842571ff8064be1c4f54961 Mon Sep 17 00:00:00 2001
+From: AlexPeshkoff <peshkoff@mail.ru>
+Date: Fri, 13 Jan 2017 14:29:54 +0300
+Subject: [PATCH] Backported fix for CORE-5452: Segfault when engine's dynamic
+ library is unloaded right after closing worker threads (GC and/or cache
+ writer)
+
+---
+ src/alice/alice_meta.epp | 1 -
+ src/burp/burp.h | 2 -
+ src/common/ThreadStart.h | 86 ++++++++++++++++++++++++++++
+ src/common/classes/Synchronize.h | 5 +-
+ src/common/classes/misc/class_perf.cpp | 1 -
+ src/common/xdr.cpp | 2 -
+ src/gpre/boot/gpre_meta_boot.cpp | 1 -
+ src/gpre/std/gpre_meta.epp | 1 -
+ src/include/fb_exception.h | 1 -
+ src/include/firebird.h | 1 -
+ src/isql/OptionsBase.cpp | 1 -
+ src/isql/extract.epp | 1 -
+ src/isql/isql.epp | 5 --
+ src/jrd/Attachment.h | 1 +
+ src/jrd/Database.h | 6 +-
+ src/jrd/Mapping.cpp | 26 +++++----
+ src/jrd/cch.cpp | 31 +++++-----
+ src/jrd/cch.h | 14 ++++-
+ src/jrd/event.cpp | 13 +++--
+ src/jrd/event_proto.h | 7 +--
+ src/jrd/intl.cpp | 1 -
+ src/jrd/trace/TraceConfigStorage.h | 1 +
+ src/jrd/vio.cpp | 23 ++++----
+ src/lock/lock.cpp | 29 ++++++----
+ src/lock/lock_proto.h | 8 +--
+ src/qli/command.cpp | 1 -
+ src/qli/dtr.h | 1 -
+ src/qli/lex.cpp | 4 --
+ src/qli/meta.epp | 1 -
+ src/utilities/gsec/gsecswi.h | 1 -
+ src/utilities/gstat/dba.epp | 1 +
+ src/utilities/nbackup/nbkswi.h | 1 -
+ src/utilities/ntrace/os/win32/FileObject.cpp | 1 -
+ src/yvalve/gds.cpp | 1 +
+ src/yvalve/preparse.cpp | 1 -
+ 35 files changed, 182 insertions(+), 99 deletions(-)
+
+diff --git a/src/alice/alice_meta.epp b/src/alice/alice_meta.epp
+index d0f59bc..65dc37e 100644
+--- a/src/alice/alice_meta.epp
++++ b/src/alice/alice_meta.epp
+@@ -30,7 +30,6 @@
+ #include "firebird.h"
+ #include <stdio.h>
+ #include "../jrd/ibase.h"
+-//#include "../jrd/license.h"
+ #include "../alice/alice.h"
+ #include "../alice/alice_meta.h"
+ #include "../yvalve/gds_proto.h"
+diff --git a/src/burp/burp.h b/src/burp/burp.h
+index 293a91f..fe26335 100644
+--- a/src/burp/burp.h
++++ b/src/burp/burp.h
+@@ -769,8 +769,6 @@ struct burp_meta_obj
+ // I need to review if we tolerate different lengths for different OS's here.
+ const unsigned int MAX_FILE_NAME_SIZE = 256;
+
+-//#include "../jrd/svc.h"
+-
+ #include "../burp/std_desc.h"
+
+ #ifdef WIN_NT
+diff --git a/src/common/ThreadStart.h b/src/common/ThreadStart.h
+index 85e6a38..823c5c1 100644
+--- a/src/common/ThreadStart.h
++++ b/src/common/ThreadStart.h
+@@ -31,6 +31,7 @@
+ #define JRD_THREADSTART_H
+
+ #include "../common/ThreadData.h"
++#include "../common/classes/semaphore.h"
+
+ #ifdef WIN_NT
+ #include <windows.h>
+@@ -89,4 +90,89 @@ inline ThreadId getThreadId()
+ return Thread::getId();
+ }
+
++
++#ifndef USE_POSIX_THREADS
++#define USE_FINI_SEM
++#endif
++
++template <typename TA>
++class ThreadFinishSync
++{
++public:
++ typedef void ThreadRoutine(TA);
++
++ ThreadFinishSync(Firebird::MemoryPool& pool, ThreadRoutine* routine, int priority_arg)
++ :
++#ifdef USE_FINI_SEM
++ fini(pool),
++#else
++ threadHandle(0),
++#endif
++ threadRoutine(routine),
++ threadPriority(priority_arg)
++ { }
++
++ void run(TA arg)
++ {
++ threadArg = arg;
++
++ Thread::start(internalRun, this, threadPriority
++#ifndef USE_FINI_SEM
++ , &threadHandle
++#endif
++ );
++ }
++
++ void waitForCompletion()
++ {
++#ifdef USE_FINI_SEM
++ fini.enter();
++#else
++ Thread::waitForCompletion(threadHandle);
++ threadHandle = 0;
++#endif
++ }
++
++private:
++#ifdef USE_FINI_SEM
++ Firebird::Semaphore fini;
++#else
++ Thread::Handle threadHandle;
++#endif
++
++ TA threadArg;
++ ThreadRoutine* threadRoutine;
++ int threadPriority;
++ bool starting;
++
++ static THREAD_ENTRY_DECLARE internalRun(THREAD_ENTRY_PARAM arg)
++ {
++ ((ThreadFinishSync*)arg)->internalRun();
++ return 0;
++ }
++
++ void internalRun()
++ {
++ try
++ {
++ threadRoutine(threadArg);
++ }
++ catch (const Firebird::Exception& ex)
++ {
++ threadArg->exceptionHandler(ex, threadRoutine);
++ }
++
++#ifdef USE_FINI_SEM
++ try
++ {
++ fini.release();
++ }
++ catch (const Firebird::Exception& ex)
++ {
++ threadArg->exceptionHandler(ex, threadRoutine);
++ }
++#endif
++ }
++};
++
+ #endif // JRD_THREADSTART_H
+diff --git a/src/common/classes/Synchronize.h b/src/common/classes/Synchronize.h
+index 198de44..3788541 100644
+--- a/src/common/classes/Synchronize.h
++++ b/src/common/classes/Synchronize.h
+@@ -33,10 +33,7 @@
+ #define CLASSES_SYNCHRONIZE_H
+
+ #include "../common/classes/SyncObject.h"
+-
+-#ifndef WIN_NT
+-#include "fb_pthread.h"
+-#endif
++#include "../common/ThreadStart.h"
+
+
+ namespace Firebird {
+diff --git a/src/common/classes/misc/class_perf.cpp b/src/common/classes/misc/class_perf.cpp
+index 97b7bb3..142bfde 100644
+--- a/src/common/classes/misc/class_perf.cpp
++++ b/src/common/classes/misc/class_perf.cpp
+@@ -28,7 +28,6 @@
+
+ #include "tree.h"
+ #include "alloc.h"
+-//#include "../memory/memory_pool.h"
+ #include <stdio.h>
+ #include <time.h>
+ #include <set>
+diff --git a/src/common/xdr.cpp b/src/common/xdr.cpp
+index b9f9f4d..1dfff76 100644
+--- a/src/common/xdr.cpp
++++ b/src/common/xdr.cpp
+@@ -26,9 +26,7 @@
+
+ #include "firebird.h"
+ #include <string.h>
+-//#include "../remote/remote.h"
+ #include "../common/xdr.h"
+-//#include "../remote/proto_proto.h"
+ #include "../common/xdr_proto.h"
+ #include "../yvalve/gds_proto.h"
+ #include "../common/gdsassert.h"
+diff --git a/src/gpre/boot/gpre_meta_boot.cpp b/src/gpre/boot/gpre_meta_boot.cpp
+index 0fde018..1f302c6 100644
+--- a/src/gpre/boot/gpre_meta_boot.cpp
++++ b/src/gpre/boot/gpre_meta_boot.cpp
+@@ -32,7 +32,6 @@
+ #include <string.h>
+ #include "../jrd/ibase.h"
+ #include "../gpre/gpre.h"
+-//#include "../jrd/license.h"
+ #include "../jrd/intl.h"
+ #include "../gpre/gpre_proto.h"
+ #include "../gpre/hsh_proto.h"
+diff --git a/src/gpre/std/gpre_meta.epp b/src/gpre/std/gpre_meta.epp
+index 34ff932..0780dd4 100644
+--- a/src/gpre/std/gpre_meta.epp
++++ b/src/gpre/std/gpre_meta.epp
+@@ -32,7 +32,6 @@
+ #include <string.h>
+ #include "../jrd/ibase.h"
+ #include "../gpre/gpre.h"
+-//#include "../jrd/license.h"
+ #include "../jrd/intl.h"
+ #include "../gpre/gpre_proto.h"
+ #include "../gpre/hsh_proto.h"
+diff --git a/src/include/fb_exception.h b/src/include/fb_exception.h
+index 030cf94..c4c1df4 100644
+--- a/src/include/fb_exception.h
++++ b/src/include/fb_exception.h
+@@ -43,7 +43,6 @@
+
+ #include "fb_types.h"
+ #include "firebird/Interface.h"
+-#include "../common/ThreadStart.h"
+
+ namespace Firebird
+ {
+diff --git a/src/include/firebird.h b/src/include/firebird.h
+index 3d74354..87f0a11 100644
+--- a/src/include/firebird.h
++++ b/src/include/firebird.h
+@@ -68,7 +68,6 @@
+
+ #ifdef __cplusplus
+ #include "../common/common.h"
+-//#include "fb_exception.h"
+ #endif
+
+ #ifndef NULL
+diff --git a/src/isql/OptionsBase.cpp b/src/isql/OptionsBase.cpp
+index 5a78540..0974fa3 100644
+--- a/src/isql/OptionsBase.cpp
++++ b/src/isql/OptionsBase.cpp
+@@ -24,7 +24,6 @@
+
+ #include "firebird.h"
+ #include "OptionsBase.h"
+-//#include "../common/utils_proto.h" // strnicmp
+ #include "../common/gdsassert.h"
+
+
+diff --git a/src/isql/extract.epp b/src/isql/extract.epp
+index ec2ddb1..99e821c 100644
+--- a/src/isql/extract.epp
++++ b/src/isql/extract.epp
+@@ -59,7 +59,6 @@
+ #include "../jrd/ods.h"
+ #include "../common/utils_proto.h"
+ #include "../jrd/constants.h"
+-//#include "../common/classes/ImplementHelper.h"
+
+ using MsgFormat::SafeArg;
+
+diff --git a/src/isql/isql.epp b/src/isql/isql.epp
+index ccadce2..98b37bb 100644
+--- a/src/isql/isql.epp
++++ b/src/isql/isql.epp
+@@ -46,7 +46,6 @@
+ #include "firebird.h"
+ #include <stdio.h>
+ #include "../yvalve/keywords.h"
+-//#include "../yvalve/gds_proto.h"
+ #include "../jrd/intl.h"
+ #include <stdlib.h>
+ #include <stdarg.h>
+@@ -79,10 +78,6 @@
+ #include <locale.h>
+ #endif
+
+-//#ifdef HAVE_IO_H
+-//#include <io.h> // mktemp
+-//#endif
+-
+ #ifdef HAVE_EDITLINE_H
+ // This is a local file included in our distribution - but not always
+ // compiled into the system
+diff --git a/src/jrd/Attachment.h b/src/jrd/Attachment.h
+index 2807db3..e71610e 100644
+--- a/src/jrd/Attachment.h
++++ b/src/jrd/Attachment.h
+@@ -39,6 +39,7 @@
+ #include "../common/classes/array.h"
+ #include "../common/classes/stack.h"
+ #include "../common/classes/timestamp.h"
++#include "../common/ThreadStart.h"
+
+ #include "../jrd/EngineInterface.h"
+
+diff --git a/src/jrd/Database.h b/src/jrd/Database.h
+index 0eab40d..f0f44d3 100644
+--- a/src/jrd/Database.h
++++ b/src/jrd/Database.h
+@@ -440,7 +440,7 @@ public:
+ GarbageCollector* dbb_garbage_collector; // GarbageCollector class
+ Firebird::Semaphore dbb_gc_sem; // Event to wake up garbage collector
+ Firebird::Semaphore dbb_gc_init; // Event for initialization garbage collector
+- Firebird::Semaphore dbb_gc_fini; // Event for finalization garbage collector
++ ThreadFinishSync<Database*> dbb_gc_fini; // Sync for finalization garbage collector
+
+ Firebird::MemoryStats dbb_memory_stats;
+ RuntimeStatistics dbb_stats;
+@@ -511,6 +511,7 @@ private:
+ dbb_owner(*p),
+ dbb_pools(*p, 4),
+ dbb_sort_buffers(*p),
++ dbb_gc_fini(*p, garbage_collector, THREAD_medium),
+ dbb_stats(*p),
+ dbb_lock_owner_id(getLockOwnerId()),
+ dbb_tip_cache(NULL),
+@@ -560,6 +561,9 @@ public:
+ // reset sweep flags and release sweep lock
+ void clearSweepFlags(thread_db* tdbb);
+
++ static void garbage_collector(Database* dbb);
++ void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<Database*>::ThreadRoutine* routine);
++
+ private:
+ //static int blockingAstSharedCounter(void*);
+ static int blocking_ast_sweep(void* ast_object);
+diff --git a/src/jrd/Mapping.cpp b/src/jrd/Mapping.cpp
+index c1bcf0e..8df7e2f 100644
+--- a/src/jrd/Mapping.cpp
++++ b/src/jrd/Mapping.cpp
+@@ -581,7 +581,8 @@ class MappingIpc FB_FINAL : public Firebird::IpcObject
+
+ public:
+ explicit MappingIpc(MemoryPool&)
+- : processId(getpid())
++ : processId(getpid()),
++ cleanupSync(*getDefaultMemoryPool(), clearDelivery, THREAD_high)
+ { }
+
+ ~MappingIpc()
+@@ -602,7 +603,7 @@ public:
+ sMem->process[process].flags &= ~MappingHeader::FLAG_ACTIVE;
+ (void) // Ignore errors in cleanup
+ sharedMemory->eventPost(&sMem->process[process].notifyEvent);
+- cleanupSemaphore.tryEnter(5);
++ cleanupSync.waitForCompletion();
+
+ // Ignore errors in cleanup
+ sharedMemory->eventFini(&sMem->process[process].notifyEvent);
+@@ -755,7 +756,7 @@ public:
+
+ try
+ {
+- Thread::start(clearDelivery, this, THREAD_high);
++ cleanupSync.run(this);
+ }
+ catch (const Exception&)
+ {
+@@ -764,6 +765,12 @@ public:
+ }
+ }
+
++ void exceptionHandler(const Exception& ex, ThreadFinishSync<MappingIpc*>::ThreadRoutine*)
++ {
++ iscLogException("Fatal error in clearDeliveryThread", ex);
++ fb_utils::logAndDie("Fatal error in clearDeliveryThread");
++ }
++
+ private:
+ void clearDeliveryThread()
+ {
+@@ -801,13 +808,10 @@ private:
+ }
+ if (startup)
+ startupSemaphore.release();
+-
+- cleanupSemaphore.release();
+ }
+ catch (const Exception& ex)
+ {
+- iscLogException("Fatal error in clearDeliveryThread", ex);
+- fb_utils::logAndDie("Fatal error in clearDeliveryThread");
++ exceptionHandler(ex, NULL);
+ }
+ }
+
+@@ -862,11 +866,9 @@ private:
+ MappingIpc* const data;
+ };
+
+- static THREAD_ENTRY_DECLARE clearDelivery(THREAD_ENTRY_PARAM par)
++ static void clearDelivery(MappingIpc* mapping)
+ {
+- MappingIpc* m = (MappingIpc*)par;
+- m->clearDeliveryThread();
+- return 0;
++ mapping->clearDeliveryThread();
+ }
+
+ AutoPtr<SharedMemory<MappingHeader> > sharedMemory;
+@@ -874,7 +876,7 @@ private:
+ const SLONG processId;
+ unsigned process;
+ Semaphore startupSemaphore;
+- Semaphore cleanupSemaphore;
++ ThreadFinishSync<MappingIpc*> cleanupSync;
+ };
+
+ GlobalPtr<MappingIpc, InstanceControl::PRIORITY_DELETE_FIRST> mappingIpc;
+diff --git a/src/jrd/cch.cpp b/src/jrd/cch.cpp
+index e1d403b..1bf714f 100644
+--- a/src/jrd/cch.cpp
++++ b/src/jrd/cch.cpp
+@@ -120,14 +120,11 @@ static BufferDesc* alloc_bdb(thread_db*, BufferControl*, UCHAR **);
+ static Lock* alloc_page_lock(Jrd::thread_db*, BufferDesc*);
+ static int blocking_ast_bdb(void*);
+ #ifdef CACHE_READER
+-static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM);
+-
+ static void prefetch_epilogue(Prefetch*, FbStatusVector *);
+ static void prefetch_init(Prefetch*, thread_db*);
+ static void prefetch_io(Prefetch*, FbStatusVector *);
+ static void prefetch_prologue(Prefetch*, SLONG *);
+ #endif
+-static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM);
+ static void check_precedence(thread_db*, WIN*, PageNumber);
+ static void clear_precedence(thread_db*, BufferDesc*);
+ static BufferDesc* dealloc_bdb(BufferDesc*);
+@@ -1438,7 +1435,7 @@ void CCH_init2(thread_db* tdbb)
+
+ try
+ {
+- Thread::start(cache_writer, dbb, THREAD_medium);
++ bcb->bcb_writer_fini.run(bcb);
+ }
+ catch (const Exception&)
+ {
+@@ -2017,7 +2014,7 @@ void CCH_shutdown(thread_db* tdbb)
+ {
+ bcb->bcb_flags &= ~BCB_cache_writer;
+ bcb->bcb_writer_sem.release(); // Wake up running thread
+- bcb->bcb_writer_fini.enter();
++ bcb->bcb_writer_fini.waitForCompletion();
+ }
+
+ SyncLockGuard bcbSync(&bcb->bcb_syncObject, SYNC_EXCLUSIVE, "CCH_shutdown");
+@@ -2692,7 +2689,7 @@ static void flushAll(thread_db* tdbb, USHORT flush_flag)
+
+
+ #ifdef CACHE_READER
+-static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
++void BufferControl::cache_reader(BufferControl* bcb)
+ {
+ /**************************************
+ *
+@@ -2706,7 +2703,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
+ * busy at a time.
+ *
+ **************************************/
+- Database* dbb = (Database*) arg;
++ Database* dbb = bcb->bcb_database;
+ Database::SyncGuard dsGuard(dbb);
+
+ FbLocalStatus status_vector;
+@@ -2846,7 +2843,7 @@ static THREAD_ENTRY_DECLARE cache_reader(THREAD_ENTRY_PARAM arg)
+ #endif
+
+
+-static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
++void BufferControl::cache_writer(BufferControl* bcb)
+ {
+ /**************************************
+ *
+@@ -2859,8 +2856,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
+ *
+ **************************************/
+ FbLocalStatus status_vector;
+- Database* const dbb = (Database*) arg;
+- BufferControl* const bcb = dbb->dbb_bcb;
++ Database* const dbb = bcb->bcb_database;
+
+ try
+ {
+@@ -2964,8 +2960,7 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
+ } // try
+ catch (const Firebird::Exception& ex)
+ {
+- ex.stuffException(&status_vector);
+- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
++ bcb->exceptionHandler(ex, cache_writer);
+ }
+
+ bcb->bcb_flags &= ~BCB_cache_writer;
+@@ -2977,15 +2972,19 @@ static THREAD_ENTRY_DECLARE cache_writer(THREAD_ENTRY_PARAM arg)
+ bcb->bcb_flags &= ~BCB_writer_start;
+ bcb->bcb_writer_init.release();
+ }
+- bcb->bcb_writer_fini.release();
+ }
+ catch (const Firebird::Exception& ex)
+ {
+- ex.stuffException(&status_vector);
+- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
++ bcb->exceptionHandler(ex, cache_writer);
+ }
++}
+
+- return 0;
++
++void BufferControl::exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* /*routine*/)
++{
++ FbLocalStatus status_vector;
++ ex.stuffException(&status_vector);
++ iscDbLogStatus(bcb_database->dbb_filename.c_str(), &status_vector);
+ }
+
+
+diff --git a/src/jrd/cch.h b/src/jrd/cch.h
+index b920566..b7f8486 100644
+--- a/src/jrd/cch.h
++++ b/src/jrd/cch.h
+@@ -29,6 +29,7 @@
+ #include "../common/classes/RefCounted.h"
+ #include "../common/classes/semaphore.h"
+ #include "../common/classes/SyncObject.h"
++#include "../common/ThreadStart.h"
+ #ifdef SUPERSERVER_V2
+ #include "../jrd/sbm.h"
+ #include "../jrd/pag.h"
+@@ -85,7 +86,8 @@ class BufferControl : public pool_alloc<type_bcb>
+ BufferControl(MemoryPool& p, Firebird::MemoryStats& parentStats)
+ : bcb_bufferpool(&p),
+ bcb_memory_stats(&parentStats),
+- bcb_memory(p)
++ bcb_memory(p),
++ bcb_writer_fini(p, cache_writer, THREAD_medium)
+ {
+ bcb_database = NULL;
+ QUE_INIT(bcb_in_use);
+@@ -144,18 +146,24 @@ public:
+ Firebird::SyncObject bcb_syncLRU;
+ //Firebird::SyncObject bcb_syncPageWrite;
+
++ typedef ThreadFinishSync<BufferControl*> BcbSync;
++
++ static void cache_writer(BufferControl* bcb);
+ Firebird::Semaphore bcb_writer_sem; // Wake up cache writer
+ Firebird::Semaphore bcb_writer_init; // Cache writer initialization
+- Firebird::Semaphore bcb_writer_fini; // Cache writer finalization
++ BcbSync bcb_writer_fini; // Cache writer finalization
+ #ifdef SUPERSERVER_V2
++ static void cache_reader(BufferControl* bcb);
+ // the code in cch.cpp is not tested for semaphore instead event !!!
+ Firebird::Semaphore bcb_reader_sem; // Wake up cache reader
+ Firebird::Semaphore bcb_reader_init; // Cache reader initialization
+- Firebird::Semaphore bcb_reader_fini; // Cache reader finalization
++ BcbSync bcb_reader_fini; // Cache reader finalization
+
+ PageBitmap* bcb_prefetch; // Bitmap of pages to prefetch
+ #endif
+
++ void exceptionHandler(const Firebird::Exception& ex, BcbSync::ThreadRoutine* routine);
++
+ bcb_repeat* bcb_rpt;
+ };
+
+diff --git a/src/jrd/event.cpp b/src/jrd/event.cpp
+index 3a6bf28..cb6dc33 100644
+--- a/src/jrd/event.cpp
++++ b/src/jrd/event.cpp
+@@ -126,6 +126,7 @@ EventManager::EventManager(const Firebird::string& id, Firebird::RefPtr<Config>
+ m_processOffset(0),
+ m_dbId(getPool(), id),
+ m_config(conf),
++ m_cleanupSync(getPool(), watcher_thread, THREAD_medium),
+ m_sharedFileCreated(false),
+ m_exiting(false)
+ {
+@@ -146,7 +147,7 @@ EventManager::~EventManager()
+ // Terminate the event watcher thread
+ m_startupSemaphore.tryEnter(5);
+ (void) m_sharedMemory->eventPost(&m_process->prb_event);
+- m_cleanupSemaphore.tryEnter(5);
++ m_cleanupSync.waitForCompletion();
+
+ #ifdef HAVE_OBJECT_MAP
+ m_sharedMemory->unmapObject(&localStatus, &m_process);
+@@ -697,7 +698,7 @@ void EventManager::create_process()
+
+ release_shmem();
+
+- Thread::start(watcher_thread, this, THREAD_medium);
++ m_cleanupSync.run(this);
+ }
+
+
+@@ -1414,12 +1415,16 @@ void EventManager::watcher_thread()
+ {
+ m_startupSemaphore.release();
+ }
+- m_cleanupSemaphore.release();
+ }
+ catch (const Firebird::Exception& ex)
+ {
+- iscLogException("Error closing event watcher thread\n", ex);
++ exceptionHandler(ex, NULL);
+ }
+ }
+
++void EventManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine*)
++{
++ iscLogException("Error closing event watcher thread\n", ex);
++}
++
+ } // namespace
+diff --git a/src/jrd/event_proto.h b/src/jrd/event_proto.h
+index 3301203..9bfd20e 100644
+--- a/src/jrd/event_proto.h
++++ b/src/jrd/event_proto.h
+@@ -63,6 +63,7 @@ public:
+
+ bool initialize(Firebird::SharedMemoryBase*, bool);
+ void mutexBug(int osErrorCode, const char* text);
++ void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<EventManager*>::ThreadRoutine* routine);
+
+ private:
+ void acquire_shmem();
+@@ -91,11 +92,9 @@ private:
+ void detach_shared_file();
+ void get_shared_file_name(Firebird::PathName&) const;
+
+- static THREAD_ENTRY_DECLARE watcher_thread(THREAD_ENTRY_PARAM arg)
++ static void watcher_thread(EventManager* eventMgr)
+ {
+- EventManager* const eventMgr = static_cast<EventManager*>(arg);
+ eventMgr->watcher_thread();
+- return 0;
+ }
+
+ static void mutex_bugcheck(const TEXT*, int);
+@@ -109,7 +108,7 @@ private:
+ Firebird::AutoPtr<Firebird::SharedMemory<evh> > m_sharedMemory;
+
+ Firebird::Semaphore m_startupSemaphore;
+- Firebird::Semaphore m_cleanupSemaphore;
++ ThreadFinishSync<EventManager*> m_cleanupSync;
+
+ bool m_sharedFileCreated;
+ bool m_exiting;
+diff --git a/src/jrd/intl.cpp b/src/jrd/intl.cpp
+index 6666c5f..b0e662b 100644
+--- a/src/jrd/intl.cpp
++++ b/src/jrd/intl.cpp
+@@ -104,7 +104,6 @@
+ #include "../intl/charsets.h"
+ #include "../intl/country_codes.h"
+ #include "../common/gdsassert.h"
+-//#include "../jrd/license.h"
+ #ifdef INTL_BUILTIN
+ #include "../intl/ld_proto.h"
+ #endif
+diff --git a/src/jrd/trace/TraceConfigStorage.h b/src/jrd/trace/TraceConfigStorage.h
+index ca973c0..3d08143 100644
+--- a/src/jrd/trace/TraceConfigStorage.h
++++ b/src/jrd/trace/TraceConfigStorage.h
+@@ -32,6 +32,7 @@
+ #include "../../common/classes/fb_string.h"
+ #include "../../common/classes/init.h"
+ #include "../../common/isc_s_proto.h"
++#include "../../common/ThreadStart.h"
+ #include "../../jrd/trace/TraceSession.h"
+ #include "../../common/classes/RefCounted.h"
+
+diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp
+index 02c5809..8ca9f66 100644
+--- a/src/jrd/vio.cpp
++++ b/src/jrd/vio.cpp
+@@ -107,7 +107,6 @@ static bool dfw_should_know(record_param* org_rpb, record_param* new_rpb,
+ USHORT irrelevant_field, bool void_update_is_relevant = false);
+ static void garbage_collect(thread_db*, record_param*, ULONG, RecordStack&);
+ static void garbage_collect_idx(thread_db*, record_param*, Record*, Record*);
+-static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM);
+
+
+ #ifdef VIO_DEBUG
+@@ -1958,7 +1957,7 @@ void VIO_fini(thread_db* tdbb)
+ {
+ dbb->dbb_flags &= ~DBB_garbage_collector;
+ dbb->dbb_gc_sem.release(); // Wake up running thread
+- dbb->dbb_gc_fini.enter();
++ dbb->dbb_gc_fini.waitForCompletion();
+ }
+ }
+
+@@ -2420,7 +2419,7 @@ void VIO_init(thread_db* tdbb)
+ {
+ try
+ {
+- Thread::start(garbage_collector, dbb, THREAD_medium);
++ dbb->dbb_gc_fini.run(dbb);
+ }
+ catch (const Exception&)
+ {
+@@ -4741,7 +4740,7 @@ static void garbage_collect_idx(thread_db* tdbb,
+ }
+
+
+-static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
++void Database::garbage_collector(Database* dbb)
+ {
+ /**************************************
+ *
+@@ -4758,7 +4757,6 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
+ *
+ **************************************/
+ FbLocalStatus status_vector;
+- Database* const dbb = (Database*) arg;
+
+ try
+ {
+@@ -4989,8 +4987,7 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
+ } // try
+ catch (const Firebird::Exception& ex)
+ {
+- ex.stuffException(&status_vector);
+- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
++ dbb->exceptionHandler(ex, NULL);
+ }
+
+ dbb->dbb_flags &= ~(DBB_garbage_collector | DBB_gc_active | DBB_gc_pending);
+@@ -5003,15 +5000,19 @@ static THREAD_ENTRY_DECLARE garbage_collector(THREAD_ENTRY_PARAM arg)
+ dbb->dbb_flags &= ~DBB_gc_starting;
+ dbb->dbb_gc_init.release();
+ }
+- dbb->dbb_gc_fini.release();
+ }
+ catch (const Firebird::Exception& ex)
+ {
+- ex.stuffException(&status_vector);
+- iscDbLogStatus(dbb->dbb_filename.c_str(), &status_vector);
++ dbb->exceptionHandler(ex, NULL);
+ }
++}
++
+
+- return 0;
++void Database::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<Database*>::ThreadRoutine* /*routine*/)
++{
++ FbLocalStatus status_vector;
++ ex.stuffException(&status_vector);
++ iscDbLogStatus(dbb_filename.c_str(), &status_vector);
+ }
+
+
+diff --git a/src/lock/lock.cpp b/src/lock/lock.cpp
+index 89eb4c5..2ab3358 100644
+--- a/src/lock/lock.cpp
++++ b/src/lock/lock.cpp
+@@ -214,6 +214,7 @@ LockManager::LockManager(const Firebird::string& id, RefPtr<Config> conf)
+ m_sharedFileCreated(false),
+ m_process(NULL),
+ m_processOffset(0),
++ m_cleanupSync(getPool(), blocking_action_thread, THREAD_high),
+ m_sharedMemory(NULL),
+ m_blockage(false),
+ m_dbId(getPool(), id),
+@@ -259,7 +260,7 @@ LockManager::~LockManager()
+ m_sharedMemory->eventPost(&m_process->prc_blocking);
+
+ // Wait for the AST thread to finish cleanup or for 5 seconds
+- m_cleanupSemaphore.tryEnter(5);
++ m_cleanupSync.waitForCompletion();
+ }
+
+ #ifdef HAVE_OBJECT_MAP
+@@ -1548,16 +1549,22 @@ void LockManager::blocking_action_thread()
+ {
+ iscLogException("Error in blocking action thread\n", x);
+ }
++}
+
+- try
+- {
+- // Wakeup the main thread waiting for our exit
+- m_cleanupSemaphore.release();
+- }
+- catch (const Firebird::Exception& x)
+- {
+- iscLogException("Error closing blocking action thread\n", x);
+- }
++
++void LockManager::exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<LockManager*>::ThreadRoutine* /*routine*/)
++{
++/**************************************
++ *
++ * e x c e p t i o n H a n d l e r
++ *
++ **************************************
++ *
++ * Functional description
++ * Handler for blocking thread close bugs.
++ *
++ **************************************/
++ iscLogException("Error closing blocking action thread\n", ex);
+ }
+
+
+@@ -1815,7 +1822,7 @@ bool LockManager::create_process(CheckStatusWrapper* statusVector)
+ {
+ try
+ {
+- Thread::start(blocking_action_thread, this, THREAD_high);
++ m_cleanupSync.run(this);
+ }
+ catch (const Exception& ex)
+ {
+diff --git a/src/lock/lock_proto.h b/src/lock/lock_proto.h
+index d991c1e..2faec49 100644
+--- a/src/lock/lock_proto.h
++++ b/src/lock/lock_proto.h
+@@ -418,6 +418,8 @@ public:
+ SINT64 readData2(USHORT, const UCHAR*, USHORT, SRQ_PTR);
+ SINT64 writeData(SRQ_PTR, SINT64);
+
++ void exceptionHandler(const Firebird::Exception& ex, ThreadFinishSync<LockManager*>::ThreadRoutine* routine);
++
+ private:
+ explicit LockManager(const Firebird::string&, Firebird::RefPtr<Config>);
+ ~LockManager();
+@@ -471,11 +473,9 @@ private:
+ void detach_shared_file(Firebird::CheckStatusWrapper*);
+ void get_shared_file_name(Firebird::PathName&, ULONG extend = 0) const;
+
+- static THREAD_ENTRY_DECLARE blocking_action_thread(THREAD_ENTRY_PARAM arg)
++ static void blocking_action_thread(LockManager* lockMgr)
+ {
+- LockManager* const lockMgr = static_cast<LockManager*>(arg);
+ lockMgr->blocking_action_thread();
+- return 0;
+ }
+
+ bool initialize(Firebird::SharedMemoryBase* sm, bool init);
+@@ -490,7 +490,7 @@ private:
+ Firebird::RWLock m_remapSync;
+ Firebird::AtomicCounter m_waitingOwners;
+
+- Firebird::Semaphore m_cleanupSemaphore;
++ ThreadFinishSync<LockManager*> m_cleanupSync;
+ Firebird::Semaphore m_startupSemaphore;
+
+ public:
+diff --git a/src/qli/command.cpp b/src/qli/command.cpp
+index 5f949f3..fbbf4fb 100644
+--- a/src/qli/command.cpp
++++ b/src/qli/command.cpp
+@@ -30,7 +30,6 @@
+ #include "../qli/parse.h"
+ #include "../qli/compile.h"
+ #include "../qli/exe.h"
+-//#include "../jrd/license.h"
+ #include "../qli/all_proto.h"
+ #include "../qli/err_proto.h"
+ #include "../qli/exe_proto.h"
+diff --git a/src/qli/dtr.h b/src/qli/dtr.h
+index ba5cd64..e246ef4 100644
+--- a/src/qli/dtr.h
++++ b/src/qli/dtr.h
+@@ -480,7 +480,6 @@ struct qli_fun
+ };
+
+ // Program wide globals
+-//#include <setjmp.h>
+
+ #ifdef QLI_MAIN
+ #define EXTERN
+diff --git a/src/qli/lex.cpp b/src/qli/lex.cpp
+index c20d1f9..9e26046 100644
+--- a/src/qli/lex.cpp
++++ b/src/qli/lex.cpp
+@@ -50,10 +50,6 @@ using MsgFormat::SafeArg;
+ #include <unistd.h>
+ #endif
+
+-//#ifdef HAVE_CTYPES_H
+-//#include <ctypes.h>
+-//#endif
+-
+ #ifdef HAVE_IO_H
+ #include <io.h> // isatty
+ #endif
+diff --git a/src/qli/meta.epp b/src/qli/meta.epp
+index a7f222c..2d55716 100644
+--- a/src/qli/meta.epp
++++ b/src/qli/meta.epp
+@@ -28,7 +28,6 @@
+ #include "../qli/dtr.h"
+ #include "../qli/compile.h"
+ #include "../qli/exe.h"
+-//#include "../jrd/license.h"
+ #include "../jrd/flags.h"
+ #include "../jrd/ibase.h"
+ #include "../qli/reqs.h"
+diff --git a/src/utilities/gsec/gsecswi.h b/src/utilities/gsec/gsecswi.h
+index b8519f5..9b560e3 100644
+--- a/src/utilities/gsec/gsecswi.h
++++ b/src/utilities/gsec/gsecswi.h
+@@ -24,7 +24,6 @@
+ #ifndef GSEC_GSECSWI_H
+ #define GSEC_GSECSWI_H
+
+-//#include "../common/common.h"
+ #include "../jrd/constants.h"
+
+ /* Switch handling constants. Note that the first IN_SW_DATA_ITEMS
+diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp
+index 379b418..19b99d1 100644
+--- a/src/utilities/gstat/dba.epp
++++ b/src/utilities/gstat/dba.epp
+@@ -56,6 +56,7 @@
+ #include "../common/classes/UserBlob.h"
+ #include "../common/os/os_utils.h"
+ #include "../common/StatusHolder.h"
++#include "../common/ThreadStart.h"
+
+ using MsgFormat::SafeArg;
+
+diff --git a/src/utilities/nbackup/nbkswi.h b/src/utilities/nbackup/nbkswi.h
+index 4326c3d..b8d43da 100644
+--- a/src/utilities/nbackup/nbkswi.h
++++ b/src/utilities/nbackup/nbkswi.h
+@@ -27,7 +27,6 @@
+ #ifndef NBACKUP_NBKSWI_H
+ #define NBACKUP_NBKSWI_H
+
+-//#include "../common/common.h"
+ #include "../jrd/constants.h"
+
+ // Switch handling constants
+diff --git a/src/utilities/ntrace/os/win32/FileObject.cpp b/src/utilities/ntrace/os/win32/FileObject.cpp
+index 73ed38f..53fbfc0 100644
+--- a/src/utilities/ntrace/os/win32/FileObject.cpp
++++ b/src/utilities/ntrace/os/win32/FileObject.cpp
+@@ -27,7 +27,6 @@
+
+ #include "firebird.h"
+ #include "../FileObject.h"
+-//#include "../common/classes/locks.h"
+
+ using namespace Firebird;
+ Firebird::Mutex open_mutex;
+diff --git a/src/yvalve/gds.cpp b/src/yvalve/gds.cpp
+index c851f7c..998bbde 100644
+--- a/src/yvalve/gds.cpp
++++ b/src/yvalve/gds.cpp
+@@ -57,6 +57,7 @@
+ #include "../common/classes/init.h"
+ #include "../common/classes/TempFile.h"
+ #include "../common/utils_proto.h"
++#include "../common/ThreadStart.h"
+
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+diff --git a/src/yvalve/preparse.cpp b/src/yvalve/preparse.cpp
+index b2335a5..e742784 100644
+--- a/src/yvalve/preparse.cpp
++++ b/src/yvalve/preparse.cpp
+@@ -25,7 +25,6 @@
+ #include "firebird.h"
+ #include <stdlib.h>
+ #include <string.h>
+-//#include "../dsql/chars.h"
+ #include "../yvalve/prepa_proto.h"
+ #include "../yvalve/gds_proto.h"
+ #include "../yvalve/YObjects.h"
+--- a/src/common/isc_sync.cpp
++++ b/src/common/isc_sync.cpp
+@@ -67,6 +67,7 @@
+ #include "../common/classes/RefMutex.h"
+ #include "../common/classes/array.h"
+ #include "../common/StatusHolder.h"
++#include "../common/ThreadStart.h"
+
+ static int process_id;
+
+--
+2.9.3
+
diff --git a/external/firebird/ExternalPackage_firebird.mk b/external/firebird/ExternalPackage_firebird.mk
new file mode 100644
index 000000000..87df3567e
--- /dev/null
+++ b/external/firebird/ExternalPackage_firebird.mk
@@ -0,0 +1,28 @@
+# -*- 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_ExternalPackage_ExternalPackage,firebird,firebird))
+
+$(eval $(call gb_ExternalPackage_use_external_project,firebird,firebird))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/ifbclient.dll,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/bin/ifbclient.dll))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/Engine12.dll,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/Engine12.dll))
+else ifeq ($(OS),MACOSX)
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.dylib.3.0.0,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.dylib.3.0.0))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libEngine12.dylib,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/libEngine12.dylib))
+else ifeq ($(DISABLE_DYNLOADING),)
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libfbclient.so.2,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.so.3.0.0))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_LIB_FOLDER)/libEngine12.so,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/libEngine12.so))
+endif
+
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_SHARE_FOLDER)/firebird/firebird.msg,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/firebird.msg))
+$(eval $(call gb_ExternalPackage_add_file,firebird,$(LIBO_SHARE_FOLDER)/firebird/security3.fdb,gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/security3.fdb))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/ExternalProject_firebird.mk b/external/firebird/ExternalProject_firebird.mk
new file mode 100644
index 000000000..ce99e909a
--- /dev/null
+++ b/external/firebird/ExternalProject_firebird.mk
@@ -0,0 +1,116 @@
+# -*- 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_ExternalProject_ExternalProject,firebird))
+
+$(eval $(call gb_ExternalProject_use_autoconf,firebird,build))
+
+$(eval $(call gb_ExternalProject_use_externals,firebird,\
+ boost_headers \
+ icu \
+ libatomic_ops \
+ libtommath \
+))
+
+$(eval $(call gb_ExternalProject_register_targets,firebird,\
+ build \
+))
+
+ifneq ($(OS),WNT)
+INVOKE_FPA:="CPU=\$$(EMPTY) $${FB_CPU_ARG}"
+endif
+
+ifeq ($(COM_IS_CLANG),TRUE)
+firebird_NO_CXX11_NARROWING := -Wno-c++11-narrowing
+endif
+
+MAKE_PRE=LC_ALL=C
+
+MAKE_POST=$(if $(filter MACOSX,$(OS)),&& $(PERL) \
+ $(SRCDIR)/solenv/bin/macosx-change-install-names.pl shl OOO \
+ $(EXTERNAL_WORKDIR)/gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/plugins/libEngine12.dylib \
+ $(EXTERNAL_WORKDIR)/gen/$(if $(ENABLE_DEBUG),Debug,Release)/firebird/lib/libfbclient.dylib.3.0.0)
+
+$(call gb_ExternalProject_get_state_target,firebird,build):
+ $(call gb_Trace_StartRange,firebird,EXTERNAL)
+ $(call gb_ExternalProject_run,build,\
+ unset MAKEFLAGS \
+ && FB_CPU_ARG='$(filter --jobserver-fds=%,$(MAKEFLAGS))' \
+ && export PKG_CONFIG="" \
+ && export CPPFLAGS=" \
+ $(if $(SYSTEM_LIBATOMIC_OPS),$(LIBATOMIC_OPS_CFLAGS), \
+ -I$(call gb_UnpackedTarball_get_dir,libatomic_ops)/src \
+ ) \
+ $(if $(SYSTEM_LIBTOMMATH),$(LIBTOMMATH_CFLAGS), \
+ -I$(call gb_UnpackedTarball_get_dir,libtommath) \
+ -L$(call gb_UnpackedTarball_get_dir,libtommath) \
+ ) \
+ $(if $(SYSTEM_ICU),$(ICU_CPPFLAGS), \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source/i18n \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source/common \
+ ) \
+ $(if $(filter GCC-INTEL,$(COM)-$(CPUNAME)),-Di386=1) \
+ " \
+ && export CXXFLAGS=" \
+ $(if $(filter MSC,$(COM)),$(if $(MSVC_USE_DEBUG_RUNTIME),-DMSVC_USE_DEBUG_RUNTIME)) \
+ $(if $(HAVE_GCC_FNO_SIZED_DEALLOCATION),-fno-sized-deallocation -fno-delete-null-pointer-checks) \
+ $(if $(SYSTEM_BOOST),$(BOOST_CPPFLAGS), \
+ $(BOOST_CPPFLAGS) \
+ -L$(call gb_UnpackedTarball_get_dir,boost)/source/lib \
+ ) \
+ $(if $(SYSTEM_ICU),$(ICU_CPPFLAGS), \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source/i18n \
+ -I$(call gb_UnpackedTarball_get_dir,icu)/source/common \
+ ) \
+ $(if $(SYSTEM_LIBTOMMATH),$(LIBTOMMATH_CFLAGS), \
+ -L$(call gb_UnpackedTarball_get_dir,libtommath) \
+ ) \
+ $(CXXFLAGS_CXX11) \
+ $(firebird_NO_CXX11_NARROWING) \
+ $(if $(call gb_Module__symbols_enabled,firebird),$(gb_DEBUGINFO_FLAGS)) \
+ " \
+ && export LDFLAGS=" \
+ $(if $(SYSTEM_ICU),$(ICU_LIBS), \
+ -L$(call gb_UnpackedTarball_get_dir,icu)/source/lib \
+ ) \
+ " \
+ && export LIBREOFFICE_ICU_LIB="$(call gb_UnpackedTarball_get_dir,icu)/source/lib" \
+ && MAKE=$(MAKE) ./configure \
+ --without-editline \
+ --with-wire-compress=no \
+ $(if $(CROSS_COMPILING),--build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM)) \
+ $(if $(DISABLE_DYNLOADING), \
+ --enable-static --disable-shared \
+ , \
+ --enable-shared --disable-static \
+ ) \
+ $(if $(filter MACOSX,$(OS)), \
+ $(if $(filter 1, \
+ $(shell expr '$(MAC_OS_X_VERSION_MIN_REQUIRED)' \
+ '<' 101200)), \
+ ac_cv_func_clock_gettime=no)) \
+ && if [ -n "$${FB_CPU_ARG}" ]; then \
+ $(MAKE_PRE) $(MAKE) \
+ $(if $(filter LINUX,$(OS)),CXXFLAGS="$$CXXFLAGS -std=gnu++11") \
+ $(if $(ENABLE_DEBUG),Debug) $(INVOKE_FPA) SHELL='$(SHELL)' \
+ LIBO_TUNNEL_LIBRARY_PATH='$(subst ','\'',$(subst $$,$$$$,$(call gb_Helper_extend_ld_path,$(call gb_UnpackedTarball_get_dir,icu)/source/lib)))' \
+ $(MAKE_POST); \
+ else \
+ $(MAKE_PRE) $(MAKE) \
+ $(if $(filter LINUX,$(OS)),CXXFLAGS="$$CXXFLAGS -std=gnu++11") \
+ $(if $(ENABLE_DEBUG),Debug) SHELL='$(SHELL)' \
+ LIBO_TUNNEL_LIBRARY_PATH='$(subst ','\'',$(subst $$,$$$$,$(call gb_Helper_extend_ld_path,$(call gb_UnpackedTarball_get_dir,icu)/source/lib)))' \
+ $(MAKE_POST); \
+ fi \
+ )
+ $(call gb_Trace_EndRange,firebird,EXTERNAL)
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/Makefile b/external/firebird/Makefile
new file mode 100644
index 000000000..e4968cf85
--- /dev/null
+++ b/external/firebird/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/external/firebird/Module_firebird.mk b/external/firebird/Module_firebird.mk
new file mode 100644
index 000000000..d74963f7f
--- /dev/null
+++ b/external/firebird/Module_firebird.mk
@@ -0,0 +1,18 @@
+# -*- 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,firebird))
+
+$(eval $(call gb_Module_add_targets,firebird,\
+ ExternalPackage_firebird \
+ ExternalProject_firebird \
+ UnpackedTarball_firebird \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/README b/external/firebird/README
new file mode 100644
index 000000000..cc7c72743
--- /dev/null
+++ b/external/firebird/README
@@ -0,0 +1,3 @@
+Firebird is an embeddable SQL RDBMS implemented in C++
+
+http://firebirdsql.org/
diff --git a/external/firebird/UnpackedTarball_firebird.mk b/external/firebird/UnpackedTarball_firebird.mk
new file mode 100644
index 000000000..a8507db38
--- /dev/null
+++ b/external/firebird/UnpackedTarball_firebird.mk
@@ -0,0 +1,63 @@
+# -*- 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_UnpackedTarball_UnpackedTarball,firebird))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,firebird,$(FIREBIRD_TARBALL)))
+
+$(eval $(call gb_UnpackedTarball_set_patchlevel,firebird,0))
+
+$(eval $(call gb_UnpackedTarball_update_autoconf_configs,firebird,\
+ builds/make.new/config \
+ extern/editline \
+))
+
+# * external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1 is upstream at
+# <https://github.com/FirebirdSQL/firebird/pull/227> "Make comparison operator member functions
+# const":
+$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird.disable-ib-util-not-found.patch.1 \
+ external/firebird/firebird-Engine12.patch \
+ external/firebird/firebird-rpath.patch.0 \
+ external/firebird/firebird-cloop-compiler.patch.1 \
+ external/firebird/firebird-gcc6.patch.1 \
+ external/firebird/wnt-dbgutil.patch \
+ external/firebird/libc++.patch \
+ external/firebird/0001-Avoid-hangup-in-SS-when-error-happens-at-system-atta.patch.1 \
+ external/firebird/0002-Backported-fix-for-CORE-5452-Segfault-when-engine-s-.patch.1 \
+ external/firebird/c++17.patch \
+ external/firebird/ubsan.patch \
+ external/firebird/asan.patch \
+ external/firebird/firebird-tdf125284.patch.1 \
+ external/firebird/0001-Make-comparison-operator-member-functions-const.patch.1 \
+ external/firebird/0001-Fix-warning-on-Win64-build-231.patch.1 \
+))
+
+ifeq ($(OS),WNT)
+$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird-cygwin-msvc.patch \
+ external/firebird/firebird-vs2017.patch.1 \
+))
+endif
+
+ifeq ($(OS),MACOSX)
+$(eval $(call gb_UnpackedTarball_add_patches,firebird,\
+ external/firebird/firebird-configure-x86-64-macosx.patch.1 \
+ external/firebird/firebird-macosx.patch.1 \
+ external/firebird/macosx-elcapitan-dyld.patch \
+))
+endif
+
+ifneq ($(filter -fsanitize=%,$(CC)),)
+$(eval $(call gb_UnpackedTarball_add_patches,firebird, \
+ external/firebird/sanitizer.patch \
+))
+endif
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/firebird/asan.patch b/external/firebird/asan.patch
new file mode 100644
index 000000000..5ee7744e1
--- /dev/null
+++ b/external/firebird/asan.patch
@@ -0,0 +1,252 @@
+--- builds/posix/Makefile.in
++++ builds/posix/Makefile.in
+@@ -323,8 +323,8 @@
+
+ metadata.fdb: $(RUN_ISQL) $(SRC_ROOT)/dbs/metadata.sql
+ -$(RM) $@
+- $(RUN_ISQL) -q -i $(SRC_ROOT)/dbs/metadata.sql
+- $(RUN_GFIX) -mode read_only $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL) -q -i $(SRC_ROOT)/dbs/metadata.sql
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -mode read_only $@
+ $(CHMOD) 0444 $@
+
+ $(HELP_FDB): help.fdb
+@@ -333,7 +333,7 @@
+ $(CHMOD) 0444 $@
+
+ help.fdb: $(BLD_ROOT)/misc/help.gbak
+- $(RUN_GBAK) -MODE read_only -R $< $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GBAK) -MODE read_only -R $< $@
+ $(CHMOD) 0444 $@
+
+ $(SECURITY_FDB): security.fdb
+@@ -343,18 +343,18 @@
+ security.fdb: $(SRC_ROOT)/dbs/security.sql
+ -$(RM) $@
+ -$(RM) $(SECURITY_TMP)
+- echo create database \'$(SECURITY_TMP)\'\; | $(RUN_ISQL)
+- $(RUN_GFIX) -write async $(SECURITY_TMP)
+- $(RUN_ISQL) -i $^ $(SECURITY_TMP)
++ echo create database \'$(SECURITY_TMP)\'\; | $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -write async $(SECURITY_TMP)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL) -i $^ $(SECURITY_TMP)
+ $(CHMOD) a=rw $(SECURITY_TMP)
+ $(CP) $(SECURITY_TMP) $@
+- $(RUN_GFIX) -write sync $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -write sync $@
+
+ msg.timestamp: $(MSG_FILES)
+ -$(RM) msg.fdb
+- echo create database \'msg.fdb\'\; | $(RUN_ISQL)
+- $(RUN_GFIX) -write async msg.fdb
+- for sql in $(MSG_FILES); do (echo $$sql; $(RUN_ISQL) -i $$sql msg.fdb) || exit; done
++ echo create database \'msg.fdb\'\; | $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_GFIX) -write async msg.fdb
++ for sql in $(MSG_FILES); do (echo $$sql; $(LIBO_TUNNEL_LIBRARY_PATH) $(RUN_ISQL) -i $$sql msg.fdb) || exit; done
+ $(TOUCH) $@
+
+
+@@ -560,7 +560,7 @@
+ message_file: $(FIREBIRD_MSG)
+
+ $(FIREBIRD_MSG): $(BUILD_FILE) msg.timestamp
+- $(BUILD_FILE) -d msg.fdb -f $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(BUILD_FILE) -d msg.fdb -f $@
+ $(CHMOD_6) $@
+
+ $(BUILD_FILE): $(BUILD_Objects) $(COMMON_LIB)
+--- builds/posix/Makefile.in.examples
++++ builds/posix/Makefile.in.examples
+@@ -123,8 +123,8 @@
+
+ $(EMPLOYEE_DB): $(EXAMPLES_DEST)/empbuild$(EXEC_EXT) $(INPUT_Sources) $(EXAMPLES_DEST)/isql$(EXEC_EXT)
+ -$(RM) $(EMPLOYEE_DB)
+- ./empbuild $(EMPLOYEE_DB)
+- $(GFIX) -write sync $(EMPLOYEE_DB)
++ $(LIBO_TUNNEL_LIBRARY_PATH) ./empbuild $(EMPLOYEE_DB)
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GFIX) -write sync $(EMPLOYEE_DB)
+ -$(CHMOD_6) $(EMPLOYEE_DB)
+
+ # To get past the fact isql is called from the programs, we create a local link in this directory
+@@ -140,7 +140,7 @@
+
+ $(EXAMPLES_DEST)/empbuild.fdb : $(EXAMPLES_DEST)/empddl.sql $(EXAMPLES_DEST)/empbld.sql $(EXAMPLES_DEST)/isql$(EXEC_EXT)
+ -$(RM) $(EXAMPLES_DEST)/empbuild.fdb
+- $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i empbld.sql
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i empbld.sql
+
+ # The chain for intlemp.fdb is the same a script file to create an empty database
+ # to allow a .e program to be compiled, to then create and populate with data
+@@ -158,7 +158,7 @@
+
+ $(EXAMPLES_DEST)/intlbuild.fdb : $(EXAMPLES_DEST)/intlddl.sql $(EXAMPLES_DEST)/intlbld.sql $(EXAMPLES_DEST)/isql$(EXEC_EXT)
+ -$(RM) intlbuild.fdb
+- $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i intlbld.sql
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(EXAMPLES_DEST)/isql$(EXEC_EXT) -i intlbld.sql
+
+
+ $(EXAMPLES_DEST)/%.sql: $(EXAMPLES_SRC)/empbuild/%.sql
+--- builds/posix/make.rules
++++ builds/posix/make.rules
+@@ -68,17 +68,17 @@
+ .SUFFIXES: .c .e .epp .cpp
+
+ .e.c:
+- $(GPRE_CURRENT) $(GPRE_FLAGS) $< $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(GPRE_FLAGS) $< $@
+
+
+ $(OBJ)/jrd/%.cpp: $(SRC_ROOT)/jrd/%.epp
+- $(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(JRD_GPRE_FLAGS) $(firstword $<) $@
+
+ $(OBJ)/isql/%.cpp: $(SRC_ROOT)/isql/%.epp
+- $(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(ISQL_GPRE_FLAGS) $< $@
+
+ $(OBJ)/%.cpp: $(SRC_ROOT)/%.epp
+- $(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
++ $(LIBO_TUNNEL_LIBRARY_PATH) $(GPRE_CURRENT) $(GPRE_FLAGS) $(firstword $<) $@
+
+
+ .SUFFIXES: .lo .o .cpp .c
+--- src/common/classes/alloc.cpp
++++ src/common/classes/alloc.cpp
+@@ -2187,7 +2187,7 @@
+
+ void* MemPool::allocRaw(size_t size)
+ {
+-#ifndef USE_VALGRIND
++#if !(defined USE_VALGRIND || defined USE_ASAN)
+ if (size == DEFAULT_ALLOCATION)
+ {
+ MutexLockGuard guard(*cache_mutex, "MemPool::allocRaw");
+@@ -2267,7 +2267,7 @@
+
+ void MemPool::releaseRaw(bool destroying, void* block, size_t size, bool use_cache) throw ()
+ {
+-#ifndef USE_VALGRIND
++#if !(defined USE_VALGRIND || defined USE_ASAN)
+ if (use_cache && (size == DEFAULT_ALLOCATION))
+ {
+ MutexLockGuard guard(*cache_mutex, "MemPool::releaseRaw");
+@@ -2277,7 +2277,7 @@
+ return;
+ }
+ }
+-#else
++#elif defined USE_VALGRIND
+ // Set access protection for block to prevent memory from deleted pool being accessed
+ int handle = /* //VALGRIND_MAKE_NOACCESS */ VALGRIND_MAKE_MEM_DEFINED(block, size);
+
+--- src/common/classes/alloc.h
++++ src/common/classes/alloc.h
+@@ -295,40 +295,60 @@
+
+ // operators new and delete
+
++#if !defined USE_ASAN
+ inline void* operator new(size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
+ inline void* operator new[](size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
++#endif
+
+ inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
++#if defined USE_ASAN
++ return operator new(s);
++#else
+ return pool.allocate(s ALLOC_PASS_ARGS);
++#endif
+ }
+ inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
++#if defined USE_ASAN
++ return operator new[](s);
++#else
+ return pool.allocate(s ALLOC_PASS_ARGS);
++#endif
+ }
+
++#if !defined USE_ASAN
+ inline void operator delete(void* mem ALLOC_PARAMS) throw()
+ {
+ MemoryPool::globalFree(mem);
+ }
+ inline void operator delete[](void* mem ALLOC_PARAMS) throw()
+ {
+ MemoryPool::globalFree(mem);
+ }
++#endif
+
+ inline void operator delete(void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) throw()
+ {
++#if defined USE_ASAN
++ return operator delete(mem);
++#else
+ MemoryPool::globalFree(mem);
++#endif
+ }
+ inline void operator delete[](void* mem, Firebird::MemoryPool& pool ALLOC_PARAMS) throw()
+ {
++#if defined USE_ASAN
++ return operator delete[](mem);
++#else
+ MemoryPool::globalFree(mem);
++#endif
+ }
+
+ #ifdef DEBUG_GDS_ALLOC
+--- src/include/firebird.h
++++ src/include/firebird.h
+@@ -38,8 +38,17 @@
+ #include "gen/autoconfig.h"
+ #endif
+
++#if defined __clang__
++//#if __has_feature(address_sanitizer)
++#define USE_ASAN
++//#endif
++#endif
++#if defined __SANITIZE_ADDRESS__
++#define USE_ASAN
++#endif
++
+ // Using our debugging code is pointless when we may use Valgrind features
+-#if defined(DEV_BUILD) && !defined(USE_VALGRIND)
++#if defined(DEV_BUILD) && !(defined(USE_VALGRIND) || defined(USE_ASAN))
+ #define DEBUG_GDS_ALLOC
+ #endif
+
+--- src/jrd/SimilarToMatcher.h
++++ src/jrd/SimilarToMatcher.h
+@@ -338,7 +338,7 @@
+ private:
+ static const unsigned INCREASE_FACTOR = 50;
+ unsigned size;
+- AutoPtr<UCHAR> data;
++ AutoPtr<UCHAR, ArrayDelete<UCHAR>> data;
+ T* end;
+ };
+ #endif // RECURSIVE_SIMILAR
+--- configure.orig 2018-06-03 17:44:50.152951348 +0200
++++ configure 2018-06-03 17:45:11.708907807 +0200
+@@ -18479,11 +18479,11 @@
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+-char dlopen ();
++char dlsym ();
+ int
+ main ()
+ {
+-return dlopen ();
++return dlsym ();
+ ;
+ return 0;
+ }
diff --git a/external/firebird/c++17.patch b/external/firebird/c++17.patch
new file mode 100644
index 000000000..f5ac666ba
--- /dev/null
+++ b/external/firebird/c++17.patch
@@ -0,0 +1,301 @@
+--- src/common/DynamicStrings.cpp
++++ src/common/DynamicStrings.cpp
+@@ -37,7 +37,7 @@
+
+ namespace Firebird {
+
+-unsigned makeDynamicStrings(unsigned length, ISC_STATUS* const dst, const ISC_STATUS* const src) throw(BadAlloc)
++unsigned makeDynamicStrings(unsigned length, ISC_STATUS* const dst, const ISC_STATUS* const src)
+ {
+ const ISC_STATUS* end = &src[length];
+
+--- src/common/DynamicStrings.h
++++ src/common/DynamicStrings.h
+@@ -34,7 +34,7 @@
+
+ namespace Firebird {
+
+-unsigned makeDynamicStrings(unsigned len, ISC_STATUS* const dst, const ISC_STATUS* const src) throw(BadAlloc);
++unsigned makeDynamicStrings(unsigned len, ISC_STATUS* const dst, const ISC_STATUS* const src);
+ char* findDynamicStrings(unsigned len, ISC_STATUS* ptr) throw();
+
+ } // namespace Firebird
+--- src/common/StatusArg.cpp
++++ src/common/StatusArg.cpp
+@@ -53,7 +53,7 @@
+
+ namespace Arg {
+
+-Base::Base(ISC_STATUS k, ISC_STATUS c) throw(Firebird::BadAlloc) :
++Base::Base(ISC_STATUS k, ISC_STATUS c) :
+ implementation(FB_NEW_POOL(*getDefaultMemoryPool()) ImplBase(k, c))
+ {
+ }
+@@ -94,28 +94,28 @@
+ assign(ex);
+ }
+
+-StatusVector::StatusVector(ISC_STATUS k, ISC_STATUS c) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(ISC_STATUS k, ISC_STATUS c) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(k, c))
+ {
+ operator<<(*(static_cast<Base*>(this)));
+ }
+
+-StatusVector::StatusVector(const ISC_STATUS* s) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(const ISC_STATUS* s) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(s))
+ {
+ }
+
+-StatusVector::StatusVector(const IStatus* s) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(const IStatus* s) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(s))
+ {
+ }
+
+-StatusVector::StatusVector(const Exception& ex) throw(Firebird::BadAlloc) :
++StatusVector::StatusVector(const Exception& ex) :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(ex))
+ {
+ }
+
+-StatusVector::StatusVector() throw(Firebird::BadAlloc) :
++StatusVector::StatusVector() :
+ Base(FB_NEW_POOL(*getDefaultMemoryPool()) ImplStatusVector(0, 0))
+ {
+ }
+--- src/common/StatusArg.h
++++ src/common/StatusArg.h
+@@ -86,7 +86,7 @@
+ virtual ~ImplBase() { }
+ };
+
+- Base(ISC_STATUS k, ISC_STATUS c) throw(Firebird::BadAlloc);
++ Base(ISC_STATUS k, ISC_STATUS c);
+ explicit Base(ImplBase* i) throw() : implementation(i) { }
+ ~Base() throw() { delete implementation; }
+
+@@ -142,13 +142,13 @@
+ explicit ImplStatusVector(const Exception& ex) throw();
+ };
+
+- StatusVector(ISC_STATUS k, ISC_STATUS v) throw(Firebird::BadAlloc);
++ StatusVector(ISC_STATUS k, ISC_STATUS v);
+
+ public:
+- explicit StatusVector(const ISC_STATUS* s) throw(Firebird::BadAlloc);
+- explicit StatusVector(const IStatus* s) throw(Firebird::BadAlloc);
+- explicit StatusVector(const Exception& ex) throw(Firebird::BadAlloc);
+- StatusVector() throw(Firebird::BadAlloc);
++ explicit StatusVector(const ISC_STATUS* s);
++ explicit StatusVector(const IStatus* s);
++ explicit StatusVector(const Exception& ex);
++ StatusVector();
+ ~StatusVector() { }
+
+ const ISC_STATUS* value() const throw() { return implementation->value(); }
+--- src/common/classes/alloc.cpp
++++ src/common/classes/alloc.cpp
+@@ -1431,7 +1431,7 @@
+
+ ~FreeObjects();
+
+- FreeObjPtr allocateBlock(MemPool* pool, size_t from, size_t& size) throw (OOM_EXCEPTION)
++ FreeObjPtr allocateBlock(MemPool* pool, size_t from, size_t& size)
+ {
+ size_t full_size = size + (from ? 0 : ListBuilder::MEM_OVERHEAD);
+ if (full_size > Limits::TOP_LIMIT)
+@@ -1498,7 +1498,7 @@
+ ListBuilder listBuilder;
+ Extent* currentExtent;
+
+- MemBlock* newBlock(MemPool* pool, unsigned slot) throw (OOM_EXCEPTION);
++ MemBlock* newBlock(MemPool* pool, unsigned slot);
+ };
+
+
+@@ -1538,26 +1538,26 @@
+ AtomicCounter used_memory, mapped_memory;
+
+ private:
+- MemBlock* alloc(size_t from, size_t& length, bool flagRedirect) throw (OOM_EXCEPTION);
++ MemBlock* alloc(size_t from, size_t& length, bool flagRedirect);
+ void releaseBlock(MemBlock *block) throw ();
+
+ public:
+- void* allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION);
+- MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS) throw (OOM_EXCEPTION);
++ void* allocate(size_t size ALLOC_PARAMS);
++ MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS);
+
+ private:
+- virtual void memoryIsExhausted(void) throw (OOM_EXCEPTION);
+- void* allocRaw(size_t length) throw (OOM_EXCEPTION);
++ virtual void memoryIsExhausted(void);
++ void* allocRaw(size_t length);
+ static void release(void* block, bool flagDecr) throw ();
+ static void releaseRaw(bool destroying, void *block, size_t size, bool use_cache = true) throw ();
+- void* getExtent(size_t from, size_t& to) throw (OOM_EXCEPTION);
++ void* getExtent(size_t from, size_t& to);
+
+ public:
+ static void releaseExtent(bool destroying, void *block, size_t size, MemPool* pool) throw ();
+
+ // pass desired size, return actual extent size
+ template <class Extent>
+- void newExtent(size_t& size, Extent** linkedList) throw (OOM_EXCEPTION);
++ void newExtent(size_t& size, Extent** linkedList);
+
+ private:
+ #ifdef USE_VALGRIND
+@@ -1667,7 +1667,7 @@
+
+
+ template <class ListBuilder, class Limits>
+-MemBlock* FreeObjects<ListBuilder, Limits>::newBlock(MemPool* pool, unsigned slot) throw (OOM_EXCEPTION)
++MemBlock* FreeObjects<ListBuilder, Limits>::newBlock(MemPool* pool, unsigned slot)
+ {
+ size_t size = Limits::getSize(slot);
+
+@@ -1902,7 +1902,7 @@
+ }
+
+ template <class Extent>
+-void MemPool::newExtent(size_t& size, Extent** linkedList) throw(OOM_EXCEPTION)
++void MemPool::newExtent(size_t& size, Extent** linkedList)
+ {
+ // No large enough block found. We need to extend the pool
+ void* memory = NULL;
+@@ -1967,7 +1967,7 @@
+ pool->setStatsGroup(newStats);
+ }
+
+-MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect) throw (OOM_EXCEPTION)
++MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect)
+ {
+ MutexEnsureUnlock guard(mutex, "MemPool::alloc");
+ guard.enter();
+@@ -2026,7 +2026,7 @@
+ #ifdef DEBUG_GDS_ALLOC
+ , const char* fileName, int line
+ #endif
+-) throw (OOM_EXCEPTION)
++)
+ {
+ size_t length = from ? size : ROUNDUP(size + VALGRIND_REDZONE, roundingSize) + GUARD_BYTES;
+ MemBlock* memory = alloc(from, length, true);
+@@ -2055,7 +2055,7 @@
+ }
+
+
+-void* MemPool::allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
++void* MemPool::allocate(size_t size ALLOC_PARAMS)
+ {
+ MemBlock* memory = allocate2(0, size ALLOC_PASS_ARGS);
+
+@@ -2180,12 +2180,12 @@
+ releaseRaw(pool_destroying, hunk, hunk->length, false);
+ }
+
+-void MemPool::memoryIsExhausted(void) throw (OOM_EXCEPTION)
++void MemPool::memoryIsExhausted(void)
+ {
+ Firebird::BadAlloc::raise();
+ }
+
+-void* MemPool::allocRaw(size_t size) throw (OOM_EXCEPTION)
++void* MemPool::allocRaw(size_t size)
+ {
+ #ifndef USE_VALGRIND
+ if (size == DEFAULT_ALLOCATION)
+@@ -2245,7 +2245,7 @@
+ }
+
+
+-void* MemPool::getExtent(size_t from, size_t& to) throw(OOM_EXCEPTION) // pass desired minimum size, return actual extent size
++void* MemPool::getExtent(size_t from, size_t& to) // pass desired minimum size, return actual extent size
+ {
+ MemBlock* extent = allocate2(from, to ALLOC_ARGS);
+ return &extent->body;
+@@ -2348,7 +2348,7 @@
+ deallocate(block);
+ }
+
+-void* MemoryPool::calloc(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
++void* MemoryPool::calloc(size_t size ALLOC_PARAMS)
+ {
+ void* block = allocate(size ALLOC_PASS_ARGS);
+ memset(block, 0, size);
+@@ -2489,7 +2489,7 @@
+ MemPool::globalFree(block);
+ }
+
+-void* MemoryPool::allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
++void* MemoryPool::allocate(size_t size ALLOC_PARAMS)
+ {
+ return pool->allocate(size ALLOC_PASS_ARGS);
+ }
+@@ -2547,11 +2547,11 @@
+ // in a case when we actually need "new" only with file/line information
+ // this version should be also present as a pair for "delete".
+ #ifdef DEBUG_GDS_ALLOC
+-void* operator new(size_t s) throw (OOM_EXCEPTION)
++void* operator new(size_t s)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_ARGS);
+ }
+-void* operator new[](size_t s) throw (OOM_EXCEPTION)
++void* operator new[](size_t s)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_ARGS);
+ }
+--- src/common/classes/alloc.h
++++ src/common/classes/alloc.h
+@@ -186,18 +186,18 @@
+ #define ALLOC_PASS_ARGS
+ #endif // DEBUG_GDS_ALLOC
+
+- void* calloc(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION);
++ void* calloc(size_t size ALLOC_PARAMS);
+
+ #ifdef LIBC_CALLS_NEW
+ static void* globalAlloc(size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION);
+ #else
+- static void* globalAlloc(size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION)
++ static void* globalAlloc(size_t s ALLOC_PARAMS)
+ {
+ return defaultMemoryManager->allocate(s ALLOC_PASS_ARGS);
+ }
+ #endif // LIBC_CALLS_NEW
+
+- void* allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION);
++ void* allocate(size_t size ALLOC_PARAMS);
+
+ static void globalFree(void* mem) throw ();
+ void deallocate(void* mem) throw ();
+@@ -295,20 +295,20 @@
+
+ // operators new and delete
+
+-inline void* operator new(size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new(size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
+-inline void* operator new[](size_t s ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new[](size_t s ALLOC_PARAMS)
+ {
+ return MemoryPool::globalAlloc(s ALLOC_PASS_ARGS);
+ }
+
+-inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new(size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
+ return pool.allocate(s ALLOC_PASS_ARGS);
+ }
+-inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS) throw (OOM_EXCEPTION)
++inline void* operator new[](size_t s, Firebird::MemoryPool& pool ALLOC_PARAMS)
+ {
+ return pool.allocate(s ALLOC_PASS_ARGS);
+ }
diff --git a/external/firebird/firebird-Engine12.patch b/external/firebird/firebird-Engine12.patch
new file mode 100644
index 000000000..f6590b300
--- /dev/null
+++ b/external/firebird/firebird-Engine12.patch
@@ -0,0 +1,16 @@
+--- src/common/utils.cpp
++++ src/common/utils.cpp
+@@ -1026,6 +1026,13 @@
+ PathUtils::concatPath(s, configDir[prefType], name);
+ return s;
+ }
++
++ // Set relative path to Engine12 dynamic library
++ if(prefType == Firebird::IConfigManager::DIR_PLUGINS)
++ {
++ s = name;
++ return s;
++ }
+ }
+
+ switch(prefType)
diff --git a/external/firebird/firebird-cloop-compiler.patch.1 b/external/firebird/firebird-cloop-compiler.patch.1
new file mode 100644
index 000000000..ac82bb0ca
--- /dev/null
+++ b/external/firebird/firebird-cloop-compiler.patch.1
@@ -0,0 +1,12 @@
+diff -ur firebird.org/extern/cloop/Makefile firebird/extern/cloop/Makefile
+--- firebird.org/extern/cloop/Makefile 2016-08-17 18:32:59.078044357 +0200
++++ firebird/extern/cloop/Makefile 2016-08-17 18:33:14.430518561 +0200
+@@ -4,8 +4,6 @@
+
+ TARGET := release
+
+-CC := gcc
+-CXX := g++
+ LD := $(CXX)
+
+ SRC_DIR := src
diff --git a/external/firebird/firebird-configure-x86-64-macosx.patch.1 b/external/firebird/firebird-configure-x86-64-macosx.patch.1
new file mode 100644
index 000000000..99a7d2db8
--- /dev/null
+++ b/external/firebird/firebird-configure-x86-64-macosx.patch.1
@@ -0,0 +1,20 @@
+--- firebird.org/configure 2015-03-27 16:00:42.000000000 +0200
++++ firebird/configure 2015-06-09 15:33:26.000000000 +0300
+@@ -2903,7 +2903,7 @@
+ ;;
+
+ i*86-*-darwin*)
+- MAKEFILE_PREFIX=darwin_i386
++ MAKEFILE_PREFIX=darwin_x86_64
+ MAKEFILE_POSTFIX=darwin
+ PLATFORM=DARWIN
+ INSTALL_PREFIX=darwin
+@@ -2913,7 +2913,7 @@
+ LIBS="$LIBS -framework CoreFoundation"
+ EDITLINE_FLG=Y
+ SHRLIB_EXT=dylib
+- CPU_TYPE=i386
++ CPU_TYPE=x86_64
+ EXPORT_SYMBOLS_STYLE=darwin
+ ;;
+
diff --git a/external/firebird/firebird-cygwin-msvc.patch b/external/firebird/firebird-cygwin-msvc.patch
new file mode 100644
index 000000000..317ea8026
--- /dev/null
+++ b/external/firebird/firebird-cygwin-msvc.patch
@@ -0,0 +1,654 @@
+--- src/include/firebird.h 2016-07-15 11:31:27.151443500 +0200
++++ src/include/firebird.h 2016-07-17 14:50:04.043792400 +0200
+@@ -32,11 +32,7 @@
+ #ifndef INCLUDE_Firebird_H
+ #define INCLUDE_Firebird_H
+
+-#ifdef _MSC_VER
+-#include "gen/autoconfig_msvc.h"
+-#else
+ #include "gen/autoconfig.h"
+-#endif
+
+ #if defined __clang__
+ //#if __has_feature(address_sanitizer)
+--- src/misc/writeBuildNum.sh 2016-07-07 15:57:04.538983200 +0200
++++ src/misc/writeBuildNum.sh 2016-07-13 11:31:18.132820200 +0200
+@@ -95,9 +95,9 @@
+ createMakeVersion() {
+
+ OdsH="${Root}/src/jrd/ods.h"
+-Mini="/tmp/miniods.h"
+-TestCpp="/tmp/test.cpp"
+-AOut="/tmp/a.out"
++Mini=$(cygpath -m "/tmp/miniods.h")
++TestCpp=$(cygpath -m "/tmp/test.cpp")
++AOut=$(cygpath -m "/tmp/a.out")
+
+ grep ODS_VERSION $OdsH | grep -v ENCODE_ODS >$Mini
+
+--- builds/make.new/config/config.h.in 2016-07-07 15:55:55.693112800 +0200
++++ builds/make.new/config/config.h.in 2016-07-08 13:38:49.994986400 +0200
+@@ -396,7 +396,7 @@
+ #undef HAVE_SIGSET
+
+ /* Define to 1 if you have the `snprintf' function. */
+-#undef HAVE_SNPRINTF
++#define HAVE_SNPRINTF
+
+ /* Define to 1 if you have the <socket.h> header file. */
+ #undef HAVE_SOCKET_H
+@@ -551,7 +551,7 @@
+ #undef HAVE_VFORK_H
+
+ /* Define to 1 if you have the `vsnprintf' function. */
+-#undef HAVE_VSNPRINTF
++#define HAVE_VSNPRINTF
+
+ /* Define to 1 if you have the <winsock2.h> header file. */
+ #undef HAVE_WINSOCK2_H
+@@ -646,7 +646,7 @@
+ #undef TIME_WITH_SYS_TIME
+
+ /* Define this if OS is Windows NT */
+-#undef WIN_NT
++#define WIN_NT
+
+ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+@@ -703,3 +703,34 @@
+ #ifndef HAVE_SOCKLEN_T
+ typedef int socklen_t;
+ #endif
++
++/* taken from src/include/gen/autoconfig_msvc.h */
++#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
++/* target architecture */
++#if defined(_M_IX86)
++/* sizeof(void *) */
++#define SIZEOF_VOID_P 4
++/* sizeof(size_t) */
++#define SIZEOF_SIZE_T 4
++/* alignment of long */
++#define FB_ALIGNMENT 4
++#elif defined(_M_AMD64)
++#define AMD64
++/* sizeof(void *) */
++#define SIZEOF_VOID_P 8
++/* sizeof(size_t) */
++#define SIZEOF_SIZE_T 8
++/* alignment of long */
++#define FB_ALIGNMENT 8
++#else
++#error unknown target platform
++#endif
++
++#define HAVE_IO_H
++
++#define HAVE_GETPAGESIZE
++
++#if defined _MSC_VER
++#define isnan _isnan
++#endif
++
+--- src/common/common.h 2016-07-15 11:31:26.366735500 +0200
++++ src/common/common.h 2016-07-17 16:18:39.121579400 +0200
+@@ -551,15 +551,6 @@
+ #endif /* WIN_NT */
+
+
+-#ifndef FB_CPU
+-#error Define FB_CPU for your platform
+-#endif
+-#ifndef FB_OS
+-#error Define FB_OS for your platform
+-#endif
+-#ifndef FB_CC
+-#error Define FB_CC for your platform
+-#endif
+
+
+ /*****************************************************
+diff -ur builds/posix/make.defaults builds/posix/make.defaults
+--- builds/posix/make.defaults 2016-07-07 13:56:13.036235166 +0200
++++ builds/posix/make.defaults 2016-07-07 14:29:52.368289242 +0200
+@@ -55,7 +55,11 @@
+ else
+ FIREBIRD=$(FB_BUILD)
+ endif
+-FIREBIRD_LOCK=$(FIREBIRD)
++ifeq (@PLATFORM@,win32)
++ FIREBIRD_LOCK=$(shell cygpath -w $(FIREBIRD) )
++else
++ FIREBIRD_LOCK=$(FIREBIRD)
++endif
+
+ export FIREBIRD
+ export FIREBIRD_LOCK
+@@ -152,7 +156,11 @@
+ CD= cd
+ CAT= cat
+ AR= ar @AR_OPTIONS@
+-LN= @LN_S@
++ifeq (@PLATFORM@,win32)
++ LN= cp
++else
++ LN= @LN_S@
++endif
+ RANLIB= @RANLIB@
+ BTYACC=$(ROOT)/extern/btyacc/btyacc
+ CLOOP=$(GEN_ROOT)/$(TARGET)/cloop/release/bin/cloop
+@@ -174,10 +182,10 @@
+
+ # Default extensions
+
+-ARCH_EXT= .a
++ARCH_EXT= .lib
+ EXEC_EXT= @EXEEXT@
+ SHRLIB_EXT=@SHRLIB_EXT@
+-LIB_PREFIX= lib
++LIB_PREFIX=
+ SHRLIB_FOREIGN_EXT= $(SHRLIB_EXT)
+
+ #_____________________________________________________________________________
+@@ -203,6 +211,7 @@
+ vpath %.so $(LIB)
+ vpath %.a $(LIB)
+ vpath %.dll $(LIB)
++vpath %.lib $(LIB)
+
+ #_____________________________________________________________________________
+
+@@ -216,9 +225,9 @@
+ #
+
+ #LibraryFileName=libfbclient
+-LibraryFileName=libfbclient
+-LibraryFullName=$(LibraryFileName).${SHRLIB_EXT}.${FirebirdVersion}
+-LibrarySoName=$(LibraryFileName).${SHRLIB_EXT}.2
++LibraryFileName=ifbclient
++LibraryFullName=$(LibraryFileName).${SHRLIB_EXT}
++LibrarySoName=$(LibraryFileName).${SHRLIB_EXT}
+ LibraryBaseName=$(LibraryFileName).${SHRLIB_EXT}
+
+ LIBFIREBIRD_FULLNAME = $(LIB)/$(LibraryFullName)
+@@ -227,7 +236,7 @@
+
+ # The firebird engine library name
+
+-EngineFileName=libEngine${OdsVersion}
++EngineFileName=Engine12
+ EngineSoName=$(EngineFileName).${SHRLIB_EXT}
+ ENGINE_SONAME = $(PLUGINS)/$(EngineSoName)
+
+@@ -241,7 +250,7 @@
+ ifeq ($(STD_EDITLINE), true)
+ LIBEDITLINE := -l$(READLINE)
+ else
+- LIBEDITLINE := $(LIB)/libedit.a
++ LIBEDITLINE := $(LIB)/edit.lib
+ endif
+ endif
+
+@@ -289,7 +298,7 @@
+ LIB_PATH_OPTS = $(call LIB_LINK_RPATH,lib) $(call LIB_LINK_RPATH,intl)
+ LIB_LINK_SONAME= -Wl,-soname,$(1)
+ LIB_LINK_MAPFILE= -Wl,--version-script,$(1)
+-FIREBIRD_LIBRARY_LINK= -L$(LIB) -lfbclient $(MATHLIB)
++FIREBIRD_LIBRARY_LINK= -L$(LIB) -lifbclient $(MATHLIB)
+
+ EXE_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) $(UNDEF_FLAGS) $(LIB_PATH_OPTS) $(LINK_EMPTY_SYMBOLS)
+ LIB_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) -shared
+@@ -329,7 +338,8 @@
+
+ # Pay attention - we place common library into obj, not lib dir
+ # It's just a set of object files, prepared to be used by ld, not an output library
+-COMMON_LIB = $(OBJ)/common.a
++
++COMMON_LIB = $(OBJ)/common.lib
+
+ # From utilities
+ CREATE_DB = $(RBIN)/create_db$(EXEC_EXT)
+--- builds/posix/Makefile.in 2016-07-07 15:56:06.459221300 +0200
++++ builds/posix/Makefile.in 2016-07-13 12:44:57.134217200 +0200
+@@ -33,7 +33,8 @@
+ # Alex Peshkoff - created single makefile based on Mark's files
+ #
+
+-ROOT=$(shell cd ..; pwd)
++#ROOT=$(shell cd ..; pwd)
++ROOT=$(shell cygpath -m '$(shell cd ..; pwd)')
+
+ include make.defaults
+ ifeq ($(CROSS_OUT), Y)
+@@ -163,7 +164,7 @@
+ .PHONY: cross1 cross2 boot yvalve engine fbintl gpre utilities plugins rest codes ids examples cross_rest
+
+ master_process:
+- ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
++ cp -f $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
+ $(MAKE) updateBuildNum
+ $(MAKE) export_lists
+ $(MAKE) extern
+@@ -186,10 +187,10 @@
+ (cd $(BIN); $(LN) $(notdir $(GPRE)) $(notdir $(GPRE_CURRENT)))
+ ifeq ($(IsDeveloper), Y)
+ # In developer mode we must regenerate various files in include/gen
+- $(MAKE) codes
++# $(MAKE) codes
+ endif
+- $(MAKE) plugins
+- $(MAKE) examples
++# $(MAKE) plugins
++ $(MAKE) include_generic
+ $(MAKE) rest
+
+
+@@ -198,7 +199,7 @@
+ $(MAKE) CROSS_OUT=Y cross2
+
+ cross1:
+- ln -sf $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
++ cp -f $(SRC_ROOT)/include/gen/autoconfig.auto $(SRC_ROOT)/include/gen/autoconfig.h
+ $(MAKE) updateBuildNum
+ $(MAKE) export_lists
+ $(MAKE) extern
+@@ -223,7 +224,7 @@
+ $(MAKE) -f Makefile.examples -C $(GEN_ROOT)/examples/
+
+ cross2:
+- ln -sf $(SRC_ROOT)/include/cross/$(CROSS_CONFIG) $(SRC_ROOT)/include/gen/autoconfig.h
++ cp -f $(SRC_ROOT)/include/cross/$(CROSS_CONFIG) $(SRC_ROOT)/include/gen/autoconfig.h
+ $(MAKE) prerequisites
+ $(MAKE) tommath
+ $(MAKE) yvalve
+@@ -275,7 +275,8 @@
+
+ # remote redirector is statically linked in main FB library
+ $(LIBFIREBIRD_FULLNAME): $(YValve_Objects) $(Remote_Client_Objects) $(COMMON_LIB)
+- $(LINK_FIREBIRD) -o $@ $^ $(LINK_FIREBIRD_LIBS)
++ @echo 'compile: $(LINK_FIREBIRD) $(CPPFLAGS) -o $@ $^ $(LINK_FIREBIRD_LIBS)'
++ $(LINK_FIREBIRD) $(CPPFLAGS) -o $@ $^ $(LINK_FIREBIRD_LIBS)
+
+
+ #___________________________________________________________________________
+@@ -284,7 +286,8 @@
+ engine: $(ENGINE_SONAME)
+
+ $(ENGINE_SONAME): $(Engine_Objects) $(SVC_Objects) $(COMMON_LIB)
+- $(LINK_ENGINE) -o $@ $^ $(LINK_ENGINE_LIBS)
++ @echo 'compile engine: $(LINK_ENGINE) $(CPPFLAGS) -o $@ $^ $(LINK_ENGINE_LIBS)'
++ $(LINK_ENGINE) $(CPPFLAGS) -o $@ $^ $(YValve_Objects) $(Remote_Client_Objects) $(LINK_ENGINE_LIBS)
+
+
+ #___________________________________________________________________________
+@@ -294,7 +297,7 @@
+ fbintl: $(LIBFBINTL_SO)
+
+ $(LIBFBINTL_SO): $(INTL_Objects) $(COMMON_LIB)
+- $(LINK_INTL) -o $@ $^ $(LINK_INTL_LIBS)
++ $(LINK_INTL) $(CPPFLAGS) -o $@ $^ $(YValve_Objects) $(Remote_Client_Objects) $(LINK_INTL_LIBS)
+
+
+ #___________________________________________________________________________
+@@ -393,7 +396,7 @@
+
+ .PHONY: firebird_server fb_lock_print fbguard fbsvcmgr fbtracemgr gbak gfix gsec gsplit gstat isql nbackup
+
+-utilities: firebird_server fb_lock_print fbguard fbsvcmgr fbtracemgr gbak gfix gsec gsplit gstat isql nbackup udfsupport
++utilities: gbak gfix isql
+
+ firebird_server: $(FB_DAEMON)
+
+@@ -540,7 +543,7 @@
+ GBAK_FILES := $(FDB_FILES:.fdb=.gbak) $(FIREBIRD)/msg.gbak
+ GBAK_FILES := $(subst Native,$(TARGET),$(GBAK_FILES))
+
+-rest: qli message_file
++rest: message_file
+
+ cross_rest: qli gbak_files
+ $(MAKE) $(BUILD_FILE)
+@@ -593,7 +595,7 @@
+ IBASE_ExtraFiles = include/types_pub.h include/consts_pub.h dsql/sqlda_pub.h common/dsc_pub.h jrd/ibase.h jrd/inf_pub.h jrd/blr.h include/gen/iberror.h
+ SRC_IBASE_ExtraFiles = $(addprefix $(SRC_ROOT)/, $(IBASE_ExtraFiles))
+ MAKE_HEADER_Src = $(addprefix $(SRC_ROOT)/, misc/makeHeader.cpp)
+-MAKE_HEADER_Bin = ./makeHeader
++MAKE_HEADER_Bin = ./makeHeader.exe
+
+ $(INCLUDE_DEST)/ibase.h: $(SRC_IBASE_ExtraFiles)
+ $(STATICEXE_LINK) -o $(MAKE_HEADER_Bin) $(MAKE_HEADER_Src)
+diff -ur builds/posix/Makefile.in.examples builds/posix/Makefile.in.examples
+--- builds/posix/Makefile.in.examples 2016-07-07 13:56:13.048235166 +0200
++++ builds/posix/Makefile.in.examples 2016-07-07 14:37:36.904301682 +0200
+@@ -65,10 +65,13 @@
+ EXAMPLES_DEST= $(GEN_ROOT)/examples
+ EXAMPLES_SRC= $(ROOT)/examples
+
+-
++ifeq ($(PLATFORM),win32)
++EMPBLD_Objects= $(EXAMPLES_DEST)/empbuild.obj
++INTLBLD_Objects= $(EXAMPLES_DEST)/intlbld.obj
++else
+ EMPBLD_Objects= $(EXAMPLES_DEST)/empbuild.o
+-
+ INTLBLD_Objects= $(EXAMPLES_DEST)/intlbld.o
++endif
+
+ INPUT_Files = empddl.sql empdml.sql indexoff.sql indexon.sql \
+ job.inp lang.inp proj.inp qtr.inp
+@@ -172,3 +175,5 @@
+
+ $(EXAMPLES_DEST)/%.h: $(EXAMPLES_SRC)/common/%.h
+ $(CP) $^ $@
++$(EXAMPLES_DEST)/%.obj: $(EXAMPLES_DEST)/%.c
++ $(CC) -c $(firstword $<) -Fo$@ $(WCFLAGS)
+diff -ur builds/posix/make.rules builds/posix/make.rules
+--- builds/posix/make.rules 2016-07-07 13:56:13.036235166 +0200
++++ builds/posix/make.rules 2016-07-07 14:31:16.116291485 +0200
+@@ -88,22 +88,20 @@
+
+ $(OBJ)/%.o: $(SRC_ROOT)/%.c
+ $(CC) $(WCFLAGS) -c $(firstword $<) -o $@
+- @sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
+
+ $(OBJ)/%.o: $(OBJ)/%.cpp
+ $(CXX) $(WCXXFLAGS) -c $(firstword $<) -o $@
+- @sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
+
+ $(OBJ)/%.o: $(SRC_ROOT)/%.cpp
+ $(CXX) $(WCXXFLAGS) -c $(firstword $<) -o $@
+- @sed $(INLINE_EDIT_SED) -e "1,2s/:/: \$$(wildcard/" -e "\$$s/\(.*\)/\\1)/" $(patsubst %.o,%.d,$@)
+
+ .SUFFIXES: .epp .e
+
+ # Rules for making resource files
+
+ $(GEN_ROOT)/%.res: $(SRC_ROOT)/%.rc
+- windres --output-format=coff --include-dir=$(<D) $< $@
++ mkdir -p $(@D)
++ rc.exe $(SOLARINC) /fo $@ $<
+
+ # Rule for making gbak files when cross-compiling
+
+--- src/common/utils.cpp 2016-07-15 11:31:26.746871100 +0200
++++ src/common/utils.cpp 2016-07-19 19:14:45.370689300 +0200
+@@ -880,15 +880,15 @@
+ FILETIME utime, stime, dummy;
+ if (GetProcessTimes(GetCurrentProcess(), &dummy, &dummy, &stime, &utime))
+ {
+- LARGE_INTEGER lint;
++ LARGE_INTEGER myLargeInt;
+
+- lint.HighPart = stime.dwHighDateTime;
+- lint.LowPart = stime.dwLowDateTime;
+- sysTime = lint.QuadPart / 10000;
+-
+- lint.HighPart = utime.dwHighDateTime;
+- lint.LowPart = utime.dwLowDateTime;
+- userTime = lint.QuadPart / 10000;
++ myLargeInt.HighPart = stime.dwHighDateTime;
++ myLargeInt.LowPart = stime.dwLowDateTime;
++ sysTime = myLargeInt.QuadPart / 10000;
++
++ myLargeInt.HighPart = utime.dwHighDateTime;
++ myLargeInt.LowPart = utime.dwLowDateTime;
++ userTime = myLargeInt.QuadPart / 10000;
+ }
+ else
+ {
+diff -ur builds/posix/prefix.mingw builds/posix/prefix.mingw
+--- builds/posix/prefix.mingw 2016-07-07 13:56:13.048235166 +0200
++++ builds/posix/prefix.mingw 2016-07-07 14:50:54.704323046 +0200
+@@ -20,8 +20,8 @@
+ #
+
+ # -Wno-unused-variable is used due to unused gpre generated variables
+-PROD_FLAGS=-O2 -DMINGW -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads -Wno-non-virtual-dtor
+-DEV_FLAGS=-ggdb -DMINGW -Wall -Wshadow -Wundef -Wno-long-long -Wno-unused-variable -Wno-sign-compare -Wno-parentheses -Wno-switch -fmessage-length=0 -Dlint -DWIN32_LEAN_AND_MEAN -MMD -mthreads -Wno-non-virtual-dtor
++PROD_FLAGS=-O2 -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN
++DEV_FLAGS=-ggdb -DMINGW -Dlint -DWIN32_LEAN_AND_MEAN
+
+ PLATFORM_PATH=os/win32
+
+@@ -29,6 +29,7 @@
+ LIB_LINK=$(LD)
+
+ LIB_LINK_OPTIONS+=-Wl,--enable-stdcall-fixup
++LIB_PLATFORM_RPATH=
+
+ # Strip symbols from release versions to decrease size
+ ifeq ($(IsProdTypeBuild),Y)
+@@ -36,6 +37,9 @@
+ LIB_LINK_OPTIONS+=-Wl,-s
+ endif
+
++LIB_LINK_OPTIONS=
++LINK_OPTS=
++
+ # Generation of fbclient_ms.lib
+ LIB_LINK_IMPLIB:=-Wl,--out-implib,firebird/lib/fbclient_ms.lib
+ LIB_GUI:= -mwindows -lcomctl32 -lgdi32
+@@ -55,7 +59,8 @@
+ ClientLibrarySoName := $(ClientLibraryName)
+
+ # Looks like MinGW 3 does not support version scripts but support def-files
+-LINK_FIREBIRD_SYMBOLS = $(BLD_ROOT)/win32/defs/fbclient_s.def $(BLD_ROOT)/win32/defs/fbclient.def
++LINK_FIREBIRD_SYMBOLS = /def:$(BLD_ROOT)/win32/defs/fbclient_s.def /def:$(BLD_ROOT)/win32/defs/firebird.def
++LINK_PLUGIN_SYMBOLS = /def:$(BLD_ROOT)/win32/defs/plugin.def
+
+ # This is required for newly built executable to find newly built shared
+ # libraries because on Win32 there is no such thing as LD_LIBRARY_PATH
+--- builds/posix/make.shared.variables 2016-07-22 17:07:46.650672300 +0200
++++ builds/posix/make.shared.variables 2016-07-23 10:44:41.311454600 +0200
+@@ -56,6 +56,7 @@
+ Remote_Server:= $(call dirObjects,remote/server) $(call dirObjects,auth/SecureRemotePassword/server)
+ Remote_Client:= $(call dirObjects,remote/client) $(call dirObjects,auth/SecureRemotePassword/client) \
+ $(call makeObjects,auth/SecurityDatabase,LegacyClient.cpp) \
++ $(call dirObjects,auth/trusted) \
+ $(call dirObjects,plugins/crypt/arc4)
+ Remote_Server_Objects:= $(Remote_Common) $(Remote_Server)
+ Remote_Client_Objects:= $(Remote_Common) $(Remote_Client)
+diff -ur configure configure
+--- configure 2016-07-07 13:55:54.976234682 +0200
++++ configure 2016-07-07 14:54:30.012328812 +0200
+@@ -3337,6 +3337,14 @@
+ SHRLIB_EXT=dll
+ ;;
+
++ *-*-cygwin*)
++ MAKEFILE_PREFIX=mingw
++ PLATFORM=win32
++ EDITLINE_FLG=N
++ RAW_DEVICES_FLG=N
++ SHRLIB_EXT=dll
++ ;;
++
+ *)
+ as_fn_error $? "unsupported platform ${build}" "$LINENO" 5
+ ;;
+@@ -8432,6 +8432,9 @@
+ mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
++cygwin*)
++ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
++ ;;
+ esac
+
+ # Try without a prefix underscore, then with it.
+diff -ur extern/btyacc/main.c extern/btyacc/main.c
+--- extern/btyacc/main.c 2016-07-07 13:55:55.448234695 +0200
++++ extern/btyacc/main.c 2016-07-07 14:56:03.560331317 +0200
+@@ -2,7 +2,7 @@
+ #include <signal.h>
+ #include <stdio.h>
+
+-#if defined(WIN32)
++#if defined(WIN32) || defined(_WIN32)
+ #include <io.h>
+ #else
+ #include <unistd.h>
+diff -ur extern/btyacc/Makefile extern/btyacc/Makefile
+--- extern/btyacc/Makefile 2016-07-07 13:55:55.448234695 +0200
++++ extern/btyacc/Makefile 2016-07-07 14:57:42.284333961 +0200
+@@ -42,7 +42,10 @@
+ all: $(PROGRAM)
+
+ $(PROGRAM): $(OBJS) $(LIBS)
+- $(CC) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LIBS)
++ $(CC) -o $(PROGRAM).exe $(OBJS) $(LIBS) $(LDFLAGS)
++
++%.o: %.c
++ $(CC) -c $< -Fo$@ $(CCFLAGS)
+
+ clean:; rm -f $(OBJS)
+
+--- extern/cloop/src/tests/test1/CppTest.cpp 2016-07-07 15:56:27.948015300 +0200
++++ extern/cloop/src/tests/test1/CppTest.cpp 2016-07-13 18:58:48.529822600 +0200
+@@ -24,6 +24,7 @@
+ #include <stdio.h>
+ #include <assert.h>
+
++#define WIN32
+ #ifdef WIN32
+ #include <windows.h>
+ #define DLL_EXPORT __declspec(dllexport)
+--- extern/cloop/src/tests/test1/CTest.c 2016-07-07 15:56:27.611791300 +0200
++++ extern/cloop/src/tests/test1/CTest.c 2016-07-13 17:04:22.805090300 +0200
+@@ -23,6 +23,7 @@
+ #include <malloc.h>
+ #include <stdio.h>
+
++#define WIN32
+ #ifdef WIN32
+ #include <windows.h>
+ #define DLL_EXPORT __declspec(dllexport)
+--- extern/cloop/Makefile 2016-07-07 15:56:28.279136300 +0200
++++ extern/cloop/Makefile 2016-07-13 16:22:38.493479800 +0200
+@@ -11,8 +11,8 @@
+ SRC_DIR := src
+ BUILD_DIR := build
+ OUT_DIR := output
+-SHRLIB_EXT := .so
+-EXE_EXT :=
++SHRLIB_EXT := .dll
++EXE_EXT := .exe
+
+ OBJ_DIR := $(BUILD_DIR)/$(TARGET)
+ BIN_DIR := $(OUT_DIR)/$(TARGET)/bin
+@@ -27,7 +27,7 @@
+ OBJS_C := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRCS_C))
+ OBJS_CPP := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS_CPP))
+
+-C_FLAGS := -ggdb -fPIC -MMD -MP -W -Wall -Wno-unused-parameter
++C_FLAGS := -fPIC
+ CXX_FLAGS := $(C_FLAGS)
+ FPC_FLAGS := -Mdelphi
+
+@@ -53,7 +53,7 @@
+ .PHONY: all mkdirs clean
+
+ all: mkdirs \
+- $(BIN_DIR)/cloop \
++ $(BIN_DIR)/cloop$(EXE_EXT) \
+ $(BIN_DIR)/test1-c$(SHRLIB_EXT) \
+ $(BIN_DIR)/test1-c$(EXE_EXT) \
+ $(BIN_DIR)/test1-cpp$(SHRLIB_EXT) \
+@@ -74,7 +74,7 @@
+ -include $(addsuffix .d,$(basename $(OBJS_C)))
+ -include $(addsuffix .d,$(basename $(OBJS_CPP)))
+
+-$(BIN_DIR)/cloop: \
++$(BIN_DIR)/cloop$(EXE_EXT): \
+ $(OBJ_DIR)/cloop/Expr.o \
+ $(OBJ_DIR)/cloop/Generator.o \
+ $(OBJ_DIR)/cloop/Lexer.o \
+@@ -83,20 +83,20 @@
+
+ $(LD) $^ -o $@
+
+-$(SRC_DIR)/tests/test1/CalcCApi.h: $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl c-header $@ CALC_C_API_H CALC_I
++$(SRC_DIR)/tests/test1/CalcCApi.h: $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl c-header $@ CALC_C_API_H CALC_I
+
+-$(SRC_DIR)/tests/test1/CalcCApi.c: $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl $(SRC_DIR)/tests/test1/CalcCApi.h
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl c-impl $@ CalcCApi.h CALC_I
++$(SRC_DIR)/tests/test1/CalcCApi.c: $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl $(SRC_DIR)/tests/test1/CalcCApi.h
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl c-impl $@ CalcCApi.h CALC_I
+
+-$(SRC_DIR)/tests/test1/CalcCppApi.h: $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl c++ $@ CALC_CPP_API_H calc I
++$(SRC_DIR)/tests/test1/CalcCppApi.h: $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl c++ $@ CALC_CPP_API_H calc I
+
+-$(SRC_DIR)/tests/test1/CalcPascalApi.pas: $(BIN_DIR)/cloop \
++$(SRC_DIR)/tests/test1/CalcPascalApi.pas: $(BIN_DIR)/cloop$(EXE_EXT) \
+ $(SRC_DIR)/tests/test1/Interface.idl \
+ $(SRC_DIR)/tests/test1/CalcPascalApi.interface.pas \
+ $(SRC_DIR)/tests/test1/CalcPascalApi.implementation.pas
+- $(BIN_DIR)/cloop $(SRC_DIR)/tests/test1/Interface.idl pascal $@ CalcPascalApi \
++ $(BIN_DIR)/cloop$(EXE_EXT) $(SRC_DIR)/tests/test1/Interface.idl pascal $@ CalcPascalApi \
+ --uses "SysUtils" \
+ --interfaceFile $(SRC_DIR)/tests/test1/CalcPascalApi.interface.pas \
+ --implementationFile $(SRC_DIR)/tests/test1/CalcPascalApi.implementation.pas \
+@@ -108,23 +108,23 @@
+ $(OBJ_DIR)/tests/test1/CalcCApi.o \
+ $(OBJ_DIR)/tests/test1/CTest.o \
+
+- $(LD) $^ -shared -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-c$(EXE_EXT): \
+ $(OBJ_DIR)/tests/test1/CalcCApi.o \
+ $(OBJ_DIR)/tests/test1/CTest.o \
+
+- $(LD) $^ -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-cpp$(SHRLIB_EXT): \
+ $(OBJ_DIR)/tests/test1/CppTest.o \
+
+- $(LD) $^ -shared -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-cpp$(EXE_EXT): \
+ $(OBJ_DIR)/tests/test1/CppTest.o \
+
+- $(LD) $^ -ldl -o $@
++ $(LD) $^ -o $@
+
+ $(BIN_DIR)/test1-pascal$(SHRLIB_EXT): \
+ $(SRC_DIR)/tests/test1/PascalClasses.pas \
+diff -ur src/common/classes/fb_string.cpp src/common/classes/fb_string.cpp
+--- src/common/classes/fb_string.cpp 2016-07-07 13:55:56.064234711 +0200
++++ src/common/classes/fb_string.cpp 2016-07-07 14:59:01.516336083 +0200
+@@ -32,6 +32,12 @@
+ #include <ctype.h>
+ #include <stdarg.h>
+
++#ifdef WIN_NT
++#pragma comment(lib, "User32.lib")
++#pragma comment(lib, "advapi32")
++#pragma comment(lib, "shell32.lib")
++#endif
++
+ #ifdef HAVE_STRCASECMP
+ #define STRNCASECMP strncasecmp
+ #else
+diff -ur src/misc/makeHeader.cpp src/misc/makeHeader.cpp
+--- src/misc/makeHeader.cpp 2016-07-07 13:56:00.100234819 +0200
++++ src/misc/makeHeader.cpp 2016-07-07 15:00:14.780338045 +0200
+@@ -1,9 +1,9 @@
+ #include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+-//#ifdef HAVE_UNISTD_H
++#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+-//#endif
++#endif
+
+
+
diff --git a/external/firebird/firebird-gcc6.patch.1 b/external/firebird/firebird-gcc6.patch.1
new file mode 100644
index 000000000..e1361415c
--- /dev/null
+++ b/external/firebird/firebird-gcc6.patch.1
@@ -0,0 +1,19 @@
+commit 3618aa2171674babf79ef935aa049c40a3db1321
+Author: asfernandes <asfernandes@users.sourceforge.net>
+Date: Sat Mar 5 03:39:36 2016 +0000
+
+ Make the generated code compatible with gcc 6 in C++-14 mode.
+
+diff --git a/src/gpre/c_cxx.cpp b/src/gpre/c_cxx.cpp
+index 2af96c6..2dcffd6 100644
+--- a/src/gpre/c_cxx.cpp
++++ b/src/gpre/c_cxx.cpp
+@@ -2820,7 +2820,7 @@ static void gen_request(const gpre_req* request)
+ printa(0, "static %sshort\n isc_%dl = %d;",
+ (request->req_flags & REQ_extend_dpb) ? "" : CONST_STR,
+ request->req_ident, request->req_length);
+- printa(0, "static %schar\n isc_%d [] = {", CONST_STR, request->req_ident);
++ printa(0, "static %sunsigned char\n isc_%d [] = {", CONST_STR, request->req_ident);
+
+ const TEXT* string_type = "blr";
+ if (gpreGlob.sw_raw)
diff --git a/external/firebird/firebird-macosx.patch.1 b/external/firebird/firebird-macosx.patch.1
new file mode 100644
index 000000000..e379ca738
--- /dev/null
+++ b/external/firebird/firebird-macosx.patch.1
@@ -0,0 +1,132 @@
+--- firebird.org/extern/cloop/src/tests/test1/CTest.c 2016-08-01 22:55:35.000000000 +0200
++++ firebird/extern/cloop/src/tests/test1/CTest.c 2016-08-02 21:11:31.000000000 +0200
+@@ -20,7 +20,7 @@
+ */
+
+ #include "CalcCApi.h"
+-#include <malloc.h>
++#include <stdlib.h>
+ #include <stdio.h>
+
+ #ifdef WIN32
+--- firebird.org/builds/posix/prefix.darwin_x86_64 2016-08-01 20:02:48.000000000 +0200
++++ firebird/builds/posix/prefix.darwin_x86_64 2016-08-01 21:42:45.000000000 +0200
+@@ -19,8 +19,6 @@
+ #
+ # Default build from 10.7 using Clang
+
+-DYLD_LIBRARY_PATH=$(HOME)/icu54/icu/source/lib
+-export DYLD_LIBRARY_PATH
+
+ #DYLD_PRINT_ENV=1
+ #export DYLD_PRINT_ENV
+@@ -31,15 +31,15 @@
+ MACOSX_DEPLOYMENT_TARGET=10.7
+ export MACOSX_DEPLOYMENT_TARGET
+
+-PROD_FLAGS=-O1 -DDARWIN -pipe -MMD -fPIC -fno-common -mmacosx-version-min=10.7
+-DEV_FLAGS=-ggdb -DDARWIN -pipe -MMD -fPIC -fno-omit-frame-pointer -fno-common -Wall -fno-optimize-sibling-calls -mmacosx-version-min=10.7 -Wno-non-virtual-dtor
++PROD_FLAGS=-O1 -DDARWIN -pipe -MMD -fPIC -fno-common
++DEV_FLAGS=-ggdb -DDARWIN -pipe -MMD -fPIC -fno-omit-frame-pointer -fno-common -Wall -fno-optimize-sibling-calls -Wno-non-virtual-dtor
+ CXXFLAGS:=$(CXXFLAGS) -fvisibility-inlines-hidden -fvisibility=hidden
+
+ EXE_LINK_OPTIONS:=
+ UNDEF_PLATFORM=
+
+ LINK_LIBS+=-liconv
+-MATHLIB=/opt/local/lib/libtommath.a
++MATHLIB=-ltommath
+ SO_LINK_LIBS+=-liconv
+
+ include $(ROOT)/gen/darwin.defaults
+--- firebird.org/builds/posix/postfix.darwin 2016-08-01 20:02:48.000000000 +0200
++++ firebird/builds/posix/postfix.darwin 2016-08-01 22:17:49.000000000 +0200
+@@ -54,9 +54,9 @@
+ cp -r ../gen/firebird/include $(FB_FW)/Versions/A/Headers
+ cp ../gen/firebird/lib/libfbembed.dylib $(FB_FW)/Versions/A/Firebird
+ cp ../gen/firebird/lib/libfbclient.dylib $(FB_FW)/Versions/A/Libraries/libfbclient.dylib
+- cp ../gen/firebird/lib/libicudata.dylib $(FB_FW)/Versions/A/Libraries/libicudata.dylib
+- cp ../gen/firebird/lib/libicui18n.dylib $(FB_FW)/Versions/A/Libraries/libicui18n.dylib
+- cp ../gen/firebird/lib/libicuuc.dylib $(FB_FW)/Versions/A/Libraries/libicuuc.dylib
++# cp ../gen/firebird/lib/libicudata.dylib $(FB_FW)/Versions/A/Libraries/libicudata.dylib
++# cp ../gen/firebird/lib/libicui18n.dylib $(FB_FW)/Versions/A/Libraries/libicui18n.dylib
++# cp ../gen/firebird/lib/libicuuc.dylib $(FB_FW)/Versions/A/Libraries/libicuuc.dylib
+ cp ../gen/firebird/lib/libib_util.dylib $(FB_FW)/Versions/A/Libraries/libib_util.dylib
+ cp ../gen/firebird/firebird.msg \
+ $(FB_FW)/Resources/English.lproj/var/firebird.msg
+@@ -68,8 +68,8 @@
+ $(FB_FW)/Resources/English.lproj/var/intl/fbintl.conf
+ chmod a+rx $(FB_FW)/Resources/English.lproj/var/intl/fbintl
+ mkdir -p $(FB_FW)/Resources/English.lproj/var/plugins
+- cp ../gen/firebird/plugins/libfbtrace.dylib \
+- $(FB_FW)/Resources/English.lproj/var/plugins/libfbtrace.dylib
++# cp ../gen/firebird/plugins/libfbtrace.dylib \
++# $(FB_FW)/Resources/English.lproj/var/plugins/libfbtrace.dylib
+ cp -r ../gen/firebird/help $(FB_FW)/Resources/English.lproj/var/help
+ cp ../gen/firebird/security2.fdb $(FB_FW)/Resources/English.lproj/var
+ mkdir -p $(FB_FW)/Resources/doc
+--- firebird.org/builds/posix/Makefile.in 2016-08-08 17:58:20.000000000 +0200
++++ firebird/builds/posix/Makefile.in 2016-08-08 17:57:17.000000000 +0200
+@@ -191,6 +191,9 @@
+ $(MAKE) plugins
+ $(MAKE) examples
+ $(MAKE) rest
++ install_name_tool -id @__________________________________________________OOO/libfbclient.dylib.3.0.0 $(LIB)/libfbclient.dylib
++ install_name_tool -id @__________________________________________________OOO/libEngine12.dylib $(PLUGINS)/libEngine12.dylib
++ install_name_tool -change $(LIB)/libfbclient.dylib.3.0.0 @loader_path/libfbclient.dylib.3.0.0 $(PLUGINS)/libEngine12.dylib
+
+
+ cross_process:
+--- firebird.org/src/common/unicode_util.cpp 2016-07-07 13:55:55.992234709 +0200
++++ firebird/src/common/unicode_util.cpp 2016-08-10 11:25:46.422331020 +0200
+@@ -63,8 +63,8 @@
+ #elif defined(DARWIN)
+ //const char* const inTemplate = "/Library/Frameworks/Firebird.framework/Versions/A/Libraries/libicui18n.dylib";
+ //const char* const ucTemplate = "/Library/Frameworks/Firebird.framework/versions/A/Libraries/libicuuc.dylib";
+-const char* const inTemplate = "libicui18n.dylib";
+-const char* const ucTemplate = "libicuuc.dylib";
++const char* const inTemplate = "libicui18n.dylib.%s";
++const char* const ucTemplate = "libicuuc.dylib.%s";
+ #elif defined(HPUX)
+ const char* const inTemplate = "libicui18n.sl.%s";
+ const char* const ucTemplate = "libicuuc.sl.%s";
+@@ -353,6 +353,16 @@
+ s.printf("%d%d", majorVersion, minorVersion);
+
+ filename.printf(templateName, s.c_str());
++ const char * envpath = getenv("LIBREOFFICE_FIREBIRD_LIB");
++ if(envpath == nullptr)
++ {
++ envpath = getenv("LIBREOFFICE_ICU_LIB");
++ }
++ if(envpath != nullptr)
++ {
++ s = filename.c_str();
++ PathUtils::concatPath(filename, envpath, s.c_str());
++ }
+ }
+
+
+--- firebird.org/src/common/utils.cpp 2016-08-16 10:11:10.000000000 +0200
++++ firebird/src/common/utils.cpp 2016-08-16 11:27:09.000000000 +0200
+@@ -1027,10 +1027,18 @@
+ return s;
+ }
+
+- // Set relative path to Engine12 dynamic library
++ // Set path to Engine12 dynamic library.
+ if(prefType == Firebird::IConfigManager::DIR_PLUGINS)
+ {
+- s = name;
++ const char * const envpath = getenv("LIBREOFFICE_FIREBIRD_LIB");
++ if(envpath != nullptr)
++ {
++ PathUtils::concatPath(s, envpath, name);
++ }
++ else
++ {
++ s = name;
++ }
+ return s;
+ }
+ }
diff --git a/external/firebird/firebird-rpath.patch.0 b/external/firebird/firebird-rpath.patch.0
new file mode 100644
index 000000000..a730e72a8
--- /dev/null
+++ b/external/firebird/firebird-rpath.patch.0
@@ -0,0 +1,11 @@
+--- builds/posix/make.defaults
++++ builds/posix/make.defaults
+@@ -279,7 +279,7 @@
+
+ ifeq (@USE_RPATH@,1)
+ ifeq ($(strip @BINRELOC_CFLAGS@),)
+- LIB_LINK_RPATH = $(call LIB_PLATFORM_RPATH,$(if $(subst intl,,$(1)),@FB_LIBDIR@,@FB_INTLDIR@))
++ LIB_LINK_RPATH = $(call LIB_PLATFORM_RPATH,'$$ORIGIN')
+ else
+ LIB_LINK_RPATH = $(call LIB_PLATFORM_RPATH,'$$ORIGIN/../$(1)')
+ endif
diff --git a/external/firebird/firebird-tdf125284.patch.1 b/external/firebird/firebird-tdf125284.patch.1
new file mode 100644
index 000000000..a1cb2043e
--- /dev/null
+++ b/external/firebird/firebird-tdf125284.patch.1
@@ -0,0 +1,27 @@
+--- firebird/src/common/config/config_file.cpp 2019-08-23 16:42:26.721439468 +0100
++++ firebird/src/common/config/config_file.cpp 2019-08-23 16:43:07.506579222 +0100
+@@ -521,16 +521,14 @@
+ unsigned code;
+ const char* name;
+ } dirs[] = {
+-#define NMDIR(a) {Firebird::IConfigManager::a, "FB_"#a},
+- NMDIR(DIR_CONF)
+- NMDIR(DIR_SECDB)
+- NMDIR(DIR_PLUGINS)
+- NMDIR(DIR_UDF)
+- NMDIR(DIR_SAMPLE)
+- NMDIR(DIR_SAMPLEDB)
+- NMDIR(DIR_INTL)
+- NMDIR(DIR_MSG)
+-#undef NMDIR
++ {Firebird::IConfigManager::DIR_CONF, "FB_dir_conf"},
++ {Firebird::IConfigManager::DIR_SECDB, "FB_dir_secdb"},
++ {Firebird::IConfigManager::DIR_PLUGINS, "FB_dir_plugins"},
++ {Firebird::IConfigManager::DIR_UDF, "FB_dir_udf"},
++ {Firebird::IConfigManager::DIR_SAMPLE, "FB_dir_sample"},
++ {Firebird::IConfigManager::DIR_SAMPLEDB, "FB_dir_sampledb"},
++ {Firebird::IConfigManager::DIR_INTL, "FB_dir_intl"},
++ {Firebird::IConfigManager::DIR_MSG, "FB_dir_msg"},
+ {Firebird::IConfigManager::DIR_COUNT, NULL}
+ };
+
diff --git a/external/firebird/firebird-vs2017.patch.1 b/external/firebird/firebird-vs2017.patch.1
new file mode 100644
index 000000000..609f380a3
--- /dev/null
+++ b/external/firebird/firebird-vs2017.patch.1
@@ -0,0 +1,11 @@
+diff -ru firebird.orig/src/common/os/win32/mod_loader.cpp firebird/src/common/os/win32/mod_loader.cpp
+--- firebird.orig/src/common/os/win32/mod_loader.cpp 2017-02-15 22:11:48.939042400 +0100
++++ firebird/src/common/os/win32/mod_loader.cpp 2017-02-15 22:12:30.062262700 +0100
+@@ -103,6 +103,6 @@
+ "msvcr120.dll",
+-#elif _MSC_VER == 1900
++#elif _MSC_VER >= 1900 && _MSC_VER < 2000
+ "vcruntime140.dll",
+ #else
+ #error Specify CRT DLL name here !
+ #endif
diff --git a/external/firebird/firebird.disable-ib-util-not-found.patch.1 b/external/firebird/firebird.disable-ib-util-not-found.patch.1
new file mode 100644
index 000000000..86dedd0dd
--- /dev/null
+++ b/external/firebird/firebird.disable-ib-util-not-found.patch.1
@@ -0,0 +1,17 @@
+--- firebird.org/src/jrd/fun.epp 2015-01-23 22:11:26.751475044 +0100
++++ firebird/src/jrd/fun.epp 2015-01-23 22:16:42.507322568 +0100
+@@ -164,10 +164,14 @@
+ if (tryLibrary(LIBNAME, message[3]))
+ return;
+
++ /* fdo#72543: quote from https://bugs.freedesktop.org/show_bug.cgi?id=72543#c8
++ "we don't need UDF support for embedded firebird,
++ hence the lack of ib_util isn't an issue and can safely be ignored"
+ // all failed - log error
+ gds__log("ib_util init failed, UDFs can't be used - looks like firebird misconfigured\n"
+ "\t%s\n\t%s\n\t%s\n\t%s", message[0].c_str(), message[1].c_str(),
+ message[2].c_str(), message[3].c_str());
++ */
+ }
+
+ void* IbUtil::alloc(long size)
diff --git a/external/firebird/libc++.patch b/external/firebird/libc++.patch
new file mode 100644
index 000000000..270c0772a
--- /dev/null
+++ b/external/firebird/libc++.patch
@@ -0,0 +1,11 @@
+--- src/common/classes/FpeControl.h
++++ src/common/classes/FpeControl.h
+@@ -222,7 +222,7 @@
+ {
+ return (!_finite (x) && !isnan(x));
+ }
+-#else
++#elif !defined _LIBCPP_VERSION || _LIBCPP_VERSION < 3900
+ #ifndef isinf
+ template <typename F>
+ inline bool isinf(F x)
diff --git a/external/firebird/macosx-elcapitan-dyld.patch b/external/firebird/macosx-elcapitan-dyld.patch
new file mode 100644
index 000000000..134cdd974
--- /dev/null
+++ b/external/firebird/macosx-elcapitan-dyld.patch
@@ -0,0 +1,58 @@
+--- examples/empbuild/empbuild.e
++++ examples/empbuild/empbuild.e
+@@ -64,7 +64,7 @@
+ * Functional description
+ *
+ **************************************/
+-TEXT cmd [140];
++TEXT cmd [8000];
+
+ if (argc > 1)
+ strcpy (Db_name, argv[1]);
+@@ -94,7 +94,9 @@
+ }
+
+ printf ("Turning forced writes off\n");
++char const * lp = getenv("DYLD_LIBRARY_PATH");
++if (!lp) lp = "";
+-sprintf (cmd, "gfix -write async %s", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s gfix -write async %s", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't turn forced writes off\n");
+@@ -104,7 +106,7 @@
+ }
+
+ printf ("Creating tables\n");
+-sprintf (cmd, "isql %s -q -i empddl.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -q -i empddl.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't create tables \n");
+@@ -120,7 +122,7 @@
+ }
+
+ printf ("Turning off indices and triggers \n");
+-sprintf (cmd, "isql %s -i indexoff.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -i indexoff.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't turn off indices and triggers \n");
+@@ -128,7 +130,7 @@
+ }
+
+ printf ("Loading column data\n");
+-sprintf (cmd, "isql %s -i empdml.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -i empdml.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't load column data \n");
+@@ -136,7 +138,7 @@
+ }
+
+ printf ("Turning on indices and triggers \n");
+-sprintf (cmd, "isql %s -i indexon.sql", Db_name);
++sprintf (cmd, "DYLD_LIBRARY_PATH=%s isql %s -i indexon.sql", lp, Db_name);
+ if (system (cmd))
+ {
+ printf ("Couldn't turn on indices and triggers \n");
diff --git a/external/firebird/sanitizer.patch b/external/firebird/sanitizer.patch
new file mode 100644
index 000000000..e727d581e
--- /dev/null
+++ b/external/firebird/sanitizer.patch
@@ -0,0 +1,80 @@
+--- builds/posix/fbintl.vers
++++ builds/posix/fbintl.vers
+@@ -29,3 +29,4 @@
+ LD_lookup_texttype
+ LD_setup_attributes
+ LD_version
++_ZTI*
+--- builds/posix/fbplugin.vers
++++ builds/posix/fbplugin.vers
+@@ -26,3 +26,4 @@
+ #
+
+ firebird_plugin
++_ZTI*
+--- builds/posix/firebird.vers
++++ builds/posix/firebird.vers
+@@ -367,3 +367,4 @@
+
+ KEYWORD_stringIsAToken
+ KEYWORD_getTokens
++_ZTI*
+--- builds/posix/make.defaults
++++ builds/posix/make.defaults
+@@ -252,7 +252,7 @@
+ # LINKER OPTIONS
+ #
+
+-UNDEF_PLATFORM = -Wl,--no-undefined
++UNDEF_PLATFORM =
+ ifeq ($(TARGET),Debug)
+ UNDEF_FLAGS = $(UNDEF_PLATFORM)
+ endif
+@@ -291,7 +291,7 @@
+ LIB_LINK_MAPFILE= -Wl,--version-script,$(1)
+ FIREBIRD_LIBRARY_LINK= -L$(LIB) -lfbclient $(MATHLIB)
+
+-EXE_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) $(UNDEF_FLAGS) $(LIB_PATH_OPTS) $(LINK_EMPTY_SYMBOLS)
++EXE_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) $(UNDEF_FLAGS) $(LIB_PATH_OPTS)
+ LIB_LINK_OPTIONS= $(LDFLAGS) $(THR_FLAGS) -shared
+
+ FB_DAEMON = $(BIN)/firebird$(EXEC_EXT)
+--- src/common/classes/alloc.cpp
++++ src/common/classes/alloc.cpp
+@@ -2535,7 +2535,7 @@
+ const char* myStack = &probeVar;
+ const char* thisLocation = (const char*) this;
+ ptrdiff_t distance = thisLocation - myStack;
+- fb_assert(absVal(distance) < 128 * 1024);
++ //fb_assert(absVal(distance) < 128 * 1024);
+ }
+ #endif
+
+--- src/common/os/posix/mod_loader.cpp
++++ src/common/os/posix/mod_loader.cpp
+@@ -88,7 +88,7 @@
+
+ ModuleLoader::Module* ModuleLoader::loadModule(const Firebird::PathName& modPath)
+ {
+- void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE);
++ void* module = dlopen(modPath.nullStr(), FB_RTLD_MODE | RTLD_GLOBAL);
+ if (module == NULL)
+ {
+ #ifdef DEV_BUILD
+--- src/jrd/met.epp
++++ src/jrd/met.epp
+@@ -1486,10 +1486,11 @@
+ USHORT offset = p[0] | (p[1] << 8);
+ p += 2;
+
+- const Ods::Descriptor* odsDflDesc = (Ods::Descriptor*) p;
+- p = (UCHAR*) (odsDflDesc + 1);
++ Ods::Descriptor odsDflDesc;
++ memcpy(&odsDflDesc, p, sizeof (Ods::Descriptor));
++ p = (UCHAR*) (((Ods::Descriptor*) p) + 1);
+
+- dsc desc = *odsDflDesc;
++ dsc desc = odsDflDesc;
+ desc.dsc_address = const_cast<UCHAR*>(p);
+ EVL_make_value(tdbb, &desc, &format->fmt_defaults[offset], relation->rel_pool);
+
diff --git a/external/firebird/ubsan.patch b/external/firebird/ubsan.patch
new file mode 100644
index 000000000..5fe298539
--- /dev/null
+++ b/external/firebird/ubsan.patch
@@ -0,0 +1,287 @@
+--- configure
++++ configure
+@@ -21349,7 +21349,7 @@
+ char a;
+ long long b;
+ };
+- exit((int)&((struct s*)0)->b);
++ exit((int)&((struct s*)1024)->b - 1024);
+ }
+ _ACEOF
+ if ac_fn_c_try_run "$LINENO"; then :
+@@ -21384,7 +21384,7 @@
+ char a;
+ double b;
+ };
+- exit((int)&((struct s*)0)->b);
++ exit((int)&((struct s*)1024)->b - 1024);
+ }
+ _ACEOF
+ if ac_fn_c_try_run "$LINENO"; then :
+--- src/common/classes/array.h
++++ src/common/classes/array.h
+@@ -149,7 +149,7 @@
+ void copyFrom(const Array<T, Storage>& source)
+ {
+ ensureCapacity(source.count, false);
+- memcpy(data, source.data, sizeof(T) * source.count);
++ if (source.count != 0) memcpy(data, source.data, sizeof(T) * source.count);
+ count = source.count;
+ }
+
+@@ -227,7 +227,7 @@
+ fb_assert(count <= FB_MAX_SIZEOF - itemsCount);
+ ensureCapacity(count + itemsCount);
+ memmove(data + index + itemsCount, data + index, sizeof(T) * (count - index));
+- memcpy(data + index, items, sizeof(T) * itemsCount);
++ if (itemsCount != 0) memcpy(data + index, items, sizeof(T) * itemsCount);
+ count += itemsCount;
+ }
+
+@@ -242,7 +242,7 @@
+ {
+ fb_assert(count <= FB_MAX_SIZEOF - itemsCount);
+ ensureCapacity(count + itemsCount);
+- memcpy(data + count, items, sizeof(T) * itemsCount);
++ if (itemsCount != 0) memcpy(data + count, items, sizeof(T) * itemsCount);
+ count += itemsCount;
+ }
+
+@@ -294,7 +294,7 @@
+ {
+ fb_assert(newCount >= count);
+ ensureCapacity(newCount);
+- memset(data + count, 0, sizeof(T) * (newCount - count));
++ if (newCount != count) memset(data + count, 0, sizeof(T) * (newCount - count));
+ count = newCount;
+ }
+
+@@ -328,7 +328,7 @@
+ {
+ fb_assert(count <= FB_MAX_SIZEOF - L.count);
+ ensureCapacity(count + L.count);
+- memcpy(data + count, L.data, sizeof(T) * L.count);
++ if (L.count != 0) memcpy(data + count, L.data, sizeof(T) * L.count);
+ count += L.count;
+ }
+
+@@ -462,7 +462,7 @@
+
+ T* newdata = static_cast<T*>
+ (this->getPool().allocate(sizeof(T) * newcapacity ALLOC_ARGS));
+- if (preserve)
++ if (preserve && count != 0)
+ memcpy(newdata, data, sizeof(T) * count);
+ freeData();
+ data = newdata;
+--- src/common/classes/fb_string.h
++++ src/common/classes/fb_string.h
+@@ -674,7 +674,8 @@
+ }
+ StringType& assign(const void* s, size_type n)
+ {
+- memcpy(baseAssign(n), s, n);
++ auto const p = baseAssign(n);
++ if (n != 0) memcpy(p, s, n);
+ return *this;
+ }
+ StringType& assign(const_pointer s)
+--- src/common/unicode_util.cpp
++++ src/common/unicode_util.cpp
+@@ -187,7 +187,7 @@
+ Mutex ciAiTransCacheMutex;
+ Array<UTransliterator*> ciAiTransCache;
+
+- void (U_EXPORT2 *uVersionToString)(UVersionInfo versionArray, char* versionString);
++ void (U_EXPORT2 *uVersionToString)(UVersionInfo const versionArray, char* versionString);
+
+ int32_t (U_EXPORT2 *ulocCountAvailable)();
+ const char* (U_EXPORT2 *ulocGetAvailable)(int32_t n);
+--- src/dsql/StmtNodes.cpp
++++ src/dsql/StmtNodes.cpp
+@@ -6643,7 +6643,7 @@
+
+ void StoreNode::genBlr(DsqlCompilerScratch* dsqlScratch)
+ {
+- const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse->as<RseNode>());
++ const dsql_msg* message = dsqlGenDmlHeader(dsqlScratch, dsqlRse == nullptr ? nullptr : dsqlRse->as<RseNode>());
+
+ dsqlScratch->appendUChar(statement2 ? blr_store2 : blr_store);
+ GEN_expr(dsqlScratch, dsqlRelation);
+--- src/gpre/hsh.cpp
++++ src/gpre/hsh.cpp
+@@ -232,7 +232,7 @@
+ {
+ SCHAR c;
+
+- SLONG value = 0;
++ ULONG value = 0;
+
+ while (c = *string++)
+ value = (value << 1) + UPPER(c);
+--- src/jrd/GlobalRWLock.cpp
++++ src/jrd/GlobalRWLock.cpp
+@@ -78,7 +78,7 @@
+
+ cachedLock = FB_NEW_RPT(getPool(), lockLen)
+ Lock(tdbb, lockLen, lckType, this, lockCaching ? blocking_ast_cached_lock : NULL);
+- memcpy(&cachedLock->lck_key, lockStr, lockLen);
++ if (lockLen != 0) memcpy(&cachedLock->lck_key, lockStr, lockLen);
+ }
+
+ GlobalRWLock::~GlobalRWLock()
+--- src/jrd/Optimizer.cpp
++++ src/jrd/Optimizer.cpp
+@@ -368,7 +368,7 @@
+
+ // Allocate needed indexScratches
+
+- index_desc* idx = csb_tail->csb_idx->items;
++ index_desc* idx = csb_tail->csb_idx == nullptr ? nullptr : csb_tail->csb_idx->items;
+ for (int i = 0; i < csb_tail->csb_indices; ++i, ++idx)
+ indexScratches.add(IndexScratch(p, tdbb, idx, csb_tail));
+ }
+--- src/jrd/blb.cpp
++++ src/jrd/blb.cpp
+@@ -1786,7 +1786,7 @@
+ arg.slice_base = array->arr_data;
+
+ SLONG variables[64];
+- memcpy(variables, param, MIN(sizeof(variables), param_length));
++ if (param_length != 0) memcpy(variables, param, MIN(sizeof(variables), param_length));
+
+ if (SDL_walk(tdbb->tdbb_status_vector, sdl, array->arr_data, &array_desc->arr_desc,
+ variables, slice_callback, &arg))
+--- src/jrd/btn.cpp
++++ src/jrd/btn.cpp
+@@ -387,7 +387,7 @@
+
+ put_short(pagePointer, offset);
+ pagePointer += sizeof(USHORT);
+- memmove(pagePointer, data, length);
++ if (length != 0) memmove(pagePointer, data, length);
+ pagePointer += length;
+ return pagePointer;
+ }
+@@ -622,7 +622,7 @@
+ }
+
+ // Store data
+- if (withData) {
++ if (withData && length != 0) {
+ memcpy(pagePointer, data, length);
+ }
+ pagePointer += length;
+--- src/jrd/btr.cpp
++++ src/jrd/btr.cpp
+@@ -5206,7 +5206,7 @@
+ // Push node on end in list
+ jumpNodes->add(jumpNode);
+ // Store new data in jumpKey, so a new jump node can calculate prefix
+- memcpy(jumpData + jumpNode.prefix, jumpNode.data, jumpNode.length);
++ if (jumpNode.length != 0) memcpy(jumpData + jumpNode.prefix, jumpNode.data, jumpNode.length);
+ jumpLength = jumpNode.length + jumpNode.prefix;
+
+ // Check if this could be our split point (if we need to split)
+@@ -5391,7 +5391,7 @@
+ // First, store needed data for beforeInsertNode into tempData.
+ HalfStaticArray<UCHAR, MAX_KEY> tempBuf;
+ UCHAR* tempData = tempBuf.getBuffer(newLength);
+- memcpy(tempData, beforeInsertNode.data + newPrefix - beforeInsertNode.prefix, newLength);
++ if (newLength != 0) memcpy(tempData, beforeInsertNode.data + newPrefix - beforeInsertNode.prefix, newLength);
+
+ beforeInsertNode.prefix = newPrefix;
+ beforeInsertNode.length = newLength;
+@@ -5611,7 +5611,7 @@
+ for (size_t i = 0; i < jumpNodes->getCount(); i++, index++)
+ {
+ UCHAR* q = new_key->key_data + walkJumpNode[i].prefix;
+- memcpy(q, walkJumpNode[i].data, walkJumpNode[i].length);
++ if (walkJumpNode[i].length != 0) memcpy(q, walkJumpNode[i].data, walkJumpNode[i].length);
+ if (index == splitJumpNodeIndex)
+ {
+ jn = &walkJumpNode[i];
+@@ -5636,7 +5636,7 @@
+ const USHORT length = walkJumpNode[i].prefix + walkJumpNode[i].length;
+ UCHAR* newData = FB_NEW_POOL(*tdbb->getDefaultPool()) UCHAR[length];
+ memcpy(newData, new_key->key_data, walkJumpNode[i].prefix);
+- memcpy(newData + walkJumpNode[i].prefix, walkJumpNode[i].data,
++ if (walkJumpNode[i].length != 0) memcpy(newData + walkJumpNode[i].prefix, walkJumpNode[i].data,
+ walkJumpNode[i].length);
+ delete[] walkJumpNode[i].data;
+ walkJumpNode[i].prefix = 0;
+--- src/jrd/evl.cpp
++++ src/jrd/evl.cpp
+@@ -415,7 +415,7 @@
+ case dtype_real:
+ case dtype_sql_time:
+ case dtype_sql_date:
+- value->vlu_misc.vlu_long = *((SLONG*) from.dsc_address);
++ memcpy(&value->vlu_misc.vlu_long, from.dsc_address, sizeof (SLONG));
+ return;
+
+ case dtype_int64:
+--- src/jrd/lck.cpp
++++ src/jrd/lck.cpp
+@@ -488,7 +488,7 @@
+ break;
+ }
+
+- dbb->dbb_lock_mgr->shutdownOwner(tdbb, owner_handle_ptr);
++ LockManager::shutdownOwner(dbb->dbb_lock_mgr, tdbb, owner_handle_ptr);
+ }
+
+
+--- src/lock/lock.cpp
++++ src/lock/lock.cpp
+@@ -441,7 +441,7 @@
+ }
+
+
+-void LockManager::shutdownOwner(thread_db* tdbb, SRQ_PTR* owner_handle)
++void LockManager::shutdownOwner(LockManager* This, thread_db* tdbb, SRQ_PTR* owner_handle)
+ {
+ /**************************************
+ *
+@@ -460,8 +460,9 @@
+ if (!owner_offset)
+ return;
+
+- LockTableGuard guard(this, FB_FUNCTION, owner_offset);
++ LockTableGuard guard(This, FB_FUNCTION, owner_offset);
+
++#define SRQ_BASE ((UCHAR*) This->m_sharedMemory->getHeader())
+ own* owner = (own*) SRQ_ABS_PTR(owner_offset);
+ if (!owner->own_count)
+ return;
+@@ -472,7 +473,7 @@
+ while (owner->own_ast_count)
+ {
+ { // checkout scope
+- LockTableCheckout checkout(this, FB_FUNCTION);
++ LockTableCheckout checkout(This, FB_FUNCTION);
+ EngineCheckout cout(tdbb, FB_FUNCTION, true);
+ Thread::sleep(10);
+ }
+@@ -484,8 +485,9 @@
+ // released before destroying the lock owner. This is not strictly required,
+ // but it enforces the proper object lifetime discipline through the codebase.
+ fb_assert(SRQ_EMPTY(owner->own_requests));
++#define SRQ_BASE ((UCHAR*) m_sharedMemory->getHeader())
+
+- purge_owner(owner_offset, owner);
++ This->purge_owner(owner_offset, owner);
+
+ *owner_handle = 0;
+ }
+--- src/lock/lock_proto.h
++++ src/lock/lock_proto.h
+@@ -402,7 +402,7 @@
+ static void destroy(LockManager*);
+
+ bool initializeOwner(Firebird::CheckStatusWrapper*, LOCK_OWNER_T, UCHAR, SRQ_PTR*);
+- void shutdownOwner(thread_db*, SRQ_PTR*);
++ static void shutdownOwner(LockManager* This, thread_db*, SRQ_PTR*);
+
+ SRQ_PTR enqueue(thread_db*, Firebird::CheckStatusWrapper*, SRQ_PTR, const USHORT,
+ const UCHAR*, const USHORT, UCHAR, lock_ast_t, void*, SINT64, SSHORT, SRQ_PTR);
diff --git a/external/firebird/wnt-dbgutil.patch b/external/firebird/wnt-dbgutil.patch
new file mode 100644
index 000000000..db859b64f
--- /dev/null
+++ b/external/firebird/wnt-dbgutil.patch
@@ -0,0 +1,63 @@
+--- configure
++++ configure
+@@ -18402,44 +18402,6 @@
+ fi
+
+
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -licuuc" >&5
+-$as_echo_n "checking for main in -licuuc... " >&6; }
+-if ${ac_cv_lib_icuuc_main+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
+- ac_check_lib_save_LIBS=$LIBS
+-LIBS="-licuuc $LIBS"
+-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-
+-int
+-main ()
+-{
+-return main ();
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+- ac_cv_lib_icuuc_main=yes
+-else
+- ac_cv_lib_icuuc_main=no
+-fi
+-rm -f core conftest.err conftest.$ac_objext \
+- conftest$ac_exeext conftest.$ac_ext
+-LIBS=$ac_check_lib_save_LIBS
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_icuuc_main" >&5
+-$as_echo "$ac_cv_lib_icuuc_main" >&6; }
+-if test "x$ac_cv_lib_icuuc_main" = xyes; then :
+- ICU_OK=yes
+-else
+- as_fn_error $? "ICU support not found - please install development ICU package" "$LINENO" 5
+-fi
+-
+-
+-
+ pre_save_restore_cflags=$CFLAGS
+ pre_save_restore_cxxflags=$CXXFLAGS
+ pre_save_restore_libs=$LIBS
+--- src/common/unicode_util.cpp
++++ src/common/unicode_util.cpp
+@@ -58,8 +58,13 @@
+
+ namespace {
+ #if defined(WIN_NT)
++#if defined(MSVC_USE_DEBUG_RUNTIME)
++const char* const inTemplate = "icuind%s.dll";
++const char* const ucTemplate = "icuucd%s.dll";
++#else
+ const char* const inTemplate = "icuin%s.dll";
+ const char* const ucTemplate = "icuuc%s.dll";
++#endif
+ #elif defined(DARWIN)
+ //const char* const inTemplate = "/Library/Frameworks/Firebird.framework/Versions/A/Libraries/libicui18n.dylib";
+ //const char* const ucTemplate = "/Library/Frameworks/Firebird.framework/versions/A/Libraries/libicuuc.dylib";