|
From: <sv...@va...> - 2005-12-23 02:30:05
|
Author: sewardj
Date: 2005-12-23 02:29:58 +0000 (Fri, 23 Dec 2005)
New Revision: 5418
Log:
Deal with function pointer vs function entry crazyness on ppc64-linux.
Memcheck is done, but any tool which generates IR helper calls will
need to be similarly adulterated.
Modified:
trunk/coregrind/m_machine.c
trunk/coregrind/m_translate.c
trunk/include/pub_tool_machine.h
trunk/memcheck/mc_translate.c
Modified: trunk/coregrind/m_machine.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_machine.c 2005-12-23 01:16:16 UTC (rev 5417)
+++ trunk/coregrind/m_machine.c 2005-12-23 02:29:58 UTC (rev 5418)
@@ -499,6 +499,29 @@
}
=20
=20
+// Given a pointer to a function as obtained by "& functionname" in C,
+// produce a pointer to the actual entry point for the function. For
+// most platforms it's the identity function. Unfortunately, on
+// ppc64-linux it isn't (sigh).
+void* VG_(fnptr_to_fnentry)( void* f )
+{
+#if defined(VGP_x86_linux)
+ return f;
+#elif defined(VGP_amd64_linux)
+ return f;
+#elif defined(VGP_ppc32_linux)
+ return f;
+#elif defined(VGP_ppc64_linux)
+ /* f is a pointer to a 3-word function descriptor, of which
+ the first word is the entry address. */
+ /* Don't ask me. Really. I have no idea why. */
+ ULong* descr =3D (ULong*)f;
+ return (void*)(descr[0]);
+#else
+# error "Unknown platform"
+#endif
+}
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_translate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_translate.c 2005-12-23 01:16:16 UTC (rev 5417)
+++ trunk/coregrind/m_translate.c 2005-12-23 02:29:58 UTC (rev 5418)
@@ -241,7 +241,8 @@
dcall =3D unsafeIRDirty_0_N( =
\
1/*regparms*/, =
\
"track_" #kind "_mem_stack_" #syze, =
\
- VG_(tdict).track_##kind##_mem_stack_##syze, =
\
+ VG_(fnptr_to_fnentry)( =
\
+ VG_(tdict).track_##kind##_mem_stack_##syze ), =
\
mkIRExprVec_1(IRExpr_Tmp(tmpp)) =
\
); =
\
dcall->nFxState =3D 1; =
\
@@ -341,7 +342,8 @@
=20
dcall =3D unsafeIRDirty_0_N(=20
2/*regparms*/,=20
- "VG_(unknown_SP_update)", &VG_(unknown_SP_update),
+ "VG_(unknown_SP_update)",=20
+ VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
mkIRExprVec_2( IRExpr_Tmp(old_SP), st->Ist.Put.data =
)=20
);
addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
Modified: trunk/include/pub_tool_machine.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/include/pub_tool_machine.h 2005-12-23 01:16:16 UTC (rev 5417)
+++ trunk/include/pub_tool_machine.h 2005-12-23 02:29:58 UTC (rev 5418)
@@ -84,6 +84,12 @@
extern Bool VG_(thread_stack_next) ( ThreadId* tid, Addr* stack_mi=
n,
Addr* stack_ma=
x );
=20
+// Given a pointer to a function as obtained by "& functionname" in C,
+// produce a pointer to the actual entry point for the function. For
+// most platforms it's the identity function. Unfortunately, on
+// ppc64-linux it isn't (sigh).
+extern void* VG_(fnptr_to_fnentry)( void* );
+
#endif // __PUB_TOOL_MACHINE_H
=20
/*--------------------------------------------------------------------*/
Modified: trunk/memcheck/mc_translate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/memcheck/mc_translate.c 2005-12-23 01:16:16 UTC (rev 5417)
+++ trunk/memcheck/mc_translate.c 2005-12-23 02:29:58 UTC (rev 5418)
@@ -30,10 +30,11 @@
*/
=20
#include "pub_tool_basics.h"
-#include "pub_tool_hashtable.h" // For mac_shared.h
+#include "pub_tool_hashtable.h" // For mac_shared.h
#include "pub_tool_libcassert.h"
#include "pub_tool_libcprint.h"
#include "pub_tool_tooliface.h"
+#include "pub_tool_machine.h" // VG_(fnptr_to_fnentry)
#include "mc_include.h"
=20
=20
@@ -845,39 +846,44 @@
=20
switch (sz) {
case 0:
- di =3D unsafeIRDirty_0_N( 0/*regparms*/,=20
- "MC_(helperc_value_check0_fail)",
- &MC_(helperc_value_check0_fail),
- mkIRExprVec_0()=20
- );
+ di =3D unsafeIRDirty_0_N(=20
+ 0/*regparms*/,=20
+ "MC_(helperc_value_check0_fail)",
+ VG_(fnptr_to_fnentry)( &MC_(helperc_value_check0_fail) =
),
+ mkIRExprVec_0()=20
+ );
break;
case 1:
- di =3D unsafeIRDirty_0_N( 0/*regparms*/,=20
- "MC_(helperc_value_check1_fail)",
- &MC_(helperc_value_check1_fail),
- mkIRExprVec_0()=20
- );
+ di =3D unsafeIRDirty_0_N(=20
+ 0/*regparms*/,=20
+ "MC_(helperc_value_check1_fail)",
+ VG_(fnptr_to_fnentry)( &MC_(helperc_value_check1_fail) =
),
+ mkIRExprVec_0()=20
+ );
break;
case 4:
- di =3D unsafeIRDirty_0_N( 0/*regparms*/,=20
- "MC_(helperc_value_check4_fail)",
- &MC_(helperc_value_check4_fail),
- mkIRExprVec_0()=20
- );
+ di =3D unsafeIRDirty_0_N(=20
+ 0/*regparms*/,=20
+ "MC_(helperc_value_check4_fail)",
+ VG_(fnptr_to_fnentry)( &MC_(helperc_value_check4_fail) =
),
+ mkIRExprVec_0()=20
+ );
break;
case 8:
- di =3D unsafeIRDirty_0_N( 0/*regparms*/,=20
- "MC_(helperc_value_check8_fail)",
- &MC_(helperc_value_check8_fail),
- mkIRExprVec_0()=20
- );
+ di =3D unsafeIRDirty_0_N(=20
+ 0/*regparms*/,=20
+ "MC_(helperc_value_check8_fail)",
+ VG_(fnptr_to_fnentry)( &MC_(helperc_value_check8_fail) =
),
+ mkIRExprVec_0()=20
+ );
break;
default:
- di =3D unsafeIRDirty_0_N( 1/*regparms*/,=20
- "MC_(helperc_complain_undef)",
- &MC_(helperc_complain_undef),
- mkIRExprVec_1( mkIRExpr_HWord( sz ))
- );
+ di =3D unsafeIRDirty_0_N(=20
+ 1/*regparms*/,=20
+ "MC_(helperc_complain_undef)",
+ VG_(fnptr_to_fnentry)( &MC_(helperc_complain_undef) ),
+ mkIRExprVec_1( mkIRExpr_HWord( sz ))
+ );
break;
}
di->guard =3D cond;
@@ -2331,7 +2337,8 @@
read. */
datavbits =3D newIRTemp(mce->bb->tyenv, ty);
di =3D unsafeIRDirty_1_N( datavbits,=20
- 1/*regparms*/, hname, helper,=20
+ 1/*regparms*/,=20
+ hname, VG_(fnptr_to_fnentry)( helper ),=20
mkIRExprVec_1( addrAct ));
setHelperAnns( mce, di );
stmt( mce->bb, IRStmt_Dirty(di) );
@@ -2594,16 +2601,18 @@
addrLo64 =3D assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasLo64)=
);
vdataLo64 =3D assignNew(mce, Ity_I64, unop(Iop_V128to64, vdata));
diLo64 =3D unsafeIRDirty_0_N(=20
- 1/*regparms*/, hname, helper,=20
- mkIRExprVec_2( addrLo64, vdataLo64 ));
-
+ 1/*regparms*/,=20
+ hname, VG_(fnptr_to_fnentry)( helper ),=20
+ mkIRExprVec_2( addrLo64, vdataLo64 )
+ );
eBiasHi64 =3D tyAddr=3D=3DIty_I32 ? mkU32(bias+offHi64) : mkU64(bi=
as+offHi64);
addrHi64 =3D assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasHi64)=
);
vdataHi64 =3D assignNew(mce, Ity_I64, unop(Iop_V128HIto64, vdata))=
;
diHi64 =3D unsafeIRDirty_0_N(=20
- 1/*regparms*/, hname, helper,=20
- mkIRExprVec_2( addrHi64, vdataHi64 ));
-
+ 1/*regparms*/,=20
+ hname, VG_(fnptr_to_fnentry)( helper ),=20
+ mkIRExprVec_2( addrHi64, vdataHi64 )
+ );
setHelperAnns( mce, diLo64 );
setHelperAnns( mce, diHi64 );
stmt( mce->bb, IRStmt_Dirty(diLo64) );
@@ -2625,13 +2634,17 @@
the back ends aren't clever enough to handle 64-bit
regparm args. Therefore be different. */
di =3D unsafeIRDirty_0_N(=20
- 1/*regparms*/, hname, helper,=20
- mkIRExprVec_2( addrAct, vdata ));
+ 1/*regparms*/,=20
+ hname, VG_(fnptr_to_fnentry)( helper ),=20
+ mkIRExprVec_2( addrAct, vdata )
+ );
} else {
di =3D unsafeIRDirty_0_N(=20
- 2/*regparms*/, hname, helper,=20
+ 2/*regparms*/,=20
+ hname, VG_(fnptr_to_fnentry)( helper ),=20
mkIRExprVec_2( addrAct,
- zwidenToHostWord( mce, vdata )));
+ zwidenToHostWord( mce, vdata ))
+ );
}
setHelperAnns( mce, di );
stmt( mce->bb, IRStmt_Dirty(di) );
@@ -2849,7 +2862,7 @@
di =3D unsafeIRDirty_0_N(
0/*regparms*/,
"MC_(helperc_MAKE_STACK_UNINIT)",
- &MC_(helperc_MAKE_STACK_UNINIT),
+ VG_(fnptr_to_fnentry)( &MC_(helperc_MAKE_STACK_UNINIT) ),
mkIRExprVec_2( base, mkIRExpr_HWord( (UInt)len) )
);
stmt( mce->bb, IRStmt_Dirty(di) );
|