From 32ada6b0f6963c8f88c3d7c5f4c8d044eef17c19 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Sun, 13 Apr 2008 16:14:15 +0000 Subject: [PATCH] use architecture-specific macros for x86-64 stack walking instead of gcc's builtins --- ChangeLog | 12 ++++++ configure.in | 10 +++++ include/jit/Makefile.am | 2 +- include/jit/jit-arch-x86-64.h | 81 +++++++++++++++++++++++++++++++++++ include/jit/jit-walk.h | 18 ++++++++ 5 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 include/jit/jit-arch-x86-64.h diff --git a/ChangeLog b/ChangeLog index 974e61e..d2e2f16 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-04-13 Klaus Treichel + + * 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 * jit/jit-rules-x86.ins: Fix the sign opcode for integers and the diff --git a/configure.in b/configure.in index aa00e4a..32bff48 100644 --- a/configure.in +++ b/configure.in @@ -19,6 +19,9 @@ case "$host" in i[[3456789]]86-*-*) JIT_ARCH=x86 ;; + x86_64-*-*) + JIT_ARCH=x86-64 + ;; *) JIT_ARCH=generic ;; @@ -333,6 +336,13 @@ case "x$CXXFLAGS" in *) ;; 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 diff --git a/include/jit/Makefile.am b/include/jit/Makefile.am index ac9fe3d..c676d89 100644 --- a/include/jit/Makefile.am +++ b/include/jit/Makefile.am @@ -29,7 +29,7 @@ libjitinclude_HEADERS = jit.h \ jit-value.h \ jit-walk.h -noinst_HEADERS = jit-arch-generic.h jit-arch-x86.h +noinst_HEADERS = jit-arch-generic.h jit-arch-x86.h jit-arch-x86-64.h DISTCLEANFILES = jit-arch.h jit-defs.h diff --git a/include/jit/jit-arch-x86-64.h b/include/jit/jit-arch-x86-64.h new file mode 100644 index 0000000..6d506f0 --- /dev/null +++ b/include/jit/jit-arch-x86-64.h @@ -0,0 +1,81 @@ +/* + * 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 + * . + */ + +#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 */ diff --git a/include/jit/jit-walk.h b/include/jit/jit-walk.h index adac90a..02db55c 100644 --- a/include/jit/jit-walk.h +++ b/include/jit/jit-walk.h @@ -71,6 +71,14 @@ void *jit_get_next_frame_address(void *frame); * 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 \ @@ -79,17 +87,27 @@ void *_jit_get_return_address(void *frame, void *frame0, void *return0); #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