]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add some functions for misaligned load/store support, and use them
authorJulian Seward <jseward@acm.org>
Tue, 7 Jul 2015 12:41:33 +0000 (12:41 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 7 Jul 2015 12:41:33 +0000 (12:41 +0000)
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

VEX/priv/host_amd64_defs.c
VEX/priv/host_x86_defs.c
VEX/priv/main_util.c
VEX/priv/main_util.h

index 7534e4378cf49f8f5ed1d6c9e691cb70d83c7395..3928d30ff59b0aac59207fb6b7289d71b183c221 100644 (file)
@@ -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;
index 28afdcd6fcb0a694a84d501e4ae86dffc576bf24..29c60236a92111ca761aab899d471a9bd92d1f69 100644 (file)
@@ -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 };
index d0732e927bbd01cf9353fc8ed1279b107bdc073e..644f542c2478ea245b6f77f9117ca835e5262ddb 100644 (file)
@@ -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 ---*/
 /*---------------------------------------------------------------*/
index 018ba4fdeb172123b8ab1e50ca6607e74db8ab53..a97647fa67a141783884967234f00bdb2bbe5a38 100644 (file)
@@ -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 */
 
 /*---------------------------------------------------------------*/