From acce84a7e58cb73342ff28d211a8ee6c15e42207 Mon Sep 17 00:00:00 2001
From: Matt Fischer <matt.fischer@garmin.com>
Date: Mon, 15 Apr 2013 09:53:29 -0500
Subject: [PATCH 3/3] Add basic support for the QNX operating system

This change adds some special cases to allow libunwind to compile
for QNX.  Only remote unwinding is supported thus far--local unwinding
requires further work.

* QNX's copy of <elf.h> resides in <sys/elf.h> instead.  To deal with this,
  an AC_CHECK_HEADERS() was added for elf.h, with a special case to deal with
  QNX when it is not found in its default location.
* Similarly, QNX does not have <endian.h>.  In cases where the file is not found,
  logic was added to refer to QNX-specific macros to determine endianness.
* Finally, the QCC compiler, which is a wrapper around GCC, cannot handle the
  option -nostartfiles.  Therefore, logic was added to check for QCC, and when
  it is found, to express the option as -Wc,-nostartfiles instead, which is
  correctly passed on to the underlying GCC.
---
 configure.ac                   | 13 ++++++++++++-
 include/libunwind_i.h          | 20 +++++++++++++++++++-
 src/Makefile.am                |  2 +-
 src/dwarf/Gfind_unwind_table.c |  1 -
 src/elfxx.h                    |  1 -
 5 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 074493d..a175c77 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,7 +37,7 @@ dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS(asm/ptrace_offsets.h endian.h sys/endian.h execinfo.h \
 		ia64intrin.h sys/uc_access.h unistd.h signal.h sys/types.h \
-		sys/procfs.h sys/ptrace.h byteswap.h)
+		sys/procfs.h sys/ptrace.h byteswap.h elf.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
@@ -274,6 +274,10 @@ if test x$GCC = xyes -a x$intel_compiler != xyes; then
 fi
 AC_MSG_RESULT([$intel_compiler])
 
+AC_MSG_CHECKING([for QCC compiler])
+AS_CASE([$CC], [qcc*|QCC*], [qcc_compiler=yes], [qcc_compiler=no])
+AC_MSG_RESULT([$qcc_compiler])
+
 if test x$intel_compiler = xyes; then
   AC_MSG_CHECKING([if linker supports -static-libcxa])
   save_LDFLAGS="$LDFLAGS"
@@ -286,6 +290,12 @@ if test x$intel_compiler = xyes; then
   AC_MSG_RESULT([$have_static_libcxa])
 fi
 
+if test x$qcc_compiler = xyes; then
+    LDFLAGS_NOSTARTFILES="-XCClinker -Wc,-nostartfiles"
+else
+    LDFLAGS_NOSTARTFILES="-XCClinker -nostartfiles"
+fi
+
 AC_MSG_CHECKING([for __builtin___clear_cache])
 AC_LINK_IFELSE(
   [AC_LANG_PROGRAM([[]], [[__builtin___clear_cache(0, 0)]])],
@@ -343,6 +353,7 @@ AC_SUBST(target_os)
 AC_SUBST(arch)
 AC_SUBST(ARCH)
 AC_SUBST(LDFLAGS_STATIC_LIBCXA)
+AC_SUBST(LDFLAGS_NOSTARTFILES)
 AC_SUBST(LIBCRTS)
 AC_SUBST(PKG_MAJOR)
 AC_SUBST(PKG_MINOR)
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index 966a3e3..4fed2b6 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -56,7 +56,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 #include <string.h>
 #include <unistd.h>
 #include <sys/mman.h>
-#include <elf.h>
+
+#if defined(HAVE_ELF_H)
+# include <elf.h>
+#else
+# if defined(__QNX__)
+#  include <sys/elf.h>
+#  include <sys/elf_dyn.h>
+# else
+#  error Could not locate <elf.h>
+# endif
+#endif
 
 #if defined(HAVE_ENDIAN_H)
 # include <endian.h>
@@ -67,6 +77,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 # define __BIG_ENDIAN		4321
 # if defined(__hpux)
 #   define __BYTE_ORDER __BIG_ENDIAN
+# elif defined(__QNX__)
+#   if defined(__BIGENDIAN__)
+#     define __BYTE_ORDER __BIG_ENDIAN
+#   elif defined(__LITTLEENDIAN__)
+#     define __BYTE_ORDER __LITTLE_ENDIAN
+#   else
+#     error Host has unknown byte-order.
+#   endif
 # else
 #   error Host has unknown byte-order.
 # endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 73e6fa7..a3b84f0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,7 @@ COREDUMP_SO_VERSION=0:0:0
 #
 # Don't link with start-files since we don't use any constructors/destructors:
 #
-COMMON_SO_LDFLAGS =	-XCClinker -nostartfiles
+COMMON_SO_LDFLAGS = $(LDFLAGS_NOSTARTFILES)
 
 lib_LIBRARIES =
 lib_LTLIBRARIES =
diff --git a/src/dwarf/Gfind_unwind_table.c b/src/dwarf/Gfind_unwind_table.c
index 961226a..eb01ae9 100644
--- a/src/dwarf/Gfind_unwind_table.c
+++ b/src/dwarf/Gfind_unwind_table.c
@@ -23,7 +23,6 @@ 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.  */
 
-#include <elf.h>
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
diff --git a/src/elfxx.h b/src/elfxx.h
index dea0463..558a235 100644
--- a/src/elfxx.h
+++ b/src/elfxx.h
@@ -24,7 +24,6 @@ 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.  */
 
-#include <elf.h>
 #include <fcntl.h>
 #include <unistd.h>
 
-- 
1.8.0.msysgit.0

