mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 06:46:43 +00:00
Port address sanitizer to LoongArch
Depends on D129371. It survived all GCC ASan tests. Changes are trivial and mostly "borrowed" RISC-V logics, except that a different SHADOW_OFFSET is used. Reviewed By: SixWeining, MaskRay, XiaodongLoong Differential Revision: https://reviews.llvm.org/D129418
This commit is contained in:
parent
9c22853ec4
commit
bba1f26f2e
@ -27,7 +27,8 @@ set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64}
|
||||
${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9}
|
||||
${HEXAGON} ${LOONGARCH64})
|
||||
set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
|
||||
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON})
|
||||
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
|
||||
${LOONGARCH64})
|
||||
set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
|
||||
|
||||
if(ANDROID)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_loongarch64.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_riscv64.inc.S"
|
||||
#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S"
|
||||
#endif
|
||||
|
@ -114,6 +114,13 @@
|
||||
// || `[0x0080000000000, 0x008ffffffffff]` || LowShadow ||
|
||||
// || `[0x0000000000000, 0x007ffffffffff]` || LowMem ||
|
||||
//
|
||||
// Default Linux/LoongArch64 (47-bit VMA) mapping:
|
||||
// || `[0x500000000000, 0x7fffffffffff]` || HighMem ||
|
||||
// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
|
||||
// || `[0x480000000000, 0x49ffffffffff]` || ShadowGap ||
|
||||
// || `[0x400000000000, 0x47ffffffffff]` || LowShadow ||
|
||||
// || `[0x000000000000, 0x3fffffffffff]` || LowMem ||
|
||||
//
|
||||
// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
|
||||
// || `[0x500000000000, 0x7fffffffffff]` || HighMem ||
|
||||
// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
|
||||
@ -196,6 +203,8 @@
|
||||
# define ASAN_SHADOW_OFFSET_CONST 0x0000002000000000
|
||||
# elif defined(__sparc__)
|
||||
# define ASAN_SHADOW_OFFSET_CONST 0x0000080000000000
|
||||
# elif SANITIZER_LOONGARCH64
|
||||
# define ASAN_SHADOW_OFFSET_CONST 0x0000400000000000
|
||||
# elif SANITIZER_WINDOWS64
|
||||
# define ASAN_SHADOW_OFFSET_DYNAMIC
|
||||
# else
|
||||
|
@ -0,0 +1,63 @@
|
||||
#if defined(__loongarch_lp64) && defined(__linux__)
|
||||
|
||||
#include "sanitizer_common/sanitizer_asm.h"
|
||||
|
||||
ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA)
|
||||
ASM_HIDDEN(_ZN14__interception10real_vforkE)
|
||||
|
||||
.bss
|
||||
.type _ZN14__interception10real_vforkE, @object
|
||||
.size _ZN14__interception10real_vforkE, 8
|
||||
_ZN14__interception10real_vforkE:
|
||||
.zero 8
|
||||
|
||||
.text
|
||||
.globl ASM_WRAPPER_NAME(vfork)
|
||||
ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
|
||||
ASM_WRAPPER_NAME(vfork):
|
||||
// Save ra in the off-stack spill area.
|
||||
// allocate space on stack
|
||||
addi.d $sp, $sp, -16
|
||||
// store $ra value
|
||||
st.d $ra, $sp, 8
|
||||
bl COMMON_INTERCEPTOR_SPILL_AREA
|
||||
// restore previous values from stack
|
||||
ld.d $ra, $sp, 8
|
||||
// adjust stack
|
||||
addi.d $sp, $sp, 16
|
||||
// store $ra by $a0
|
||||
st.d $ra, $a0, 0
|
||||
|
||||
// Call real vfork. This may return twice. User code that runs between the first and the second return
|
||||
// may clobber the stack frame of the interceptor; that's why it does not have a frame.
|
||||
la.local $a0, _ZN14__interception10real_vforkE
|
||||
ld.d $a0, $a0, 0
|
||||
jirl $ra, $a0, 0
|
||||
|
||||
// adjust stack
|
||||
addi.d $sp, $sp, -16
|
||||
// store $a0 by adjusted stack
|
||||
st.d $a0, $sp, 8
|
||||
// jump to exit label if $a0 is 0
|
||||
beqz $a0, .L_exit
|
||||
|
||||
// $a0 != 0 => parent process. Clear stack shadow.
|
||||
// put old $sp to $a0
|
||||
addi.d $a0, $sp, 16
|
||||
bl %plt(COMMON_INTERCEPTOR_HANDLE_VFORK)
|
||||
|
||||
.L_exit:
|
||||
// Restore $ra
|
||||
bl COMMON_INTERCEPTOR_SPILL_AREA
|
||||
ld.d $ra, $a0, 0
|
||||
// load value by stack
|
||||
ld.d $a0, $sp, 8
|
||||
// adjust stack
|
||||
addi.d $sp, $sp, 16
|
||||
jr $ra
|
||||
ASM_SIZE(vfork)
|
||||
|
||||
.weak vfork
|
||||
.set vfork, ASM_WRAPPER_NAME(vfork)
|
||||
|
||||
#endif
|
@ -121,7 +121,7 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
|
||||
uhwptr pc1 = caller_frame[2];
|
||||
#elif defined(__s390__)
|
||||
uhwptr pc1 = frame[14];
|
||||
#elif defined(__riscv)
|
||||
#elif defined(__loongarch__) || defined(__riscv)
|
||||
// frame[-1] contains the return address
|
||||
uhwptr pc1 = frame[-1];
|
||||
#else
|
||||
@ -136,7 +136,7 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
|
||||
trace_buffer[size++] = (uptr) pc1;
|
||||
}
|
||||
bottom = (uptr)frame;
|
||||
#if defined(__riscv)
|
||||
#if defined(__loongarch__) || defined(__riscv)
|
||||
// frame[-2] contain fp of the previous frame
|
||||
uptr new_bp = (uptr)frame[-2];
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user