Imported Upstream version 1.2
[platform/upstream/libunwind.git] / include / libunwind_i.h
index 23f615e..ee2ea2f 100644 (file)
@@ -1,7 +1,7 @@
 /* libunwind - a platform-independent unwind library
    Copyright (C) 2001-2005 Hewlett-Packard Co
    Copyright (C) 2007 David Mosberger-Tang
-       Contributed by David Mosberger-Tang <dmosberger@gmail.com>
+        Contributed by David Mosberger-Tang <dmosberger@gmail.com>
 
 This file is part of libunwind.
 
@@ -46,7 +46,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 
 /* Platform-independent libunwind-internal declarations.  */
 
-#include <sys/types.h> /* HP-UX needs this before include of pthread.h */
+#include <sys/types.h>  /* HP-UX needs this before include of pthread.h */
 
 #include <assert.h>
 #include <libunwind.h>
@@ -56,26 +56,47 @@ 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>
+#elif defined(HAVE_SYS_ELF_H)
+# include <sys/elf.h>
+#else
+# error Could not locate <elf.h>
+#endif
 
 #if defined(HAVE_ENDIAN_H)
 # include <endian.h>
 #elif defined(HAVE_SYS_ENDIAN_H)
 # include <sys/endian.h>
 #else
-# define __LITTLE_ENDIAN       1234
-# define __BIG_ENDIAN          4321
+# define __LITTLE_ENDIAN        1234
+# 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
 #endif
 
+#if defined(HAVE__BUILTIN_UNREACHABLE)
+# define unreachable() __builtin_unreachable()
+#else
+# define unreachable() do { } while (1)
+#endif
+
 #ifdef DEBUG
-# define UNW_DEBUG     1
+# define UNW_DEBUG      1
 #else
-# define UNW_DEBUG     0
+# define UNW_DEBUG      0
 #endif
 
 /* Make it easy to write thread-safe code which may or may not be
@@ -87,12 +108,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
 #pragma weak pthread_mutex_lock
 #pragma weak pthread_mutex_unlock
 
-#define mutex_init(l)                                                  \
-       (pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0)
-#define mutex_lock(l)                                                  \
-       (pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0)
-#define mutex_unlock(l)                                                        \
-       (pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0)
+#define mutex_init(l)                                                   \
+        (pthread_mutex_init != NULL ? pthread_mutex_init ((l), NULL) : 0)
+#define mutex_lock(l)                                                   \
+        (pthread_mutex_lock != NULL ? pthread_mutex_lock (l) : 0)
+#define mutex_unlock(l)                                                 \
+        (pthread_mutex_unlock != NULL ? pthread_mutex_unlock (l) : 0)
 
 #ifdef HAVE_ATOMIC_OPS_H
 # include <atomic_ops.h>
@@ -109,8 +130,8 @@ cmpxchg_ptr (void *addr, void *old, void *new)
   u.vp = addr;
   return AO_compare_and_swap(u.aop, (AO_t) old, (AO_t) new);
 }
-# define fetch_and_add1(_ptr)          AO_fetch_and_add1(_ptr)
-# define fetch_and_add(_ptr, value)    AO_fetch_and_add(_ptr, value)
+# define fetch_and_add1(_ptr)           AO_fetch_and_add1(_ptr)
+# define fetch_and_add(_ptr, value)     AO_fetch_and_add(_ptr, value)
    /* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */
 #  if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
 #   define HAVE_CMPXCHG
@@ -133,14 +154,14 @@ cmpxchg_ptr (void *addr, void *old, void *new)
   u.vp = addr;
   return __sync_bool_compare_and_swap(u.vlp, (long) old, (long) new);
 }
-# define fetch_and_add1(_ptr)          __sync_fetch_and_add(_ptr, 1)
-# define fetch_and_add(_ptr, value)    __sync_fetch_and_add(_ptr, value)
+# define fetch_and_add1(_ptr)           __sync_fetch_and_add(_ptr, 1)
+# define fetch_and_add(_ptr, value)     __sync_fetch_and_add(_ptr, value)
 # define HAVE_CMPXCHG
 # define HAVE_FETCH_AND_ADD
 #endif
-#define atomic_read(ptr)       (*(ptr))
+#define atomic_read(ptr)        (*(ptr))
 
-#define UNWI_OBJ(fn)     UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
+#define UNWI_OBJ(fn)      UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
 #define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
 
 #define unwi_full_mask    UNWI_ARCH_OBJ(full_mask)
