From 8fd919b8d4c7a00a53eddeee6eba04a8d6fb5e77 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Sun, 24 Sep 2006 20:36:51 +0000 Subject: [PATCH] resolve stack-walking problem with gcc 4.1 and introduce jit-arch-*.h headers that may contain architecture dependent code. --- ChangeLog | 18 ++++++++++++++++++ configure.in | 13 +++++++++++++ include/jit/Makefile.am | 10 +++++++++- include/jit/jit-walk.h | 16 +++++++++++++++- jit/jit-walk.c | 14 ++++++++++++++ tools/gen-apply.c | 18 +++++++++++++++--- 6 files changed, 84 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c670ed3..9da24fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2006-09-25 Aleksey Demakov + + * include/jit/jit-arch-x86.h, include/jit/jit-arch-generic.h: add + headers for architecture-specific definitions. + (_JIT_ARCH_GET_CURRENT_FRAME): add macro to find the stack frame + pointer. + + * include/jit/Makefile.am: create jit-arch.h as a symlink to one of + the jit-arch-*.h files depending on the JIT_ARCH value. + * configure.in: set JIT_ARCH according to the system architecture. + + * include/jit/jit-walk.h (jit_get_current_frame): + * jit/jit-walk.c (jit_get_starting_frame): + * tools/gen-apply.c (find_return_offset, detect_frame_offsets): use + _JIT_ARCH_GET_CURRENT_FRAME macro if available. This resolves the + problem with gcc 4.1.* where __builtin_frame_address() function is + broken (thanks Klaus for identifing the problem). + 2006-09-15 Radek Polak * include/jit/jit-insn.h, jit/jit-insn.c, jit/jit-debugger.c: new diff --git a/configure.in b/configure.in index 7caac87..0f4a2cd 100644 --- a/configure.in +++ b/configure.in @@ -12,6 +12,19 @@ dnl Set the version number for the shared libraries. AC_SUBST(LIBJIT_VERSION) LIBJIT_VERSION=0:0:0 +dnl Determine the architecture. +AC_MSG_CHECKING([architecture]) +AC_SUBST(JIT_ARCH) +case "$host" in + i[[3456789]]86-*-*) + JIT_ARCH=x86 + ;; + *) + JIT_ARCH=generic + ;; +esac +AC_MSG_RESULT($JIT_ARCH) + dnl Turn off the cygwin library if building for Win32. dnl Note: We have to include if we will be using "__int64" dnl because otherwise the mingw32 compiler won't define it correctly. diff --git a/include/jit/Makefile.am b/include/jit/Makefile.am index 8ed359b..b281798 100644 --- a/include/jit/Makefile.am +++ b/include/jit/Makefile.am @@ -1,6 +1,8 @@ +ARCH_HEADER = jit-arch-@JIT_ARCH@.h libjitincludedir = $(includedir)/jit libjitinclude_HEADERS = jit.h \ + jit-arch.h \ jit-apply.h \ jit-block.h \ jit-common.h \ @@ -25,4 +27,10 @@ libjitinclude_HEADERS = jit.h \ jit-value.h \ jit-walk.h -DISTCLEANFILES = jit-defs.h +noinst_HEADERS = jit-arch-generic.h jit-arch-x86.h + +DISTCLEANFILES = jit-arch.h jit-defs.h + +jit-arch.h: $(ARCH_HEADER) + rm -f $@ + $(LN_S) $(srcdir)/$(ARCH_HEADER) $@ diff --git a/include/jit/jit-walk.h b/include/jit/jit-walk.h index 0c2df9c..ff936fd 100644 --- a/include/jit/jit-walk.h +++ b/include/jit/jit-walk.h @@ -21,6 +21,8 @@ #ifndef _JIT_WALK_H #define _JIT_WALK_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -32,7 +34,7 @@ extern "C" { void *_jit_get_frame_address(void *start, unsigned int n); #if defined(__GNUC__) #define jit_get_frame_address(n) \ - (_jit_get_frame_address(__builtin_frame_address(0), (n))) + (_jit_get_frame_address(jit_get_current_frame(), (n))) #else #define jit_get_frame_address(n) (_jit_get_frame_address(0, (n))) #endif @@ -40,9 +42,21 @@ void *_jit_get_frame_address(void *start, unsigned int n); /* * Get the frame address for the current frame. May be more efficient * than using "jit_get_frame_address(0)". + * + * Note: some gcc vestions have broken __builtin_frame_address() so use + * _JIT_ARCH_GET_CURRENT_FRAME() if available. */ #if defined(__GNUC__) +#if defined(_JIT_ARCH_GET_CURRENT_FRAME) +#define jit_get_current_frame() \ + ({ \ + void *address; \ + _JIT_ARCH_GET_CURRENT_FRAME(address); \ + address; \ + }) +#else #define jit_get_current_frame() (__builtin_frame_address(0)) +#endif #else #define jit_get_current_frame() (jit_get_frame_address(0)) #endif diff --git a/jit/jit-walk.c b/jit/jit-walk.c index a55aacb..ae2ef7f 100644 --- a/jit/jit-walk.c +++ b/jit/jit-walk.c @@ -72,8 +72,21 @@ * Fetch the starting frame address if the caller did not supply it * (probably because the caller wasn't compiled with gcc). The address * that we want is actually one frame out from where we are at the moment. + * + * Note: some gcc vestions have broken __builtin_frame_address() so use + * _JIT_ARCH_GET_CURRENT_FRAME() if available. */ #if defined(__GNUC__) +#if defined(_JIT_ARCH_GET_CURRENT_FRAME) +#define jit_get_starting_frame() \ + do { \ + _JIT_ARCH_GET_CURRENT_FRAME(start); \ + if(start) \ + { \ + start = jit_next_frame_pointer(start); \ + } \ + } while (0) +#else #define jit_get_starting_frame() \ do { \ start = __builtin_frame_address(0); \ @@ -82,6 +95,7 @@ start = jit_next_frame_pointer(start); \ } \ } while (0) +#endif #elif defined(_MSC_VER) && defined(_M_IX86) #define jit_get_starting_frame() \ __asm \ diff --git a/tools/gen-apply.c b/tools/gen-apply.c index 3de45e9..47e4b92 100644 --- a/tools/gen-apply.c +++ b/tools/gen-apply.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #define JIT_MEMCPY "mem_copy" #include "jit-apply-func.h" @@ -1329,7 +1330,13 @@ void find_frame_offset_inner(void *looking_for, void **frame) } void find_frame_offset_outer(void *looking_for) { - find_frame_offset_inner(looking_for, (void **)__builtin_frame_address(0)); + void *frame_address; +#if defined(_JIT_ARCH_GET_CURRENT_FRAME) + _JIT_ARCH_GET_CURRENT_FRAME(frame_address); +#else + frame_address = __builtin_frame_address(0); +#endif + find_frame_offset_inner(looking_for, (void **)frame_address); } void find_return_offset(void *looking_for, void **frame) { @@ -1357,8 +1364,13 @@ void find_return_offset(void *looking_for, void **frame) } void detect_frame_offsets(void) { - void *frame_address = __builtin_frame_address(0); - void *return_address = __builtin_return_address(0); + void *frame_address, *return_address; +#if defined(_JIT_ARCH_GET_CURRENT_FRAME) + _JIT_ARCH_GET_CURRENT_FRAME(frame_address); +#else + frame_address = __builtin_frame_address(0); +#endif + return_address = __builtin_return_address(0); find_frame_offset_outer(frame_address); find_return_offset(return_address, frame_address); if(parent_frame_offset == 0 && return_address_offset == 0) -- 2.47.3