[compiler-rt] Sanitizer/MIPS: fix build fail on pre-R6 (PR #76894)
YunQiang Su via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 3 22:10:23 PST 2024
https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/76894
>From dbbe6c5e36db8e77ee45f14740a8050860dedb01 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang.su at cipunited.com>
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