From: Julian Seward Date: Wed, 19 Feb 2014 17:42:59 +0000 (+0000) Subject: Implement unchainXDirect_ARM64. X-Git-Tag: svn/VALGRIND_3_10_1^2~148 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=846561abadc6896692f0a961662c695bb48c9a1f;p=thirdparty%2Fvalgrind.git Implement unchainXDirect_ARM64. git-svn-id: svn://svn.valgrind.org/vex/trunk@2822 --- diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c index 21e12813a6..44773b3a70 100644 --- a/VEX/priv/host_arm64_defs.c +++ b/VEX/priv/host_arm64_defs.c @@ -6264,6 +6264,7 @@ VexInvalRange chainXDirect_ARM64 ( void* place_to_chain, vassert(is_imm64_to_iregNo_EXACTLY4( p, /*x*/9, Ptr_to_ULong(disp_cp_chain_me_EXPECTED))); vassert(p[4] == 0xD63F0120); + /* And what we want to change it to is: movw x9, place_to_jump_to[15:0] movk x9, place_to_jump_to[31:15], lsl 16 @@ -6276,7 +6277,6 @@ VexInvalRange chainXDirect_ARM64 ( void* place_to_chain, The replacement has the same length as the original. */ - (void)imm64_to_iregNo_EXACTLY4( p, /*x*/9, Ptr_to_ULong(place_to_jump_to)); p[4] = 0xD61F0120; @@ -6286,67 +6286,47 @@ VexInvalRange chainXDirect_ARM64 ( void* place_to_chain, } -//ZZ /* NB: what goes on here has to be very closely coordinated with the -//ZZ emitInstr case for XDirect, above. */ -//ZZ VexInvalRange unchainXDirect_ARM ( void* place_to_unchain, -//ZZ void* place_to_jump_to_EXPECTED, -//ZZ void* disp_cp_chain_me ) -//ZZ { -//ZZ /* What we're expecting to see is: -//ZZ (general case) -//ZZ movw r12, lo16(place_to_jump_to_EXPECTED) -//ZZ movt r12, lo16(place_to_jump_to_EXPECTED) -//ZZ bx r12 -//ZZ viz -//ZZ <8 bytes generated by imm32_to_iregNo_EXACTLY2> -//ZZ E1 2F FF 1C -//ZZ ---OR--- -//ZZ in the case where the displacement falls within 26 bits -//ZZ b disp24; undef; undef -//ZZ viz -//ZZ EA <3 bytes == disp24> -//ZZ FF 00 00 00 -//ZZ FF 00 00 00 -//ZZ */ -//ZZ UInt* p = (UInt*)place_to_unchain; -//ZZ vassert(0 == (3 & (HWord)p)); -//ZZ -//ZZ Bool valid = False; -//ZZ if (is_imm32_to_iregNo_EXACTLY2( -//ZZ p, /*r*/12, (UInt)Ptr_to_ULong(place_to_jump_to_EXPECTED)) -//ZZ && p[2] == 0xE12FFF1C) { -//ZZ valid = True; /* it's the long form */ -//ZZ if (0) -//ZZ vex_printf("QQQ unchainXDirect_ARM: found long form\n"); -//ZZ } else -//ZZ if ((p[0] >> 24) == 0xEA && p[1] == 0xFF000000 && p[2] == 0xFF000000) { -//ZZ /* It's the short form. Check the displacement is right. */ -//ZZ Int simm24 = p[0] & 0x00FFFFFF; -//ZZ simm24 <<= 8; simm24 >>= 8; -//ZZ if ((UChar*)p + (simm24 << 2) + 8 == (UChar*)place_to_jump_to_EXPECTED) { -//ZZ valid = True; -//ZZ if (0) -//ZZ vex_printf("QQQ unchainXDirect_ARM: found short form\n"); -//ZZ } -//ZZ } -//ZZ vassert(valid); -//ZZ -//ZZ /* And what we want to change it to is: -//ZZ movw r12, lo16(disp_cp_chain_me) -//ZZ movt r12, hi16(disp_cp_chain_me) -//ZZ blx r12 -//ZZ viz -//ZZ <8 bytes generated by imm32_to_iregNo_EXACTLY2> -//ZZ E1 2F FF 3C -//ZZ */ -//ZZ (void)imm32_to_iregNo_EXACTLY2( -//ZZ p, /*r*/12, (UInt)Ptr_to_ULong(disp_cp_chain_me)); -//ZZ p[2] = 0xE12FFF3C; -//ZZ VexInvalRange vir = {(HWord)p, 12}; -//ZZ return vir; -//ZZ } -//ZZ -//ZZ +/* NB: what goes on here has to be very closely coordinated with the + emitInstr case for XDirect, above. */ +VexInvalRange unchainXDirect_ARM64 ( void* place_to_unchain, + void* place_to_jump_to_EXPECTED, + void* disp_cp_chain_me ) +{ + /* What we're expecting to see is: + movw x9, place_to_jump_to_EXPECTED[15:0] + movk x9, place_to_jump_to_EXPECTED[31:15], lsl 16 + movk x9, place_to_jump_to_EXPECTED[47:32], lsl 32 + movk x9, place_to_jump_to_EXPECTED[63:48], lsl 48 + br x9 + viz + <16 bytes generated by imm64_to_iregNo_EXACTLY4> + D6 1F 01 20 + */ + UInt* p = (UInt*)place_to_unchain; + vassert(0 == (3 & (HWord)p)); + vassert(is_imm64_to_iregNo_EXACTLY4( + p, /*x*/9, Ptr_to_ULong(place_to_jump_to_EXPECTED))); + vassert(p[4] == 0xD61F0120); + + /* And what we want to change it to is: + movw x9, disp_cp_chain_me_to[15:0] + movk x9, disp_cp_chain_me_to[31:15], lsl 16 + movk x9, disp_cp_chain_me_to[47:32], lsl 32 + movk x9, disp_cp_chain_me_to[63:48], lsl 48 + blr x9 + viz + <16 bytes generated by imm64_to_iregNo_EXACTLY4> + D6 3F 01 20 + */ + (void)imm64_to_iregNo_EXACTLY4( + p, /*x*/9, Ptr_to_ULong(disp_cp_chain_me)); + p[4] = 0xD63F0120; + + VexInvalRange vir = {(HWord)p, 20}; + return vir; +} + + //ZZ /* Patch the counter address into a profile inc point, as previously //ZZ created by the ARMin_ProfInc case for emit_ARMInstr. */ //ZZ VexInvalRange patchProfInc_ARM ( void* place_to_patch, diff --git a/VEX/priv/host_arm64_defs.h b/VEX/priv/host_arm64_defs.h index b6e4da8185..c84117118b 100644 --- a/VEX/priv/host_arm64_defs.h +++ b/VEX/priv/host_arm64_defs.h @@ -1116,10 +1116,10 @@ extern VexInvalRange chainXDirect_ARM64 ( void* place_to_chain, void* disp_cp_chain_me_EXPECTED, void* place_to_jump_to ); -//ZZ extern VexInvalRange unchainXDirect_ARM ( void* place_to_unchain, -//ZZ void* place_to_jump_to_EXPECTED, -//ZZ void* disp_cp_chain_me ); -//ZZ +extern VexInvalRange unchainXDirect_ARM64 ( void* place_to_unchain, + void* place_to_jump_to_EXPECTED, + void* disp_cp_chain_me ); + //ZZ /* Patch the counter location into an existing ProfInc point. */ //ZZ extern VexInvalRange patchProfInc_ARM ( void* place_to_patch, //ZZ ULong* location_of_counter ); diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c index 2ca1df1f5c..93ca478cce 100644 --- a/VEX/priv/main_main.c +++ b/VEX/priv/main_main.c @@ -1048,6 +1048,8 @@ VexInvalRange LibVEX_UnChain ( VexArch arch_host, unchainXDirect = unchainXDirect_AMD64; break; case VexArchARM: unchainXDirect = unchainXDirect_ARM; break; + case VexArchARM64: + unchainXDirect = unchainXDirect_ARM64; break; case VexArchS390X: unchainXDirect = unchainXDirect_S390; break; case VexArchPPC32: