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