[compiler-rt] 9eeb2c9 - [msan] Check for AVX regs using offset

Petr Hosek via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 5 19:25:50 PST 2022


Author: Petr Hosek
Date: 2022-01-05T19:24:00-08:00
New Revision: 9eeb2c98f4528856c63618e3ef94529fa6f4ff11

URL: https://github.com/llvm/llvm-project/commit/9eeb2c98f4528856c63618e3ef94529fa6f4ff11
DIFF: https://github.com/llvm/llvm-project/commit/9eeb2c98f4528856c63618e3ef94529fa6f4ff11.diff

LOG: [msan] Check for AVX regs using offset

glibc versions < 2.26 use different names for the fields.
However the layout is unchanged, so using the offset should be a
portable way to address this issue across platforms.

Fixes: https://github.com/llvm/llvm-project/issues/53014

Patch By: paulkirth

Differential Revision: https://reviews.llvm.org/D116695

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
    compiler-rt/test/msan/Linux/signal_mcontext.cpp
    compiler-rt/test/msan/Linux/signal_mcontext2.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
index 0ffbb816bb882..349cdbcda6d98 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -224,9 +224,13 @@ namespace __sanitizer {
 #    if SANITIZER_LINUX && SANITIZER_X64
     // See kernel arch/x86/kernel/fpu/signal.c for details.
     const auto *fpregs = static_cast<ucontext_t *>(ctx)->uc_mcontext.fpregs;
-    if (fpregs->__glibc_reserved1[12] == FP_XSTATE_MAGIC1)
-      return reinterpret_cast<const char *>(fpregs) +
-             fpregs->__glibc_reserved1[13] - static_cast<const char *>(ctx);
+    // The member names 
diff er across header versions, but the actual layout
+    // is always the same.  So avoid using members, just use arithmetic.
+    const uint32_t *after_xmm =
+        reinterpret_cast<const uint32_t *>(fpregs + 1) - 24;
+    if (after_xmm[12] == FP_XSTATE_MAGIC1)
+      return reinterpret_cast<const char *>(fpregs) + after_xmm[13] -
+             static_cast<const char *>(ctx);
 #    endif
     return sizeof(ucontext_t);
   }

diff  --git a/compiler-rt/test/msan/Linux/signal_mcontext.cpp b/compiler-rt/test/msan/Linux/signal_mcontext.cpp
index f1184a4b6943d..932b4b8c09775 100644
--- a/compiler-rt/test/msan/Linux/signal_mcontext.cpp
+++ b/compiler-rt/test/msan/Linux/signal_mcontext.cpp
@@ -3,6 +3,7 @@
 #include <pthread.h>
 #include <sanitizer/msan_interface.h>
 #include <signal.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <ucontext.h>
 #include <unistd.h>
@@ -12,7 +13,11 @@ void handler(int sig, siginfo_t *info, void *uctx) {
 #if defined(__x86_64__)
   auto *mctx = &static_cast<ucontext_t *>(uctx)->uc_mcontext;
   if (auto *fpregs = mctx->fpregs) {
-    if (fpregs->__glibc_reserved1[12] == FP_XSTATE_MAGIC1) {
+    // The member names 
diff er across header versions, but the actual layout
+    // is always the same.  So avoid using members, just use arithmetic.
+    const uint32_t *after_xmm =
+        reinterpret_cast<const uint32_t *>(fpregs + 1) - 24;
+    if (after_xmm[12] == FP_XSTATE_MAGIC1) {
       auto *xstate = reinterpret_cast<_xstate *>(mctx->fpregs);
       __msan_check_mem_is_initialized(xstate, sizeof(*xstate));
     }

diff  --git a/compiler-rt/test/msan/Linux/signal_mcontext2.cpp b/compiler-rt/test/msan/Linux/signal_mcontext2.cpp
index ec75d2c94ac82..6bb6740c6fa7c 100644
--- a/compiler-rt/test/msan/Linux/signal_mcontext2.cpp
+++ b/compiler-rt/test/msan/Linux/signal_mcontext2.cpp
@@ -4,13 +4,18 @@
 
 #include <pthread.h>
 #include <signal.h>
+#include <stdint.h>
 #include <ucontext.h>
 
 void handler(int sig, siginfo_t *info, void *uctx) {
   volatile int uninit;
   auto *mctx = &static_cast<ucontext_t *>(uctx)->uc_mcontext;
   auto *fpregs = mctx->fpregs;
-  if (fpregs && fpregs->__glibc_reserved1[12] == FP_XSTATE_MAGIC1)
+  // The member names 
diff er across header versions, but the actual layout
+  // is always the same.  So avoid using members, just use arithmetic.
+  const uint32_t *after_xmm =
+      reinterpret_cast<const uint32_t *>(fpregs + 1) - 24;
+  if (after_xmm[12] == FP_XSTATE_MAGIC1)
     reinterpret_cast<_xstate *>(mctx->fpregs)->ymmh.ymmh_space[0] = uninit;
   else
     mctx->gregs[REG_RAX] = uninit;


        


More information about the llvm-commits mailing list