]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Use a different way to tell where the syscall handler was interrupted on FreeBSD...
authorPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 6 Jun 2022 13:18:29 +0000 (15:18 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 6 Jun 2022 13:18:29 +0000 (15:18 +0200)
I was using a global variable. This would be set to '1' just before
calling the function to save cflags and cleared just after, then
using the variable to fill in the 'outside_rnage_ condition
in VG_(fixup_guest_state_after_syscall_interrupted)

Even though I haven't experienced any isseus with that, the comments just before
do_syscall_for_client made me want to try an alternative.

This code is very ugly and won't please the language lawyers.
Functions aren't guaranteed to have an address and there is no
guarantee that the binary layout will reflect the source layout.
Sadly C doesn't have something like "sizeof(*function)" to give
the size of a function in bytes. The next best that I could
manage was to use dummy 'marker' functions just after the
ones I want the end address of and then use the address of
'marker - 1'

I did think of one other way to do this. That would be to
generate a C file containing the function sizes. This would
require

1. "put_flag_size.c" would depend on the VEX guest_(x86|amd64)_helpers
   object files
2. Extract the sizes, for instance

echo -n "const size_t x86_put_eflag_c_size = 0x" > put_flag_size.c
nm -F sysv libvex_x86_freebsd_a-guest_x86_helpers.o | awk -F\| '/LibVEX_GuestX86_put_eflag_c/{print $5}' >> put_flag_size.c
echo ";" >> put_flag_size.c

That seems fairly difficult to do in automake and I'm not sure if
it would be robust.

VEX/priv/guest_amd64_helpers.c
VEX/priv/guest_x86_helpers.c
VEX/pub/libvex_guest_amd64.h
VEX/pub/libvex_guest_x86.h
coregrind/m_syswrap/syscall-amd64-darwin.S
coregrind/m_syswrap/syscall-amd64-freebsd.S
coregrind/m_syswrap/syscall-x86-darwin.S
coregrind/m_syswrap/syscall-x86-freebsd.S
coregrind/m_syswrap/syswrap-main.c

index ba71c1b62f164455afe67babedf9c537fb3ad017..abd2a1e370cf89bd48c6cd29cc907c3b1c2636df 100644 (file)
@@ -768,6 +768,25 @@ ULong amd64g_calculate_rflags_all_WRK ( ULong cc_op,
    }
 }
 
+#if defined(VGO_freebsd) || defined(VGO_darwin)
+
+/* This dummy function is just used to have an address just after
+   amd64g_calculate_rflags_all_WRK */
+
+static
+void _______VVVVVVVV_amd64g_calculate_rflags_all_WRK_VVVVVVVV_______ (void)
+{
+}
+
+/* Export addresses of amd64g_calculate_rflags_all_WRK and
+   _______VVVVVVVV_amd64g_calculate_rflags_all_WRK_VVVVVVVV_______
+   Used in syswrap-main.c / VG_(post_syscall) in the case where
+   the above function was interrupted and we need to work out
+   what needs to be done for the resumption */
+
+Addr addr_amd64g_calculate_rflags_all_WRK = (Addr)amd64g_calculate_rflags_all_WRK;
+Addr addr________VVVVVVVV_amd64g_calculate_rflags_all_WRK_VVVVVVVV_______ = (Addr)_______VVVVVVVV_amd64g_calculate_rflags_all_WRK_VVVVVVVV_______;
+#endif
 
 /* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate all the 6 flags from the supplied thunk parameters. */
@@ -994,6 +1013,15 @@ LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
    vex_state->guest_CC_NDEP = 0;
 }
 
+#if defined(VGO_freebsd) || defined(VGO_darwin)
+/* Used in syswrap-main.c / VG_(post_syscall) in the case where
+   the above function was interrupted and we need to work out
+   what needs to be done for the resumption. These functions
+   are extern so no need for 'addr' global variables */
+void _______VVVVVVVV_after_GuestAMD64_put_rflag_c_VVVVVVVV_______ (void)
+{
+}
+#endif
 
 /*---------------------------------------------------------------*/
 /*--- %rflags translation-time function specialisers.         ---*/
index c0a4d33edcdfc70a4fa68a23f1ff31ae2ecdd005..7b229cb79593d530a9a1cb96242262cdf94e4920 100644 (file)
@@ -567,6 +567,20 @@ UInt x86g_calculate_eflags_all_WRK ( UInt cc_op,
    }
 }
 
