[clang] [compiler-rt] Sanitizer prer6 (PR #76894)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 3 21:11:56 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: YunQiang Su (wzssyqa)

<details>
<summary>Changes</summary>

On MIPS pre-R6, instruction b can only work within 64KiB,
which is not enough now.

We need the help of GOT.
For __mips64, we can get GOT by:

   lui $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func)))))
   daddu $t8, $t8, $t9
   daddiu $t8, $t8, %hi(%neg(%gp_rel(SANITIZER_STRINGIFY(TRAMPOLINE(func)))))

And then get the address of __interceptor_func, and jump to it

   ld $t9, %got_disp(__interceptor_" SANITIZER_STRINGIFY(func) ")($t8)
   jr $t9

MIPS/O32 has .cpload, which can help to generate 3 instructions to get GOT.

MIPSr6 has instruction bc, which can jump long enough.

---
Full diff: https://github.com/llvm/llvm-project/pull/76894.diff


4 Files Affected:

- (modified) clang/lib/Driver/ToolChains/Arch/Mips.cpp (+6-2) 
- (modified) clang/test/Driver/mips-features.c (+7-1) 
- (modified) compiler-rt/lib/interception/interception.h (+3-2) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_asm.h (+21) 


``````````diff
diff --git a/clang/lib/Driver/ToolChains/Arch/Mips.cpp b/clang/lib/Driver/ToolChains/Arch/Mips.cpp
index f9f14c01b2b9f0..fe9d112b8800b1 100644
--- a/clang/lib/Driver/ToolChains/Arch/Mips.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -221,6 +221,7 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   bool IsN64 = ABIName == "64";
   bool IsPIC = false;
   bool NonPIC = false;
+  bool HasNaN2008Opt = false;
 
   Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
                                     options::OPT_fpic, options::OPT_fno_pic,
@@ -285,9 +286,10 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
   if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
     StringRef Val = StringRef(A->getValue());
     if (Val == "2008") {
-      if (mips::getIEEE754Standard(CPUName) & mips::Std2008)
+      if (mips::getIEEE754Standard(CPUName) & mips::Std2008) {
         Features.push_back("+nan2008");
-      else {
+        HasNaN2008Opt = true;
+      } else {
         Features.push_back("-nan2008");
         D.Diag(diag::warn_target_unsupported_nan2008) << CPUName;
       }
@@ -323,6 +325,8 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
       D.Diag(diag::err_drv_unsupported_option_argument)
           << A->getSpelling() << Val;
     }
+  } else if (HasNaN2008Opt) {
+    Features.push_back("+abs2008");
   }
 
   AddTargetFeature(Args, Features, options::OPT_msingle_float,
diff --git a/clang/test/Driver/mips-features.c b/clang/test/Driver/mips-features.c
index 5ae566774959f1..fad6009ffb89ba 100644
--- a/clang/test/Driver/mips-features.c
+++ b/clang/test/Driver/mips-features.c
@@ -213,7 +213,13 @@
 // RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \
 // RUN:     -mnan=legacy -mnan=2008 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NAN2008 %s
-// CHECK-NAN2008: "-target-feature" "+nan2008"
+// CHECK-NAN2008: "-target-feature" "+nan2008" "-target-feature" "+abs2008"
+//
+// -mnan=2008 -mabs=legacy
+// RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \
+// RUN:     -mabs=legacy -mnan=2008 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-ABSLEGACYNAN2008 %s
+// CHECK-ABSLEGACYNAN2008: "-target-feature" "+nan2008" "-target-feature" "-abs2008"
 //
 // -mnan=legacy
 // RUN: %clang -target mips-linux-gnu -march=mips32r3 -### -c %s \
diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h
index 9d8b60b2eef58c..58e969378a9082 100644
--- a/compiler-rt/lib/interception/interception.h
+++ b/compiler-rt/lib/interception/interception.h
@@ -205,8 +205,9 @@ const interpose_substitution substitution_##func_name[]             \
          ASM_TYPE_FUNCTION_STR "\n"                                            \
        SANITIZER_STRINGIFY(TRAMPOLINE(func)) ":\n"                             \
        SANITIZER_STRINGIFY(CFI_STARTPROC) "\n"                                 \
-       SANITIZER_STRINGIFY(ASM_TAIL_CALL) " __interceptor_"                    \
-         SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func)) "\n"                   \
+       C_ASM_TAIL_CALL(SANITIZER_STRINGIFY(TRAMPOLINE(func)),                  \
+                       "__interceptor_"                                        \
+                         SANITIZER_STRINGIFY(ASM_PREEMPTIBLE_SYM(func))) "\n"  \
        SANITIZER_STRINGIFY(CFI_ENDPROC) "\n"                                   \
        ".size  " SANITIZER_STRINGIFY(TRAMPOLINE(func)) ", "                    \
             ".-" SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n"                    \
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
index bbb18cfbdf15fe..37fa77b2d6759e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
@@ -44,6 +44,8 @@
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__sparc__)
 # define ASM_TAIL_CALL jmp
+#elif defined(__mips__) && __mips_isa_rev >= 6
+# define ASM_TAIL_CALL bc
 #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \
     defined(__powerpc__) || defined(__loongarch_lp64)
 # define ASM_TAIL_CALL b
@@ -53,6 +55,25 @@
 # define ASM_TAIL_CALL tail
 #endif
 
+#if defined(__mips64) && __mips_isa_rev < 6
+# define C_ASM_TAIL_CALL(tfunc, ifunc)                        \
+    "lui $t8, %hi(%neg(%gp_rel(" tfunc ")))\n"                \
+    "daddu $t8, $t8, $t9\n"                                   \
+    "daddu $t8, $t8, %lo(%neg(%gp_rel(" tfunc ")))\n"         \
+    "ld $t9, %got_disp(" ifunc ")($t8)\n"                     \
+    "jr $t9\n"
+#elif defined(__mips__) && __mips_isa_rev < 6
+# define C_ASM_TAIL_CALL(tfunc, ifunc)                        \
+    ".set    noreorder\n"                                     \
+    ".cpload $t9\n"                                           \
+    ".set    reorder\n"                                       \
+    "lw $t9, %got(" ifunc ")($gp)\n"                          \
+    "jr $t9\n"
+#elif defined(ASM_TAIL_CALL)
+#  define C_ASM_TAIL_CALL(tfunc, ifunc) \
+    SANITIZER_STRINGIFY(ASM_TAIL_CALL) " " ifunc
+#endif
+
 #if defined(__ELF__) && defined(__x86_64__) || defined(__i386__) || \
     defined(__riscv)
 # define ASM_PREEMPTIBLE_SYM(sym) sym at plt

``````````

</details>


https://github.com/llvm/llvm-project/pull/76894


More information about the llvm-commits mailing list