]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD: put back stacktrace hack for syscalls in older versions
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 27 Oct 2024 16:48:58 +0000 (17:48 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 27 Oct 2024 16:56:41 +0000 (17:56 +0100)
coregrind/m_stacktrace.c
memcheck/tests/freebsd/scalar.c
memcheck/tests/freebsd/setproctitle.c

index 2cb0f3233e3d0a84c722b2ac60f85782be882a06..630b5b87524c236106b805be643d1a65a5f70a11 100644 (file)
@@ -282,6 +282,26 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
    i = 1;
    if (do_stats) stats.nr++;
 
+   // Does this apply to macOS 10.14 and earlier?
+#  if defined(VGO_freebsd) && (__FreeBSD_version < 1300000)
+   if (VG_(is_valid_tid)(tid_if_known) &&
+      VG_(is_in_syscall)(tid_if_known) &&
+      i < max_n_ips) {
+      /* On FreeBSD, all the system call stubs have no function
+       * prolog.  So instead of top of the stack being a new
+       * frame comprising a saved BP and a return address, we
+       * just have the return address in the caller's frame.
+       * Adjust for this by recording the return address.
+       */
+      if (debug)
+         VG_(printf)("     in syscall, use XSP-1\n");
+      ips[i] = *(Addr *)uregs.xsp - 1;
+      if (sps) sps[i] = uregs.xsp;
+      if (fps) fps[i] = uregs.xbp;
+      i++;
+   }
+#  endif
+
    while (True) {
 
       if (i >= max_n_ips)
@@ -502,19 +522,19 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
     || defined(VGP_amd64_solaris) || defined(VGP_amd64_freebsd)
 
 /*
- * Concerning the comment in the function about syscalls, this also used to
- * apply to FreeBSD. I'm not sure what changed or when. The situation with
- * FreeBSD going at least as far back as version 12.1 (so Nov 2019) is that
- * system calls are implemented with generated wrappers that call through
- * an interposing table of function pointers. The restult when built with
- * clang is that code for the frame pointer prolog is generated but then
- * an optimized sibling call is made. That means the frame pointer is popped
- * off the stack and a jmp is made to the function in the table rather than
+ * Concerning the comment in the function about syscalls, I'm not sure
+ * what changed or when with FreeBSD. The situation going at least
+ * as far back as FreeBSD 12.1 (so Nov 2019) is that system calls are
+ * implemented with generated wrappers that call through an interposing
+ * table of function pointers. The result when built with clang is that
+ * code for the frame pointer prolog is generated but then an optimized
+ * sibling call is made. That means the frame pointer is popped off
+ * the stack and a jmp is made to the function in the table rather than
  * a call.
  *
  * The end result is that, when we are in a syscall it is as though there were
- * no prolog but a copy of the frame pointer is stored 64byte word below the
- * stack pointer. If FreeBSD uses the hack for Darwin that sets
+ * no prolog but a copy of the frame pointer is stored one 64bit word below the
+ * stack pointer. If more recent FreeBSD uses the hack that sets
  *  ips[i] = *(Addr *)uregs.xsp - 1;
  * then the caller of the syscall gets added twice.
  */
@@ -592,7 +612,7 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known,
       VG_(printf)("     ipsS[%d]=%#08lx rbp %#08lx rsp %#08lx\n",
                   i-1, ips[i-1], uregs.xbp, uregs.xsp);
 
-#  if defined(VGO_darwin)
+#  if defined(VGO_darwin) || (defined(VGO_freebsd) && __FreeBSD_version < 1300000)
    if (VG_(is_valid_tid)(tid_if_known) &&
       VG_(is_in_syscall)(tid_if_known) &&
       i < max_n_ips) {
index e9d936e4742ef106508b8588b034a2be8c515ca9..8862f3df3e4fac0acd5f47a06396e1c15721f4d0 100644 (file)
@@ -334,7 +334,7 @@ int main(void)
 
    /* SYS_mprotect                74 */
    GO(SYS_mprotect, "3s 0m");
-   SY(SYS_mprotect, x0+1, x0+1, x0+9999); FAIL;
+   //SY(SYS_mprotect, x0+1, x0+1, x0+9999); FAIL;
 
    /* SYS_madvise                 75 */
    GO(SYS_madvise, "3s 0m");
@@ -372,7 +372,7 @@ int main(void)
 
    /* SYS_swapon                  85 */
    GO(SYS_swapon, "1s 1m");
-   SY(SYS_swapon, x0); FAIL;
+   //SY(SYS_swapon, x0+1); SUCC;
 
    /* SYS_getitimer               86 */
    GO(SYS_getitimer, "2s 1m");
index cc0357f42f10384940902fa0a42a26a4c36ec3a3..44e7514a2ef3ae99beb18541602047e1aa235c6e 100644 (file)
@@ -10,7 +10,7 @@
 
 int main(void)
 {
-#if defined(KERN_PS_STRINGS)
+#if defined(KERN_PS_STRINGS) && defined(AT_PS_STRINGS)
    unsigned long ul_ps_strings;
    struct ps_strings* v1;
    struct ps_strings* v2;