1diff -ruN gc-7.2/dyn_load.c gc-7.2.qnx/dyn_load.c
2--- gc-7.2/dyn_load.c	2012-08-09 22:25:13.000000000 +0200
3+++ gc-7.2.qnx/dyn_load.c	2013-09-21 13:42:34.158631800 +0200
4@@ -63,7 +63,7 @@
5     !(defined(FREEBSD) && defined(__ELF__)) && \
6     !(defined(OPENBSD) && (defined(__ELF__) || defined(M68K))) && \
7     !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
8-    !defined(DARWIN) && !defined(CYGWIN32)
9+    !defined(DARWIN) && !defined(CYGWIN32) && !defined(QNX)
10  --> We only know how to find data segments of dynamic libraries for the
11  --> above.  Additional SVR4 variants might not be too
12  --> hard to add.
13@@ -76,6 +76,13 @@
14 #   include <link.h>
15 #endif
16
17+#ifdef QNX
18+#   include <sys/elf.h>
19+#   include <sys/link.h>
20+#   include <dlfcn.h>
21+#   define HAVE_DL_ITERATE_PHDR
22+#endif
23+
24 #if defined(NETBSD)
25 #   include <sys/param.h>
26 #   include <dlfcn.h>
27@@ -228,7 +235,8 @@
28
29 #if defined(SCO_ELF) || defined(DGUX) || defined(HURD) \
30     || (defined(__ELF__) && (defined(LINUX) || defined(FREEBSD) \
31-                             || defined(NETBSD) || defined(OPENBSD)))
32+                             || defined(NETBSD) || defined(OPENBSD) \
33+			     || defined(QNX)))
34
35 #ifdef USE_PROC_FOR_LIBRARIES
36
37@@ -621,11 +629,11 @@
38 #   ifndef PF_W
39 #     define PF_W       2
40 #   endif
41-# elif !defined(PLATFORM_ANDROID)
42+# elif !defined(PLATFORM_ANDROID) && !defined(QNX)
43 #  include <elf.h>
44 # endif
45
46-# ifndef PLATFORM_ANDROID
47+# if !defined(PLATFORM_ANDROID) && !defined(QNX)
48 #   include <link.h>
49 # endif
50
51diff -ruN gc-7.2/include/gc_config_macros.h gc-7.2.qnx/include/gc_config_macros.h
52--- gc-7.2/include/gc_config_macros.h	2012-08-09 22:25:13.000000000 +0200
53+++ gc-7.2.qnx/include/gc_config_macros.h	2013-09-21 13:38:24.027325100 +0200
54@@ -68,7 +68,8 @@
55     || defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) \
56     || defined(GC_NETBSD_THREADS) || defined(GC_OPENBSD_THREADS) \
57     || defined(GC_OSF1_THREADS) || defined(GC_SOLARIS_THREADS) \
58-    || defined(GC_WIN32_THREADS) || defined(GC_RTEMS_PTHREADS)
59+    || defined(GC_WIN32_THREADS) || defined(GC_RTEMS_PTHREADS) \
60+    || defined(GC_QNX_THREADS)
61 # ifndef GC_THREADS
62 #   define GC_THREADS
63 # endif
64diff -ruN gc-7.2/include/private/gcconfig.h gc-7.2.qnx/include/private/gcconfig.h
65--- gc-7.2/include/private/gcconfig.h	2012-08-09 22:25:13.000000000 +0200
66+++ gc-7.2.qnx/include/private/gcconfig.h	2013-09-21 13:40:27.678397600 +0200
67@@ -43,6 +43,33 @@
68 #   define LINUX
69 # endif
70
71+/* for BB10 support */
72+# if defined(__QNX__)
73+#  if defined(__arm__)
74+#    define ARM32
75+     extern int __data_start[];
76+#    define DATASTART ((ptr_t)__data_start)
77+     extern char _end[];
78+#    define DATAEND ((ptr_t)(&_end))
79+#  else
80+/* for simulator */
81+#    define I386
82+     extern char etext[];
83+#    define DATASTART ((ptr_t)(etext))
84+     extern int _end[];
85+#    define DATAEND (_end)
86+#  endif
87+/* common things */
88+#  define QNX
89+#  define OS_TYPE "QNX"
90+#  define SA_RESTART 0
91+#  define HEURISTIC2
92+#  define USE_MMAP
93+#  define USE_MMAP_ANON
94+#  define DYNAMIC_LOADING
95+#  define mach_type_known
96+# endif
97+
98 /* And one for NetBSD: */
99 # if defined(__NetBSD__)
100 #    define NETBSD
101@@ -73,7 +100,8 @@
102 # if defined(__arm) || defined(__arm__) || defined(__thumb__)
103 #    define ARM32
104 #    if !defined(LINUX) && !defined(NETBSD) && !defined(OPENBSD) \
105-        && !defined(DARWIN) && !defined(_WIN32) && !defined(__CEGCC__)
106+        && !defined(DARWIN) && !defined(_WIN32) && !defined(__CEGCC__) \
107+        && !defined(QNX)
108 #      define NOSYS
109 #      define mach_type_known
110 #    endif
111@@ -2404,7 +2432,7 @@
112 #if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
113     || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
114     || defined(DGUX) || defined(BSD) || defined(HURD) \
115-    || defined(AIX) || defined(DARWIN) || defined(OSF1)
116+    || defined(AIX) || defined(DARWIN) || defined(OSF1) || defined(QNX)
117 # define UNIX_LIKE      /* Basic Unix-like system calls work.   */
118 #endif
119
120@@ -2482,7 +2510,8 @@
121
122 #if ((defined(UNIX_LIKE) && (defined(DARWIN) || defined(HURD) \
123                              || defined(OPENBSD) || defined(ARM32) \
124-                             || defined(MIPS) || defined(AVR32))) \
125+                             || defined(MIPS) || defined(AVR32)	   \
126+			     || defined(QNX)))			   \
127      || (defined(LINUX) && (defined(SPARC) || defined(M68K))) \
128      || (defined(RTEMS) && defined(I386))) && !defined(NO_GETCONTEXT)
129 # define NO_GETCONTEXT
130@@ -2568,6 +2597,9 @@
131     && !defined(MSWINCE)
132 # error --> inconsistent configuration
133 #endif
134+#if defined(GC_QNX_THREADS) && !defined(QNX)
135+# error --> inconsistent configuration
136+#endif
137
138 #if defined(PCR) || defined(GC_WIN32_THREADS) || defined(GC_PTHREADS) \
139     || defined(SN_TARGET_PS3)
140diff -ruN gc-7.2/include/private/thread_local_alloc.h gc-7.2.qnx/include/private/thread_local_alloc.h
141--- gc-7.2/include/private/thread_local_alloc.h	2012-08-09 22:25:13.000000000 +0200
142+++ gc-7.2.qnx/include/private/thread_local_alloc.h	2013-09-21 13:38:24.128330900 +0200
143@@ -47,7 +47,8 @@
144 #   define USE_COMPILER_TLS
145 # elif defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) \
146        || defined(GC_DARWIN_THREADS) || defined(GC_AIX_THREADS) \
147-       || defined(GC_NETBSD_THREADS) || defined(GC_RTEMS_PTHREADS)
148+       || defined(GC_NETBSD_THREADS) || defined(GC_RTEMS_PTHREADS) \
149+       || defined(GC_QNX_THREADS)
150 #   define USE_PTHREAD_SPECIFIC
151 # elif defined(GC_HPUX_THREADS)
152 #   ifdef __GNUC__
153diff -ruN gc-7.2/os_dep.c gc-7.2.qnx/os_dep.c
154--- gc-7.2/os_dep.c	2012-08-09 22:25:13.000000000 +0200
155+++ gc-7.2.qnx/os_dep.c	2013-09-21 13:38:24.184334100 +0200
156@@ -98,6 +98,7 @@
157 #endif
158
159 #if defined(LINUX) || defined(FREEBSD) || defined(SOLARIS) || defined(IRIX5) \
160+        || defined(QNX)							\
161         || ((defined(USE_MMAP) || defined(USE_MUNMAP)) \
162         && !defined(MSWIN32) && !defined(MSWINCE))
163 # define MMAP_SUPPORTED
164@@ -828,10 +829,12 @@
165     typedef void (*GC_fault_handler_t)(int);
166
167 #   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \
168-       || defined(HURD) || defined(NETBSD)
169+       || defined(HURD) || defined(NETBSD) \
170+       || defined(QNX)
171         static struct sigaction old_segv_act;
172 #       if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) \
173-           || defined(HURD) || defined(NETBSD) || defined(FREEBSD)
174+           || defined(HURD) || defined(NETBSD) || defined(FREEBSD)\
175+           || defined(QNX)
176             static struct sigaction old_bus_act;
177 #       endif
178 #   else
179@@ -841,7 +844,8 @@
180     GC_INNER void GC_set_and_save_fault_handler(GC_fault_handler_t h)
181     {
182 #       if defined(SUNOS5SIGS) || defined(IRIX5) \
183-           || defined(OSF1) || defined(HURD) || defined(NETBSD)
184+           || defined(OSF1) || defined(HURD) || defined(NETBSD) \
185+           || defined(QNX)
186           struct sigaction act;
187
188           act.sa_handler = h;
189@@ -863,7 +867,7 @@
190             (void) sigaction(SIGSEGV, &act, &old_segv_act);
191 #           if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \
192                || defined(HPUX) || defined(HURD) || defined(NETBSD) \
193-               || defined(FREEBSD)
194+               || defined(FREEBSD) || defined(QNX)
195               /* Under Irix 5.x or HP/UX, we may get SIGBUS.    */
196               /* Pthreads doesn't exist under Irix 5.x, so we   */
197               /* don't have to worry in the threads case.       */
198@@ -901,11 +905,12 @@
199     GC_INNER void GC_reset_fault_handler(void)
200     {
201 #       if defined(SUNOS5SIGS) || defined(IRIX5) \
202-           || defined(OSF1) || defined(HURD) || defined(NETBSD)
203+           || defined(OSF1) || defined(HURD) || defined(NETBSD) \
204+           || defined(QNX)
205           (void) sigaction(SIGSEGV, &old_segv_act, 0);
206 #         if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \
207              || defined(HPUX) || defined(HURD) || defined(NETBSD) \
208-             || defined(FREEBSD)
209+             || defined(FREEBSD) || defined(QNX)
210               (void) sigaction(SIGBUS, &old_bus_act, 0);
211 #         endif
212 #       else
213@@ -1371,6 +1376,31 @@
214 # define HAVE_GET_STACK_BASE
215 #endif /* GC_RTEMS_PTHREADS */
216
217+#if defined (GC_QNX_THREADS)
218+
219+#  include <pthread.h>
220+  GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *b)
221+  {
222+    pthread_attr_t attr;
223+    size_t size;
224+    if (pthread_attr_init(&attr) == 0) {
225+      if (pthread_attr_getstack(&attr, &b->mem_base, &size) == 0) {
226+	pthread_attr_destroy(&attr);
227+	if (GC_print_stats == VERBOSE) {
228+	  GC_log_printf("Stack base address %p\n", b->mem_base);
229+	}
230+	return GC_SUCCESS;
231+      }
232+      pthread_attr_destroy(&attr);
233+    }
234+    WARN("pthread_attr_init or pthread_attr_getstack failed"
235+	 " for main thread\n", 0);
236+    return GC_UNIMPLEMENTED;
237+  }
238+# define HAVE_GET_STACK_BASE
239+#endif
240+
241+
242 #ifndef HAVE_GET_STACK_BASE
243   /* Retrieve stack base.                                               */
244   /* Using the GC_find_limit version is risky.                          */
245diff -ruN gc-7.2/pthread_support.c gc-7.2.qnx/pthread_support.c
246--- gc-7.2/pthread_support.c	2012-08-09 22:25:13.000000000 +0200
247+++ gc-7.2.qnx/pthread_support.c	2013-09-21 13:38:24.214335800 +0200
248@@ -935,6 +935,10 @@
249                                         ptr_t *startp, ptr_t *endp);
250 #endif
251
252+#ifdef GC_QNX_THREADS
253+# include <sys/syspage.h>
254+#endif
255+
256 /* We hold the allocation lock. */
257 GC_INNER void GC_thr_init(void)
258 {
259@@ -1012,6 +1016,8 @@
260       GC_nprocs = GC_get_nprocs();
261 #   elif defined(GC_RTEMS_PTHREADS)
262       GC_nprocs = 1; /* not implemented */
263+#   elif defined(GC_QNX_THREADS)
264+      GC_nprocs = _syspage_ptr->num_cpu;
265 #   endif
266   }
267   if (GC_nprocs <= 0) {
268