@@ -165,91 +186,94 @@ static inline void mark_as_used(void *v UNUSED) {
 # define SIGPROCMASK(how, new_mask, old_mask) mark_as_used(old_mask)
 #endif
 
+/* Prefer adaptive mutexes if available */
+#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+#else
+#define UNW_PTHREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+#endif
+
 #define define_lock(name) \
-  pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
-#define lock_init(l)           mutex_init (l)
-#define lock_acquire(l,m)                              \
-do {                                                   \
-  SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m));    \
-  mutex_lock (l);                                      \
+  pthread_mutex_t name = UNW_PTHREAD_MUTEX_INITIALIZER
+#define lock_init(l)            mutex_init (l)
+#define lock_acquire(l,m)                               \
+do {                                                    \
+  SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &(m));     \
+  mutex_lock (l);                                       \
 } while (0)
-#define lock_release(l,m)                      \
-do {                                           \
-  mutex_unlock (l);                            \
-  SIGPROCMASK (SIG_SETMASK, &(m), NULL);       \
+#define lock_release(l,m)                       \
+do {                                            \
+  mutex_unlock (l);                             \
+  SIGPROCMASK (SIG_SETMASK, &(m), NULL);        \
 } while (0)
 
-#define SOS_MEMORY_SIZE 16384  /* see src/mi/mempool.c */
+#define SOS_MEMORY_SIZE 16384   /* see src/mi/mempool.c */
 
 #ifndef MAP_ANONYMOUS
 # define MAP_ANONYMOUS MAP_ANON
 #endif
-#define GET_MEMORY(mem, size)                                              \
-do {                                                                       \
+#define GET_MEMORY(mem, size)                                               \
+do {                                                                        \
   /* Hopefully, mmap() goes straight through to a system call stub...  */   \
-  mem = mmap (NULL, size, PROT_READ | PROT_WRITE,                          \
-             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);                          \
-  if (mem == MAP_FAILED)                                                   \
-    mem = NULL;                                                                    \
+  mem = mmap (NULL, size, PROT_READ | PROT_WRITE,                           \
+              MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);                          \
+  if (mem == MAP_FAILED)                                                    \
+    mem = NULL;                                                             \
 } while (0)
 
-#define unwi_find_dynamic_proc_info    UNWI_OBJ(find_dynamic_proc_info)
-#define unwi_extract_dynamic_proc_info UNWI_OBJ(extract_dynamic_proc_info)
-#define unwi_put_dynamic_unwind_info   UNWI_OBJ(put_dynamic_unwind_info)
-#define unwi_dyn_remote_find_proc_info UNWI_OBJ(dyn_remote_find_proc_info)
-#define unwi_dyn_remote_put_unwind_info        UNWI_OBJ(dyn_remote_put_unwind_info)
-#define unwi_dyn_validate_cache                UNWI_OBJ(dyn_validate_cache)
+#define unwi_find_dynamic_proc_info     UNWI_OBJ(find_dynamic_proc_info)
+#define unwi_extract_dynamic_proc_info  UNWI_OBJ(extract_dynamic_proc_info)
+#define unwi_put_dynamic_unwind_info    UNWI_OBJ(put_dynamic_unwind_info)
+#define unwi_dyn_remote_find_proc_info  UNWI_OBJ(dyn_remote_find_proc_info)
+#define unwi_dyn_remote_put_unwind_info UNWI_OBJ(dyn_remote_put_unwind_info)
+#define unwi_dyn_validate_cache         UNWI_OBJ(dyn_validate_cache)
 
 extern int unwi_find_dynamic_proc_info (unw_addr_space_t as,
-                                       unw_word_t ip,
-                                       unw_proc_info_t *pi,
-                                       int need_unwind_info, void *arg);
+                                        unw_word_t ip,
+                                        unw_proc_info_t *pi,
+                                        int need_unwind_info, void *arg);
 extern int unwi_extract_dynamic_proc_info (unw_addr_space_t as,
-                                          unw_word_t ip,
-                                          unw_proc_info_t *pi,
-                                          unw_dyn_info_t *di,
-                                          int need_unwind_info,
-                                          void *arg);
+                                           unw_word_t ip,
+                                           unw_proc_info_t *pi,
+                                           unw_dyn_info_t *di,
+                                           int need_unwind_info,
+                                           void *arg);
 extern void unwi_put_dynamic_unwind_info (unw_addr_space_t as,
-                                         unw_proc_info_t *pi, void *arg);
+                                          unw_proc_info_t *pi, void *arg);
 
 /* These handle the remote (cross-address-space) case of accessing
    dynamic unwind info. */
 
 extern int unwi_dyn_remote_find_proc_info (unw_addr_space_t as,
-                                          unw_word_t ip,
-                                          unw_proc_info_t *pi,
-                                          int need_unwind_info,
-                                          void *arg);
+                                           unw_word_t ip,
+                                           unw_proc_info_t *pi,
+                                           int need_unwind_info,
+                                           void *arg);
 extern void unwi_dyn_remote_put_unwind_info (unw_addr_space_t as,
-                                            unw_proc_info_t *pi,
-                                            void *arg);
+                                             unw_proc_info_t *pi,
+                                             void *arg);
 extern int unwi_dyn_validate_cache (unw_addr_space_t as, void *arg);
 
 extern unw_dyn_info_list_t _U_dyn_info_list;
 extern pthread_mutex_t _U_dyn_info_list_lock;
 
 #if UNW_DEBUG
