]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Deal with function pointer vs function entry crazyness on ppc64-linux.
authorJulian Seward <jseward@acm.org>
Fri, 23 Dec 2005 02:29:58 +0000 (02:29 +0000)
committerJulian Seward <jseward@acm.org>
Fri, 23 Dec 2005 02:29:58 +0000 (02:29 +0000)
Memcheck is done, but any tool which generates IR helper calls will
need to be similarly adulterated.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5418

coregrind/m_machine.c
coregrind/m_translate.c
include/pub_tool_machine.h
memcheck/mc_translate.c

index 482a1f3354d61cd5b73cc290988fc9432ef5e64e..80b58ecf1258ea55f73ea4882a5841189ed5a048 100644 (file)
@@ -499,6 +499,29 @@ void VG_(machine_get_VexArchInfo)( /*OUT*/VexArch* pVa,
 }
 
 
+// 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 = (ULong*)f;
+   return (void*)(descr[0]);
+#else
+#  error "Unknown platform"
+#endif
+}
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index 09ce93dc4182fd5f66f457514b2229429d827a4a..5e0548ee65de9cfaa7fd0c911905542f6a5e98f7 100644 (file)
@@ -241,7 +241,8 @@ IRBB* vg_SP_update_pass ( IRBB*             bb_in,
          dcall = 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 = 1;                                           \
@@ -341,7 +342,8 @@ IRBB* vg_SP_update_pass ( IRBB*             bb_in,
 
          dcall = unsafeIRDirty_0_N( 
                     2/*regparms*/, 
-                    "VG_(unknown_SP_update)", &VG_(unknown_SP_update),
+                    "VG_(unknown_SP_update)", 
+                    VG_(fnptr_to_fnentry)( &VG_(unknown_SP_update) ),
                     mkIRExprVec_2( IRExpr_Tmp(old_SP), st->Ist.Put.data ) 
                  );
          addStmtToIRBB( bb, IRStmt_Dirty(dcall) );
index fe4d8473439232ecac8715f3130fe44f993d2aa0..948df5ac6c1bada853afe41503327fd69c637d2b 100644 (file)
@@ -84,6 +84,12 @@ extern void VG_(thread_stack_reset_iter) ( void );
 extern Bool VG_(thread_stack_next)       ( ThreadId* tid, Addr* stack_min,
                                                           Addr* stack_max );
 
+// 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
 
 /*--------------------------------------------------------------------*/
index c5e991a45a473466ecd735d42b44c8ddfa20ab6b..46f870672437d374235711b5fd644690b46313d2 100644 (file)
 */
 
 #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"
 
 
@@ -845,39 +846,44 @@ static void complainIfUndefined ( MCEnv* mce, IRAtom* atom )
 
    switch (sz) {
       case 0:
-         di = unsafeIRDirty_0_N( 0/*regparms*/, 
-                                 "MC_(helperc_value_check0_fail)",
-                                 &MC_(helperc_value_check0_fail),
-                                 mkIRExprVec_0() 
-                               );
+         di = unsafeIRDirty_0_N( 
+                 0/*regparms*/, 
+                 "MC_(helperc_value_check0_fail)",
+                 VG_(fnptr_to_fnentry)( &MC_(helperc_value_check0_fail) ),
+                 mkIRExprVec_0() 
+              );
          break;
       case 1:
-         di = unsafeIRDirty_0_N( 0/*regparms*/, 
-                                 "MC_(helperc_value_check1_fail)",
-                                 &MC_(helperc_value_check1_fail),
-                                 mkIRExprVec_0() 
-                               );
+         di = unsafeIRDirty_0_N( 
+                 0/*regparms*/, 
+                 "MC_(helperc_value_check1_fail)",
+                 VG_(fnptr_to_fnentry)( &MC_(helperc_value_check1_fail) ),
+                 mkIRExprVec_0() 
+              );
          break;
       case 4:
-         di = unsafeIRDirty_0_N( 0/*regparms*/, 
-                                 "MC_(helperc_value_check4_fail)",
-                                 &MC_(helperc_value_check4_fail),
-                                 mkIRExprVec_0() 
-                               );
+         di = unsafeIRDirty_0_N( 
+                 0/*regparms*/, 
+                 "MC_(helperc_value_check4_fail)",
+                 VG_(fnptr_to_fnentry)( &MC_(helperc_value_check4_fail) ),
+                 mkIRExprVec_0() 
+              );
          break;
       case 8:
-         di = unsafeIRDirty_0_N( 0/*regparms*/, 
-                                 "MC_(helperc_value_check8_fail)",
-                                 &MC_(helperc_value_check8_fail),
-                                 mkIRExprVec_0() 
-                               );
+         di = unsafeIRDirty_0_N( 
+                 0/*regparms*/, 
+                 "MC_(helperc_value_check8_fail)",
+                 VG_(fnptr_to_fnentry)( &MC_(helperc_value_check8_fail) ),
+                 mkIRExprVec_0() 
+              );
          break;
       default:
-         di = unsafeIRDirty_0_N( 1/*regparms*/, 
-                                 "MC_(helperc_complain_undef)",
-                                 &MC_(helperc_complain_undef),
-                                 mkIRExprVec_1( mkIRExpr_HWord( sz ))
-                               );
+         di = unsafeIRDirty_0_N( 
+                 1/*regparms*/, 
+                 "MC_(helperc_complain_undef)",
+                 VG_(fnptr_to_fnentry)( &MC_(helperc_complain_undef) ),
+                 mkIRExprVec_1( mkIRExpr_HWord( sz ))
+              );
          break;
    }
    di->guard = cond;
@@ -2331,7 +2337,8 @@ IRAtom* expr2vbits_Load_WRK ( MCEnv* mce,
       read. */
    datavbits = newIRTemp(mce->bb->tyenv, ty);
    di = unsafeIRDirty_1_N( datavbits, 
-                           1/*regparms*/, hname, helper, 
+                           1/*regparms*/, 
+                           hname, VG_(fnptr_to_fnentry)( helper ), 
                            mkIRExprVec_1( addrAct ));
    setHelperAnns( mce, di );
    stmt( mce->bb, IRStmt_Dirty(di) );
@@ -2594,16 +2601,18 @@ void do_shadow_Store ( MCEnv* mce,
       addrLo64  = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasLo64) );
       vdataLo64 = assignNew(mce, Ity_I64, unop(Iop_V128to64, vdata));
       diLo64    = unsafeIRDirty_0_N( 
-                     1/*regparms*/, hname, helper, 
-                     mkIRExprVec_2( addrLo64, vdataLo64 ));
-
+                     1/*regparms*/, 
+                     hname, VG_(fnptr_to_fnentry)( helper ), 
+                     mkIRExprVec_2( addrLo64, vdataLo64 )
+                  );
       eBiasHi64 = tyAddr==Ity_I32 ? mkU32(bias+offHi64) : mkU64(bias+offHi64);
       addrHi64  = assignNew(mce, tyAddr, binop(mkAdd, addr, eBiasHi64) );
       vdataHi64 = assignNew(mce, Ity_I64, unop(Iop_V128HIto64, vdata));
       diHi64    = unsafeIRDirty_0_N( 
-                     1/*regparms*/, hname, helper, 
-                     mkIRExprVec_2( addrHi64, vdataHi64 ));
-
+                     1/*regparms*/, 
+                     hname, VG_(fnptr_to_fnentry)( helper ), 
+                     mkIRExprVec_2( addrHi64, vdataHi64 )
+                  );
       setHelperAnns( mce, diLo64 );
       setHelperAnns( mce, diHi64 );
       stmt( mce->bb, IRStmt_Dirty(diLo64) );
@@ -2625,13 +2634,17 @@ void do_shadow_Store ( MCEnv* mce,
             the back ends aren't clever enough to handle 64-bit
             regparm args.  Therefore be different. */
          di = unsafeIRDirty_0_N( 
-                 1/*regparms*/, hname, helper, 
-                 mkIRExprVec_2( addrAct, vdata ));
+                 1/*regparms*/, 
+                 hname, VG_(fnptr_to_fnentry)( helper ), 
+                 mkIRExprVec_2( addrAct, vdata )
+              );
       } else {
          di = unsafeIRDirty_0_N( 
-                 2/*regparms*/, hname, helper, 
+                 2/*regparms*/, 
+                 hname, VG_(fnptr_to_fnentry)( helper ), 
                  mkIRExprVec_2( addrAct,
-                                zwidenToHostWord( mce, vdata )));
+                                zwidenToHostWord( mce, vdata ))
+              );
       }
       setHelperAnns( mce, di );
       stmt( mce->bb, IRStmt_Dirty(di) );
@@ -2849,7 +2862,7 @@ void do_AbiHint ( MCEnv* mce, IRExpr* base, Int len )
    di = 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) );