From: Paul Floyd Date: Thu, 29 May 2025 06:52:28 +0000 (+0200) Subject: Bug 504936 - Add FreeBSD amd64 sysarch subcommands AMD64_SET_TLSBASE and AMD64_GET_TL... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f7b087df5ccd4ac1c0803a5dfd168327dc25286c;p=thirdparty%2Fvalgrind.git Bug 504936 - Add FreeBSD amd64 sysarch subcommands AMD64_SET_TLSBASE and AMD64_GET_TLSBASE --- diff --git a/NEWS b/NEWS index 1450dfba8..7cf33d52e 100644 --- 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 diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c index b4e37fcbd..8313d58b4 100644 --- a/VEX/priv/guest_amd64_helpers.c +++ b/VEX/priv/guest_amd64_helpers.c @@ -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; } diff --git a/VEX/pub/libvex_guest_amd64.h b/VEX/pub/libvex_guest_amd64.h index 8f6bb560c..9be073a21 100644 --- a/VEX/pub/libvex_guest_amd64.h +++ b/VEX/pub/libvex_guest_amd64.h @@ -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; diff --git a/coregrind/m_syswrap/syswrap-amd64-freebsd.c b/coregrind/m_syswrap/syswrap-amd64-freebsd.c index e1316eac3..4c69e762b 100644 --- a/coregrind/m_syswrap/syswrap-amd64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-amd64-freebsd.c @@ -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: diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index 253997999..6be56c27a 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -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 diff --git a/memcheck/mc_machine.c b/memcheck/mc_machine.c index 34df0011a..b0026a6bd 100644 --- a/memcheck/mc_machine.c +++ b/memcheck/mc_machine.c @@ -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 */