diff options
-rw-r--r-- | include/compiler.h | 16 | ||||
-rw-r--r-- | include/dwarf-eh.h | 10 | ||||
-rw-r--r-- | include/libunwind-aarch64.h | 10 | ||||
-rw-r--r-- | include/libunwind-arm.h | 6 | ||||
-rw-r--r-- | include/libunwind_i.h | 11 | ||||
-rw-r--r-- | include/tdep-aarch64/libunwind_i.h | 10 | ||||
-rw-r--r-- | include/tdep-arm/libunwind_i.h | 10 | ||||
-rw-r--r-- | include/tdep-x86_64/libunwind_i.h | 10 | ||||
-rw-r--r-- | src/aarch64/Gtrace.c | 4 | ||||
-rw-r--r-- | src/arm/Gtrace.c | 4 | ||||
-rw-r--r-- | src/dwarf/Gexpr.c | 43 | ||||
-rw-r--r-- | src/os-linux.h | 4 | ||||
-rw-r--r-- | src/x86_64/Gglobal.c | 2 | ||||
-rw-r--r-- | src/x86_64/Ginit.c | 4 | ||||
-rw-r--r-- | src/x86_64/Gtrace.c | 4 |
15 files changed, 124 insertions, 24 deletions
diff --git a/include/compiler.h b/include/compiler.h index 2fa59eff..3100be09 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -30,6 +30,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef COMPILER_H #define COMPILER_H +#if defined(__STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L // C11 +# include <thread.h> +# define THREAD_LOCAL thread_local +#elseif defined(__GNUC__) +# define THREAD_LOCAL __thread +#else +# define THREAD_LOCAL +#endif + #ifdef __GNUC__ # define ALIGNED(x) __attribute__((aligned(x))) # define CONST_ATTR __attribute__((__const__)) @@ -67,6 +76,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # define unlikely(x) (x) #endif +#ifdef _MSC_VER +#include <inttypes.h> +uint32_t fetch_and_add(uint32_t* ptr, uint32_t value); +# define fetch_and_add1(_ptr) fetch_and_add(_ptr, 1) +# define HAVE_FETCH_AND_ADD +#endif + #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) #endif /* COMPILER_H */ diff --git a/include/dwarf-eh.h b/include/dwarf-eh.h index 96002a1b..f48e9190 100644 --- a/include/dwarf-eh.h +++ b/include/dwarf-eh.h @@ -107,6 +107,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define DW_EH_VERSION 1 /* The version we're implementing */ +#ifdef _MSC_VER +#pragma pack(push, 1) +#define __attribute__(x) +#endif + struct __attribute__((packed)) dwarf_eh_frame_hdr { unsigned char version; @@ -126,4 +131,9 @@ struct __attribute__((packed)) dwarf_eh_frame_hdr binary_search_table[fde_count]; */ }; +#ifdef _MSC_VER +#pragma pack(pop) +#undef __attribute__ +#endif + #endif /* dwarf_eh_h */ diff --git a/include/libunwind-aarch64.h b/include/libunwind-aarch64.h index 2716afcc..2463d00c 100644 --- a/include/libunwind-aarch64.h +++ b/include/libunwind-aarch64.h @@ -34,6 +34,11 @@ extern "C" { #include <inttypes.h> #include <stddef.h> #include <ucontext.h> +#include "compiler.h" + +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT +#endif #define UNW_TARGET aarch64 #define UNW_TARGET_AARCH64 1 @@ -60,6 +65,7 @@ typedef long double unw_tdep_fpreg_t; typedef struct { /* no aarch64-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; @@ -169,10 +175,10 @@ aarch64_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; - /* On AArch64, we can directly use ucontext_t as the unwind context, * however, the __reserved struct is quite large: tune it down to only * the necessary used fields. */ @@ -184,7 +190,7 @@ struct unw_sigcontext uint64_t sp; uint64_t pc; uint64_t pstate; - uint8_t __reserved[(66 * 8)] __attribute__((__aligned__(16))); + uint8_t __reserved[(66 * 8)] ALIGNED(16); }; typedef struct diff --git a/include/libunwind-arm.h b/include/libunwind-arm.h index 6709b7ab..ea14577b 100644 --- a/include/libunwind-arm.h +++ b/include/libunwind-arm.h @@ -32,6 +32,10 @@ extern "C" { #include <inttypes.h> #include <stddef.h> +#ifndef UNW_EMPTY_STRUCT +# define UNW_EMPTY_STRUCT +#endif + #define UNW_TARGET arm #define UNW_TARGET_ARM 1 @@ -247,6 +251,7 @@ arm_regnum_t; typedef struct unw_tdep_save_loc { /* Additional target-dependent info on a save location. */ + UNW_EMPTY_STRUCT } unw_tdep_save_loc_t; @@ -288,6 +293,7 @@ unw_tdep_context_t; typedef struct { /* no arm-specific auxiliary proc-info */ + UNW_EMPTY_STRUCT } unw_tdep_proc_info_t; diff --git a/include/libunwind_i.h b/include/libunwind_i.h index e0f45401..3eecab72 100644 --- a/include/libunwind_i.h +++ b/include/libunwind_i.h @@ -275,7 +275,7 @@ extern pthread_mutex_t _U_dyn_info_list_lock; extern long unwi_debug_level; # include <stdio.h> -# define Debug(level,format...) \ +# define Debug(level, /* format */ ...) \ do { \ if (unwi_debug_level >= level) \ { \ @@ -283,13 +283,14 @@ do { \ if (_n > 16) \ _n = 16; \ fprintf (stderr, "%*c>%s: ", _n, ' ', __FUNCTION__); \ - fprintf (stderr, format); \ + fprintf (stderr, /* format */ __VA_ARGS__); \ } \ } while (0) -# define Dprintf(format...) fprintf (stderr, format) +# define Dprintf(/* format */ ...) \ + fprintf (stderr, /* format */ __VA_ARGS__) #else -# define Debug(level,format...) -# define Dprintf(format...) +# define Debug(level, /* format */ ...) +# define Dprintf( /* format */ ...) #endif static ALWAYS_INLINE int diff --git a/include/tdep-aarch64/libunwind_i.h b/include/tdep-aarch64/libunwind_i.h index b91273fa..6996b98b 100644 --- a/include/tdep-aarch64/libunwind_i.h +++ b/include/tdep-aarch64/libunwind_i.h @@ -160,8 +160,14 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) # define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) + +static inline int +dwarf_is_null_loc(dwarf_loc_t l) +{ + return l.val == 0 && l.type == 0; +} + +# define DWARF_IS_NULL_LOC(l) dwarf_is_null_loc(l) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h index 2602f41c..19ae4c30 100644 --- a/include/tdep-arm/libunwind_i.h +++ b/include/tdep-arm/libunwind_i.h @@ -151,8 +151,14 @@ dwarf_put (struct dwarf_cursor *c, dwarf_loc_t loc, unw_word_t val) # define DWARF_LOC_TYPE_FP (1 << 0) # define DWARF_LOC_TYPE_REG (1 << 1) # define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) + +static inline int +dwarf_is_null_loc(dwarf_loc_t l) +{ + return l.val == 0 && l.type == 0; +} + +# define DWARF_IS_NULL_LOC(l) dwarf_is_null_loc(l) # define DWARF_LOC(r, t) ((dwarf_loc_t) { .val = (r), .type = (t) }) # define DWARF_IS_REG_LOC(l) (((l).type & DWARF_LOC_TYPE_REG) != 0) # define DWARF_IS_FP_LOC(l) (((l).type & DWARF_LOC_TYPE_FP) != 0) diff --git a/include/tdep-x86_64/libunwind_i.h b/include/tdep-x86_64/libunwind_i.h index 6b798c71..ddfd7da1 100644 --- a/include/tdep-x86_64/libunwind_i.h +++ b/include/tdep-x86_64/libunwind_i.h @@ -130,8 +130,14 @@ dwarf_get_uc(const struct dwarf_cursor *cursor) #else /* !UNW_LOCAL_ONLY */ # define DWARF_NULL_LOC DWARF_LOC (0, 0) -# define DWARF_IS_NULL_LOC(l) \ - ({ dwarf_loc_t _l = (l); _l.val == 0 && _l.type == 0; }) + +static inline int +dwarf_is_null_loc(dwarf_loc_t l) +{ + return l.val == 0 && l.type == 0; +} + +# define DWARF_IS_NULL_LOC(l) dwarf_is_null_loc(l) # define DWARF_REG_LOC(c,r) DWARF_LOC((r), DWARF_LOC_TYPE_REG) # define DWARF_FPREG_LOC(c,r) DWARF_LOC((r), (DWARF_LOC_TYPE_REG \ | DWARF_LOC_TYPE_FP)) diff --git a/src/aarch64/Gtrace.c b/src/aarch64/Gtrace.c index c67faf0e..2f8c3f8d 100644 --- a/src/aarch64/Gtrace.c +++ b/src/aarch64/Gtrace.c @@ -52,8 +52,8 @@ static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; static sig_atomic_t trace_cache_once_happen; static pthread_key_t trace_cache_key; static struct mempool trace_cache_pool; -static __thread unw_trace_cache_t *tls_cache; -static __thread int tls_cache_destroyed; +static THREAD_LOCAL unw_trace_cache_t *tls_cache; +static THREAD_LOCAL int tls_cache_destroyed; /* Free memory for a thread's trace cache. */ static void diff --git a/src/arm/Gtrace.c b/src/arm/Gtrace.c index 2f277520..7ed320cc 100644 --- a/src/arm/Gtrace.c +++ b/src/arm/Gtrace.c @@ -52,8 +52,8 @@ static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; static sig_atomic_t trace_cache_once_happen; static pthread_key_t trace_cache_key; static struct mempool trace_cache_pool; -static __thread unw_trace_cache_t *tls_cache; -static __thread int tls_cache_destroyed; +static THREAD_LOCAL unw_trace_cache_t *tls_cache; +static THREAD_LOCAL int tls_cache_destroyed; /* Free memory for a thread's trace cache. */ static void diff --git a/src/dwarf/Gexpr.c b/src/dwarf/Gexpr.c index 2af45433..830fd14c 100644 --- a/src/dwarf/Gexpr.c +++ b/src/dwarf/Gexpr.c @@ -251,6 +251,7 @@ dwarf_eval_expr (struct dwarf_cursor *c, unw_word_t stack_val, unw_word_t *addr, uint32_t u32; uint64_t u64; int ret; +#ifdef __GNUC__ # define pop() \ ({ \ if ((tos - 1) >= MAX_EXPR_STACK_SIZE) \ @@ -280,6 +281,48 @@ do { \ } \ stack[_index]; \ }) +#else // __GNUC__ +// We don't have non-standard statement expressions +// Use multiple statements instead +int stackerror = 0; + +// pop() is either followed by a semicolon or +// used in a push() macro +// In either case we can sneak in an extra statement +# define pop() \ +(((tos - 1) >= MAX_EXPR_STACK_SIZE) ? \ + stackerror++ : stack[--tos]); \ +if (stackerror) \ + { \ + Debug (1, "Stack underflow\n"); \ + return -UNW_EINVAL; \ + } + +// Removed the parentheses on the asignment +// to allow the extra stack error check +// when x is evaluated +# define push(x) \ +do { \ + unw_word_t _x = x; \ + if (tos >= MAX_EXPR_STACK_SIZE) \ + { \ + Debug (1, "Stack overflow\n"); \ + return -UNW_EINVAL; \ + } \ + stack[tos++] = _x; \ +} while (0) + +// Pick is always used in a push() macro +// In either case we can sneak in an extra statement +# define pick(n) \ +(((tos - 1 - (n)) >= MAX_EXPR_STACK_SIZE) ? \ + stackerror++ : stack[tos - 1 - (n)]); \ +if (stackerror) \ + { \ + Debug (1, "Out-of-stack pick\n"); \ + return -UNW_EINVAL; \ + } +#endif // __GNUC__ as = c->as; arg = c->as_arg; diff --git a/src/os-linux.h b/src/os-linux.h index 3976b38c..5a9b0b40 100644 --- a/src/os-linux.h +++ b/src/os-linux.h @@ -38,7 +38,7 @@ struct map_iterator }; static inline char * -ltoa (char *buf, long val) +unw_ltoa (char *buf, long val) { char *cp = buf, tmp; ssize_t i, len; @@ -68,7 +68,7 @@ maps_init (struct map_iterator *mi, pid_t pid) char path[sizeof ("/proc/0123456789/maps")], *cp; memcpy (path, "/proc/", 6); - cp = ltoa (path + 6, pid); + cp = unw_ltoa (path + 6, pid); assert (cp + 6 < path + sizeof (path)); memcpy (cp, "/maps", 6); diff --git a/src/x86_64/Gglobal.c b/src/x86_64/Gglobal.c index 9a7b1957..73ba02e3 100644 --- a/src/x86_64/Gglobal.c +++ b/src/x86_64/Gglobal.c @@ -96,9 +96,9 @@ tdep_init (void) dwarf_init (); +#ifndef UNW_REMOTE_ONLY tdep_init_mem_validate (); -#ifndef UNW_REMOTE_ONLY x86_64_local_addr_space_init (); #endif fetch_and_add1(&tdep_init_done); /* signal that we're initialized... */ diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c index fd8d418b..81c663c1 100644 --- a/src/x86_64/Ginit.c +++ b/src/x86_64/Ginit.c @@ -205,8 +205,8 @@ tdep_init_mem_validate (void) #define NLGA 4 #if defined(HAVE___THREAD) && HAVE___THREAD // thread-local variant -static __thread unw_word_t last_good_addr[NLGA]; -static __thread int lga_victim; +static THREAD_LOCAL unw_word_t last_good_addr[NLGA]; +static THREAD_LOCAL int lga_victim; static int is_cached_valid_mem(unw_word_t addr) diff --git a/src/x86_64/Gtrace.c b/src/x86_64/Gtrace.c index 824527f9..7be10a00 100644 --- a/src/x86_64/Gtrace.c +++ b/src/x86_64/Gtrace.c @@ -50,8 +50,8 @@ static pthread_once_t trace_cache_once = PTHREAD_ONCE_INIT; static sig_atomic_t trace_cache_once_happen; static pthread_key_t trace_cache_key; static struct mempool trace_cache_pool; -static __thread unw_trace_cache_t *tls_cache; -static __thread int tls_cache_destroyed; +static THREAD_LOCAL unw_trace_cache_t *tls_cache; +static THREAD_LOCAL int tls_cache_destroyed; /* Free memory for a thread's trace cache. */ static void |