This is an archive of the discontinued LLVM Phabricator instance.

Sanitizer/MIPS: fix build fail on pre-R6
Needs ReviewPublic

Authored by wzssyqa on Aug 22 2023, 12:35 AM.

Details

Summary

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.

Diff Detail

Event Timeline

wzssyqa created this revision.Aug 22 2023, 12:35 AM
wzssyqa requested review of this revision.Aug 22 2023, 12:35 AM

This large pile of mips code makes me nervous. What I really want is to eliminate code related to some older mips ports.
For example, just claim that defined(__mips__) && __mips_isa_rev < 6 is not supported for sanitizers.

jrtc27 requested changes to this revision.Aug 22 2023, 11:11 AM

Why not define a SANITIZER_TAIL_CALL(sym) that expands to the assembly string to tail call sym? Give it the default implementation of the current ASM_TAIL_CALL sym and then add MIPS overrides as needed. That should drastically reduce the amount of boilerplate; this copy-pasta is not good.

This revision now requires changes to proceed.Aug 22 2023, 11:11 AM
wzssyqa updated this revision to Diff 552595.Aug 22 2023, 11:13 PM

This large pile of mips code makes me nervous. What I really want is to eliminate code related to some older mips ports.
For example, just claim that defined(__mips__) && __mips_isa_rev < 6 is not supported for sanitizers.

Pre-R6 is what currently widely used mostly.
I wish it can be supported.

wzssyqa updated this revision to Diff 552599.Aug 22 2023, 11:28 PM
wzssyqa updated this revision to Diff 552649.Aug 23 2023, 3:52 AM
wzssyqa edited the summary of this revision. (Show Details)
wzssyqa updated this revision to Diff 553382.Aug 24 2023, 11:47 PM
compiler-rt/lib/sanitizer_common/sanitizer_asm.h
48

One space not two

49

Should mips be removed?

59

One space for these

60

No spaces before \n

62

Why $t8 rather than another temporary or $gp?

wzssyqa added inline comments.Aug 25 2023, 12:41 AM
compiler-rt/lib/sanitizer_common/sanitizer_asm.h
49

Should mips be removed?

No. Since ASM_INTERCEPTOR_TRAMPOLINE uses it.
For full asm functions, like vfork, the distance of these 2 functions is quite near.
b is enough for it.
See https://reviews.llvm.org/D158268

62

Why $t8 rather than another temporary or $gp?

In fact, I don't know. I tested with $gp, while something wrong (segfault) always happen.
I have no idea why...

wzssyqa updated this revision to Diff 553398.Aug 25 2023, 12:45 AM
wzssyqa updated this revision to Diff 553401.Aug 25 2023, 12:48 AM
wzssyqa marked 4 inline comments as done.
wzssyqa marked an inline comment as done.

Ah, I went and reminded myself of the MIPS ABI. N32/N64 has GP as call-preserved. O32 has GP as call-preserved for non-PIC, call-clobbered for PIC.

Also %got_disp forces eager binding and is a function pointer. If this can be adapted to use %call16 that would be better. I assume there's something similar for O32 but am not familiar enough with it.

@MaskRay do you think it could be merged now ? thanks
i have been told that it is necessary for Debian

ping. This problem affects gcc now.