|
From: <sv...@va...> - 2015-07-07 12:41:42
|
Author: sewardj
Date: Tue Jul 7 13:41:33 2015
New Revision: 3160
Log:
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.
Modified:
trunk/priv/host_amd64_defs.c
trunk/priv/host_x86_defs.c
trunk/priv/main_util.c
trunk/priv/main_util.h
Modified: trunk/priv/host_amd64_defs.c
==============================================================================
--- trunk/priv/host_amd64_defs.c (original)
+++ trunk/priv/host_amd64_defs.c Tue Jul 7 13:41:33 2015
@@ -3758,7 +3758,7 @@
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 @@
/* 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 @@
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 @@
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 @@
&& 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 @@
*/
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;
Modified: trunk/priv/host_x86_defs.c
==============================================================================
--- trunk/priv/host_x86_defs.c (original)
+++ trunk/priv/host_x86_defs.c Tue Jul 7 13:41:33 2015
@@ -3360,7 +3360,8 @@
*/
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 @@
/* 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 @@
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 @@
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 };
Modified: trunk/priv/main_util.c
==============================================================================
--- trunk/priv/main_util.c (original)
+++ trunk/priv/main_util.c Tue Jul 7 13:41:33 2015
@@ -580,6 +580,59 @@
}
+/*---------------------------------------------------------*/
+/*--- 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 ---*/
/*---------------------------------------------------------------*/
Modified: trunk/priv/main_util.h
==============================================================================
--- trunk/priv/main_util.h (original)
+++ trunk/priv/main_util.h Tue Jul 7 13:41:33 2015
@@ -163,6 +163,14 @@
#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 */
/*---------------------------------------------------------------*/
|