1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* HOW TO USE 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov13 Dec '05 - Linker no longer used (apart from mymalloc) 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovSimply compile and link switchback.c with test_xxx.c, 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanove.g. for ppc64: 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov$ (cd .. && make EXTRA_CFLAGS="-m64" libvex_ppc64_linux.a) && gcc -m64 -mregnames -Wall -Wshadow -Wno-long-long -Winline -O -g -o switchback switchback.c linker.c ../libvex_ppc64_linux.a test_xxx.c 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovTest file test_xxx.c must have an entry point called "entry", 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovwhich expects to take a single argument which is a function pointer 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov(to "serviceFn"). 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovTest file may not reference any other symbols. 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovNOTE: POWERPC: it is critical, when using this on ppc, to set 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovCacheLineSize to the right value. Values we currently know of: 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov imac (G3): 32 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov G5 (ppc970): 128 20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovARM64: 22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (cd .. && make -f Makefile-gcc libvex-arm64-linux.a) \ 23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && $CC -Wall -O -g -o switchback switchback.c linker.c \ 24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ../libvex-arm64-linux.a test_emfloat.c 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h> 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <assert.h> 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdlib.h> 30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <string.h> 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/types.h> 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/stat.h> 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <unistd.h> 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_basictypes.h" 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_x86.h" 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_amd64.h" 38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_ppc32.h" 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_guest_ppc64.h" 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "../pub/libvex_guest_arm64.h" 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex.h" 42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "../pub/libvex_trc_values.h" 43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "linker.h" 44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong n_bbs_done = 0; 46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Int n_translations_made = 0; 47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__i386__) 50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VexGuestState VexGuestX86State 51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define LibVEX_Guest_initialise LibVEX_GuestX86_initialise 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VexArch VexArchX86 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VexSubArch VexSubArchX86_sse1 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define GuestPC guest_EIP 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define CacheLineSize 0/*irrelevant*/ 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(__aarch64__) && !defined(__arm__) 58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define VexGuestState VexGuestARM64State 59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define LibVEX_Guest_initialise LibVEX_GuestARM64_initialise 60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define VexArch VexArchARM64 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define VexSubArch VexSubArch_NONE 62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define GuestPC guest_PC 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# define CacheLineSize 0/*irrelevant*/ 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# error "Unknown arch" 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 7: show conversion into IR */ 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 6: show after initial opt */ 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 5: show after instrumentation */ 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 4: show after second opt */ 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 3: show after tree building */ 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 2: show selected insns */ 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 1: show after reg-alloc */ 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 0: show final assembly */ 77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define TEST_FLAGS ((1<<7)|(1<<3)|(1<<2)|(1<<1)|(1<<0)) 78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define DEBUG_TRACE_FLAGS ((0<<7)|(0<<6)|(0<<5)|(0<<4)| \ 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (0<<3)|(0<<2)|(0<<1)|(0<<0)) 80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef unsigned long int Addr; 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* guest state */ 85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovULong gstack[64000] __attribute__((aligned(16))); 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVexGuestState gst; 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVexControl vcon; 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* only used for the switchback transition */ 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* i386: helper1 = &gst, helper2 = %EFLAGS */ 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* amd64: helper1 = &gst, helper2 = %EFLAGS */ 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* ppc32: helper1 = &gst, helper2 = %CR, helper3 = %XER */ 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* arm64: helper1 = &gst, helper2 = 32x0:NZCV:28x0 */ 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord sb_helper1 = 0; 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord sb_helper2 = 0; 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord sb_helper3 = 0; 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* translation cache */ 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_TRANS_CACHE 1000000 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_TRANS_TABLE 10000 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovULong trans_cache[N_TRANS_CACHE]; 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVexGuestExtents trans_table [N_TRANS_TABLE]; 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovULong* trans_tableP[N_TRANS_TABLE]; 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt trans_cache_used = 0; 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovInt trans_table_used = 0; 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool chase_into_ok ( void* opaque, Addr64 dst ) { 110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return False; 111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic UInt needs_self_check ( void* opaque, VexGuestExtents* vge ) { 114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* For providing services. */ 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HWord serviceFn ( HWord arg1, HWord arg2 ) 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch (arg1) { 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 0: /* EXIT */ 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("---STOP---\n"); 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("serviceFn:EXIT\n"); 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%llu bbs simulated\n", n_bbs_done); 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%d translations made, %d tt bytes\n", 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_translations_made, 8*trans_cache_used); 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(0); 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 1: /* PUTC */ 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov putchar(arg2); 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 2: /* MALLOC */ 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (HWord)malloc(arg2); 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 3: /* FREE */ 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov free((void*)arg2); 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(0); 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// needed for arm64 ? 144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void invalidate_icache(void *ptr, unsigned long nbytes) 145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // This function, invalidate_icache, for arm64_linux, 147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // is copied from 148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // https://github.com/armvixl/vixl/blob/master/src/a64/cpu-a64.cc 149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // which has the following copyright notice: 150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright 2013, ARM Limited 152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov All rights reserved. 153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Redistribution and use in source and binary forms, with or without 155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov modification, are permitted provided that the following conditions are met: 156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Redistributions of source code must retain the above copyright notice, 158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov this list of conditions and the following disclaimer. 159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Redistributions in binary form must reproduce the above copyright notice, 160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov this list of conditions and the following disclaimer in the documentation 161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov and/or other materials provided with the distribution. 162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Neither the name of ARM Limited nor the names of its contributors may be 163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov used to endorse or promote products derived from this software without 164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov specific prior written permission. 165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Ask what the I and D line sizes are 179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt cache_type_register; 180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Copy the content of the cache type register to a core register. 181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT 182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : [ctr] "=r" (cache_type_register)); 183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const Int kDCacheLineSizeShift = 16; 185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const Int kICacheLineSizeShift = 0; 186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const UInt kDCacheLineSizeMask = 0xf << kDCacheLineSizeShift; 187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const UInt kICacheLineSizeMask = 0xf << kICacheLineSizeShift; 188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // The cache type register holds the size of the I and D caches as a power of 190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // two. 191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const UInt dcache_line_size_power_of_two = 192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (cache_type_register & kDCacheLineSizeMask) >> kDCacheLineSizeShift; 193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const UInt icache_line_size_power_of_two = 194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (cache_type_register & kICacheLineSizeMask) >> kICacheLineSizeShift; 195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const UInt dcache_line_size_ = 1 << dcache_line_size_power_of_two; 197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const UInt icache_line_size_ = 1 << icache_line_size_power_of_two; 198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr start = (Addr)ptr; 200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Sizes will be used to generate a mask big enough to cover a pointer. 201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr dsize = (Addr)dcache_line_size_; 202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr isize = (Addr)icache_line_size_; 203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Cache line sizes are always a power of 2. 205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr dstart = start & ~(dsize - 1); 206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr istart = start & ~(isize - 1); 207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr end = start + nbytes; 208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ __volatile__ ( 210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Clean every line of the D cache containing the target data. 211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "0: \n\t" 212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // dc : Data Cache maintenance 213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // c : Clean 214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // va : by (Virtual) Address 215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // u : to the point of Unification 216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // The point of unification for a processor is the point by which the 217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // instruction and data caches are guaranteed to see the same copy of a 218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // memory location. See ARM DDI 0406B page B2-12 for more information. 219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "dc cvau, %[dline] \n\t" 220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "add %[dline], %[dline], %[dsize] \n\t" 221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "cmp %[dline], %[end] \n\t" 222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "b.lt 0b \n\t" 223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Barrier to make sure the effect of the code above is visible to the rest 224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // of the world. 225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // dsb : Data Synchronisation Barrier 226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // ish : Inner SHareable domain 227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // The point of unification for an Inner Shareable shareability domain is 228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // the point by which the instruction and data caches of all the processors 229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // in that Inner Shareable shareability domain are guaranteed to see the 230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // same copy of a memory location. See ARM DDI 0406B page B2-12 for more 231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // information. 232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "dsb ish \n\t" 233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Invalidate every line of the I cache containing the target data. 234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "1: \n\t" 235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // ic : instruction cache maintenance 236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // i : invalidate 237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // va : by address 238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // u : to the point of unification 239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "ic ivau, %[iline] \n\t" 240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "add %[iline], %[iline], %[isize] \n\t" 241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "cmp %[iline], %[end] \n\t" 242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "b.lt 1b \n\t" 243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Barrier to make sure the effect of the code above is visible to the rest 244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // of the world. 245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "dsb ish \n\t" 246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // Barrier to ensure any prefetching which happened before this code is 247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // discarded. 248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // isb : Instruction Synchronisation Barrier 249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "isb \n\t" 250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : [dline] "+r" (dstart), 251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov [iline] "+r" (istart) 252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : [dsize] "r" (dsize), 253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov [isize] "r" (isize), 254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov [end] "r" (end) 255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // This code does not write to memory but without the dependency gcc might 256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov // move this code before the code is generated. 257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : "cc", "memory" 258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ); 259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* -------------------- */ 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* continue execution on the real CPU (never returns) */ 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(__i386__) 267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void switchback_asm(void); 269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovasm( 270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"switchback_asm:\n" 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl sb_helper1, %eax\n" // eax = guest state ptr 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl 16(%eax), %esp\n" // switch stacks 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" pushl 56(%eax)\n" // push continuation addr 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl sb_helper2, %ebx\n" // get eflags 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" pushl %ebx\n" // eflags:CA 276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" pushl 0(%eax)\n" // EAX:eflags:CA 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl 4(%eax), %ecx\n" 278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl 8(%eax), %edx\n" 279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl 12(%eax), %ebx\n" 280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl 20(%eax), %ebp\n" 281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl 24(%eax), %esi\n" 282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl 28(%eax), %edi\n" 283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" popl %eax\n" 284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" popfl\n" 285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" ret\n" 286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov); 287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid switchback ( void ) 288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sb_helper1 = (HWord)&gst; 290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sb_helper2 = LibVEX_GuestX86_get_eflags(&gst); 291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switchback_asm(); // never returns 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(__aarch64__) 295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void switchback_asm(HWord x0_gst, HWord x1_pstate); 297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovasm( 298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"switchback_asm:" 299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" mrs x30, nzcv" "\n" 300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" and x30, x30, #0xFFFFFFFF0FFFFFFF" "\n" 301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" and x1, x1, #0x00000000F0000000" "\n" 302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" orr x30, x30, x1" "\n" 303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" msr nzcv, x30" "\n" 304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x30, [x0, #16 + 8*37]" "\n" 306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" msr tpidr_el0, x30" "\n" 307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x30, [x0, #16 + 8*31]" "\n" 309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" mov sp, x30" "\n" 310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" add x30, x0, #(16 + 8*38 + 16*0)" "\n" 312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q0, [x30], #16" "\n" 313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q1, [x30], #16" "\n" 314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q2, [x30], #16" "\n" 315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q3, [x30], #16" "\n" 316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q4, [x30], #16" "\n" 317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q5, [x30], #16" "\n" 318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q6, [x30], #16" "\n" 319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q7, [x30], #16" "\n" 320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q8, [x30], #16" "\n" 321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q9, [x30], #16" "\n" 322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q10, [x30], #16" "\n" 323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q11, [x30], #16" "\n" 324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q12, [x30], #16" "\n" 325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q13, [x30], #16" "\n" 326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q14, [x30], #16" "\n" 327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q15, [x30], #16" "\n" 328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q16, [x30], #16" "\n" 329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q17, [x30], #16" "\n" 330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q18, [x30], #16" "\n" 331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q19, [x30], #16" "\n" 332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q20, [x30], #16" "\n" 333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q21, [x30], #16" "\n" 334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q22, [x30], #16" "\n" 335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q23, [x30], #16" "\n" 336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q24, [x30], #16" "\n" 337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q25, [x30], #16" "\n" 338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q26, [x30], #16" "\n" 339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q27, [x30], #16" "\n" 340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q28, [x30], #16" "\n" 341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q29, [x30], #16" "\n" 342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q30, [x30], #16" "\n" 343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr q31, [x30], #16" "\n" 344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x30, [x0, #16+8*30]" "\n" 346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x29, [x0, #16+8*29]" "\n" 347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x28, [x0, #16+8*28]" "\n" 348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x27, [x0, #16+8*27]" "\n" 349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x26, [x0, #16+8*26]" "\n" 350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x25, [x0, #16+8*25]" "\n" 351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x24, [x0, #16+8*24]" "\n" 352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x23, [x0, #16+8*23]" "\n" 353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x22, [x0, #16+8*22]" "\n" 354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x21, [x0, #16+8*21]" "\n" 355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x20, [x0, #16+8*20]" "\n" 356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x19, [x0, #16+8*19]" "\n" 357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x18, [x0, #16+8*18]" "\n" 358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x17, [x0, #16+8*17]" "\n" 359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x16, [x0, #16+8*16]" "\n" 360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x15, [x0, #16+8*15]" "\n" 361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x14, [x0, #16+8*14]" "\n" 362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x13, [x0, #16+8*13]" "\n" 363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x12, [x0, #16+8*12]" "\n" 364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x11, [x0, #16+8*11]" "\n" 365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x10, [x0, #16+8*10]" "\n" 366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x9, [x0, #16+8*9]" "\n" 367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x8, [x0, #16+8*8]" "\n" 368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x7, [x0, #16+8*7]" "\n" 369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x6, [x0, #16+8*6]" "\n" 370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x5, [x0, #16+8*5]" "\n" 371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x4, [x0, #16+8*4]" "\n" 372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x3, [x0, #16+8*3]" "\n" 373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x2, [x0, #16+8*2]" "\n" 374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x1, [x0, #16+8*1]" "\n" 375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x0, [x0, #16+8*0]" "\n" 376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"nop_start_point:" "\n" 378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" nop" "\n" // this will be converted into a relative jump 379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"nop_end_point:" "\n" 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov); 381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void nop_start_point(void); 383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void nop_end_point(void); 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid switchback ( void ) 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(offsetof(VexGuestARM64State, guest_X0) == 16 + 8*0); 388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(offsetof(VexGuestARM64State, guest_X30) == 16 + 8*30); 389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(offsetof(VexGuestARM64State, guest_SP) == 16 + 8*31); 390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(offsetof(VexGuestARM64State, guest_TPIDR_EL0) == 16 + 8*37); 391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(offsetof(VexGuestARM64State, guest_Q0) == 16 + 8*38 + 16*0); 392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HWord arg0 = (HWord)&gst; 394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HWord arg1 = LibVEX_GuestARM64_get_nzcv(&gst); 395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Copy the entire switchback_asm procedure into writable and 397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov executable memory. */ 398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UChar* sa_start = (UChar*)&switchback_asm; 400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UChar* sa_nop_start = (UChar*)&nop_start_point; 401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UChar* sa_end = (UChar*)&nop_end_point; 402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int i; 404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int nbytes = sa_end - sa_start; 405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int off_nopstart = sa_nop_start - sa_start; 406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0) 407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("nbytes = %d, nopstart = %d\n", nbytes, off_nopstart); 408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* copy it into mallocville */ 410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* copy = mymalloc(nbytes); 411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(copy); 412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < nbytes; i++) 413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov copy[i] = sa_start[i]; 414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UInt* p = (UInt*)(©[off_nopstart]); 416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Addr64 addr_of_nop = (Addr64)p; 418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr64 where_to_go = gst.guest_PC; 419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Long diff = ((Long)where_to_go) - ((Long)addr_of_nop); 420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 421436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0) { 422436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("addr of first nop = 0x%llx\n", addr_of_nop); 423436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("where to go = 0x%llx\n", where_to_go); 424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("diff = 0x%llx\n", diff); 425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (diff < -0x8000000LL || diff >= 0x8000000LL) { 428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // we're hosed. Give up 429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("hosed -- offset too large\n"); 430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(0); 431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* stay sane ... */ 434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(p[0] == 0xd503201f); /* nop */ 435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* branch to diff */ 437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov p[0] = 0x14000000 | ((diff >> 2) & 0x3FFFFFF); 438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache( copy, nbytes ); 440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ( (void(*)(HWord,HWord))copy )(arg0, arg1); 442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# error "Unknown plat" 446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* -------------------- */ 451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// f holds is the host code address 452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// gp holds the guest state pointer to use 453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// res is to hold the result. Or some such. 454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic HWord block[2]; // f, gp; 455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern HWord run_translation_asm(void); 456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern void disp_chain_assisted(void); 458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined(__aarch64__) 460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovasm( 461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"run_translation_asm:" "\n" 462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" stp x29, x30, [sp, #-16]!" "\n" 463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" stp x27, x28, [sp, #-16]!" "\n" 464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" stp x25, x26, [sp, #-16]!" "\n" 465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" stp x23, x24, [sp, #-16]!" "\n" 466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" stp x21, x22, [sp, #-16]!" "\n" 467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" stp x19, x20, [sp, #-16]!" "\n" 468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" stp x0, xzr, [sp, #-16]!" "\n" 469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" adrp x0, block" "\n" 470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" add x0, x0, :lo12:block" "\n" 471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x21, [x0, #8]" "\n" // load GSP 472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldr x1, [x0, #0]" "\n" // Host address 473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" br x1" "\n" // go (we wind up at disp_chain_assisted) 474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov"disp_chain_assisted:" "\n" // x21 holds the trc. Return it. 476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" mov x1, x21" "\n" 477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Restore int regs, but not x1. */ 478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldp x0, xzr, [sp], #16" "\n" 479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldp x19, x20, [sp], #16" "\n" 480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldp x21, x22, [sp], #16" "\n" 481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldp x23, x24, [sp], #16" "\n" 482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldp x25, x26, [sp], #16" "\n" 483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldp x27, x28, [sp], #16" "\n" 484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ldp x29, x30, [sp], #16" "\n" 485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" mov x0, x1" "\n" 486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" ret" "\n" 487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov); 488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(__i386__) 490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovasm( 492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov"run_translation_asm:\n" 493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" pushal\n" 494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl gp, %ebp\n" 495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl f, %eax\n" 496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" call *%eax\n" 497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" movl %eax, res\n" 498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" popal\n" 499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" ret\n" 500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov); 501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# error "Unknown arch" 504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Run a translation at host address 'translation' and return the TRC. 508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/ 509436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovHWord run_translation ( HWord translation ) 510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0 && DEBUG_TRACE_FLAGS) { 512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" run translation %p\n", (void*)translation ); 513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" simulated bb: %llu\n", n_bbs_done); 514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 515436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov block[0] = translation; 516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov block[1] = (HWord)&gst; 517436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HWord trc = run_translation_asm(); 518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_bbs_done ++; 519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return trc; 520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovHWord find_translation ( Addr64 guest_addr ) 523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i; 525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HWord __res; 526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) 527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("find translation %p ... ", ULong_to_Ptr(guest_addr)); 528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < trans_table_used; i++) 529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (trans_table[i].base[0] == guest_addr) 530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i == trans_table_used) { 532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) printf("none\n"); 533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; /* not found */ 534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Move this translation one step towards the front, so finding it 537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov next time round is just that little bit cheaper. */ 538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i > 2) { 539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VexGuestExtents tmpE = trans_table[i-1]; 540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong* tmpP = trans_tableP[i-1]; 541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_table[i-1] = trans_table[i]; 542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_tableP[i-1] = trans_tableP[i]; 543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_table[i] = tmpE; 544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_tableP[i] = tmpP; 545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov i--; 546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov __res = (HWord)trans_tableP[i]; 549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) printf("%p\n", (void*)__res); 550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return __res; 551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_TRANSBUF 5000 554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UChar transbuf[N_TRANSBUF]; 555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid make_translation ( Addr64 guest_addr, Bool verbose ) 556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VexTranslateArgs vta; 558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VexTranslateResult tres; 559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VexArchInfo vex_archinfo; 560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int trans_used, i, ws_needed; 561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov memset(&vta, 0, sizeof(vta)); 563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov memset(&tres, 0, sizeof(tres)); 564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov memset(&vex_archinfo, 0, sizeof(vex_archinfo)); 565436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (trans_table_used >= N_TRANS_TABLE 567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || trans_cache_used >= N_TRANS_CACHE-1000) { 568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* If things are looking to full, just dump 569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov all the translations. */ 570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_cache_used = 0; 571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_table_used = 0; 572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(trans_table_used < N_TRANS_TABLE); 575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) 576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("make translation %p\n", ULong_to_Ptr(guest_addr)); 577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov LibVEX_default_VexArchInfo(&vex_archinfo); 579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov //vex_archinfo.subarch = VexSubArch; 580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov //vex_archinfo.ppc_icache_line_szB = CacheLineSize; 581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* */ 583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.arch_guest = VexArch; 584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.archinfo_guest = vex_archinfo; 585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.arch_host = VexArch; 586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.archinfo_host = vex_archinfo; 587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.guest_bytes = (UChar*)ULong_to_Ptr(guest_addr); 588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.guest_bytes_addr = (Addr64)guest_addr; 589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.chase_into_ok = chase_into_ok; 590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// vta.guest_extents = &vge; 591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.guest_extents = &trans_table[trans_table_used]; 592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.host_bytes = transbuf; 593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.host_bytes_size = N_TRANSBUF; 594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.host_bytes_used = &trans_used; 595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.instrument1 = NULL; 596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.instrument2 = NULL; 597436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vta.needs_self_check = needs_self_check; 598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vta.traceflags = verbose ? TEST_FLAGS : DEBUG_TRACE_FLAGS; 599436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 600436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vta.disp_cp_chain_me_to_slowEP = NULL; //disp_chain_fast; 601436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vta.disp_cp_chain_me_to_fastEP = NULL; //disp_chain_slow; 602436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vta.disp_cp_xindir = NULL; //disp_chain_indir; 603436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vta.disp_cp_xassisted = disp_chain_assisted; 604436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 605436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vta.addProfInc = False; 606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tres = LibVEX_Translate ( &vta ); 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(tres.status == VexTransOK); 610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(tres.offs_profInc == -1); 611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ws_needed = (trans_used+7) / 8; 613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(ws_needed > 0); 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(trans_cache_used + ws_needed < N_TRANS_CACHE); 615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov n_translations_made++; 616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < trans_used; i++) { 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* dst = ((HChar*)(&trans_cache[trans_cache_used])) + i; 619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HChar* src = (HChar*)(&transbuf[i]); 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *dst = *src; 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined(__aarch64__) 624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov invalidate_icache( &trans_cache[trans_cache_used], trans_used ); 625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_tableP[trans_table_used] = &trans_cache[trans_cache_used]; 628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_table_used++; 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov trans_cache_used += ws_needed; 630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((unused)) 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool overlap ( Addr64 start, UInt len, VexGuestExtents* vge ) 635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Int i; 637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for (i = 0; i < vge->n_used; i++) { 638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (vge->base[i]+vge->len[i] <= start 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || vge->base[i] >= start+len) { 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* ok */ 641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else { 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return True; 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return False; /* no overlap */ 646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong stopAfter = 0; 649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic UChar* entryP = NULL; 650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov__attribute__ ((noreturn)) 653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid failure_exit ( void ) 655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stdout, "VEX did failure_exit. Bye.\n"); 657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fprintf(stdout, "bb counter = %llu\n\n", n_bbs_done); 658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic 662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid log_bytes ( HChar* bytes, Int nbytes ) 663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fwrite ( bytes, 1, nbytes, stdout ); 665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fflush ( stdout ); 666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* run simulated code forever (it will exit by calling 670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov serviceFn(0)). */ 671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void run_simulator ( void ) 672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov static Addr64 last_guest = 0; 674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Addr64 next_guest; 675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HWord next_host; 676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (1) { 677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov next_guest = gst.GuestPC; 678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (0) 680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\nnext_guest: 0x%x\n", (UInt)next_guest); 681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (next_guest == Ptr_to_ULong(&serviceFn)) { 683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* "do" the function call to serviceFn */ 685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(__i386__) 686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov HWord esp = gst.guest_ESP; 688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gst.guest_EIP = *(UInt*)(esp+0); 689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gst.guest_EAX = serviceFn( *(UInt*)(esp+4), *(UInt*)(esp+8) ); 690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gst.guest_ESP = esp+4; 691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov next_guest = gst.guest_EIP; 692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 693436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# elif defined(__aarch64__) 694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.guest_X0 = serviceFn( gst.guest_X0, gst.guest_X1 ); 696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.guest_PC = gst.guest_X30; 697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov next_guest = gst.guest_PC; 698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# else 700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# error "Unknown arch" 701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov next_host = find_translation(next_guest); 705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (next_host == 0) { 706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov make_translation(next_guest,False); 707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov next_host = find_translation(next_guest); 708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(next_host != 0); 709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // Switchback 712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (n_bbs_done == stopAfter) { 713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("---begin SWITCHBACK at bb:%llu---\n", n_bbs_done); 714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 1 715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (last_guest) { 716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n*** Last run translation (bb:%llu):\n", n_bbs_done-1); 717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov make_translation(last_guest,True); 718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (next_guest) { 722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n*** Current translation (bb:%llu):\n", n_bbs_done); 723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov make_translation(next_guest,True); 724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("--- end SWITCHBACK at bb:%llu ---\n", n_bbs_done); 727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switchback(); 728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov assert(0); /*NOTREACHED*/ 729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov last_guest = next_guest; 732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HWord trc = run_translation(next_host); 733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0) printf("------- trc = %lu\n", trc); 734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (trc != VEX_TRC_JMP_BORING) { 735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (1) printf("------- trc = %lu\n", trc); 736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov assert(trc == VEX_TRC_JMP_BORING); 738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void usage ( void ) 743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("usage: switchback #bbs\n"); 745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" - begins switchback for basic block #bbs\n"); 746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" - use -1 for largest possible run without switchback\n\n"); 747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main ( Int argc, HChar** argv ) 752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (argc != 2) 754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov usage(); 755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov stopAfter = (ULong)atoll(argv[1]); 757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov extern void entry ( void*(*service)(int,int) ); 759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov entryP = (UChar*)&entry; 760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!entryP) { 762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("switchback: can't find entry point\n"); 763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov exit(1); 764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov LibVEX_default_VexControl(&vcon); 767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vcon.guest_max_insns=50 - 49; 768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vcon.guest_chase_thresh=0; 769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vcon.iropt_level=2; 770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov LibVEX_Init( failure_exit, log_bytes, 1, False, &vcon ); 772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov LibVEX_Guest_initialise(&gst); 773436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.host_EvC_COUNTER = 999999999; // so we should never get an exit 774436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.host_EvC_FAILADDR = 0x5a5a5a5a5a5a5a5a; 775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* set up as if a call to the entry point passing serviceFn as 777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the one and only parameter */ 778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if defined(__i386__) 779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov gst.guest_EIP = (UInt)entryP; 780436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.guest_ESP = (UInt)&gstack[32000]; 781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *(UInt*)(gst.guest_ESP+4) = (UInt)serviceFn; 782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *(UInt*)(gst.guest_ESP+0) = 0x12345678; 783436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 784436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# elif defined(__aarch64__) 785436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.guest_PC = (ULong)entryP; 786436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.guest_SP = (ULong)&gstack[32000]; 787436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.guest_X0 = (ULong)serviceFn; 788436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HWord tpidr_el0 = 0; 789436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ __volatile__("mrs %0, tpidr_el0" : "=r"(tpidr_el0)); 790436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gst.guest_TPIDR_EL0 = tpidr_el0; 791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# else 793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# error "Unknown arch" 794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# endif 795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n---START---\n"); 797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 1 799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov run_simulator(); 800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ( (void(*)(HWord(*)(HWord,HWord))) entryP ) (serviceFn); 802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 807