]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 504936 - Add FreeBSD amd64 sysarch subcommands AMD64_SET_TLSBASE and AMD64_GET_TL...
authorPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 29 May 2025 06:52:28 +0000 (08:52 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 29 May 2025 07:58:31 +0000 (09:58 +0200)
NEWS
VEX/priv/guest_amd64_helpers.c
VEX/pub/libvex_guest_amd64.h
coregrind/m_syswrap/syswrap-amd64-freebsd.c
include/vki/vki-freebsd.h
memcheck/mc_machine.c

diff --git a/NEWS b/NEWS
index 1450dfba820250ce4293197f18ba1f45e22d262d..7cf33d52e5d128ea1fee5a0d6f73d28b6b6a78cc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -36,6 +36,8 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 504265  FreeBSD: missing syscall wrappers for fchroot and setcred
 504341  Valgrind killed by LTP syscall testcase setrlimit05
 504466  Double close causes SEGV
+504936  Add FreeBSD amd64 sysarch subcommands AMD64_SET_TLSBASE and
+        AMD64_GET_TLSBASE
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index b4e37fcbd66bf0f317dcf0a5f6de55490fa43d53..8313d58b47a51f24f5a767b18d1561baeccb1845 100644 (file)
@@ -2665,6 +2665,7 @@ void amd64g_dirtyhelper_FINIT ( VexGuestAMD64State* gst )
 {
    Int i;
    gst->guest_FTOP = 0;
+   gst->pad1 = 0;
    for (i = 0; i < 8; i++) {
       gst->guest_FPTAG[i] = 0; /* empty */
       gst->guest_FPREG[i] = 0; /* IEEE754 64-bit zero */
@@ -4831,7 +4832,7 @@ void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state )
    vex_state->guest_GS_CONST = 0;
 
    vex_state->guest_IP_AT_SYSCALL = 0;
-   vex_state->pad1 = 0;
+   vex_state->guest_TLSBASE = 0;
 }
 
 
index 8f6bb560cb12eb8403fa1310fd0f9d7d21d54748..9be073a21fb62b29009ba91945f6a4dd38a27b50 100644 (file)
@@ -170,8 +170,11 @@ typedef
          been interrupted by a signal. */
       ULong guest_IP_AT_SYSCALL;
 
-      /* Padding to make it have an 16-aligned size */
-      ULong pad3;
+      /* Used on FreeBSD as part of a mechanism to allow signal handlers
+           to use TLS. */
+      ULong guest_TLSBASE;
+
+      /* Add padding here to make it have an 16-aligned size */
    }
    VexGuestAMD64State;
 
index e1316eac3e034a2beea8d791878d5398337c486c..4c69e762bdd980b93cdc19a35c0552dca7465552 100644 (file)
@@ -128,13 +128,18 @@ PRE(sys_sysarch)
    PRE_REG_READ2(int, "sysarch", int, number, void *, args);
    switch (ARG1) {
    case VKI_AMD64_SET_FSBASE:
-      PRINT("sys_amd64_set_fsbase ( %#lx )", ARG2);
+   case VKI_AMD64_SET_TLSBASE:
+      PRINT("sys_amd64_set_%ssbase ( %#lx )", (ARG1 == VKI_AMD64_SET_FSBASE ? "f" : "tl"), ARG2);
 
       if (ML_(safe_to_deref)((void**)ARG2, sizeof(void*))) {
          /* On FreeBSD, the syscall loads the %gs selector for us, so do it now. */
          tst = VG_(get_ThreadState)(tid);
          p = (void**)ARG2;
          tst->arch.vex.guest_FS_CONST = (UWord)*p;
+         if (ARG1 == VKI_AMD64_SET_TLSBASE) {
+            tst->arch.vex.guest_TLSBASE = (UWord)*p;
+            // kernel also calls "set_pcb_flags(pcb, PCB_TLSBASE);"
+         }
          /* "do" the syscall ourselves; the kernel never sees it */
          SET_STATUS_Success2((ULong)*p, tst->arch.vex.guest_RDX );
       } else {
@@ -165,6 +170,22 @@ PRE(sys_sysarch)
       tst = VG_(get_ThreadState)(tid);
       SET_STATUS_Success2( tst->arch.vex.guest_FPTAG[0], tst->arch.vex.guest_FPTAG[0] );
       break;
+   //case VKI_AMD64_SET_PKRU:
+   //case VKI_AMD64_CLEAR_PKRU:
+   case VKI_AMD64_GET_TLSBASE:
+      PRINT("sys_amd64_get_tlsbase ( %#lx )", ARG2);
+      PRE_MEM_WRITE( "amd64_get_fsbase(basep)", ARG2, sizeof(void *) );
+      if (ML_(safe_to_deref)((void**)ARG2, sizeof(void*))) {
+         /* "do" the syscall ourselves; the kernel never sees it */
+         tst = VG_(get_ThreadState)(tid);
+         SET_STATUS_Success2( tst->arch.vex.guest_TLSBASE, tst->arch.vex.guest_RDX );
+      } else {
+         SET_STATUS_Failure( VKI_EINVAL );
+      }
+      break;
+
+      PRINT("sys_amd64_set_tlsbase ( %#lx )", ARG2);
+      break;
    default:
       VG_(message) (Vg_UserMsg, "unhandled sysarch cmd %lu", ARG1);
       VG_(unimplemented) ("unhandled sysarch cmd");
@@ -179,6 +200,7 @@ POST(sys_sysarch)
       break;
    case VKI_AMD64_GET_FSBASE:
    case VKI_AMD64_GET_XFPUSTATE:
+   case VKI_AMD64_GET_TLSBASE:
       POST_MEM_WRITE( ARG2, sizeof(void *) );
       break;
    default:
index 25399799952d69de70eb3533f4a1e8146933ac3f..6be56c27ad4982ab895da00c3b150faa5664eadb 100644 (file)
@@ -1857,12 +1857,19 @@ struct vki_ptrace_vm_entry {
 #define VKI_I386_GET_GSBASE     9
 #define VKI_I386_SET_GSBASE     10
 #define VKI_I386_GET_XFPUSTATE  11
+#define VKI_I386_SET_PKRU       12
+#define VKI_I386_CLEAR_PKRU     13
 
 #define VKI_AMD64_GET_FSBASE    128
 #define VKI_AMD64_SET_FSBASE    129
 #define VKI_AMD64_GET_GSBASE    130
 #define VKI_AMD64_SET_GSBASE    131
-#define VKI_AMD64_GET_XFPUSTATE  132
+#define VKI_AMD64_GET_XFPUSTATE 132
+#define VKI_AMD64_SET_PKRU      133
+#define VKI_AMD64_CLEAR_PKRU    134
+#define VKI_AMD64_GET_TLSBASE   135
+#define VKI_AMD64_SET_TLSBASE   136
+
 
 //----------------------------------------------------------------------
 // From sys/module.h
index 34df0011ac8bc6a240c591fd1b4fa2137f3a4f62..b0026a6bd56ce560dbec71dd7f6bb810acb81302 100644 (file)
@@ -647,6 +647,7 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
    if (o == GOF(DFLAG)   && sz == 8) return -1; /* slot used for %CH */
    if (o == GOF(RIP)     && sz == 8) return -1; /* slot unused */
    if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
+   if (o == GOF(TLSBASE) && sz == 8) return -1; /* slot unused */
    if (o == GOF(IDFLAG)  && sz == 8) return -1; /* slot used for %DH */
    if (o == GOF(ACFLAG)  && sz == 8) return -1; /* slot unused */
    if (o == GOF(FS_CONST) && sz == 8) return -1; /* slot unused */