+2008-04-13 Klaus Treichel <ktreichel@web.de>
+
+ * include/jit/Makefile.am:
+ * include/jit/jit-arch-x86-64.h: new file with x86-64 architecture
+ specific macros for stack frame inspection.
+
+ * configure.in: check for x86-64 arch, add -fno-omit-frame-pointer
+ flag.
+
+ * include/jit/jit-walk.h: use _JIT_ARCH_GET_RETURN_ADDRESS and
+ _JIT_ARCH_GET_CURRENT_RETURN if available.
+
2008-03-31 Klaus Treichel <ktreichel@web.de>
* jit/jit-rules-x86.ins: Fix the sign opcode for integers and the
i[[3456789]]86-*-*)
JIT_ARCH=x86
;;
+ x86_64-*-*)
+ JIT_ARCH=x86-64
+ ;;
*)
JIT_ARCH=generic
;;
*) ;;
esac
+dnl Add "-fno-omit-frame-pointer" to the CFLAGS because current gcc versions
+dnl have no frame pointers by default on some archs.
+if test x$GCC = xyes ; then
+ CFLAGS="$CFLAGS -fno-omit-frame-pointer"
+ CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer"
+fi
+
dnl Find the option to use to turn on C++ exception handling.
AC_CACHE_CHECK(for C++ exception handling option, ac_cv_prog_cxx_exceptions,
[echo 'int main(int argc, char **argv){try { throw 1; } catch(int i) { return i; } return 0;}' > conftest.c
--- /dev/null
+/*
+ * jit-arch-x86.h - Architecture-specific definitions.
+ *
+ * Copyright (C) 2008 Southern Storm Software, Pty Ltd.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _JIT_ARCH_X86_64_H
+#define _JIT_ARCH_X86_64_H
+
+/*
+ * The frame header structure for X86_64
+ */
+typedef struct _jit_arch_frame _jit_arch_frame_t;
+struct _jit_arch_frame
+{
+ _jit_arch_frame_t *next_frame;
+ void *return_address;
+};
+
+/*
+ * If defined _JIT_ARCH_GET_CURRENT_FRAME() macro assigns the current frame
+ * pointer to the supplied argument that has to be a void pointer.
+ */
+#if defined(__GNUC__)
+#define _JIT_ARCH_GET_CURRENT_FRAME(f) \
+ do { \
+ register void *__f asm("rbp"); \
+ f = __f; \
+ } while(0)
+#elif defined(_MSC_VER) && defined(_M_IX86)
+#define _JIT_ARCH_GET_CURRENT_FRAME(f) \
+ do { \
+ __asm \
+ { \
+ mov qword ptr f, rbp \
+ } \
+ } while(0)
+#else
+#undef _JIT_ARCH_GET_CURRENT_FRAME
+#endif
+
+/*
+ * If defined _JIT_ARCH_GET_NEXT_FRAME assigns the frame address following
+ * the frame supplied as second arg to the value supplied as first argument.
+ */
+#define _JIT_ARCH_GET_NEXT_FRAME(n, f) \
+ do { \
+ (n) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->next_frame : 0); \
+ } while(0)
+
+/*
+ * If defined _JIT_ARCH_GET_RETURN_ADDRESS assigns the return address of the frame
+ * supplied as second arg to the value supplied as first argument.
+ */
+#define _JIT_ARCH_GET_RETURN_ADDRESS(r, f) \
+ do { \
+ (r) = (void *)((f) ? ((_jit_arch_frame_t *)(f))->return_address : 0); \
+ } while(0)
+
+#define _JIT_ARCH_GET_CURRENT_RETURN(r) \
+ do { \
+ void *__frame; \
+ _JIT_ARCH_GET_CURRENT_FRAME(__frame); \
+ _JIT_ARCH_GET_RETURN_ADDRESS((r), __frame); \
+ } while(0)
+
+#endif /* _JIT_ARCH_X86_64_H */
* Get the return address for a specific frame.
*/
void *_jit_get_return_address(void *frame, void *frame0, void *return0);
+#if defined(_JIT_ARCH_GET_RETURN_ADDRESS)
+#define jit_get_return_address(frame) \
+ ({ \
+ void *address; \
+ _JIT_ARCH_GET_RETURN_ADDRESS(address, (frame)); \
+ address; \
+ })
+#else
#if defined(__GNUC__)
#define jit_get_return_address(frame) \
(_jit_get_return_address \
#define jit_get_return_address(frame) \
(_jit_get_return_address((frame), 0, 0))
#endif
+#endif
/*
* Get the return address for the current frame. May be more efficient
* than using "jit_get_return_address(0)".
*/
+#if defined(_JIT_ARCH_GET_CURRENT_RETURN)
+#define jit_get_current_return() \
+ ({ \
+ void *address; \
+ _JIT_ARCH_GET_CURRENT_RETURN(address); \
+ address; \
+ })
+#else
#if defined(__GNUC__)
#define jit_get_current_return() (__builtin_return_address(0))
#else
#define jit_get_current_return() \
(jit_get_return_address(jit_get_current_frame()))
#endif
+#endif
/*
* Declare a stack crawl mark variable. The address of this variable