-#define unwi_debug_level               UNWI_ARCH_OBJ(debug_level)
+#define unwi_debug_level                UNWI_ARCH_OBJ(debug_level)
 extern long unwi_debug_level;
 
 # include <stdio.h>
-# define Debug(level,format...)                                                \
-do {                                                                   \
-  if (unwi_debug_level >= level)                                       \
-    {                                                                  \
-      int _n = level;                                                  \
-      if (_n > 16)                                                     \
-       _n = 16;                                                        \
-      fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__);             \
-      fprintf (stderr, format);                                                \
-    }                                                                  \
+# define Debug(level,format...)                                         \
+do {                                                                    \
+  if (unwi_debug_level >= level)                                        \
+    {                                                                   \
+      int _n = level;                                                   \
+      if (_n > 16)                                                      \
+        _n = 16;                                                        \
+      fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__);              \
+      fprintf (stderr, format);                                         \
+    }                                                                   \
 } while (0)
-# define Dprintf(format...)        fprintf (stderr, format)
-# ifdef __GNUC__
-#  undef inline
-#  define inline       UNUSED
-# endif
+# define Dprintf(format...)         fprintf (stderr, format)
 #else
 # define Debug(level,format...)
 # define Dprintf(format...)
@@ -261,17 +285,17 @@ print_error (const char *string)
   return write (2, string, strlen (string));
 }
 
-#define mi_init                UNWI_ARCH_OBJ(mi_init)
+#define mi_init         UNWI_ARCH_OBJ(mi_init)
 
-extern void mi_init (void);    /* machine-independent initializations */
+extern void mi_init (void);     /* machine-independent initializations */
 extern unw_word_t _U_dyn_info_list_addr (void);
 
 /* This is needed/used by ELF targets only.  */
 
 struct elf_image
   {
-    void *image;               /* pointer to mmap'd image */
-    size_t size;               /* (file-) size of the image */
+    void *image;                /* pointer to mmap'd image */
+    size_t size;                /* (file-) size of the image */
   };
 
 struct elf_dyn_info
@@ -311,16 +335,21 @@ static inline void invalidate_edi (struct elf_dyn_info *edi)
 /* Define GNU and processor specific values for the Phdr p_type field in case
    they aren't defined by <elf.h>.  */
 #ifndef PT_GNU_EH_FRAME
-# define PT_GNU_EH_FRAME       0x6474e550
+# define PT_GNU_EH_FRAME        0x6474e550
 #endif /* !PT_GNU_EH_FRAME */
 #ifndef PT_ARM_EXIDX
-# define PT_ARM_EXIDX          0x70000001      /* ARM unwind segment */
+# define PT_ARM_EXIDX           0x70000001      /* ARM unwind segment */
 #endif /* !PT_ARM_EXIDX */
 
 #include "tdep/libunwind_i.h"
 
 #ifndef tdep_get_func_addr
-# define tdep_get_func_addr(as,addr,v)         (*(v) = addr, 0)
+# define tdep_get_func_addr(as,addr,v)          (*(v) = addr, 0)
+#endif
+
+#ifndef DWARF_VAL_LOC
+# define DWARF_IS_VAL_LOC(l)    0
+# define DWARF_VAL_LOC(c,v)     DWARF_NULL_LOC
 #endif
 
 #define UNW_ALIGN(x,a) (((x)+(a)-1UL)&~((a)-1UL))