aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYunQiang Su <yunqiang.su@cipunited.com>2024-01-17 15:11:33 +0800
committerYunQiang Su <syq@gcc.gnu.org>2024-01-17 17:03:08 +0800
commit557dbbac8e6a344d44fedff75e16008fa8a5ffb7 (patch)
tree5576b16c6514d14e57fdfbcd67c749b5f5577a88
parentde4c9a27ba51e409e9d9e2a2827da53b1c979b09 (diff)
Sanitizer/MIPS: Use $t9 for preemptible function call
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.
-rw-r--r--libsanitizer/interception/interception.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_asm.h23
2 files changed, 26 insertions, 2 deletions
diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h
index 9d8b60b2eef..58e969378a9 100644
--- a/libsanitizer/interception/interception.h
+++ b/libsanitizer/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/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h
index bbb18cfbdf1..3af66a4e449 100644
--- a/libsanitizer/sanitizer_common/sanitizer_asm.h
+++ b/libsanitizer/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@plt