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

YunQiang Su via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 3 22:07:28 PST 2024


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

>From c74541cc8d604a5655d3cd2780170d52a03f727f Mon Sep 17 00:00:00 2001
From: YunQiang Su <syq at gcc.gnu.org>
Date: Thu, 4 Jan 2024 13:07:41 +0800
Subject: [PATCH] Sanitizer/MIPS: fix build fail on pre-R6

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.
---
 compiler-rt/lib/interception/interception.h   | 17 +++++++------
 .../lib/sanitizer_common/sanitizer_asm.h      | 25 +++++++++++++++++++
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h
index 9d8b60b2eef58c..deb5a811fcd3e2 100644
--- a/compiler-rt/lib/interception/interception.h
+++ b/compiler-rt/lib/interception/interception.h
@@ -191,12 +191,12 @@ const interpose_substitution substitution_##func_name[]             \
 #   define ASM_TYPE_FUNCTION_STR "@function"
 #  endif
 // Keep trampoline implementation in sync with sanitizer_common/sanitizer_asm.h
-#  define DECLARE_WRAPPER(ret_type, func, ...)                                 \
-     extern "C" ret_type func(__VA_ARGS__);                                    \
-     extern "C" ret_type TRAMPOLINE(func)(__VA_ARGS__);                        \
-     extern "C" ret_type __interceptor_##func(__VA_ARGS__)                     \
-       INTERCEPTOR_ATTRIBUTE __attribute__((weak)) ALIAS(WRAP(func));          \
-     asm(                                                                      \
+#    define DECLARE_WRAPPER(ret_type, func, ...)                         \
+      extern "C" ret_type func(__VA_ARGS__);                             \
+      extern "C" ret_type TRAMPOLINE(func)(__VA_ARGS__);                 \
+      extern "C" ret_type __interceptor_##func(__VA_ARGS__)              \
+          INTERCEPTOR_ATTRIBUTE __attribute__((weak)) ALIAS(WRAP(func)); \
+      asm(                                                                      \
        ".text\n"                                                               \
        __ASM_WEAK_WRAPPER(func)                                                \
        ".set " #func ", " SANITIZER_STRINGIFY(TRAMPOLINE(func)) "\n"           \
@@ -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..b558748b511d3c 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,29 @@
 # 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



More information about the llvm-commits mailing list