2008-07-23 12:49:23 -04:00
|
|
|
; AMD64 and Core 2 calling conventions checking.
|
|
|
|
|
|
|
|
; Copyright 2000, 2003, 2004 Free Software Foundation, Inc.
|
2008-07-24 17:14:10 -04:00
|
|
|
;
|
|
|
|
; Copyright 2008 Jason Worth-Martin
|
2008-07-23 12:49:23 -04:00
|
|
|
;
|
2008-07-24 17:14:10 -04:00
|
|
|
; This file is part of the MPIR Library.
|
2008-07-23 12:49:23 -04:00
|
|
|
;
|
2008-07-24 17:14:10 -04:00
|
|
|
; The MPIR Library is free software; you can redistribute it and/or
|
2008-07-23 12:49:23 -04:00
|
|
|
; 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.
|
|
|
|
;
|
2008-07-24 17:14:10 -04:00
|
|
|
; The MPIR Library is distributed in the hope that it will be useful,
|
2008-07-23 12:49:23 -04:00
|
|
|
; 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
|
2008-07-24 17:14:10 -04:00
|
|
|
; License along with the MPIR Library; see the file COPYING.LIB. If
|
2008-07-23 12:49:23 -04:00
|
|
|
; not, write to the Free Software Foundation, Inc., 51 Franklin Street,
|
|
|
|
; Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
|
2009-03-03 16:40:13 -05:00
|
|
|
%include 'yasm_mac.inc'
|
2008-07-23 12:49:23 -04:00
|
|
|
|
|
|
|
%ifdef GSYM_PREFIX
|
|
|
|
%define G_EX(a) _ %+ a
|
|
|
|
%else
|
|
|
|
%define G_EX(a) a
|
|
|
|
%endif
|
|
|
|
|
|
|
|
G_EXTERN calling_conventions_save_rbx
|
|
|
|
G_EXTERN calling_conventions_save_rbp
|
|
|
|
G_EXTERN calling_conventions_save_r12
|
|
|
|
G_EXTERN calling_conventions_save_r13
|
|
|
|
G_EXTERN calling_conventions_save_r14
|
|
|
|
G_EXTERN calling_conventions_save_r15
|
|
|
|
G_EXTERN calling_conventions_function
|
|
|
|
G_EXTERN calling_conventions_rbx
|
|
|
|
G_EXTERN calling_conventions_rbp
|
|
|
|
G_EXTERN calling_conventions_r12
|
|
|
|
G_EXTERN calling_conventions_r13
|
|
|
|
G_EXTERN calling_conventions_r14
|
|
|
|
G_EXTERN calling_conventions_r15
|
|
|
|
G_EXTERN calling_conventions_rflags
|
|
|
|
G_EXTERN calling_conventions_fenv
|
|
|
|
G_EXTERN calling_conventions_retaddr
|
|
|
|
|
|
|
|
|
|
|
|
BITS 64
|
|
|
|
|
|
|
|
; void x86_fldcw (unsigned short cw);
|
|
|
|
;
|
|
|
|
; Execute an fldcw, setting the x87 control word to cw.
|
|
|
|
|
|
|
|
GLOBAL_FUNC x86_fldcw
|
|
|
|
mov [rsp-8], rdi
|
|
|
|
fldcw [rsp-8]
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
; unsigned short x86_fstcw (void);
|
|
|
|
;
|
|
|
|
; Execute an fstcw, returning the current x87 control word.
|
|
|
|
|
|
|
|
GLOBAL_FUNC x86_fstcw
|
|
|
|
xor rax, rax
|
|
|
|
mov [rsp-8], rax
|
|
|
|
fstcw [rsp-8]
|
|
|
|
mov rax, [rsp+8]
|
|
|
|
ret
|
|
|
|
|
|
|
|
; int calling_conventions (...);
|
|
|
|
;
|
|
|
|
; The global variable "calling_conventions_function" is the function to
|
|
|
|
; call, with the arguments as passed here.
|
|
|
|
;
|
|
|
|
; Perhaps the finit should be done only if the tags word isn't clear, but
|
|
|
|
; nothing uses the rounding mode or anything at the moment.
|
|
|
|
|
|
|
|
|
|
|
|
default rel
|
|
|
|
ALIGN 32
|
|
|
|
GLOBAL_FUNC calling_conventions
|
|
|
|
mov rax, [rsp]
|
|
|
|
mov [G_EX(calling_conventions_retaddr)], rax
|
|
|
|
|
|
|
|
lea rax, [return]
|
|
|
|
mov [rsp], rax
|
|
|
|
|
|
|
|
mov [G_EX(calling_conventions_save_rbx)], rbx
|
|
|
|
mov [G_EX(calling_conventions_save_rbp)], rbp
|
|
|
|
mov [G_EX(calling_conventions_save_r12)], r12
|
|
|
|
mov [G_EX(calling_conventions_save_r13)], r13
|
|
|
|
mov [G_EX(calling_conventions_save_r14)], r14
|
|
|
|
mov [G_EX(calling_conventions_save_r15)], r15
|
|
|
|
|
|
|
|
mov rbx, [G_EX(calling_conventions_save_rbx)]
|
|
|
|
mov rbp, [G_EX(calling_conventions_save_rbp)]
|
|
|
|
mov r12, [G_EX(calling_conventions_save_r12)]
|
|
|
|
mov r13, [G_EX(calling_conventions_save_r13)]
|
|
|
|
mov r14, [G_EX(calling_conventions_save_r14)]
|
|
|
|
mov r15, [G_EX(calling_conventions_save_r15)]
|
|
|
|
|
|
|
|
; values we expect to see unchanged, as per amd64check.c
|
|
|
|
|
|
|
|
mov rbx, 0x1234567887654321
|
|
|
|
mov rbp, 0x89ABCDEFFEDCBA98
|
|
|
|
mov r12, 0xDEADBEEFBADECAFE
|
|
|
|
mov r13, 0xFFEEDDCCBBAA9988
|
|
|
|
mov r14, 0x0011223344556677
|
|
|
|
mov r15, 0x1234432156788765
|
|
|
|
|
|
|
|
; Try to provoke a problem by starting with junk in the registers,
|
|
|
|
; especially %rax which will be the return value.
|
|
|
|
;
|
|
|
|
; ENHANCE-ME: If we knew how many of the parameter registers were
|
|
|
|
; actually being used we could put junk in the rest. Maybe we could
|
|
|
|
; get try.c to communicate this to us.
|
|
|
|
;
|
|
|
|
|
|
|
|
mov rax, 0xFEEDABBACAAFBEED
|
|
|
|
mov r10, 0xAB78DE89FF5125BB
|
|
|
|
mov r11, 0x1238901890189031
|
|
|
|
|
|
|
|
jmp [G_EX(calling_conventions_function)]
|
|
|
|
|
|
|
|
return:
|
|
|
|
mov [G_EX(calling_conventions_rbx)], rbx
|
|
|
|
mov [G_EX(calling_conventions_rbp)], rbp
|
|
|
|
mov [G_EX(calling_conventions_r12)], r12
|
|
|
|
mov [G_EX(calling_conventions_r13)], r13
|
|
|
|
mov [G_EX(calling_conventions_r14)], r14
|
|
|
|
mov [G_EX(calling_conventions_r15)], r15
|
|
|
|
|
|
|
|
pushf
|
|
|
|
pop rbx
|
|
|
|
mov [G_EX(calling_conventions_rflags)], rbx
|
|
|
|
|
|
|
|
fstenv [G_EX(calling_conventions_fenv)]
|
|
|
|
finit
|
|
|
|
|
|
|
|
mov rbx, [G_EX(calling_conventions_save_rbx)]
|
|
|
|
mov rbp, [G_EX(calling_conventions_save_rbp)]
|
|
|
|
mov r12, [G_EX(calling_conventions_save_r12)]
|
|
|
|
mov r13, [G_EX(calling_conventions_save_r13)]
|
|
|
|
mov r14, [G_EX(calling_conventions_save_r14)]
|
|
|
|
mov r15, [G_EX(calling_conventions_save_r15)]
|
|
|
|
|
|
|
|
jmp [G_EX(calling_conventions_retaddr)]
|