+#if defined(VGO_freebsd) || defined(VGO_darwin)
+
+/* see guest_amd64_helpers.c
+   Used in syswrap-main.c / VG_(post_syscall) for signal
+   resumption */
+
+static void _______VVVVVVVV_after_x86g_calculate_eflags_all_WRK_VVVVVVVV_______ (void)
+{
+}
+
+Addr addr_x86g_calculate_eflags_all_WRK = (Addr)x86g_calculate_eflags_all_WRK;
+Addr addr________VVVVVVVV_x86g_calculate_eflags_all_WRK_VVVVVVVV_______ = (Addr)_______VVVVVVVV_after_x86g_calculate_eflags_all_WRK_VVVVVVVV_______;
+#endif
+
 
 /* CALLED FROM GENERATED CODE: CLEAN HELPER */
 /* Calculate all the 6 flags from the supplied thunk parameters. */
@@ -790,6 +804,15 @@ LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
    vex_state->guest_CC_NDEP = 0;
 }
 
+#if defined(VGO_freebsd) || defined(VGO_darwin)
+
+/* Used in syswrap-main.c / VG_(post_syscall) for signal resumption */
+
+void _______VVVVVVVV_after_LibVEX_GuestX86_put_eflag_c_VVVVVVVV_______ (void)
+{
+}
+#endif
+
 
 /*---------------------------------------------------------------*/
 /*--- %eflags translation-time function specialisers.         ---*/
index 1518ba304cffc9fb9760173c6b1b41b475b1ff99..864b54b04ecc162b5a8bdccfc36ac02558526319 100644 (file)
@@ -203,6 +203,13 @@ void
 LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
                                 /*MOD*/VexGuestAMD64State* vex_state );
 
+#if defined(VGO_freebsd) || defined(VGO_darwin)
+void _______VVVVVVVV_after_GuestAMD64_put_rflag_c_VVVVVVVV_______ (void);
+extern Addr addr_amd64g_calculate_rflags_all_WRK;
+extern Addr addr________VVVVVVVV_amd64g_calculate_rflags_all_WRK_VVVVVVVV_______;
+#endif
+
+
 /* Do FXSAVE from the supplied VexGuestAMD64tate structure and store the
    result at the given address which represents a buffer of at least 416
    bytes. */
index fabafe113ccce3ae4d80c6f52a230264557b12de..53f72acb8cf01b6bc127703f699fa519c1d099a0 100644 (file)
@@ -292,6 +292,12 @@ void
 LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
                               /*MOD*/VexGuestX86State* vex_state );
 
+#if defined(VGO_freebsd) || defined(VGO_darwin)
+extern void _______VVVVVVVV_after_LibVEX_GuestX86_put_eflag_c_VVVVVVVV_______ (void);
+extern Addr addr_x86g_calculate_eflags_all_WRK;
+extern Addr addr________VVVVVVVV_x86g_calculate_eflags_all_WRK_VVVVVVVV_______;
+#endif
+
 /* Do x87 save from the supplied VexGuestX86State structure and store the
    result at the given address which represents a buffer of at least 108
    bytes. */
index 8a970fa0881b7eea022df6bc32c6a21bcbd9a811..ed93a851ebfabded3ff5fae2503f41a9efc4009e 100644 (file)
@@ -248,11 +248,6 @@ ML_(blksys_complete_UNIX): .quad MK_L_SCCLASS_N(UNIX,3)
 ML_(blksys_committed_UNIX):    .quad MK_L_SCCLASS_N(UNIX,4)
 ML_(blksys_finished_UNIX):     .quad MK_L_SCCLASS_N(UNIX,5)
 
-.data
-globl ML_(blksys_saving_cflag)
-ML_(blksys_saving_cflag):      .quad 0
-.previous
-
 #endif // defined(VGP_amd64_darwin)
 
 /* Let the linker know we don't need an executable stack */
index 55d53f0b76c54858b8b9d02f064d0e8fa91f20c6..8f084c3e1989b85b82f570d497a8f549496d9d25 100644 (file)
@@ -153,9 +153,7 @@ ML_(do_syscall_for_client_WRK):
    movq  %rax, %rdi      /* arg1 = new flag */
    movq  %r11, %rsi      /* arg2 = vex state */
    addq  $24, %rsp       /* remove syscall parameters */
-   movq  $0x1,  ML_(blksys_saving_cflag)
    call  LibVEX_GuestAMD64_put_rflag_c
-   movq  $0x0,  ML_(blksys_saving_cflag)
 
 4: /* Re-block signals.  If eip is in [4,5), then the syscall
       is complete and we needn't worry about it. */
@@ -208,12 +206,6 @@ ML_(blksys_committed):     .quad 4b
 ML_(blksys_finished):  .quad 5b
 .previous
 
- .data
- .globl ML_(blksys_saving_cflag)
- ML_(blksys_saving_cflag):     .quad 0
- .previous
-
-
 #endif /* defined(VGP_amd64_freebsd) */
 
 /* Let the linker know we don't need an executable stack */
