amd64check.c revision 1.1.1.1
11828Serikj/* AMD64 calling conventions checking. 21828Serikj 31828SerikjCopyright 2000, 2001, 2004, 2007 Free Software Foundation, Inc. 41828Serikj 51828SerikjThis file is part of the GNU MP Library. 61828Serikj 71828SerikjThe GNU MP Library is free software; you can redistribute it and/or modify 81828Serikjit under the terms of the GNU Lesser General Public License as published by 91828Serikjthe Free Software Foundation; either version 3 of the License, or (at your 101828Serikjoption) any later version. 111828Serikj 121828SerikjThe GNU MP Library is distributed in the hope that it will be useful, but 131828SerikjWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 141828Serikjor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 151828SerikjLicense for more details. 161839Serikj 171828SerikjYou should have received a copy of the GNU Lesser General Public License 181828Serikjalong with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 191828Serikj 201828Serikj#include <stdio.h> 211828Serikj#include "gmp.h" 221828Serikj#include "gmp-impl.h" 231828Serikj#include "tests.h" 241828Serikj 251828Serikj 261828Serikj/* Vector if constants and register values. We use one vector to allow access 271828Serikj via a base pointer, very beneficial for the PIC-enabled amd64call.asm. */ 281828Serikjmp_limb_t calling_conventions_values[23] = 291828Serikj{ 301828Serikj CNST_LIMB(0x1234567887654321), /* want_rbx */ 311828Serikj CNST_LIMB(0x89ABCDEFFEDCBA98), /* want_rbp */ 321828Serikj CNST_LIMB(0xDEADBEEFBADECAFE), /* want_r12 */ 331828Serikj CNST_LIMB(0xFFEEDDCCBBAA9988), /* want_r13 */ 341828Serikj CNST_LIMB(0x0011223344556677), /* want_r14 */ 351828Serikj CNST_LIMB(0x1234432156788765), /* want_r15 */ 361828Serikj 371828Serikj CNST_LIMB(0xFEEDABBACAAFBEED), /* JUNK_RAX */ 381828Serikj CNST_LIMB(0xAB78DE89FF5125BB), /* JUNK_R10 */ 391828Serikj CNST_LIMB(0x1238901890189031) /* JUNK_R11 */ 401828Serikj 411828Serikj /* rest of array used for dynamic values. */ 421828Serikj}; 431828Serikj 441828Serikj/* Index starts for various regions in above vector. */ 451828Serikj#define WANT 0 461828Serikj#define JUNK 6 471828Serikj#define SAVE 9 481828Serikj#define RETADDR 15 491828Serikj#define VAL 16 501828Serikj#define RFLAGS 22 511828Serikj 521828Serikj/* values to check */ 531828Serikjstruct { 541828Serikj int control; 551828Serikj int status; 561828Serikj int tag; 571828Serikj int other[4]; 581828Serikj} calling_conventions_fenv; 591828Serikj 601828Serikj 611828Serikjchar *regname[6] = {"rbx", "rbp", "r12", "r13", "r14", "r15"}; 621828Serikj 631828Serikj#define DIR_BIT(rflags) (((rflags) & (1<<10)) != 0) 641828Serikj 651828Serikj 661828Serikj/* Return 1 if ok, 0 if not */ 671828Serikj 681828Serikjint 691828Serikjcalling_conventions_check (void) 701828Serikj{ 711828Serikj const char *header = "Violated calling conventions:\n"; 721828Serikj int ret = 1; 731828Serikj int i; 741828Serikj 751828Serikj#define CHECK(callreg, regstr, value) \ 761828Serikj if (callreg != value) \ 771828Serikj { \ 781828Serikj printf ("%s %s got 0x%016lX want 0x%016lX\n", \ 791828Serikj header, regstr, callreg, value); \ 801828Serikj header = ""; \ 811828Serikj ret = 0; \ 821828Serikj } 831828Serikj 841828Serikj for (i = 0; i < 6; i++) 851828Serikj { 861828Serikj CHECK (calling_conventions_values[VAL+i], regname[i], calling_conventions_values[WANT+i]); 871828Serikj } 881828Serikj 891828Serikj if (DIR_BIT (calling_conventions_values[RFLAGS]) != 0) 901828Serikj { 911828Serikj printf ("%s rflags dir bit got %d want 0\n", 921828Serikj header, DIR_BIT (calling_conventions_values[RFLAGS])); 931828Serikj header = ""; 941828Serikj ret = 0; 951828Serikj } 961828Serikj 971828Serikj if ((calling_conventions_fenv.tag & 0xFFFF) != 0xFFFF) 981828Serikj { 991828Serikj printf ("%s fpu tags got 0x%X want 0xFFFF\n", 1001828Serikj header, calling_conventions_fenv.tag & 0xFFFF); 1011828Serikj header = ""; 1021828Serikj ret = 0; 1031828Serikj } 1041828Serikj 1051828Serikj return ret; 1061828Serikj} 1071828Serikj