From: Julian Seward Date: Tue, 7 Jul 2015 12:41:33 +0000 (+0000) Subject: Add some functions for misaligned load/store support, and use them X-Git-Tag: svn/VALGRIND_3_11_0^2~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58f90d0b3b2f9c51fdf90f8ccd3a44eff1a4ee29;p=thirdparty%2Fvalgrind.git Add some functions for misaligned load/store support, and use them in the x86 and amd64 chainer/unchainer. This makes it possible to run at least some programs when built with gcc 5.1, with ubsan misaligned checking enabled. git-svn-id: svn://svn.valgrind.org/vex/trunk@3160 --- diff --git a/VEX/priv/host_amd64_defs.c b/VEX/priv/host_amd64_defs.c index 7534e4378c..3928d30ff5 100644 --- a/VEX/priv/host_amd64_defs.c +++ b/VEX/priv/host_amd64_defs.c @@ -3758,7 +3758,7 @@ VexInvalRange chainXDirect_AMD64 ( VexEndness endness_host, UChar* p = (UChar*)place_to_chain; vassert(p[0] == 0x49); vassert(p[1] == 0xBB); - vassert(*(Addr*)(&p[2]) == (Addr)disp_cp_chain_me_EXPECTED); + vassert(read_misaligned_ULong_LE(&p[2]) == (Addr)disp_cp_chain_me_EXPECTED); vassert(p[10] == 0x41); vassert(p[11] == 0xFF); vassert(p[12] == 0xD3); @@ -3807,10 +3807,7 @@ VexInvalRange chainXDirect_AMD64 ( VexEndness endness_host, /* And make the modifications. */ if (shortOK) { p[0] = 0xE9; - p[1] = (delta >> 0) & 0xFF; - p[2] = (delta >> 8) & 0xFF; - p[3] = (delta >> 16) & 0xFF; - p[4] = (delta >> 24) & 0xFF; + write_misaligned_UInt_LE(&p[1], (UInt)(Int)delta); p[5] = 0x0F; p[6] = 0x0B; p[7] = 0x0F; p[8] = 0x0B; p[9] = 0x0F; p[10] = 0x0B; @@ -3820,7 +3817,7 @@ VexInvalRange chainXDirect_AMD64 ( VexEndness endness_host, vassert(delta == 0LL || delta == -1LL); } else { /* Minimal modifications from the starting sequence. */ - *(Addr*)(&p[2]) = (Addr)place_to_jump_to; + write_misaligned_ULong_LE(&p[2], (ULong)(Addr)place_to_jump_to); p[12] = 0xE3; } VexInvalRange vir = { (HWord)place_to_chain, 13 }; @@ -3855,7 +3852,8 @@ VexInvalRange unchainXDirect_AMD64 ( VexEndness endness_host, UChar* p = (UChar*)place_to_unchain; Bool valid = False; if (p[0] == 0x49 && p[1] == 0xBB - && *(Addr*)(&p[2]) == (Addr)place_to_jump_to_EXPECTED + && read_misaligned_ULong_LE(&p[2]) + == (ULong)(Addr)place_to_jump_to_EXPECTED && p[10] == 0x41 && p[11] == 0xFF && p[12] == 0xE3) { /* it's the long form */ valid = True; @@ -3867,7 +3865,7 @@ VexInvalRange unchainXDirect_AMD64 ( VexEndness endness_host, && p[9] == 0x0F && p[10] == 0x0B && p[11] == 0x0F && p[12] == 0x0B) { /* It's the short form. Check the offset is right. */ - Int s32 = *(Int*)(&p[1]); + Int s32 = (Int)read_misaligned_UInt_LE(&p[1]); Long s64 = (Long)s32; if ((UChar*)p + 5 + s64 == place_to_jump_to_EXPECTED) { valid = True; @@ -3886,7 +3884,7 @@ VexInvalRange unchainXDirect_AMD64 ( VexEndness endness_host, */ p[0] = 0x49; p[1] = 0xBB; - *(Addr*)(&p[2]) = (Addr)disp_cp_chain_me; + write_misaligned_ULong_LE(&p[2], (ULong)(Addr)disp_cp_chain_me); p[10] = 0x41; p[11] = 0xFF; p[12] = 0xD3; diff --git a/VEX/priv/host_x86_defs.c b/VEX/priv/host_x86_defs.c index 28afdcd6fc..29c60236a9 100644 --- a/VEX/priv/host_x86_defs.c +++ b/VEX/priv/host_x86_defs.c @@ -3360,7 +3360,8 @@ VexInvalRange chainXDirect_X86 ( VexEndness endness_host, */ UChar* p = (UChar*)place_to_chain; vassert(p[0] == 0xBA); - vassert(*(UInt*)(&p[1]) == (UInt)(Addr)disp_cp_chain_me_EXPECTED); + vassert(read_misaligned_UInt_LE(&p[1]) + == (UInt)(Addr)disp_cp_chain_me_EXPECTED); vassert(p[5] == 0xFF); vassert(p[6] == 0xD2); /* And what we want to change it to is: @@ -3377,11 +3378,8 @@ VexInvalRange chainXDirect_X86 ( VexEndness endness_host, /* And make the modifications. */ p[0] = 0xE9; - p[1] = (delta >> 0) & 0xFF; - p[2] = (delta >> 8) & 0xFF; - p[3] = (delta >> 16) & 0xFF; - p[4] = (delta >> 24) & 0xFF; - p[5] = 0x0F; p[6] = 0x0B; + write_misaligned_UInt_LE(&p[1], (UInt)(ULong)delta); + p[5] = 0x0F; p[6] = 0x0B; /* sanity check on the delta -- top 32 are all 0 or all 1 */ delta >>= 32; vassert(delta == 0LL || delta == -1LL); @@ -3409,9 +3407,9 @@ VexInvalRange unchainXDirect_X86 ( VexEndness endness_host, UChar* p = (UChar*)place_to_unchain; Bool valid = False; if (p[0] == 0xE9 - && p[5] == 0x0F && p[6] == 0x0B) { + && p[5] == 0x0F && p[6] == 0x0B) { /* Check the offset is right. */ - Int s32 = *(Int*)(&p[1]); + Int s32 = (Int)read_misaligned_UInt_LE(&p[1]); if ((UChar*)p + 5 + s32 == place_to_jump_to_EXPECTED) { valid = True; if (0) @@ -3428,7 +3426,7 @@ VexInvalRange unchainXDirect_X86 ( VexEndness endness_host, So it's the same length (convenient, huh). */ p[0] = 0xBA; - *(UInt*)(&p[1]) = (UInt)(Addr)disp_cp_chain_me; + write_misaligned_UInt_LE(&p[1], (UInt)(Addr)disp_cp_chain_me); p[5] = 0xFF; p[6] = 0xD2; VexInvalRange vir = { (HWord)place_to_unchain, 7 }; diff --git a/VEX/priv/main_util.c b/VEX/priv/main_util.c index d0732e927b..644f542c24 100644 --- a/VEX/priv/main_util.c +++ b/VEX/priv/main_util.c @@ -580,6 +580,59 @@ UInt vex_sprintf ( HChar* buf, const HChar *format, ... ) } +/*---------------------------------------------------------*/ +/*--- Misaligned memory access support ---*/ +/*---------------------------------------------------------*/ + +UInt read_misaligned_UInt_LE ( void* addr ) +{ + UChar* p = (UChar*)addr; + UInt w = 0; + w = (w << 8) | p[3]; + w = (w << 8) | p[2]; + w = (w << 8) | p[1]; + w = (w << 8) | p[0]; + return w; +} + +ULong read_misaligned_ULong_LE ( void* addr ) +{ + UChar* p = (UChar*)addr; + ULong w = 0; + w = (w << 8) | p[7]; + w = (w << 8) | p[6]; + w = (w << 8) | p[5]; + w = (w << 8) | p[4]; + w = (w << 8) | p[3]; + w = (w << 8) | p[2]; + w = (w << 8) | p[1]; + w = (w << 8) | p[0]; + return w; +} + +void write_misaligned_UInt_LE ( void* addr, UInt w ) +{ + UChar* p = (UChar*)addr; + p[0] = (w & 0xFF); w >>= 8; + p[1] = (w & 0xFF); w >>= 8; + p[2] = (w & 0xFF); w >>= 8; + p[3] = (w & 0xFF); w >>= 8; +} + +void write_misaligned_ULong_LE ( void* addr, ULong w ) +{ + UChar* p = (UChar*)addr; + p[0] = (w & 0xFF); w >>= 8; + p[1] = (w & 0xFF); w >>= 8; + p[2] = (w & 0xFF); w >>= 8; + p[3] = (w & 0xFF); w >>= 8; + p[4] = (w & 0xFF); w >>= 8; + p[5] = (w & 0xFF); w >>= 8; + p[6] = (w & 0xFF); w >>= 8; + p[7] = (w & 0xFF); w >>= 8; +} + + /*---------------------------------------------------------------*/ /*--- end main_util.c ---*/ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/main_util.h b/VEX/priv/main_util.h index 018ba4fdeb..a97647fa67 100644 --- a/VEX/priv/main_util.h +++ b/VEX/priv/main_util.h @@ -163,6 +163,14 @@ static inline void* LibVEX_Alloc_inline ( SizeT nbytes ) #endif } +/* Misaligned memory access support. */ + +extern UInt read_misaligned_UInt_LE ( void* addr ); +extern ULong read_misaligned_ULong_LE ( void* addr ); + +extern void write_misaligned_UInt_LE ( void* addr, UInt w ); +extern void write_misaligned_ULong_LE ( void* addr, ULong w ); + #endif /* ndef __VEX_MAIN_UTIL_H */ /*---------------------------------------------------------------*/