[compiler-rt] 0a64367 - Sanitizer/MIPS: Use $t9 for preemptible function call (#76894)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 16 20:11:55 PST 2024


Author: YunQiang Su
Date: 2024-01-16T23:11:50-05:00
New Revision: 0a64367a72f1634321f5051221f05f2f364bd882

URL: https://github.com/llvm/llvm-project/commit/0a64367a72f1634321f5051221f05f2f364bd882
DIFF: https://github.com/llvm/llvm-project/commit/0a64367a72f1634321f5051221f05f2f364bd882.diff

LOG: Sanitizer/MIPS: Use $t9 for preemptible function call (#76894)

Currently, almost all of the shared libraries of MIPS, rely on $t9
to get the address of current function, instead of PCREL instructions,
even on MIPSr6. So we have to set $t9 properly.

To get the address of preemptible function, we need the help of GOT.
MIPS/O32 has .cpload, which can help to generate 3 instructions to get 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

Fixes #74047

Co-authored-by: YunQiang Su <yunqiang.su at cipunited.com>

Added: 
    

Modified: 
    compiler-rt/lib/interception/interception.h
    compiler-rt/lib/sanitizer_common/sanitizer_asm.h

Removed: 
    


################################################################################
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..3af66a4e449988 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_asm.h
@@ -53,6 +53,29 @@
 # define ASM_TAIL_CALL tail
 #endif
 
+// Currently, almost all of the shared libraries rely on the value of
+// $t9 to get the address of current function, instead of PCREL, even
+// on MIPSr6. To be compatiable with them, we have to set $t9 properly.
+// MIPS uses GOT to get the address of preemptible functions.
+#if defined(__mips64)
+#  define C_ASM_TAIL_CALL(t_func, i_func)                       \
+    "lui $t8, %hi(%neg(%gp_rel(" t_func ")))\n"                 \
+    "daddu $t8, $t8, $t9\n"                                     \
+    "daddiu $t8, $t8, %lo(%neg(%gp_rel(" t_func ")))\n"         \
+    "ld $t9, %got_disp(" i_func ")($t8)\n"                      \
+    "jr $t9\n"
+#elif defined(__mips__)
+#  define C_ASM_TAIL_CALL(t_func, i_func)                       \
+    ".set    noreorder\n"                                       \
+    ".cpload $t9\n"                                             \
+    ".set    reorder\n"                                         \
+    "lw $t9, %got(" i_func ")($gp)\n"                           \
+    "jr $t9\n"
+#elif defined(ASM_TAIL_CALL)
+#  define C_ASM_TAIL_CALL(t_func, i_func)                       \
+    SANITIZER_STRINGIFY(ASM_TAIL_CALL) " " i_func
+#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