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.
This commit is contained in:
YunQiang Su 2024-01-17 15:11:33 +08:00 committed by YunQiang Su
parent de4c9a27ba
commit 557dbbac8e
2 changed files with 26 additions and 2 deletions

View 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" \

View File

@ -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