index cbeadc52f826c9592a2de7d44d4fc3c2ce5af97e..903242268501060da090b830596fda21ca23ddc9 100644 (file)
@@ -246,10 +246,6 @@ ML_(blksys_complete_UNIX): .long MK_L_SCCLASS_N(UNIX,3)
 ML_(blksys_committed_UNIX):    .long MK_L_SCCLASS_N(UNIX,4)
 ML_(blksys_finished_UNIX):     .long MK_L_SCCLASS_N(UNIX,5)
 
-.data
-.globl ML_(blksys_saving_cflag)
-ML_(blksys_saving_cflag):      .long 0
-.previous
 #endif // defined(VGP_x86_darwin)
 
 /* Let the linker know we don't need an executable stack */
index 523d3d2e0df0a4dab206c3be96daea0c90a68d81..1faa74c4d67d9a05738237670767b612b164e546 100644 (file)
@@ -143,9 +143,7 @@ ML_(do_syscall_for_client_WRK):
    movl  $0, 0(%esp)
    movb  12(%esp), %al
    movb  %al, 0(%esp)
-   movl  $0x1, ML_(blksys_saving_cflag)
    call  LibVEX_GuestX86_put_eflag_c
-   movl  $0x0, ML_(blksys_saving_cflag)
    addl  $12, %esp
 
 4: /* Re-block signals.  If eip is in [4,5), then the syscall is
@@ -193,11 +191,6 @@ ML_(blksys_committed):  .long 4b
 ML_(blksys_finished):   .long 5b
 .previous
 
- .data
- .globl ML_(blksys_saving_cflag)
- ML_(blksys_saving_cflag):     .long 0
- .previous
-
 #endif // defined(VGP_x86_freebsd)
 
 /* Let the linker know we don't need an executable stack */
index 5824a1dbea082f432583379f119a60797b6b1601..5077a7da73f706cbbd2ff7b6b050596bdc2b518f 100644 (file)
@@ -2569,9 +2569,6 @@ void VG_(post_syscall) (ThreadId tid)
   extern const Addr ML_(blksys_complete);
   extern const Addr ML_(blksys_committed);
   extern const Addr ML_(blksys_finished);
-#if defined(VGO_freebsd)
-  extern const Addr ML_(blksys_saving_cflag);
-#endif
 #elif defined(VGO_darwin)
   /* Darwin requires extra uglyness */
   extern const Addr ML_(blksys_setup_MACH);
@@ -2589,7 +2586,6 @@ void VG_(post_syscall) (ThreadId tid)
   extern const Addr ML_(blksys_complete_UNIX);
   extern const Addr ML_(blksys_committed_UNIX);
   extern const Addr ML_(blksys_finished_UNIX);
-  extern const Addr ML_(blksys_saving_cflag);
 #elif defined(VGO_solaris)
   extern const Addr ML_(blksys_setup);
   extern const Addr ML_(blksys_complete);
@@ -3123,7 +3119,35 @@ VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
 #if defined(VGO_freebsd) || defined(VGO_darwin)
   if (outside_range)
   {
-     if (ML_(blksys_saving_cflag))
+     /* This is not guaranteed to work since the compiler / link editor
+        could lay out the binary functions in a different order to
+        the source file. However, it seems to work. */
+
+#if defined (VGA_amd64)
+
+     vg_assert((Addr)_______VVVVVVVV_after_GuestAMD64_put_rflag_c_VVVVVVVV_______ >
+               (Addr)LibVEX_GuestAMD64_put_rflag_c );
+
+     vg_assert(addr________VVVVVVVV_amd64g_calculate_rflags_all_WRK_VVVVVVVV_______ >
+               addr_amd64g_calculate_rflags_all_WRK);
+
+     if ((ip >= (Addr)LibVEX_GuestAMD64_put_rflag_c &&
+          ip <  (Addr)_______VVVVVVVV_after_GuestAMD64_put_rflag_c_VVVVVVVV_______) ||
+         (ip >= addr_amd64g_calculate_rflags_all_WRK &&
+         ip < addr________VVVVVVVV_amd64g_calculate_rflags_all_WRK_VVVVVVVV_______))
+#else
+
+     vg_assert((Addr)_______VVVVVVVV_after_LibVEX_GuestX86_put_eflag_c_VVVVVVVV_______ >
+               (Addr)LibVEX_GuestX86_put_eflag_c);
+     vg_assert(addr________VVVVVVVV_x86g_calculate_eflags_all_WRK_VVVVVVVV_______>
+              addr_x86g_calculate_eflags_all_WRK);
+
+     if ((ip >= (Addr)LibVEX_GuestX86_put_eflag_c &&
+         ip <  (Addr)_______VVVVVVVV_after_LibVEX_GuestX86_put_eflag_c_VVVVVVVV_______) ||
+         (ip >= addr_x86g_calculate_eflags_all_WRK &&
+          ip < addr________VVVVVVVV_x86g_calculate_eflags_all_WRK_VVVVVVVV_______))
+#endif
      {
         outside_range = False;
         in_complete_to_committed = True;