Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 mono (3.2.3+dfsg-3) experimental; urgency=low
 .
   * [2b7198e] Fix buggy Replaces section on
     libmono-system-windows-forms-datavisualization4.0a-cil package
     (Closes: #728340)
   * [8a07907] There is a bug in the silicon on Loongson 2E and 2F
     processors, which can cause the traditional NOP instruction
     (which doesn't exist on MIPS but is an alias to 'sll 0,0,0')
     to fail intermittently under high load. This is worked around
     in binutils
     (https://sourceware.org/ml/binutils/2009-11/msg00387.html) but
     that only applies to software compiled via binutils, not via a
     JITter like Mono. The fix uses a different no-op instruction
     which does not trigger the CPU bug. Thanks to Alex Rønne
     Petersen for his help.
Author: Jo Shields <directhex@apebox.org>
Bug-Debian: http://bugs.debian.org/728340

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- mono-3.2.3+dfsg.orig/configure.in
+++ mono-3.2.3+dfsg/configure.in
@@ -143,6 +143,17 @@ case "$host" in
 		with_sigaltstack=no
 		use_sigposix=yes
 		;;
+	*-*-kfreebsd*-gnu)
+		platform_win32=no
+		CPPFLAGS="$CPPFLAGS -DGC_FREEBSD_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP -DTHREAD_LOCAL_ALLOC -pthread"
+		libmono_cflags="-D_REENTRANT -DTHREAD_LOCAL_ALLOC -pthread"
+		libmono_ldflags="-lpthread -pthread"
+		libdl="-ldl"
+		libgc_threads=pthreads
+		need_link_unlink=yes
+		with_sigaltstack=no
+		use_sigposix=yes
+		;;
 	*-*-*freebsd*)
 		host_win32=no
 		if test "x$PTHREAD_CFLAGS" = "x"; then
@@ -2508,7 +2519,7 @@ case "$host" in
 			sgen_supported=true
 			AOT_SUPPORTED="yes"
 			;;
-		  darwin*|openbsd*|freebsd*)
+		  darwin*|openbsd*|freebsd*|kfreebsd-gnu*)
 			sgen_supported=true
 		        ;;
 		esac
@@ -2526,7 +2537,7 @@ case "$host" in
 			sgen_supported=true
 			AOT_SUPPORTED="yes"
 			;;
-		  darwin*|openbsd*|freebsd*)
+		  darwin*|openbsd*|freebsd*|kfreebsd-gnu*)
 			sgen_supported=true
 			;;
 		esac
@@ -2769,7 +2780,7 @@ esac
 dnl Use GCC atomic ops if they work on the target.
 if test x$GCC = "xyes"; then
 	case $TARGET in
-	X86 | AMD64 | ARM | POWERPC | POWERPC64 | MIPS)
+	X86 | AMD64 | ARM | POWERPC | POWERPC64 | MIPS | S390X)
 		AC_DEFINE(USE_GCC_ATOMIC_OPS, 1, [...])
 		;;
 	esac
@@ -2882,6 +2893,11 @@ case "$host" in
 	LIBC="libc.so.12"
 	INTL="libintl.so.0"
 	;;
+     *-*-kfreebsd*-gnu)
+	LIBC="libc.so.0.1"
+	INTL="libc.so.0.1"
+	X11="libX11.so.6"
+	;;
     *-*-*freebsd*)
     	LIBC="libc.so"
 	INTL="libintl.so"
--- mono-3.2.3+dfsg.orig/Makefile.am
+++ mono-3.2.3+dfsg/Makefile.am
@@ -3,7 +3,7 @@ ACLOCAL_AMFLAGS = -I m4
 MONOTOUCH_SUBDIRS = $(libgc_dir) eglib/src mono
 
 if CROSS_COMPILING
-SUBDIRS = po $(libgc_dir) eglib mono $(ikvm_native_dir) data runtime scripts man samples msvc $(docs_dir)
+SUBDIRS = po $(libgc_dir) eglib mono $(ikvm_native_dir) data runtime scripts man samples msvc
 # Keep in sync with SUBDIRS
 ## 'tools' is not normally built
 DIST_SUBDIRS = m4 po libgc eglib mono ikvm-native data runtime scripts man samples tools msvc docs
@@ -11,7 +11,7 @@ else
 if ONLY_MONOTOUCH
 SUBDIRS = $(MONOTOUCH_SUBDIRS) runtime
 else
-SUBDIRS = po $(libgc_dir) eglib mono $(ikvm_native_dir) support data runtime scripts man samples msvc $(docs_dir)
+SUBDIRS = po $(libgc_dir) eglib mono $(ikvm_native_dir) support data runtime scripts man samples msvc
 # Keep in sync with SUBDIRS
 ## 'tools' is not normally built
 DIST_SUBDIRS = m4 po libgc eglib mono ikvm-native support data runtime scripts man samples tools msvc docs
--- mono-3.2.3+dfsg.orig/support/syslog.c
+++ mono-3.2.3+dfsg/support/syslog.c
@@ -38,7 +38,16 @@ Mono_Posix_Syscall_closelog (void)
 int
 Mono_Posix_Syscall_syslog (int priority, const char* message)
 {
+#ifdef __GNUC__
+	#pragma GCC diagnostic push
+	#pragma GCC diagnostic ignored "-Wformat-security"
+#endif
+
 	syslog (priority, message);
+
+#ifdef __GNUC__
+	#pragma GCC diagnostic pop
+#endif
 	return 0;
 }
 
--- mono-3.2.3+dfsg.orig/mono/tests/Makefile.am
+++ mono-3.2.3+dfsg/mono/tests/Makefile.am
@@ -338,7 +338,6 @@ BASE_TEST_CS_SRC=		\
 	modules.cs	\
 	bug-81673.cs	\
 	bug-81691.cs	\
-	bug-80307.cs	\
 	bug-415577.cs	\
 	filter-stack.cs	\
 	vararg2.cs	\
--- mono-3.2.3+dfsg.orig/mono/tests/sgen-descriptors.cs
+++ mono-3.2.3+dfsg/mono/tests/sgen-descriptors.cs
@@ -1,4 +1,5 @@
 using System;
