|
From: <sv...@va...> - 2006-01-10 08:02:44
|
Author: sewardj
Date: 2006-01-10 08:02:41 +0000 (Tue, 10 Jan 2006)
New Revision: 5507
Log:
Function wrapping support for amd64.
Modified:
branches/FNWRAP/coregrind/m_redir.c
branches/FNWRAP/coregrind/m_scheduler/scheduler.c
branches/FNWRAP/include/pub_tool_machine.h
branches/FNWRAP/include/valgrind.h
Modified: branches/FNWRAP/coregrind/m_redir.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_redir.c 2006-01-09 09:30:48 UTC (rev 5506=
)
+++ branches/FNWRAP/coregrind/m_redir.c 2006-01-10 08:02:41 UTC (rev 5507=
)
@@ -470,8 +470,17 @@
Kludge: because this can get called befor the trampoline area (a
bunch of magic 'to' addresses) has its ownership changed from V
to C, we can't check the 'to' address similarly. Sigh.
- */
- if (!is_plausible_guest_addr(act.from_addr)) {
+
+ amd64-linux hack: the vsysinfo pages appear to have no
+ permissions
+ ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0
+ so skip the check for them. */
+ if (!is_plausible_guest_addr(act.from_addr)
+# if defined(VGP_amd64_linux)
+ && act.from_addr !=3D 0xFFFFFFFFFF600000ULL
+ && act.from_addr !=3D 0xFFFFFFFFFF600400ULL
+# endif
+ ) {
what =3D "redirection from-address is in non-executable area";
goto bad;
}
Modified: branches/FNWRAP/coregrind/m_scheduler/scheduler.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/coregrind/m_scheduler/scheduler.c 2006-01-09 09:30:48=
UTC (rev 5506)
+++ branches/FNWRAP/coregrind/m_scheduler/scheduler.c 2006-01-10 08:02:41=
UTC (rev 5507)
@@ -600,13 +600,13 @@
" pushl %ebp\n"
" pushl %ebx\n"
=20
-" movl 20(%esp), %esi\n"
-" movl 4(%esi), %ebp\n"
-" call *0(%esi)\n"
+" movl 20(%esp), %edi\n"
+" movl 4(%edi), %ebp\n"
+" call *0(%edi)\n"
=20
-" movl 20(%esp), %esi\n"
-" movl %eax, 8(%esi)\n"
-" movl %ebp, 12(%esi)\n"
+" movl 20(%esp), %edi\n"
+" movl %eax, 8(%edi)\n"
+" movl %ebp, 12(%edi)\n"
=20
" popl %ebx\n"
" popl %ebp\n"
@@ -615,6 +615,34 @@
" ret\n"
".previous\n"
);
+#elif defined(VGP_amd64_linux)
+asm("\n"
+".text\n"
+"run_a_translation:\n"
+" pushq %rbx\n"
+" pushq %rbp\n"
+" pushq %r12\n"
+" pushq %r13\n"
+" pushq %r14\n"
+" pushq %r15\n"
+
+" pushq %rdi\n" /* we will need it after running the translation */
+" movq 8(%rdi), %rbp\n"
+" call *0(%rdi)\n"
+
+" popq %rdi\n"
+" movq %rax, 16(%rdi)\n"
+" movq %rbp, 24(%rdi)\n"
+
+" popq %r15\n"
+" popq %r14\n"
+" popq %r13\n"
+" popq %r12\n"
+" popq %rbp\n"
+" popq %rbx\n"
+" ret\n"
+".previous\n"
+);
#else
# error "Not implemented"
#endif
Modified: branches/FNWRAP/include/pub_tool_machine.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/include/pub_tool_machine.h 2006-01-09 09:30:48 UTC (r=
ev 5506)
+++ branches/FNWRAP/include/pub_tool_machine.h 2006-01-10 08:02:41 UTC (r=
ev 5507)
@@ -34,13 +34,13 @@
#if defined(VGA_x86)
# define VG_MIN_INSTR_SZB 1 // min length of native instructi=
on
# define VG_MAX_INSTR_SZB 16 // max length of native instructi=
on
-# define VG_CLREQ_SZB 18 // length of a client request, ma=
y
+# define VG_CLREQ_SZB 14 // length of a client request, ma=
y
// be larger than VG_MAX_INSTR_=
SZB
# define VG_STACK_REDZONE_SZB 0 // number of addressable bytes be=
low SP
#elif defined(VGA_amd64)
# define VG_MIN_INSTR_SZB 1
# define VG_MAX_INSTR_SZB 16
-# define VG_CLREQ_SZB 18
+# define VG_CLREQ_SZB 19
# define VG_STACK_REDZONE_SZB 128
#elif defined(VGA_ppc32)
# define VG_MIN_INSTR_SZB 4
Modified: branches/FNWRAP/include/valgrind.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/FNWRAP/include/valgrind.h 2006-01-09 09:30:48 UTC (rev 5506)
+++ branches/FNWRAP/include/valgrind.h 2006-01-10 08:02:41 UTC (rev 5507)
@@ -161,32 +161,33 @@
/* ---------------------------- x86 ---------------------------- */
=20
#if defined(ARCH_x86)
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "roll $3, %%edi ; roll $13, %%edi\n\t" \
+ "roll $29, %%edi ; roll $19, %%edi\n\t" \
+
#define VALGRIND_DO_CLIENT_REQUEST( \
_zzq_rlval, _zzq_default, _zzq_request, \
_zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
- { unsigned int _zzq_args[5]; \
+ { volatile unsigned int _zzq_args[5]; \
+ volatile unsigned int _zzq_result; \
_zzq_args[0] =3D (unsigned int)(_zzq_request); \
_zzq_args[1] =3D (unsigned int)(_zzq_arg1); \
_zzq_args[2] =3D (unsigned int)(_zzq_arg2); \
_zzq_args[3] =3D (unsigned int)(_zzq_arg3); \
_zzq_args[4] =3D (unsigned int)(_zzq_arg4); \
- __asm__ volatile(/* "Special" instruction preamble */ \
- "roll $3, %%edi ; roll $13, %%edi\n\t" \
- "roll $29, %%edi ; roll $19, %%edi\n\t" \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
/* %EDX =3D client_request ( %EAX ) */ \
"xchgl %%ebx,%%ebx" \
- : "=3Dd" (_zzq_rlval) \
+ : "=3Dd" (_zzq_result) \
: "a" (&_zzq_args[0]), "0" (_zzq_default) \
: "cc", "memory" \
); \
+ _zzq_rlval =3D _zzq_result; \
}
=20
#define VALGRIND_GET_NRADDR(_zzq_rlval) \
- { unsigned int __addr; \
- __asm__ volatile("movl $0, %%eax\n\t" \
- /* "Special" instruction preamble */ \
- "roll $3, %%edi ; roll $13, %%edi\n\t" \
- "roll $29, %%edi ; roll $19, %%edi\n\t" \
+ { volatile unsigned int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
/* %EAX =3D guest_NRADDR */ \
"xchgl %%ecx,%%ecx" \
: "=3Da" (__addr) \
@@ -197,9 +198,7 @@
}
=20
#define VALGRIND_CALL_NOREDIR_EAX \
- /* "Special" instruction preamble */ \
- "roll $3, %%edi ; roll $13, %%edi\n\t" \
- "roll $29, %%edi ; roll $19, %%edi\n\t" \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
/* call-noredir *%EAX */ \
"xchgl %%edx,%%edx\n\t"
#endif /* ARCH_x86 */
@@ -207,24 +206,46 @@
/* --------------------------- amd64 --------------------------- */
=20
#if defined(ARCH_amd64)
+#define __SPECIAL_INSTRUCTION_PREAMBLE \
+ "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
+ "rolq $61, %%rdi ; rolq $51, %%rdi\n\t" \
+
#define VALGRIND_DO_CLIENT_REQUEST( \
_zzq_rlval, _zzq_default, _zzq_request, \
_zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4) \
- \
- { volatile unsigned long long _zzq_args[5]; \
- _zzq_args[0] =3D (volatile unsigned long long)(_zzq_request); \
- _zzq_args[1] =3D (volatile unsigned long long)(_zzq_arg1); \
- _zzq_args[2] =3D (volatile unsigned long long)(_zzq_arg2); \
- _zzq_args[3] =3D (volatile unsigned long long)(_zzq_arg3); \
- _zzq_args[4] =3D (volatile unsigned long long)(_zzq_arg4); \
- __asm__ volatile("roll $29, %%eax ; roll $3, %%eax\n\t" \
- "rorl $27, %%eax ; rorl $5, %%eax\n\t" \
- "roll $13, %%eax ; roll $19, %%eax" \
- : "=3Dd" (_zzq_rlval) \
+ { volatile unsigned long long int _zzq_args[5]; \
+ volatile unsigned long long int _zzq_result; \
+ _zzq_args[0] =3D (unsigned long long int)(_zzq_request); \
+ _zzq_args[1] =3D (unsigned long long int)(_zzq_arg1); \
+ _zzq_args[2] =3D (unsigned long long int)(_zzq_arg2); \
+ _zzq_args[3] =3D (unsigned long long int)(_zzq_arg3); \
+ _zzq_args[4] =3D (unsigned long long int)(_zzq_arg4); \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %RDX =3D client_request ( %RAX ) */ \
+ "xchgq %%rbx,%%rbx" \
+ : "=3Dd" (_zzq_result) \
: "a" (&_zzq_args[0]), "0" (_zzq_default) \
: "cc", "memory" \
); \
+ _zzq_rlval =3D _zzq_result; \
}
+
+#define VALGRIND_GET_NRADDR(_zzq_rlval) \
+ { volatile unsigned long long int __addr; \
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
+ /* %RAX =3D guest_NRADDR */ \
+ "xchgq %%rcx,%%rcx" \
+ : "=3Da" (__addr) \
+ : \
+ : "cc", "memory" \
+ ); \
+ _zzq_rlval =3D (void*)__addr; \
+ }
+
+#define VALGRIND_CALL_NOREDIR_RAX \
+ __SPECIAL_INSTRUCTION_PREAMBLE \
+ /* call-noredir *%RAX */ \
+ "xchgq %%rdx,%%rdx\n\t"
#endif /* ARCH_amd64 */
=20
/* --------------------------- ppc32 --------------------------- */
@@ -305,7 +326,7 @@
=20
The naming scheme is as follows:
=20
- CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,WWWWW,WWWWWW,etc}
+ CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
=20
'W' stands for "word" and 'v' for "void". Hence there are
different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
@@ -340,9 +361,9 @@
=20
#define CALL_FN_W_v(lval, fnptr) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[1]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
__asm__ volatile( \
"movl (%%eax), %%eax\n\t" /* target->%eax */ \
@@ -359,9 +380,9 @@
=20
#define CALL_FN_W_W(lval, fnptr, arg1) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[2]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
__asm__ volatile( \
@@ -378,9 +399,9 @@
=20
#define CALL_FN_W_WW(lval, fnptr, arg1,arg2) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[3]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[3]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
_argvec[2] =3D (unsigned long)(arg2); \
@@ -399,9 +420,9 @@
=20
#define CALL_FN_W_WWWW(lval, fnptr, arg1,arg2,arg3,arg4) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[5]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[5]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
_argvec[2] =3D (unsigned long)(arg2); \
@@ -424,9 +445,9 @@
=20
#define CALL_FN_W_5W(lval, fnptr, arg1,arg2,arg3,arg4,arg5) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[6]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[6]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
_argvec[2] =3D (unsigned long)(arg2); \
@@ -451,9 +472,9 @@
=20
#define CALL_FN_W_6W(lval, fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[7]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[7]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
_argvec[2] =3D (unsigned long)(arg2); \
@@ -481,9 +502,9 @@
#define CALL_FN_W_7W(lval, fnptr, arg1,arg2,arg3,arg4,arg5,arg6, \
arg7) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[8]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[8]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
_argvec[2] =3D (unsigned long)(arg2); \
@@ -513,9 +534,9 @@
#define CALL_FN_W_8W(lval, fnptr, arg1,arg2,arg3,arg4,arg5,arg6, \
arg7,arg8) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[9]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[9]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
_argvec[2] =3D (unsigned long)(arg2); \
@@ -548,9 +569,9 @@
arg6,arg7,arg8,arg9,arg10, \
arg11,arg12) \
do { \
- void* _fnptr =3D (fnptr); \
- unsigned long _argvec[13]; \
- unsigned long _res; \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[13]; \
+ volatile unsigned long _res; \
_argvec[0] =3D (unsigned long)_fnptr; \
_argvec[1] =3D (unsigned long)(arg1); \
_argvec[2] =3D (unsigned long)(arg2); \
@@ -591,6 +612,57 @@
=20
/* --------------------------- amd64 --------------------------- */
=20
+/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
+
+#if defined(ARCH_amd64)
+
+/* These regs are trashed by the hidden call. */
+#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
+ "rdi", "r8", "r9", "r10", "r11"
+
+/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
+ long) =3D=3D 8. */
+
+#define CALL_FN_W_v(lval, fnptr) \
+ do { \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[1]; \
+ volatile unsigned long _res; \
+ _argvec[0] =3D (unsigned long)_fnptr; \
+ __asm__ volatile( \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#define CALL_FN_v_v(fnptr) \
+ do { volatile unsigned long _junk; \
+ CALL_FN_W_v(_junk,fnptr); } while (0)
+
+#define CALL_FN_W_W(lval, fnptr, arg1) \
+ do { \
+ volatile void* _fnptr =3D (fnptr); \
+ volatile unsigned long _argvec[2]; \
+ volatile unsigned long _res; \
+ _argvec[0] =3D (unsigned long)_fnptr; \
+ _argvec[1] =3D (unsigned long)(arg1); \
+ __asm__ volatile( \
+ "movq 8(%%rax), %%rdi\n\t" \
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
+ VALGRIND_CALL_NOREDIR_RAX \
+ : /*out*/ "=3Da" (_res) \
+ : /*in*/ "a" (&_argvec[0]) \
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
+ ); \
+ lval =3D (__typeof__(lval)) _res; \
+ } while (0)
+
+#endif /* ARCH_amd64 */
+
/* --------------------------- ppc32 --------------------------- */
=20
/* --------------------------- ppc64 --------------------------- */
|