]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Sanitizer/MIPS: Use $t9 for preemptible function call
authorYunQiang Su <yunqiang.su@cipunited.com>
Wed, 17 Jan 2024 07:11:33 +0000 (15:11 +0800)
committerYunQiang Su <syq@gcc.gnu.org>
Wed, 17 Jan 2024 09:03:08 +0000 (17:03 +0800)
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

Upstream-Commit: 0a64367a72f1634321f5051221f05f2f364bd882

libsanitizer

* interception/interception.h (substitution_##func_name):
Use macro C_ASM_TAIL_CALL.
* sanitizer_common/sanitizer_asm.h: Define C_ASM_TAIL_CALL
for MIPS with help of t9.

libsanitizer/interception/interception.h
libsanitizer/sanitizer_common/sanitizer_asm.h

index 9d8b60b2eef58c2f0ade5e3791766b1523ade5e3..58e969378a90822ce727dc24af74944f225da189 100644 (file)
@@ -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"                    \
index bbb18cfbdf15feb0f75ca2fb35d325da2cea1931..3af66a4e44998822dc300e308c53f9582cbd4088 100644 (file)
 # 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@plt