+using System.Runtime.InteropServices;
 
 public struct SmallMixed
 {
@@ -47,6 +48,13 @@ public class HugePtrFree {
 	public LargeStruct2 c;
 }
 
+[StructLayout (LayoutKind.Sequential)]
+public class Non32bitBitmap {
+	public object o;
+	public long i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, i34, i35;
+	public object o2;
+}
+
 /*
 This is a stress test for descriptors.
 */
@@ -54,10 +62,10 @@ class Driver {
 	static char[] FOO = new char[] { 'f', 'o', 'b' };
 
 	static void Fill (int cycles) {
-		object[] root = new object [12];
+		object[] root = new object [13];
 		object[] current = root;
 		for (int i = 0; i < cycles; ++i) {
-			current [0] = new object [12];
+			current [0] = new object [13];
 			current [1] = new int [6];
 			current [2] = new int [2,3];
 			current [3] = new string (FOO);
@@ -72,6 +80,9 @@ class Driver {
 				current [10] = new HugePtrFree ();
 			if ((i %  10000) == 0)
 				current [11] = new LargeStruct2 [1];
+
+			/* Test for 64 bit bitmap descriptors (#14834) */
+			current [12] = new Non32bitBitmap () { o = new object (), i32 = 1, i33 = 1, i34 = 1, i35 = 1, o2 = new object () };
 	
 			current = (object[])current [0];
 		}
--- mono-3.2.3+dfsg.orig/mono/metadata/boehm-gc.c
+++ mono-3.2.3+dfsg/mono/metadata/boehm-gc.c
@@ -22,6 +22,7 @@
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/runtime.h>
 #include <mono/utils/mono-logger-internal.h>
+#include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/dtrace.h>
@@ -624,6 +625,12 @@ mono_gc_wbarrier_generic_store (gpointer
 }
 
 void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+	mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+}
+
+void
 mono_gc_wbarrier_generic_nostore (gpointer ptr)
 {
 }
--- mono-3.2.3+dfsg.orig/mono/metadata/sgen-gc.c
+++ mono-3.2.3+dfsg/mono/metadata/sgen-gc.c
@@ -317,6 +317,7 @@ static int stat_wbarrier_set_field = 0;
 static int stat_wbarrier_set_arrayref = 0;
 static int stat_wbarrier_arrayref_copy = 0;
 static int stat_wbarrier_generic_store = 0;
+static int stat_wbarrier_generic_store_atomic = 0;
 static int stat_wbarrier_set_root = 0;
 static int stat_wbarrier_value_copy = 0;
 static int stat_wbarrier_object_copy = 0;
@@ -2217,6 +2218,7 @@ init_stats (void)
 	mono_counters_register ("WBarrier set arrayref", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_set_arrayref);
 	mono_counters_register ("WBarrier arrayref copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_arrayref_copy);
 	mono_counters_register ("WBarrier generic store called", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_generic_store);
+	mono_counters_register ("WBarrier generic atomic store called", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_generic_store_atomic);
 	mono_counters_register ("WBarrier set root", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_set_root);
 	mono_counters_register ("WBarrier value copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_value_copy);
 	mono_counters_register ("WBarrier object copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_object_copy);
@@ -4424,6 +4426,24 @@ mono_gc_wbarrier_generic_store (gpointer
 	sgen_dummy_use (value);
 }
 
+/* Same as mono_gc_wbarrier_generic_store () but performs the store
+ * as an atomic operation with release semantics.
+ */
+void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+	HEAVY_STAT (++stat_wbarrier_generic_store_atomic);
+
+	SGEN_LOG (8, "Wbarrier atomic store at %p to %p (%s)", ptr, value, value ? safe_name (value) : "null");
+
+	mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+
+	if (ptr_in_nursery (value))
+		mono_gc_wbarrier_generic_nostore (ptr);
+
+	sgen_dummy_use (value);
+}
+
 void mono_gc_wbarrier_value_copy_bitmap (gpointer _dest, gpointer _src, int size, unsigned bitmap)
 {
 	mword *dest = _dest;
--- mono-3.2.3+dfsg.orig/mono/metadata/sgen-descriptor.h
+++ mono-3.2.3+dfsg/mono/metadata/sgen-descriptor.h
@@ -170,21 +170,43 @@ sgen_gc_descr_has_references (mword desc
 		}	\
 	} while (0)
 
-#ifdef __GNUC__
+#if defined(__GNUC__) && SIZEOF_VOID_P==4
 #define OBJ_BITMAP_FOREACH_PTR(desc,obj)       do {    \
 		/* there are pointers */        \
 		void **_objptr = (void**)(obj); \
 		gsize _bmap = (desc) >> 16;     \
 		_objptr += OBJECT_HEADER_WORDS; \
 		{ \
-			int _index = __builtin_ctz (_bmap); \
+			int _index = __builtin_ctz (_bmap);		\
 			_objptr += _index; \
 			_bmap >>= (_index + 1);				\
 			HANDLE_PTR (_objptr, (obj));		\
 			_objptr ++;							\
 			} \
 		while (_bmap) { \
-			int _index = __builtin_ctz (_bmap); \
+			int _index = __builtin_ctz (_bmap);		\
+			_objptr += _index; \
+			_bmap >>= (_index + 1);				\
+			HANDLE_PTR (_objptr, (obj));		\
+			_objptr ++;							\
+		}										\
+	} while (0)
+#elif defined(__GNUC__) && SIZEOF_VOID_P==8
+/* Same as above, but use _builtin_ctzl () */
+#define OBJ_BITMAP_FOREACH_PTR(desc,obj)       do {    \
+		/* there are pointers */        \
+		void **_objptr = (void**)(obj); \
+		gsize _bmap = (desc) >> 16;     \
+		_objptr += OBJECT_HEADER_WORDS; \
+		{ \
+			int _index = __builtin_ctzl (_bmap);		\
+			_objptr += _index; \
+			_bmap >>= (_index + 1);				\
+			HANDLE_PTR (_objptr, (obj));		\
+			_objptr ++;							\
+			} \
+		while (_bmap) { \
+			int _index = __builtin_ctzl (_bmap);		\
 			_objptr += _index; \
 			_bmap >>= (_index + 1);				\
 			HANDLE_PTR (_objptr, (obj));		\
--- mono-3.2.3+dfsg.orig/mono/metadata/null-gc.c
+++ mono-3.2.3+dfsg/mono/metadata/null-gc.c
@@ -193,6 +193,12 @@ mono_gc_wbarrier_generic_store (gpointer
 }
 
 void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+	mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+}
+
+void
 mono_gc_wbarrier_generic_nostore (gpointer ptr)
 {
 }
--- mono-3.2.3+dfsg.orig/mono/metadata/sgen-os-posix.c
+++ mono-3.2.3+dfsg/mono/metadata/sgen-os-posix.c
@@ -35,7 +35,7 @@
 #include "metadata/sgen-archdep.h"
 #include "metadata/object-internals.h"
 
-#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 const static int suspend_signal_num = SIGXFSZ;
 #else
 const static int suspend_signal_num = SIGPWR;
--- mono-3.2.3+dfsg.orig/mono/metadata/object.h
+++ mono-3.2.3+dfsg/mono/metadata/object.h
@@ -316,6 +316,7 @@ MONO_API void mono_gc_wbarrier_set_field
 MONO_API void mono_gc_wbarrier_set_arrayref  (MonoArray *arr, void* slot_ptr, MonoObject* value);
 MONO_API void mono_gc_wbarrier_arrayref_copy (void* dest_ptr, void* src_ptr, int count);
 MONO_API void mono_gc_wbarrier_generic_store (void* ptr, MonoObject* value);
+MONO_API void mono_gc_wbarrier_generic_store_atomic (void *ptr, MonoObject *value);
 MONO_API void mono_gc_wbarrier_generic_nostore (void* ptr);
 MONO_API void mono_gc_wbarrier_value_copy    (void* dest, void* src, int count, MonoClass *klass);
 MONO_API void mono_gc_wbarrier_object_copy   (MonoObject* obj, MonoObject *src);
--- mono-3.2.3+dfsg.orig/mono/metadata/threads.c
+++ mono-3.2.3+dfsg/mono/metadata/threads.c
@@ -48,6 +48,7 @@
 #include <mono/utils/hazard-pointer.h>
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/atomic.h>
+#include <mono/utils/mono-memory-model.h>
 
 #include <mono/metadata/gc-internal.h>
 
@@ -1182,8 +1183,6 @@ HANDLE ves_icall_System_Threading_Thread
 
 void ves_icall_System_Threading_InternalThread_Thread_free_internal (MonoInternalThread *this, HANDLE thread)
 {
-	MONO_ARCH_SAVE_REGS;
-
 	THREAD_DEBUG (g_message ("%s: Closing thread %p, handle %p", __func__, this, thread));
 
 	if (thread)
@@ -1273,8 +1272,6 @@ void ves_icall_System_Threading_Thread_S
 gint32
 ves_icall_System_Threading_Thread_GetDomainID (void) 
 {
-	MONO_ARCH_SAVE_REGS;
-
 	return mono_domain_get()->domain_id;
 }
 
@@ -1640,8 +1637,6 @@ ves_icall_System_Threading_WaitHandle_Si
 	guint32 ret;
 	MonoInternalThread *thread = mono_thread_internal_current ();
 
-	MONO_ARCH_SAVE_REGS;
-
 	if (ms == -1)
 		ms = INFINITE;
 
@@ -1660,8 +1655,6 @@ HANDLE ves_icall_System_Threading_Mutex_
 { 
 	HANDLE mutex;
 	
-	MONO_ARCH_SAVE_REGS;
-   
 	*created = TRUE;
 	
 	if (name == NULL) {
@@ -1678,8 +1671,6 @@ HANDLE ves_icall_System_Threading_Mutex_
 }                                                                   
 
 MonoBoolean ves_icall_System_Threading_Mutex_ReleaseMutex_internal (HANDLE handle ) { 
-	MONO_ARCH_SAVE_REGS;
-
 	return(ReleaseMutex (handle));
 }
 
@@ -1689,8 +1680,6 @@ HANDLE ves_icall_System_Threading_Mutex_
 {
 	HANDLE ret;
 	
-	MONO_ARCH_SAVE_REGS;
-	
 	*error = ERROR_SUCCESS;
 	
 	ret = OpenMutex (rights, FALSE, mono_string_chars (name));
@@ -1706,8 +1695,6 @@ HANDLE ves_icall_System_Threading_Semaph
 { 
 	HANDLE sem;
 	
-	MONO_ARCH_SAVE_REGS;
-   
 	*created = TRUE;
 	
 	if (name == NULL) {
@@ -1728,8 +1715,6 @@ gint32 ves_icall_System_Threading_Semaph
 { 
 	gint32 prevcount;
 	
-	MONO_ARCH_SAVE_REGS;
-
 	*fail = !ReleaseSemaphore (handle, releaseCount, &prevcount);
 
 	return (prevcount);
@@ -1739,8 +1724,6 @@ HANDLE ves_icall_System_Threading_Semaph
 {
 	HANDLE ret;
 	
-	MONO_ARCH_SAVE_REGS;
-	
 	*error = ERROR_SUCCESS;
 	
 	ret = OpenSemaphore (rights, FALSE, mono_string_chars (name));
@@ -1755,8 +1738,6 @@ HANDLE ves_icall_System_Threading_Events
 {
 	HANDLE event;
 	
-	MONO_ARCH_SAVE_REGS;
-
 	*created = TRUE;
 
 	if (name == NULL) {
@@ -1774,21 +1755,15 @@ HANDLE ves_icall_System_Threading_Events
 }
 
 gboolean ves_icall_System_Threading_Events_SetEvent_internal (HANDLE handle) {
-	MONO_ARCH_SAVE_REGS;
-
 	return (SetEvent(handle));
 }
 
 gboolean ves_icall_System_Threading_Events_ResetEvent_internal (HANDLE handle) {
-	MONO_ARCH_SAVE_REGS;
-
 	return (ResetEvent(handle));
 }
 
 void
 ves_icall_System_Threading_Events_CloseEvent_internal (HANDLE handle) {
-	MONO_ARCH_SAVE_REGS;
-
 	CloseHandle (handle);
 }
 
@@ -1798,8 +1773,6 @@ HANDLE ves_icall_System_Threading_Events
 {
 	HANDLE ret;
 	
-	MONO_ARCH_SAVE_REGS;
-	
 	*error = ERROR_SUCCESS;
 	
 	ret = OpenEvent (rights, FALSE, mono_string_chars (name));
@@ -1812,53 +1785,26 @@ HANDLE ves_icall_System_Threading_Events
 
 gint32 ves_icall_System_Threading_Interlocked_Increment_Int (gint32 *location)
 {
-	MONO_ARCH_SAVE_REGS;
-
 	return InterlockedIncrement (location);
 }
 
 gint64 ves_icall_System_Threading_Interlocked_Increment_Long (gint64 *location)
 {
-	gint64 ret;
-
-	MONO_ARCH_SAVE_REGS;
-
-	mono_interlocked_lock ();
-
-	ret = ++ *location;
-	
-	mono_interlocked_unlock ();
-
-	
-	return ret;
+	return InterlockedIncrement64 (location);
 }
 
 gint32 ves_icall_System_Threading_Interlocked_Decrement_Int (gint32 *location)
 {
-	MONO_ARCH_SAVE_REGS;
-
 	return InterlockedDecrement(location);
 }
 
 gint64 ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
 {
-	gint64 ret;
-
-	MONO_ARCH_SAVE_REGS;
-
-	mono_interlocked_lock ();
-
-	ret = -- *location;
-	
-	mono_interlocked_unlock ();
-
-	return ret;
+	return InterlockedDecrement64 (location);
 }
 
 gint32 ves_icall_System_Threading_Interlocked_Exchange_Int (gint32 *location, gint32 value)
 {
-	MONO_ARCH_SAVE_REGS;
-
 	return InterlockedExchange(location, value);
 }
 
@@ -1879,8 +1825,6 @@ gfloat ves_icall_System_Threading_Interl
 {
 	IntFloatUnion val, ret;
 
-	MONO_ARCH_SAVE_REGS;
-
 	val.fval = value;
 	ret.ival = InterlockedExchange((gint32 *) location, val.ival);
 
@@ -1890,54 +1834,22 @@ gfloat ves_icall_System_Threading_Interl
 gint64 
 ves_icall_System_Threading_Interlocked_Exchange_Long (gint64 *location, gint64 value)
 {
-#if SIZEOF_VOID_P == 8
-	return (gint64) InterlockedExchangePointer((gpointer *) location, (gpointer)value);
-#else
-	gint64 res;
-
-	/* 
-	 * According to MSDN, this function is only atomic with regards to the 
-	 * other Interlocked functions on 32 bit platforms.
-	 */
-	mono_interlocked_lock ();
-	res = *location;
-	*location = value;
-	mono_interlocked_unlock ();
-
-	return res;
-#endif
+	return InterlockedExchange64 (location, value);
 }
 
 gdouble 
 ves_icall_System_Threading_Interlocked_Exchange_Double (gdouble *location, gdouble value)
 {
-#if SIZEOF_VOID_P == 8
 	LongDoubleUnion val, ret;
 
 	val.fval = value;
-	ret.ival = (gint64)InterlockedExchangePointer((gpointer *) location, (gpointer)val.ival);
+	ret.ival = (gint64)InterlockedExchange64((gint64 *) location, val.ival);
 
 	return ret.fval;
-#else
-	gdouble res;
-
-	/* 
-	 * According to MSDN, this function is only atomic with regards to the 
-	 * other Interlocked functions on 32 bit platforms.
-	 */
-	mono_interlocked_lock ();
-	res = *location;
-	*location = value;
-	mono_interlocked_unlock ();
-
-	return res;
-#endif
 }
 
 gint32 ves_icall_System_Threading_Interlocked_CompareExchange_Int(gint32 *location, gint32 value, gint32 comparand)
 {
-	MONO_ARCH_SAVE_REGS;
-
 	return InterlockedCompareExchange(location, value, comparand);
 }
 
@@ -1958,8 +1870,6 @@ gfloat ves_icall_System_Threading_Interl
 {
 	IntFloatUnion val, ret, cmp;
 
-	MONO_ARCH_SAVE_REGS;
-
 	val.fval = value;
 	cmp.fval = comparand;
 	ret.ival = InterlockedCompareExchange((gint32 *) location, val.ival, cmp.ival);
@@ -2034,14 +1944,7 @@ ves_icall_System_Threading_Interlocked_A
 	mono_raise_exception (mono_get_exception_not_implemented (NULL));
 	return 0;
 #else
-	gint32 orig;
-
-	mono_interlocked_lock ();
-	orig = *location;
-	*location = orig + value;
-	mono_interlocked_unlock ();
-
-	return orig + value;
+	return InterlockedAdd (location, value);
 #endif
 }
 
@@ -2053,39 +1956,20 @@ ves_icall_System_Threading_Interlocked_A
 	mono_raise_exception (mono_get_exception_not_implemented (NULL));
 	return 0;
 #else
-	gint64 orig;
-
-	mono_interlocked_lock ();
-	orig = *location;
-	*location = orig + value;
-	mono_interlocked_unlock ();
-
-	return orig + value;
+	return InterlockedAdd64 (location, value);
 #endif
 }
 
 gint64 
 ves_icall_System_Threading_Interlocked_Read_Long (gint64 *location)
 {
-#if SIZEOF_VOID_P == 8
-	/* 64 bit reads are already atomic */
-	return *location;
-#else
-	gint64 res;
-
-	mono_interlocked_lock ();
-	res = *location;
-	mono_interlocked_unlock ();
-
-	return res;
-#endif
+	return InterlockedRead64 (location);
 }
 
 void
 ves_icall_System_Threading_Thread_MemoryBarrier (void)
 {
-	mono_threads_lock ();
-	mono_threads_unlock ();
+	mono_memory_barrier ();
 }
 
 void
@@ -2512,108 +2396,119 @@ void mono_thread_stop (MonoThread *threa
 gint8
 ves_icall_System_Threading_Thread_VolatileRead1 (void *ptr)
 {
-	return *((volatile gint8 *) (ptr));
+	gint8 tmp;
+	mono_atomic_load_acquire (tmp, gint8, (volatile gint8 *) ptr);
+	return tmp;
 }
 
 gint16
 ves_icall_System_Threading_Thread_VolatileRead2 (void *ptr)
 {
-	return *((volatile gint16 *) (ptr));
+	gint16 tmp;
+	mono_atomic_load_acquire (tmp, gint16, (volatile gint16 *) ptr);
+	return tmp;
 }
 
 gint32
 ves_icall_System_Threading_Thread_VolatileRead4 (void *ptr)
 {
-	return *((volatile gint32 *) (ptr));
+	gint32 tmp;
+	mono_atomic_load_acquire (tmp, gint32, (volatile gint32 *) ptr);
+	return tmp;
 }
 
 gint64
 ves_icall_System_Threading_Thread_VolatileRead8 (void *ptr)
 {
-#if SIZEOF_VOID_P == 8
-	return *((volatile gint64 *) (ptr));
-#else
-	return InterlockedCompareExchange64 (ptr, 0, 0); /*Must ensure atomicity of the operation. */
-#endif
+	gint64 tmp;
+	mono_atomic_load_acquire (tmp, gint64, (volatile gint64 *) ptr);
+	return tmp;
 }
 
 void *
 ves_icall_System_Threading_Thread_VolatileReadIntPtr (void *ptr)
 {
-	return (void *)  *((volatile void **) ptr);
+	volatile void *tmp;
+	mono_atomic_load_acquire (tmp, volatile void *, (volatile void **) ptr);
+	return (void *) tmp;
 }
 
 double
 ves_icall_System_Threading_Thread_VolatileReadDouble (void *ptr)
 {
-	return *((volatile double *) (ptr));
+	double tmp;
+	mono_atomic_load_acquire (tmp, double, (volatile double *) ptr);
+	return tmp;
 }
 
 float
 ves_icall_System_Threading_Thread_VolatileReadFloat (void *ptr)
 {
-	return *((volatile float *) (ptr));
+	float tmp;
+	mono_atomic_load_acquire (tmp, float, (volatile float *) ptr);
+	return tmp;
 }
 
 MonoObject*
 ves_icall_System_Threading_Volatile_Read_T (void *ptr)
 {
-	return (MonoObject*)*((volatile MonoObject**)ptr);
+	volatile MonoObject *tmp;
+	mono_atomic_load_acquire (tmp, volatile MonoObject *, (volatile MonoObject **) ptr);
+	return (MonoObject *) tmp;
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWrite1 (void *ptr, gint8 value)
 {
-	*((volatile gint8 *) ptr) = value;
+	mono_atomic_store_release ((volatile gint8 *) ptr, value);
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWrite2 (void *ptr, gint16 value)
 {
-	*((volatile gint16 *) ptr) = value;
+	mono_atomic_store_release ((volatile gint16 *) ptr, value);
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWrite4 (void *ptr, gint32 value)
 {
-	*((volatile gint32 *) ptr) = value;
+	mono_atomic_store_release ((volatile gint32 *) ptr, value);
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWrite8 (void *ptr, gint64 value)
 {
-	*((volatile gint64 *) ptr) = value;
+	mono_atomic_store_release ((volatile gint64 *) ptr, value);
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWriteIntPtr (void *ptr, void *value)
 {
-	*((volatile void **) ptr) = value;
+	mono_atomic_store_release ((volatile void **) ptr, value);
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWriteObject (void *ptr, void *value)
 {
-	mono_gc_wbarrier_generic_store (ptr, value);
+	mono_gc_wbarrier_generic_store_atomic (ptr, value);
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWriteDouble (void *ptr, double value)
 {
-	*((volatile double *) ptr) = value;
+	mono_atomic_store_release ((volatile double *) ptr, value);
 }
 
 void
 ves_icall_System_Threading_Thread_VolatileWriteFloat (void *ptr, float value)
 {
-	*((volatile float *) ptr) = value;
+	mono_atomic_store_release ((volatile float *) ptr, value);
 }
 
 void
 ves_icall_System_Threading_Volatile_Write_T (void *ptr, MonoObject *value)
 {
-	*((volatile MonoObject **) ptr) = value;
-	mono_gc_wbarrier_generic_nostore (ptr);
+	mono_gc_wbarrier_generic_store_atomic (ptr, value);
 }
 
 void
--- mono-3.2.3+dfsg.orig/mono/metadata/security.c
+++ mono-3.2.3+dfsg/mono/metadata/security.c
@@ -13,6 +13,7 @@
 
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/appdomain.h>
+#include <mono/metadata/assembly.h>
 #include <mono/metadata/image.h>
 #include <mono/metadata/exception.h>
 #include <mono/metadata/object-internals.h>
--- mono-3.2.3+dfsg.orig/mono/io-layer/io.c
+++ mono-3.2.3+dfsg/mono/io-layer/io.c
@@ -4227,7 +4227,7 @@ get_fstypename (gchar *utfpath)
 }
 
 /* Linux has struct statfs which has a different layout */
-#if defined (PLATFORM_MACOSX) || defined (__linux__) || defined(PLATFORM_BSD) || defined(__native_client__)
+#if defined (PLATFORM_MACOSX) || defined (__linux__) || defined(PLATFORM_BSD) || defined(__native_client__) || defined(__FreeBSD_kernel__)
 gboolean
 GetVolumeInformation (const gunichar2 *path, gunichar2 *volumename, int volumesize, int *outserial, int *maxcomp, int *fsflags, gunichar2 *fsbuffer, int fsbuffersize)
 {
--- mono-3.2.3+dfsg.orig/mono/mini/mini-x86.h
+++ mono-3.2.3+dfsg/mono/mini/mini-x86.h
@@ -48,7 +48,7 @@ struct sigcontext {
 #endif /* __HAIKU__ */
 
 #if defined( __linux__) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || \
-       defined(__FreeBSD__) || defined(__OpenBSD__)
+       defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
 #define MONO_ARCH_USE_SIGACTION
 #endif
 
--- mono-3.2.3+dfsg.orig/mono/mini/Makefile.am
+++ mono-3.2.3+dfsg/mono/mini/Makefile.am
@@ -193,7 +193,7 @@ buildver-boehm.h: libmini-static.la $(mo
 else
 buildver-boehm.h: libmini-static.la $(monodir)/mono/metadata/libmonoruntime-static.la
 endif
-	@echo "const char *build_date = \"`date`\";" > buildver-boehm.h
+	@echo "const char *build_date;" > buildver-boehm.h
 mono_boehm-main.$(OBJEXT): buildver-boehm.h
 endif
 
@@ -202,7 +202,7 @@ buildver-sgen.h: libmini-static.la $(mon
 else
 buildver-sgen.h: libmini-static.la $(monodir)/mono/metadata/libmonoruntimesgen-static.la
 endif
-	@echo "const char *build_date = \"`date`\";" > buildver-sgen.h
+	@echo "const char *build_date;" > buildver-sgen.h
 mono_sgen-main-sgen.$(OBJEXT): buildver-sgen.h
 
 if DTRACE_G_REQUIRED
@@ -742,16 +742,7 @@ EXTRA_DIST = TestDriver.cs ldscript ldsc
 	Makefile.am.in
 
 version.h: Makefile
-	if test -d $(top_srcdir)/.git; then \
-		(cd $(top_srcdir); \
-			LANG=C; export LANG; \
-			branch=`git branch | grep '^\*' | cut -d ' ' -f 2`; \
-			version=`git log --no-color --first-parent -n1 --pretty=format:%h`; \
-			echo "#define FULL_VERSION \"$$branch/$$version\""; \
-		); \
-	else \
-		echo "#define FULL_VERSION \"tarball\""; \
-	fi > version.h
+	echo "#define FULL_VERSION \"Debian $$(dpkg-parsechangelog -l$(top_srcdir)/debian/changelog | grep ^Vers | cut -d\  -f2)\"" > version.h
 
 # Utility target for patching libtool to speed up linking
 patch-libtool:
--- mono-3.2.3+dfsg.orig/mono/mini/mini-amd64.h
+++ mono-3.2.3+dfsg/mono/mini/mini-amd64.h
@@ -290,7 +290,7 @@ typedef struct MonoCompileArch {
 
 #define MONO_ARCH_NOMAP32BIT
 
-#elif defined (__FreeBSD__)
+#elif defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
 
 #define REG_RAX 7
 #define REG_RCX 4
--- mono-3.2.3+dfsg.orig/mono/mini/mini.c
+++ mono-3.2.3+dfsg/mono/mini/mini.c
@@ -6766,7 +6766,6 @@ mini_create_ftnptr (MonoDomain *domain,
 	desc [0] = addr;
 	desc [1] = NULL;
 #	elif defined(__ppc64__) || defined(__powerpc64__)
-	gpointer *desc;
 
 	desc = mono_domain_alloc0 (domain, 3 * sizeof (gpointer));
 
--- mono-3.2.3+dfsg.orig/mono/utils/atomic.c
+++ mono-3.2.3+dfsg/mono/utils/atomic.c
@@ -13,12 +13,14 @@
 
 #include <mono/utils/atomic.h>
 
-#if defined (WAPI_NO_ATOMIC_ASM) || !defined (HAS_64BITS_ATOMIC)
+#if defined (WAPI_NO_ATOMIC_ASM) || defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
 
 #include <pthread.h>
 
 static pthread_mutex_t spin = PTHREAD_MUTEX_INITIALIZER;
 
+#define NEED_64BIT_CMPXCHG_FALLBACK
+
 #endif
 
 #ifdef WAPI_NO_ATOMIC_ASM
@@ -82,6 +84,52 @@ gpointer InterlockedCompareExchangePoint
 	return(old);
 }
 
+gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
+{
+	gint32 ret;
+	int thr_ret;
+
+	mono_once(&spin_once, spin_init);
+
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	*dest += add;
+	ret= *dest;
+
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+
+	pthread_cleanup_pop (0);
+
+	return(ret);
+}
+
+gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
+{
+	gint64 ret;
+	int thr_ret;
+
+	mono_once(&spin_once, spin_init);
+
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	*dest += add;
+	ret= *dest;
+
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+
+	pthread_cleanup_pop (0);
+
+	return(ret);
+}
+
 gint32 InterlockedIncrement(volatile gint32 *dest)
 {
 	gint32 ret;
@@ -105,6 +153,29 @@ gint32 InterlockedIncrement(volatile gin
 	return(ret);
 }
 
+gint64 InterlockedIncrement64(volatile gint64 *dest)
+{
+	gint64 ret;
+	int thr_ret;
+
+	mono_once(&spin_once, spin_init);
+
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	(*dest)++;
+	ret= *dest;
+
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+
+	pthread_cleanup_pop (0);
+
+	return(ret);
+}
+
 gint32 InterlockedDecrement(volatile gint32 *dest)
 {
 	gint32 ret;
@@ -128,6 +199,29 @@ gint32 InterlockedDecrement(volatile gin
 	return(ret);
 }
 
+gint64 InterlockedDecrement64(volatile gint64 *dest)
+{
+	gint64 ret;
+	int thr_ret;
+
+	mono_once(&spin_once, spin_init);
+
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	(*dest)--;
+	ret= *dest;
+
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+
+	pthread_cleanup_pop (0);
+
+	return(ret);
+}
+
 gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch)
 {
 	gint32 ret;
@@ -151,6 +245,29 @@ gint32 InterlockedExchange(volatile gint
 	return(ret);
 }
 
+gint64 InterlockedExchange64(volatile gint64 *dest, gint64 exch)
+{
+	gint64 ret;
+	int thr_ret;
+
+	mono_once(&spin_once, spin_init);
+
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	ret=*dest;
+	*dest=exch;
+
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+
+	pthread_cleanup_pop (0);
+
+	return(ret);
+}
+
 gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch)
 {
 	gpointer ret;
@@ -197,40 +314,116 @@ gint32 InterlockedExchangeAdd(volatile g
 	return(ret);
 }
 
-#endif
+gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add)
+{
+	gint64 ret;
+	int thr_ret;
+	
+	mono_once(&spin_once, spin_init);
+	
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
 
-#ifndef HAS_64BITS_ATOMICS
+	ret= *dest;
+	*dest+=add;
+	
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
 
-#if defined (TARGET_MACH) && defined (TARGET_ARM) && (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__))
+	pthread_cleanup_pop (0);
 
-gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)  __attribute__ ((naked));
+	return(ret);
+}
 
-gint64
-InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
+gint32 InterlockedRead(volatile gint32 *src)
 {
-	__asm__ (
-	"push {r4, r5, r6, r7}\n"
-	"ldr r4, [sp, #16]\n"
-	"dmb\n"
-"1:\n"
-	"ldrexd	r6, r7, [r0]\n"
-	"cmp	r7, r4\n"
-	"bne 2f\n"
-	"cmp	r6, r3\n"
-	"bne	2f\n"
-	"strexd	r5, r1, r2, [r0]\n"
-	"cmp	r5, #0\n"
-	"bne	1b\n"
-"2:\n"
-	"dmb\n"
-	"mov	r0, r6\n"
-	"mov	r1, r7\n"
-	"pop {r4, r5, r6, r7}\n"
-	"bx	lr\n"
-	);
+	gint32 ret;
+	int thr_ret;
+	
+	mono_once(&spin_once, spin_init);
+	
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	ret= *src;
+	
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+
+	pthread_cleanup_pop (0);
+
+	return(ret);
 }
 
-#elif defined (TARGET_MACH) && (defined (TARGET_X86) || defined (TARGET_AMD64))
+gint64 InterlockedRead64(volatile gint64 *src)
+{
+	gint64 ret;
+	int thr_ret;
+	
+	mono_once(&spin_once, spin_init);
+	
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	ret= *src;
+	
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+
+	pthread_cleanup_pop (0);
+
+	return(ret);
+}
+
+void InterlockedWrite(volatile gint32 *dst, gint32 val)
+{
+	int thr_ret;
+	
+	mono_once(&spin_once, spin_init);
+	
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	*dst=val;
+	
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+	
+	pthread_cleanup_pop (0);
+}
+
+void InterlockedWrite64(volatile gint64 *dst, gint64 val)
+{
+	int thr_ret;
+	
+	mono_once(&spin_once, spin_init);
+	
+	pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+			      (void *)&spin);
+	thr_ret = pthread_mutex_lock(&spin);
+	g_assert (thr_ret == 0);
+
+	*dst=val;
+	
+	thr_ret = pthread_mutex_unlock(&spin);
+	g_assert (thr_ret == 0);
+	
+	pthread_cleanup_pop (0);
+}
+
+#endif
+
+#if defined (NEED_64BIT_CMPXCHG_FALLBACK)
+
+#if defined (TARGET_OSX)
 
 gint64
 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
@@ -238,6 +431,12 @@ InterlockedCompareExchange64(volatile gi
 	return __sync_val_compare_and_swap (dest, comp, exch);
 }
 
+#elif defined (HAVE_64BIT_CMPXCHG_FALLBACK)
+
+#ifdef ENABLE_EXTENSION_MODULE
+#include "../../../mono-extensions/mono/utils/atomic.c"
+#endif
+
 #else
 
 gint64
@@ -256,4 +455,5 @@ InterlockedCompareExchange64(volatile gi
 }
 
 #endif
+
 #endif
--- mono-3.2.3+dfsg.orig/mono/utils/mono-sigcontext.h
+++ mono-3.2.3+dfsg/mono/utils/mono-sigcontext.h
@@ -16,14 +16,14 @@
 
 #if defined(TARGET_X86)
 
-#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__DragonFly__)
 #include <ucontext.h>
 #endif
 #if defined(__APPLE__)
 #include <AvailabilityMacros.h>
 #endif
 
-#if defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
 	#define UCONTEXT_REG_EAX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_eax)
 	#define UCONTEXT_REG_EBX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_ebx)
 	#define UCONTEXT_REG_ECX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_ecx)
@@ -154,7 +154,7 @@ typedef struct ucontext {
 
 #elif defined(TARGET_AMD64)
 
-#if defined(__FreeBSD__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <ucontext.h>
 #endif
 
@@ -176,7 +176,7 @@ typedef struct ucontext {
 	#define UCONTEXT_REG_R13(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r13)
 	#define UCONTEXT_REG_R14(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r14)
 	#define UCONTEXT_REG_R15(ctx) (((ucontext_t*)(ctx))->uc_mcontext->__ss.__r15)
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 	#define UCONTEXT_REG_RAX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rax)
 	#define UCONTEXT_REG_RBX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rbx)
 	#define UCONTEXT_REG_RCX(ctx) (((ucontext_t*)(ctx))->uc_mcontext.mc_rcx)
--- mono-3.2.3+dfsg.orig/mono/utils/atomic.h
+++ mono-3.2.3+dfsg/mono/utils/atomic.h
@@ -11,16 +11,6 @@
 #ifndef _WAPI_ATOMIC_H_
 #define _WAPI_ATOMIC_H_
 
-#if defined(__NetBSD__)
-#include <sys/param.h>
-
-#if __NetBSD_Version__ > 499004000
-#include <sys/atomic.h>
-#define HAVE_ATOMIC_OPS
-#endif
-
-#endif
-
 #include "config.h"
 #include <glib.h>
 
@@ -32,7 +22,6 @@
 #if defined(__WIN32__) || defined(_WIN32)
 
 #include <windows.h>
-#define HAS_64BITS_ATOMICS 1
 
 /* mingw is missing InterlockedCompareExchange64 () from winbase.h */
 #ifdef __MINGW32__
@@ -42,6 +31,30 @@ static inline gint64 InterlockedCompareE
 }
 #endif
 
+/* And now for some dirty hacks... The Windows API doesn't
+ * provide any useful primitives for this (other than getting
+ * into architecture-specific madness), so use CAS. */
+
+static inline gint32 InterlockedRead(volatile gint32 *src)
+{
+	return InterlockedCompareExchange (src, 0, 0);
+}
+
+static inline gint64 InterlockedRead64(volatile gint64 *src)
+{
+	return InterlockedCompareExchange64 (src, 0, 0);
+}
+
+static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
+{
+	InterlockedExchange (dst, val);
+}
+
+static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
+{
+	InterlockedExchange64 (dst, val);
+}
+
 /* Prefer GCC atomic ops if the target supports it (see configure.in). */
 #elif defined(USE_GCC_ATOMIC_OPS)
 
@@ -56,6 +69,11 @@ static inline gpointer InterlockedCompar
 	return __sync_val_compare_and_swap (dest, comp, exch);
 }
 
+static inline gint32 InterlockedAdd(volatile gint32 *dest, gint32 add)
+{
+	return __sync_add_and_fetch (dest, add);
+}
+
 static inline gint32 InterlockedIncrement(volatile gint32 *val)
 {
 	return __sync_add_and_fetch (val, 1);
@@ -63,7 +81,7 @@ static inline gint32 InterlockedIncremen
 
 static inline gint32 InterlockedDecrement(volatile gint32 *val)
 {
-	return __sync_add_and_fetch (val, -1);
+	return __sync_sub_and_fetch (val, 1);
 }
 
 static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
@@ -90,59 +108,127 @@ static inline gint32 InterlockedExchange
 	return __sync_fetch_and_add (val, add);
 }
 
-#if defined (TARGET_OSX)
+static inline gint32 InterlockedRead(volatile gint32 *src)
+{
+	/* Kind of a hack, but GCC doesn't give us anything better, and it's
+	   certainly not as bad as using a CAS loop. */
+	return __sync_fetch_and_add (src, 0);
+}
+
+static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
+{
+	/* Nothing useful from GCC at all, so fall back to CAS. */
+	InterlockedExchange (dst, val);
+}
+
+#if defined (TARGET_OSX) || defined (__arm__) || (defined (__mips__) && !defined (__mips64)) || (defined (__powerpc__) && !defined (__powerpc64__))
 #define BROKEN_64BIT_ATOMICS_INTRINSIC 1
 #endif
 
-
 #if !defined (BROKEN_64BIT_ATOMICS_INTRINSIC)
-#define HAS_64BITS_ATOMICS 1
 
 static inline gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp)
 {
 	return __sync_val_compare_and_swap (dest, comp, exch);
 }
 
-#endif
+static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
+{
+	return __sync_add_and_fetch (dest, add);
+}
 
+static inline gint64 InterlockedIncrement64(volatile gint64 *val)
+{
+	return __sync_add_and_fetch (val, 1);
+}
 
-#elif defined(__NetBSD__) && defined(HAVE_ATOMIC_OPS)
+static inline gint64 InterlockedDecrement64(volatile gint64 *val)
+{
+	return __sync_sub_and_fetch (val, 1);
+}
 
-static inline gint32 InterlockedCompareExchange(volatile gint32 *dest,
-       gint32 exch, gint32 comp)
+static inline gint64 InterlockedExchangeAdd64(volatile gint64 *val, gint64 add)
 {
-       return atomic_cas_32((uint32_t*)dest, comp, exch);
+	return __sync_fetch_and_add (val, add);
 }
 
-static inline gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp)
+static inline gint64 InterlockedRead64(volatile gint64 *src)
 {
-       return atomic_cas_ptr(dest, comp, exch);
+	/* Kind of a hack, but GCC doesn't give us anything better. */
+	return __sync_fetch_and_add (src, 0);
 }
 
-static inline gint32 InterlockedIncrement(volatile gint32 *val)
+#else
+
+/* Implement 64-bit cmpxchg by hand or emulate it. */
+extern gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp);
+
+/* Implement all other 64-bit atomics in terms of a specialized CAS
+ * in this case, since chances are that the other 64-bit atomic
+ * intrinsics are broken too.
+ */
+
+static inline gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add)
 {
-       return atomic_inc_32_nv((uint32_t*)val);
+	gint64 old_val;
+	do {
+		old_val = *dest;
+	} while (InterlockedCompareExchange64 (dest, old_val + add, old_val) != old_val);
+	return old_val;
 }
 
-static inline gint32 InterlockedDecrement(volatile gint32 *val)
+static inline gint64 InterlockedIncrement64(volatile gint64 *val)
 {
-       return atomic_dec_32_nv((uint32_t*)val);
+	gint64 get, set;
+	do {
+		get = *val;
+		set = get + 1;
+	} while (InterlockedCompareExchange64 (val, set, get) != get);
+	return set;
 }
 
-static inline gint32 InterlockedExchange(volatile gint32 *val, gint32 new_val)
+static inline gint64 InterlockedDecrement64(volatile gint64 *val)
 {
-       return atomic_swap_32((uint32_t*)val, new_val);
+	gint64 get, set;
+	do {
+		get = *val;
+		set = get - 1;
+	} while (InterlockedCompareExchange64 (val, set, get) != get);
+	return set;
 }
 
-static inline gpointer InterlockedExchangePointer(volatile gpointer *val,
-               gpointer new_val)
+static inline gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add)
 {
-       return atomic_swap_ptr(val, new_val);
+	gint64 get, set;
+	do {
+		get = *dest;
+		set = get + add;
+	} while (InterlockedCompareExchange64 (dest, set, get) != get);
+	return set;
 }
 
-static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
+static inline gint64 InterlockedRead64(volatile gint64 *src)
+{
+	return InterlockedCompareExchange64 (src, 0, 0);
+}
+
+#endif
+
+/* We always implement this in terms of a 64-bit cmpxchg since
+ * GCC doesn't have an intrisic to model it anyway. */
+static inline gint64 InterlockedExchange64(volatile gint64 *val, gint64 new_val)
+{
+	gint64 old_val;
+	do {
+		old_val = *val;
+	} while (InterlockedCompareExchange64 (val, new_val, old_val) != old_val);
+	return old_val;
+}
+
+static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
 {
-       return atomic_add_32_nv((uint32_t*)val, add) - add;
+	/* Nothing useful from GCC at all, so fall back to CAS. */
+	InterlockedExchange64 (dst, val);
 }
 
 #elif (defined(sparc) || defined (__sparc__)) && defined(__GNUC__)
@@ -305,126 +391,6 @@ static inline gint32 InterlockedExchange
         return ret;
 }
 
-#elif __s390x__
-
-static inline gint32 
-InterlockedCompareExchange(volatile gint32 *dest,
-			   gint32 exch, gint32 comp)
-{
-	gint32 old;
-
-	__asm__ __volatile__ ("\tLA\t1,%0\n"
-			      "\tLR\t%1,%3\n"
-			      "\tCS\t%1,%2,0(1)\n"
-			      : "+m" (*dest), "=&r" (old)
-			      : "r" (exch), "r" (comp)
-			      : "1", "cc");	
-	return(old);
-}
-
-static inline gpointer 
-InterlockedCompareExchangePointer(volatile gpointer *dest, 
-				  gpointer exch, 
-			          gpointer comp)
-{
-	gpointer old;
-
-	__asm__ __volatile__ ("\tLA\t1,%0\n"
-			      "\tLGR\t%1,%3\n"
-			      "\tCSG\t%1,%2,0(1)\n"
-			      : "+m" (*dest), "=&r" (old)
-			      : "r" (exch), "r" (comp)
-			      : "1", "cc");
-
-	return(old);
-}
-
-static inline gint32 
-InterlockedIncrement(volatile gint32 *val)
-{
-	gint32 tmp;
-	
-	__asm__ __volatile__ ("\tLA\t2,%1\n"
-			      "0:\tLGF\t%0,%1\n"
-			      "\tLGFR\t1,%0\n"
-			      "\tAGHI\t1,1\n"
-			      "\tCS\t%0,1,0(2)\n"
-			      "\tJNZ\t0b\n"
-			      "\tLGFR\t%0,1"
-			      : "=r" (tmp), "+m" (*val)
-			      : : "1", "2", "cc");
-
-	return(tmp);
-}
-
-static inline gint32 
-InterlockedDecrement(volatile gint32 *val)
-{
-	gint32 tmp;
-	
-	__asm__ __volatile__ ("\tLA\t2,%1\n"
-			      "0:\tLGF\t%0,%1\n"
-			      "\tLGFR\t1,%0\n"
-			      "\tAGHI\t1,-1\n"
-			      "\tCS\t%0,1,0(2)\n"
-			      "\tJNZ\t0b\n"
-			      "\tLGFR\t%0,1"
-			      : "=r" (tmp), "+m" (*val)
-			      : : "1", "2", "cc");
-
-	return(tmp);
-}
-
-static inline gint32 
-InterlockedExchange(volatile gint32 *val, gint32 new_val)
-{
-	gint32 ret;
-	
-	__asm__ __volatile__ ("\tLA\t1,%0\n"
-			      "0:\tL\t%1,%0\n"
-			      "\tCS\t%1,%2,0(1)\n"
-			      "\tJNZ\t0b"
-			      : "+m" (*val), "=&r" (ret)
-			      : "r" (new_val)
-			      : "1", "cc");
-
-	return(ret);
-}
-
-static inline gpointer
-InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
-{
-	gpointer ret;
-	
-	__asm__ __volatile__ ("\tLA\t1,%0\n"
-			      "0:\tLG\t%1,%0\n"
-			      "\tCSG\t%1,%2,0(1)\n"
-			      "\tJNZ\t0b"
-			      : "+m" (*val), "=&r" (ret)
-			      : "r" (new_val)
-			      : "1", "cc");
-
-	return(ret);
-}
-
-static inline gint32 
-InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
-{
-	gint32 ret;
-
-	__asm__ __volatile__ ("\tLA\t2,%1\n"
-			      "0:\tLGF\t%0,%1\n"
-			      "\tLGFR\t1,%0\n"
-			      "\tAGR\t1,%2\n"
-			      "\tCS\t%0,1,0(2)\n"
-			      "\tJNZ\t0b"
-			      : "=&r" (ret), "+m" (*val)
-			      : "r" (add) 
-			      : "1", "2", "cc");
-	
-	return(ret);
-}
-
 #elif defined(__ia64__)
 
 #ifdef __INTEL_COMPILER
@@ -546,17 +512,24 @@ static inline gint32 InterlockedExchange
 #define WAPI_NO_ATOMIC_ASM
 
 extern gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch, gint32 comp);
+extern gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp);
 extern gpointer InterlockedCompareExchangePointer(volatile gpointer *dest, gpointer exch, gpointer comp);
+extern gint32 InterlockedAdd(volatile gint32 *dest, gint32 add);
+extern gint64 InterlockedAdd64(volatile gint64 *dest, gint64 add);
 extern gint32 InterlockedIncrement(volatile gint32 *dest);
+extern gint64 InterlockedIncrement64(volatile gint64 *dest);
 extern gint32 InterlockedDecrement(volatile gint32 *dest);
+extern gint64 InterlockedDecrement64(volatile gint64 *dest);
 extern gint32 InterlockedExchange(volatile gint32 *dest, gint32 exch);
+extern gint64 InterlockedExchange64(volatile gint64 *dest, gint64 exch);
 extern gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch);
 extern gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add);
+extern gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add);
+extern gint32 InterlockedRead(volatile gint32 *src);
+extern gint64 InterlockedRead64(volatile gint64 *src);
+extern void InterlockedWrite(volatile gint32 *dst, gint32 val);
+extern void InterlockedWrite64(volatile gint64 *dst, gint64 val);
 
 #endif
 
-#ifndef HAS_64BITS_ATOMICS
-extern gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp);
-#endif
-
 #endif /* _WAPI_ATOMIC_H_ */
--- mono-3.2.3+dfsg.orig/mono/arch/mips/mips-codegen.h
+++ mono-3.2.3+dfsg/mono/arch/mips/mips-codegen.h
@@ -334,7 +334,7 @@ enum {
 /* misc and coprocessor ops */
 #define mips_move(c,dest,src) mips_addu(c,dest,src,mips_zero)
 #define mips_dmove(c,dest,src) mips_daddu(c,dest,src,mips_zero)
-#define mips_nop(c) mips_sll(c,0,0,0)
+#define mips_nop(c) mips_or(c,mips_at,mips_at,0)
 #define mips_break(c,code) mips_emit32(c, ((code)<<6)|13)
 #define mips_mfhi(c,dest) mips_format_r(c,0,0,0,dest,0,16)
 #define mips_mflo(c,dest) mips_format_r(c,0,0,0,dest,0,18)
--- mono-3.2.3+dfsg.orig/msvc/mono.def
+++ mono-3.2.3+dfsg/msvc/mono.def
@@ -331,6 +331,7 @@ mono_gc_walk_heap
 mono_gc_wbarrier_arrayref_copy
 mono_gc_wbarrier_generic_nostore
 mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
 mono_gc_wbarrier_object_copy
 mono_gc_wbarrier_set_arrayref
 mono_gc_wbarrier_set_field
--- mono-3.2.3+dfsg.orig/data/mono.pc.in
+++ mono-3.2.3+dfsg/data/mono.pc.in
@@ -1,5 +1,5 @@
-prefix=${pcfiledir}/../..
-exec_prefix=${pcfiledir}/../..
+prefix=@prefix@
+exec_prefix=${prefix}
 libdir=${prefix}/@reloc_libdir@
 includedir=${prefix}/include/mono-@API_VER@
 sysconfdir=@sysconfdir@
--- mono-3.2.3+dfsg.orig/data/mono-cairo.pc.in
+++ mono-3.2.3+dfsg/data/mono-cairo.pc.in
@@ -1,5 +1,5 @@
-prefix=${pcfiledir}/../..
-exec_prefix=${pcfiledir}/../..
+prefix=@prefix@
+exec_prefix=${prefix}
 libdir=${prefix}/@reloc_libdir@
 includedir=${prefix}/include
 
--- mono-3.2.3+dfsg.orig/docs/current-api
+++ mono-3.2.3+dfsg/docs/current-api
@@ -307,6 +307,7 @@ mono_gc_out_of_memory
 mono_gc_wbarrier_arrayref_copy
 mono_gc_wbarrier_generic_nostore
 mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
 mono_gc_wbarrier_object_copy
 mono_gc_wbarrier_set_arrayref
 mono_gc_wbarrier_set_field
--- mono-3.2.3+dfsg.orig/docs/public-api
+++ mono-3.2.3+dfsg/docs/public-api
@@ -307,6 +307,7 @@ mono_gc_out_of_memory
 mono_gc_wbarrier_arrayref_copy
 mono_gc_wbarrier_generic_nostore
 mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
 mono_gc_wbarrier_object_copy
 mono_gc_wbarrier_set_arrayref
 mono_gc_wbarrier_set_field
--- mono-3.2.3+dfsg.orig/libgc/configure.in
+++ mono-3.2.3+dfsg/libgc/configure.in
@@ -114,6 +114,17 @@ case "$THREADS" in
 	AC_DEFINE(THREAD_LOCAL_ALLOC)
 	THREADDLLIBS="-lpthread -lrt"
 	;;
+     *-*-kfreebsd*-gnu)
+	AC_DEFINE(GC_FREEBSD_THREADS)
+	INCLUDES="$INCLUDES -pthread"
+	THREADDLLIBS=-pthread
+	AC_DEFINE(_REENTRANT)
+	if test "${enable_parallel_mark}" = yes; then
+		AC_DEFINE(PARALLEL_MARK)
+	fi
+	AC_DEFINE(THREAD_LOCAL_ALLOC)
+	AC_DEFINE(USE_COMPILER_TLS)
+	;;
       *-*-freebsd*)
 	AC_DEFINE(GC_FREEBSD_THREADS)
 	if test "x$PTHREAD_CFLAGS" != "x"; then
--- mono-3.2.3+dfsg.orig/libgc/dyn_load.c
+++ mono-3.2.3+dfsg/libgc/dyn_load.c
@@ -26,7 +26,7 @@
  * None of this is safe with dlclose and incremental collection.
  * But then not much of anything is safe in the presence of dlclose.
  */
-#if (defined(__linux__) || defined(__native_client__)) && !defined(_GNU_SOURCE)
+#if (defined(__linux__) || defined(__GLIBC__) || defined(__native_client__)) && !defined(_GNU_SOURCE)
     /* Can't test LINUX, since this must be define before other includes */
 #   define _GNU_SOURCE
 #endif
@@ -394,7 +394,7 @@ GC_bool GC_register_main_static_data()
 /* For glibc 2.2.4+.  Unfortunately, it doesn't work for older	*/
 /* versions.  Thanks to Jakub Jelinek for most of the code.	*/
 
-# if (defined(LINUX) || defined(NACL)) /* Are others OK here, too? */ \
+# if (defined(LINUX) || defined (__GLIBC__) || defined(NACL)) /* Are others OK here, too? */ \
      && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
          || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) 
 
--- mono-3.2.3+dfsg.orig/libgc/include/gc.h
+++ mono-3.2.3+dfsg/libgc/include/gc.h
@@ -493,7 +493,7 @@ GC_API GC_PTR GC_malloc_atomic_ignore_of
 #   define GC_RETURN_ADDR (GC_word)__return_address
 #endif
 
-#ifdef __linux__
+#if defined(__linux__) || defined(__GLIBC__)
 # include <features.h>
 # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
      && !defined(__ia64__)
--- mono-3.2.3+dfsg.orig/libgc/include/private/gcconfig.h
+++ mono-3.2.3+dfsg/libgc/include/private/gcconfig.h
@@ -55,7 +55,7 @@
 # endif
 
 /* And one for FreeBSD: */
-# if defined(__FreeBSD__) && !defined(FREEBSD)
+# if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__)) && !defined(FREEBSD)
 #    define FREEBSD
 # endif
 
@@ -1371,8 +1371,15 @@
 #	ifndef GC_FREEBSD_THREADS
 #	    define MPROTECT_VDB
 #	endif
-#      define SIG_SUSPEND SIGTSTP
-#      define SIG_THR_RESTART SIGCONT
+#       ifdef __GLIBC__
+#           define SIG_SUSPEND          (32+6)
+#           define SIG_THR_RESTART      (32+5)
+            extern int _end[];
+#           define DATAEND (_end)
+#       else
+#           define SIG_SUSPEND SIGTSTP
+#           define SIG_THR_RESTART SIGCONT
+#       endif
 #	define FREEBSD_STACKBOTTOM
 #	ifdef __ELF__
 #	    define DYNAMIC_LOADING
@@ -2143,6 +2150,28 @@
 	extern char * GC_FreeBSDGetDataStart();
 #	define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
 #   endif
+#   ifdef FREEBSD
+#	define OS_TYPE "FREEBSD"
+#	ifndef GC_FREEBSD_THREADS
+#	    define MPROTECT_VDB
+#	endif
+#	ifdef __GLIBC__
+#	    define SIG_SUSPEND		(32+6)
+#	    define SIG_THR_RESTART	(32+5)
+	    extern int _end[];
+#	    define DATAEND (_end)
+#	else
+#	    define SIG_SUSPEND SIGUSR1
+#	    define SIG_THR_RESTART SIGUSR2
+#	endif
+#	define FREEBSD_STACKBOTTOM
+#	ifdef __ELF__
+#	    define DYNAMIC_LOADING
+#	endif
+	extern char etext[];
+	extern char * GC_FreeBSDGetDataStart();
+#	define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
+#   endif
 #   ifdef NETBSD
 #	define OS_TYPE "NETBSD"
 #	ifdef __ELF__
@@ -2230,7 +2259,7 @@
 #   define SUNOS5SIGS
 # endif
 
-# if defined(FREEBSD) && (__FreeBSD__ >= 4)
+# if defined(FREEBSD) && ((__FreeBSD__ >= 4) || (__FreeBSD_kernel__ >= 4))
 #   define SUNOS5SIGS
 # endif
 
@@ -2293,7 +2322,7 @@
 #   define CACHE_LINE_SIZE 32	/* Wild guess	*/
 # endif
 
-# ifdef LINUX
+# if defined(LINUX) || defined(__GLIBC__)
 #   define REGISTER_LIBRARIES_EARLY
     /* We sometimes use dl_iterate_phdr, which may acquire an internal	*/
     /* lock.  This isn't safe after the world has stopped.  So we must	*/
@@ -2374,7 +2403,7 @@
 #if defined(SPARC)
 # define CAN_SAVE_CALL_ARGS
 #endif
-#if (defined(I386) || defined(X86_64)) && defined(LINUX)
+#if (defined(I386) || defined(X86_64)) && (defined(LINUX) || defined(__GLIBC__))
 	    /* SAVE_CALL_CHAIN is supported if the code is compiled to save	*/
 	    /* frame pointers by default, i.e. no -fomit-frame-pointer flag.	*/
 # define CAN_SAVE_CALL_ARGS
--- mono-3.2.3+dfsg.orig/mcs/class/Mono.WebBrowser/Mono.WebBrowser.dll.sources
+++ mono-3.2.3+dfsg/mcs/class/Mono.WebBrowser/Mono.WebBrowser.dll.sources
@@ -133,6 +133,9 @@ Mono.Mozilla/interfaces/nsIWebNavigation
 Mono.Mozilla/interfaces/extras/NodeType.cs
 Mono.Mozilla/interfaces/extras/nsIWriteSegmentFun.cs
 Mono.Mozilla/interfaces/extras/Options.cs
+Mono.NullBrowser/Base.cs
+Mono.NullBrowser/WebBrowser.cs
+Mono.NullBrowser/DOM/Navigation.cs
 Mono.WebBrowser/DOM/IDocumentType.cs
 Mono.WebBrowser/DOM/IDOMImplementation.cs
 Mono.WebBrowser/DOM/IMediaList.cs
--- mono-3.2.3+dfsg.orig/mcs/class/Mono.WebBrowser/Mono.WebBrowser/Manager.cs
+++ mono-3.2.3+dfsg/mcs/class/Mono.WebBrowser/Mono.WebBrowser/Manager.cs
@@ -52,8 +52,15 @@ namespace Mono.WebBrowser
 				}
 			}
 #endif
-			if (browserEngine == null || browserEngine == "mozilla")
-				return new Mono.Mozilla.WebBrowser (platform);
+			if (browserEngine == "mozilla") {
+				try {
+					return new Mono.Mozilla.WebBrowser (platform);
+				} catch {
+					browserEngine = null;
+				}
+			}
+			if (browserEngine == null)
+				return new Mono.NullBrowser.WebBrowser (platform);
 			throw new Exception (Mono.WebBrowser.Exception.ErrorCodes.EngineNotSupported, browserEngine);
 		}
 
--- /dev/null
+++ mono-3.2.3+dfsg/mcs/class/Mono.WebBrowser/Mono.NullBrowser/WebBrowser.cs
@@ -0,0 +1,414 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2007, 2008 Novell, Inc.
+// Copyright (c) 2013 Jo Shields
+//
+// Authors:
+//	Andreia Gaita (avidigal@novell.com)
+//	Jo Shields (directhex@apebox.org)
+//
+
+#undef debug
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Diagnostics;
+using Mono.WebBrowser;
+using Mono.WebBrowser.DOM;
+
+namespace Mono.NullBrowser
+{
+	internal class WebBrowser : IWebBrowser
+	{
+		bool loaded;
+		internal bool created = false;
+		bool creating = false;
+
+                internal DOM.Navigation navigation;
+
+		internal Platform platform;
+		internal Platform enginePlatform;
+		System.ComponentModel.EventHandlerList events;
+		System.ComponentModel.EventHandlerList domEvents;
+
+		string statusText;
+
+		bool streamingMode;
+		
+		internal Hashtable documents;
+
+		int width;
+		int height;
+		bool isDirty;
+		
+		public WebBrowser (Platform platform)
+		{
+			this.platform = platform;
+			loaded = Base.Init (this, platform);
+			documents = new Hashtable ();
+		}
+
+		public bool Load (IntPtr handle, int width, int height)
+		{
+			loaded = Base.Bind (this, handle, width, height);
+			return loaded;
+		}
+
+		bool Created {
+			get {
+				if (!creating && !created) {
+					creating = true;
+					created = Base.Create (this);
+					if (created && isDirty) {
+						isDirty = false;
+						Base.Resize (this, width, height);
+					}
+				}
+				return created;
+			}
+		}
+
+		public void Shutdown ()
+		{
+			Base.Shutdown (this);
+		}
+		
+		internal void Reset ()
+		{
+			this.DomEvents.Dispose ();
+			this.domEvents = null;
+			this.documents.Clear ();
+		}
+
+		public bool Initialized {
+			get { return this.loaded; }
+		}
+		
+		public IWindow Window {
+			get {
+				return null;
+			}
+		}
+
+		public IDocument Document {
+			get {
+				return null;
+			}
+		}
+
+		public INavigation Navigation {
+			get {
+                                if (!Created) return null;
+
+                                if (navigation == null) {
+
+                                        navigation = new DOM.Navigation ();
+                                }
+                                return navigation as INavigation;
+			}
+		}
+		
+		public string StatusText {
+			get { return statusText; }
+		}
+		
+		public bool Offline {
+			get {
+				return false;
+			}
+			set {
+			}
+		}
+		
+		internal System.ComponentModel.EventHandlerList DomEvents {
+			get {
+				if (domEvents == null)
+					domEvents = new System.ComponentModel.EventHandlerList();
+
+				return domEvents;
+			}
+		}
+
+		internal System.ComponentModel.EventHandlerList Events {
+			get {
+				if (events == null)
+					events = new System.ComponentModel.EventHandlerList();
+
+				return events;
+			}
+		}
+		
+		#region Layout
+		public void FocusIn (FocusOption focus)
+		{
+			if (!created) return;
+			Base.Focus (this, focus);
+		}
+		public void FocusOut ()
+		{
+			if (!created) return;
+			Base.Blur (this);
+		}
+		
+		public void Activate ()
+		{
+			if (!Created) return;
+			Base.Activate (this);
+		}
+		public void Deactivate ()
+		{
+			if (!created) return;
+			Base.Deactivate (this);
+		}
+
+		public void Resize (int width, int height)
+		{
+			this.width = width;
+			this.height = height;
+			isDirty = true;
+			if (!created) return;
+			Base.Resize (this, width, height);			
+		}
+
+		public void Render (byte[] data)
+		{
+			if (!Created) return;
+			if (data == null)
+				throw new ArgumentNullException ("data");
+			string html = System.Text.ASCIIEncoding.UTF8.GetString (data);
+			Render (html);
+		}
+
+		public void Render (string html)
+		{
+			if (!Created) return;
+			Render (html, "file:///", "text/html");
+		}
+
+				
+		public void Render (string html, string uri, string contentType)
+		{
+			if (!Created) return;
+			throw new Mono.WebBrowser.Exception (Mono.WebBrowser.Exception.ErrorCodes.Navigation);
+
+			IntPtr native_html = Marshal.StringToHGlobalAnsi (html);
+			Marshal.FreeHGlobal (native_html);
+
+
+		}
+		
+		public void ExecuteScript (string script) {
+			if (!Created) return;
+			Base.EvalScript (this, script);
+		}
+				
+		internal void AttachEvent (INode node, string eve, EventHandler handler) {
+			string key = String.Intern (node.GetHashCode() + ":" + eve);
+#if debug
+			Console.Error.WriteLine ("Event Attached: " + key);
+#endif
+			DomEvents.AddHandler (key, handler);
+		}
+
+		internal void DetachEvent (INode node, string eve, EventHandler handler) {
+			string key = String.Intern (node.GetHashCode() + ":" + eve);
+#if debug			
+			Console.Error.WriteLine ("Event Detached: " + key);
+#endif			
+			DomEvents.RemoveHandler (key, handler);
+		}
+		
+		#endregion
+
+		#region Events
+		internal static object KeyDownEvent = new object ();
+		internal static object KeyPressEvent = new object ();
+		internal static object KeyUpEvent = new object ();
+		internal static object MouseClickEvent = new object ();
+		internal static object MouseDoubleClickEvent = new object ();
+		internal static object MouseDownEvent = new object ();
+		internal static object MouseEnterEvent = new object ();
+		internal static object MouseLeaveEvent = new object ();
+		internal static object MouseMoveEvent = new object ();
+		internal static object MouseUpEvent = new object ();
+		internal static object FocusEvent = new object ();
+		internal static object BlurEvent = new object ();
+		internal static object CreateNewWindowEvent = new object ();
+		internal static object AlertEvent = new object ();
+			
+		internal static object LoadStartedEvent = new object ();
+		internal static object LoadCommitedEvent = new object ();
+		internal static object ProgressChangedEvent = new object ();
+		internal static object LoadFinishedEvent = new object ();	
+		
+		internal static object LoadEvent = new object ();
+		internal static object UnloadEvent = new object ();
+		internal static object StatusChangedEvent = new object ();
+		internal static object SecurityChangedEvent = new object ();
+		internal static object ProgressEvent = new object ();
+		internal static object ContextMenuEvent = new object ();
+		
+		internal static object NavigationRequestedEvent = new object ();
+		
+		public event NodeEventHandler KeyDown
+		{
+			add { Events.AddHandler (KeyDownEvent, value); }
+			remove { Events.RemoveHandler (KeyDownEvent, value); }
+		}
+
+		public event NodeEventHandler KeyPress
+		{
+			add { Events.AddHandler (KeyPressEvent, value); }
+			remove { Events.RemoveHandler (KeyPressEvent, value); }
+		}
+		public event NodeEventHandler KeyUp
+		{
+			add { Events.AddHandler (KeyUpEvent, value); }
+			remove { Events.RemoveHandler (KeyUpEvent, value); }
+		}
+		public event NodeEventHandler MouseClick
+		{
+			add { Events.AddHandler (MouseClickEvent, value); }
+			remove { Events.RemoveHandler (MouseClickEvent, value); }
+		}
+		public event NodeEventHandler MouseDoubleClick
+		{
+			add { Events.AddHandler (MouseDoubleClickEvent, value); }
+			remove { Events.RemoveHandler (MouseDoubleClickEvent, value); }
+		}
+		public event NodeEventHandler MouseDown
+		{
+			add { Events.AddHandler (MouseDownEvent, value); }
+			remove { Events.RemoveHandler (MouseDownEvent, value); }
+		}
+		public event NodeEventHandler MouseEnter
+		{
+			add { Events.AddHandler (MouseEnterEvent, value); }
+			remove { Events.RemoveHandler (MouseEnterEvent, value); }
+		}
+		public event NodeEventHandler MouseLeave
+		{
+			add { Events.AddHandler (MouseLeaveEvent, value); }
+			remove { Events.RemoveHandler (MouseLeaveEvent, value); }
+		}
+		public event NodeEventHandler MouseMove
+		{
+			add { Events.AddHandler (MouseMoveEvent, value); }
+			remove { Events.RemoveHandler (MouseMoveEvent, value); }
+		}
+		public event NodeEventHandler MouseUp
+		{
+			add { Events.AddHandler (MouseUpEvent, value); }
+			remove { Events.RemoveHandler (MouseUpEvent, value); }
+		}
+		public event EventHandler Focus
+		{
+			add { Events.AddHandler (FocusEvent, value); }
+			remove { Events.RemoveHandler (FocusEvent, value); }
+		}
+		public event EventHandler Blur
+		{
+			add { Events.AddHandler (BlurEvent, value); }
+			remove { Events.RemoveHandler (BlurEvent, value); }
+		}
+		public event CreateNewWindowEventHandler CreateNewWindow
+		{
+			add { Events.AddHandler (CreateNewWindowEvent, value); }
+			remove { Events.RemoveHandler (CreateNewWindowEvent, value); }
+		}
+		public event AlertEventHandler Alert
+		{
+			add { Events.AddHandler (AlertEvent, value); }
+			remove { Events.RemoveHandler (AlertEvent, value); }
+		}
+		public event EventHandler Loaded
+		{
+			add { Events.AddHandler (LoadEvent, value); }
+			remove { Events.RemoveHandler (LoadEvent, value); }
+		}
+		public event EventHandler Unloaded
+		{
+			add { Events.AddHandler (UnloadEvent, value); }
+			remove { Events.RemoveHandler (UnloadEvent, value); }
+		}
+
+ 		public event StatusChangedEventHandler StatusChanged
+		{
+			add { Events.AddHandler (StatusChangedEvent, value); }
+			remove { Events.RemoveHandler (StatusChangedEvent, value); }
+		}
+		
+ 		public event SecurityChangedEventHandler SecurityChanged
+		{
+			add { Events.AddHandler (SecurityChangedEvent, value); }
+			remove { Events.RemoveHandler (SecurityChangedEvent, value); }
+		}
+
+		public event LoadStartedEventHandler LoadStarted
+		{
+			add { Events.AddHandler (LoadStartedEvent, value); }
+			remove { Events.RemoveHandler (LoadStartedEvent, value); }
+		}
+		
+		public event LoadCommitedEventHandler LoadCommited
+		{
+			add { Events.AddHandler (LoadCommitedEvent, value); }
+			remove { Events.RemoveHandler (LoadCommitedEvent, value); }
+		}		
+		
+		public event ProgressChangedEventHandler ProgressChanged
+		{
+			add { Events.AddHandler (ProgressChangedEvent, value); }
+			remove { Events.RemoveHandler (ProgressChangedEvent, value); }
+		}
+		
+		public event LoadFinishedEventHandler LoadFinished
+		{
+			add { Events.AddHandler (LoadFinishedEvent, value); }
+			remove { Events.RemoveHandler (LoadFinishedEvent, value); }
+		}
+
+		public event ContextMenuEventHandler ContextMenuShown
+		{
+			add { Events.AddHandler (ContextMenuEvent, value); }
+			remove { Events.RemoveHandler (ContextMenuEvent, value); }
+		}
+
+		public event NavigationRequestedEventHandler NavigationRequested
+		{
+			add { }
+			remove { }
+		}
+
+		internal static object GenericEvent = new object ();
+		internal event EventHandler Generic
+		{
+			add { Events.AddHandler (GenericEvent, value); }
+			remove { Events.RemoveHandler (GenericEvent, value); }
+		}
+
+		#endregion
+
+
+	}
+}
--- /dev/null
+++ mono-3.2.3+dfsg/mcs/class/Mono.WebBrowser/Mono.NullBrowser/Base.cs
@@ -0,0 +1,174 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2007, 2008 Novell, Inc.
+//
+// Authors:
+//	Andreia Gaita (avidigal@novell.com)
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using Mono.WebBrowser;
+
+namespace Mono.NullBrowser
+{
+	internal class Base
+	{
+		private static Hashtable boundControls;
+		private static bool initialized;
+		private static object initLock = new object ();
+		private static string monoMozDir;
+
+		private static bool isInitialized ()
+		{
+			if (!initialized)
+				return false;
+			return true;
+		}
+
+		static Base ()
+		{
+			boundControls = new Hashtable ();
+		}
+
+		public Base () { }
+
+		public static bool Init (WebBrowser control, Platform platform)
+		{
+			lock (initLock) {
+				if (!initialized) {
+				
+					initialized = true;
+				}
+			}
+			return initialized;
+		}
+
+		public static bool Bind (WebBrowser control, IntPtr handle, int width, int height)
+		{
+			if (!isInitialized ())
+				return false;
+
+			
+			return true;
+		}
+
+		public static bool Create (IWebBrowser control) {
+			if (!isInitialized ())
+				return false;
+
+			return true;
+		}
+
+		public static void Shutdown (IWebBrowser control)
+		{
+			lock (initLock) {
+				if (!initialized)
+					return;
+					
+				
+				boundControls.Remove (control);
+				if (boundControls.Count == 0) {
+					initialized = false;
+				}
+			}
+		}
+
+		// layout
+		public static void Focus (IWebBrowser control, FocusOption focus)
+		{
+			if (!isInitialized ())
+				return;
+
+		}
+
+
+		public static void Blur (IWebBrowser control)
+		{
+			if (!isInitialized ())
+				return;
+
+		}
+
+		public static void Activate (IWebBrowser control)
+		{
+			if (!isInitialized ())
+				return;
+
+		}
+
+		public static void Deactivate (IWebBrowser control)
+		{
+			if (!isInitialized ())
+				return;
+
+		}
+
+		public static void Resize (IWebBrowser control, int width, int height)
+		{
+			if (!isInitialized ())
+				return;
+
+		}
+
+		// navigation
+		public static void Home (IWebBrowser control)
+		{
+			if (!isInitialized ())
+				return;
+
+		}
+
+
+		public static IntPtr StringInit ()
+		{
+			return IntPtr.Zero;
+		}
+
+		public static void StringFinish (HandleRef str)
+		{
+		}
+
+		public static string StringGet (HandleRef str)
+		{
+			return String.Empty;
+		}
+
+		public static void StringSet (HandleRef str, string text)
+		{
+		}
+
+
+		public static object GetProxyForObject (IWebBrowser control, Guid iid, object obj)
+		{
+			return null;
+		}
+
+		public static string EvalScript (IWebBrowser control, string script)
+		{
+			return null;
+		}
+
+
+	}
+}
--- /dev/null
+++ mono-3.2.3+dfsg/mcs/class/Mono.WebBrowser/Mono.NullBrowser/DOM/Navigation.cs
@@ -0,0 +1,127 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2007, 2008 Novell, Inc.
+//
+// Authors:
+//	Andreia Gaita (avidigal@novell.com)
+//
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using Mono.WebBrowser;
+using Mono.WebBrowser.DOM;
+
+namespace Mono.NullBrowser.DOM
+{
+	internal class Navigation: INavigation
+	{
+
+
+		#region INavigation Members
+
+		public bool CanGoBack {
+			get {
+				return false;
+			}
+		}
+
+		public bool CanGoForward {
+			get {
+				return false;
+			}
+		}
+
+		public bool Back ()
+		{
+			return false;
+		}
+
+		public bool Forward ()
+		{
+			return false;
+		}
+
+		public void Home ()
+		{
+		}
+
+		public void Reload ()
+		{
+		}
+
+		public void Reload (ReloadOption option)
+		{
+		}
+
+		public void Stop ()
+		{
+		}
+		
+		
+		/// <summary>
+		/// Navigate to the page in the history, by index.
+		/// </summary>
+		/// <param name="index">
+		/// A <see cref="System.Int32"/> representing an absolute index in the 
+		/// history (that is, > -1 and < history length
+		/// </param>
+		public void Go (int index)
+		{
+		}
+
+		/// <summary>
+		/// 
+		/// </summary>
+		/// <param name="index">
+		/// A <see cref="System.Int32"/> representing an index in the 
+		/// history, that can be relative or absolute depending on the relative argument
+		/// </param>
+		/// <param name="relative">
+		/// A <see cref="System.Boolean"/> indicating whether the index is relative to 
+		/// the current place in history or not (i.e., if relative = true, index can be
+		/// positive or negative, and index=-1 means load the previous page in the history.
+		/// if relative = false, index must be > -1, and index = 0 means load the first
+		/// page of the history.
+		/// </param>
+		public void Go (int index, bool relative) {
+		}
+		
+		public void Go (string url)
+		{
+		}
+
+		public void Go (string url, LoadFlags flags) 
+		{
+		}
+
+		public int HistoryCount {
+			get {
+				return 0;
+			}
+		}
+
+		#endregion
+
+		public override int GetHashCode () {
+			return 0;
+		}		
+	}
+}
--- mono-3.2.3+dfsg.orig/mcs/class/corlib/System/Console.cs
+++ mono-3.2.3+dfsg/mcs/class/corlib/System/Console.cs
@@ -127,8 +127,7 @@ namespace System
 				int code_page = 0;
 				Encoding.InternalCodePage (ref code_page);
 
-				if (code_page != -1 && ((code_page & 0x0fffffff) == 3 // UTF8Encoding.UTF8_CODE_PAGE
-					|| ((code_page & 0x10000000) != 0)))
+				if (code_page == UTF8Encoding.UTF8_CODE_PAGE || ((code_page & 0x10000000) != 0))
 					inputEncoding = outputEncoding = Encoding.UTF8Unmarked;
 				else
 					inputEncoding = outputEncoding = Encoding.Default;
--- mono-3.2.3+dfsg.orig/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs
+++ mono-3.2.3+dfsg/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs
@@ -553,14 +553,16 @@ namespace Microsoft.Build.BuildEngine {
 
 		public string DefaultToolsVersion {
 			get {
-				// This is used as the fall back version if the
-				// project can't find a version to use
-				// Hard-coded to 2.0, so it allows even vs2005 projects
-				// to build correctly, as they won't have a ToolsVersion
-				// set!
-				return String.IsNullOrEmpty (defaultToolsVersion)
-						? "2.0"
-						: defaultToolsVersion;
+				if (String.IsNullOrEmpty (defaultToolsVersion))
+#if NET_4_0
+					return "4.0";
+#elif NET_3_5
+					return "3.5";
+#else
+					return "2.0";
+#endif
+				
+				return defaultToolsVersion;
 			}
 			set {
 				if (Toolsets [value] == null)
--- mono-3.2.3+dfsg.orig/mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs
+++ mono-3.2.3+dfsg/mcs/class/monodoc/Monodoc/providers/EcmaDoc.cs
@@ -541,10 +541,11 @@ namespace Monodoc.Providers
 				break;
 			// binary operators: overloading is possible [ECMA-335 §10.3.2]
 			default:
-				memberSignature =
-					nicename + "("
-					+ string.Join (",", member.Element ("Parameters").Elements ("Parameter").Select (p => (string)p.Attribute ("Type")))
-					+ ")";
+				if (member.Element ("Parameters") != null)
+					memberSignature =
+						nicename + "("
+						+ string.Join (",", member.Element ("Parameters").Elements ("Parameter").Select (p => (string)p.Attribute ("Type")))
+						+ ")";
 				break;
 			}
 
