1 Star 0 Fork 33

renbo02/gcc

forked from src-anolis-os/gcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
LoongArch-Add-sanitizer-support.patch 43.38 KB
一键复制 编辑 原始数据 按行查看 历史
ticat_fp 提交于 2024-01-16 14:18 . Re-enable support for LoongArch
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
From c985960fa4baae43ed4a1bfcaab9214b78a15020 Mon Sep 17 00:00:00 2001
From: Xing Li <lixing@loongson.cn>
Date: Fri, 6 Jan 2023 10:39:21 +0800
Subject: [PATCH 2/2] LoongArch: Add sanitizer support
Signed-off-by: Xing Li <lixing@loongson.cn>
Signed-off-by: Peng Fan <fanpeng@loongson.cn>
---
gcc/config/loongarch/loongarch.c | 14 +-
libsanitizer/asan/asan_mapping.h | 6 +
libsanitizer/configure.tgt | 10 ++
libsanitizer/lsan/lsan_allocator.cc | 2 +-
libsanitizer/lsan/lsan_allocator.h | 2 +-
libsanitizer/lsan/lsan_common.cc | 2 +
libsanitizer/sanitizer_common/Makefile.am | 2 +-
libsanitizer/sanitizer_common/Makefile.in | 3 +-
.../sanitizer_common_syscalls.inc | 6 +-
.../sanitizer_common/sanitizer_linux.cc | 94 ++++++++++-
.../sanitizer_common/sanitizer_linux.h | 4 +-
.../sanitizer_linux_libcdep.cc | 15 +-
.../sanitizer_linux_loongarch64.S | 22 +++
.../sanitizer_common/sanitizer_platform.h | 21 ++-
.../sanitizer_platform_interceptors.h | 4 +-
.../sanitizer_platform_limits_linux.cc | 2 +-
.../sanitizer_platform_limits_posix.cc | 22 ++-
.../sanitizer_platform_limits_posix.h | 7 +-
.../sanitizer_common/sanitizer_stacktrace.cc | 2 +-
.../sanitizer_common/sanitizer_stacktrace.h | 5 +-
.../sanitizer_stoptheworld_linux_libcdep.cc | 14 +-
.../sanitizer_tls_get_addr.cc | 2 +
libsanitizer/tsan/Makefile.am | 2 +-
libsanitizer/tsan/Makefile.in | 3 +-
libsanitizer/tsan/tsan_interceptors.cc | 5 +-
libsanitizer/tsan/tsan_platform.h | 38 +++++
libsanitizer/tsan/tsan_platform_posix.cc | 3 +
libsanitizer/tsan/tsan_rtl.cc | 16 +-
libsanitizer/tsan/tsan_rtl.h | 3 +-
libsanitizer/tsan/tsan_rtl_loongarch64.S | 156 ++++++++++++++++++
30 files changed, 447 insertions(+), 40 deletions(-)
create mode 100644 libsanitizer/sanitizer_common/sanitizer_linux_loongarch64.S
create mode 100644 libsanitizer/tsan/tsan_rtl_loongarch64.S
diff --git a/gcc/config/loongarch/loongarch.c b/gcc/config/loongarch/loongarch.c
index a1dde5a0f..82be582ff 100644
--- a/gcc/config/loongarch/loongarch.c
+++ b/gcc/config/loongarch/loongarch.c
@@ -10724,7 +10724,16 @@ loongarch_prefetch_cookie (rtx write, rtx locality)
gcc_unreachable ();
}
-
+/* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
+
+static unsigned HOST_WIDE_INT
+loongarch_asan_shadow_offset (void)
+{
+ /* We only have libsanitizer support for LOONGARCH64 at present.
+ This value is taken from the file libsanitizer/asan/asan_mappint.h. */
+ return TARGET_64BIT ? (HOST_WIDE_INT_1 << 37) : (0x0aaa0000);
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -10952,6 +10961,9 @@ loongarch_prefetch_cookie (rtx write, rtx locality)
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD loongarch_secondary_reload
+#undef TARGET_ASAN_SHADOW_OFFSET
+#define TARGET_ASAN_SHADOW_OFFSET loongarch_asan_shadow_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-loongarch.h"
diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h
index 5496df66d..77c8061ad 100644
--- a/libsanitizer/asan/asan_mapping.h
+++ b/libsanitizer/asan/asan_mapping.h
@@ -141,6 +141,8 @@ static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;
static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
+static const u64 kLoongArch32_ShadowOffset32 = 0x0aaa0000;
+static const u64 kLoongArch64_ShadowOffset64 = 1ULL << 37;
static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
@@ -157,6 +159,8 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
# define SHADOW_OFFSET (0)
# elif defined(__mips__)
# define SHADOW_OFFSET kMIPS32_ShadowOffset32
+# elif defined(__loongarch__)
+# define SHADOW_OFFSET kLoongArch32_ShadowOffset32
# elif SANITIZER_FREEBSD
# define SHADOW_OFFSET kFreeBSD_ShadowOffset32
# elif SANITIZER_WINDOWS
@@ -191,6 +195,8 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
# define SHADOW_OFFSET kDefaultShadowOffset64
# elif defined(__mips64)
# define SHADOW_OFFSET kMIPS64_ShadowOffset64
+# elif defined(__loongarch64)
+# define SHADOW_OFFSET kLoongArch64_ShadowOffset64
# elif SANITIZER_WINDOWS64
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
# else
diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt
index 573e3b482..8da064c1e 100644
--- a/libsanitizer/configure.tgt
+++ b/libsanitizer/configure.tgt
@@ -55,6 +55,16 @@ case "${target}" in
x86_64-*-darwin[1]* | i?86-*-darwin[1]*)
TSAN_SUPPORTED=no
;;
+ loongarch*-*-linux*)
+ if echo "int x = __loongarch64;" | $CC -c -x c -o /dev/null - > /dev/null 2>&1; then
+ SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS=sanitizer_linux_loongarch64.lo
+ fi
+ if test x$ac_cv_sizeof_void_p = x8; then
+ TSAN_SUPPORTED=yes
+ LSAN_SUPPORTED=yes
+ TSAN_TARGET_DEPENDENT_OBJECTS=tsan_rtl_loongarch64.lo
+ fi
+ ;;
*)
UNSUPPORTED=1
;;
diff --git a/libsanitizer/lsan/lsan_allocator.cc b/libsanitizer/lsan/lsan_allocator.cc
index 9e1668077..b3ef2400e 100644
--- a/libsanitizer/lsan/lsan_allocator.cc
+++ b/libsanitizer/lsan/lsan_allocator.cc
@@ -26,7 +26,7 @@ extern "C" void *memset(void *ptr, int value, uptr num);
namespace __lsan {
#if defined(__i386__) || defined(__arm__)
static const uptr kMaxAllowedMallocSize = 1UL << 30;
-#elif defined(__mips64) || defined(__aarch64__)
+#elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch64)
static const uptr kMaxAllowedMallocSize = 4UL << 30;
#else
static const uptr kMaxAllowedMallocSize = 8UL << 30;
diff --git a/libsanitizer/lsan/lsan_allocator.h b/libsanitizer/lsan/lsan_allocator.h
index b0c0ec241..5793dd372 100644
--- a/libsanitizer/lsan/lsan_allocator.h
+++ b/libsanitizer/lsan/lsan_allocator.h
@@ -49,7 +49,7 @@ struct ChunkMetadata {
};
#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \
- defined(__arm__)
+ defined(__arm__) || defined(__loongarch64)
static const uptr kRegionSizeLog = 20;
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
diff --git a/libsanitizer/lsan/lsan_common.cc b/libsanitizer/lsan/lsan_common.cc
index 4afce9df0..e1dce25c7 100644
--- a/libsanitizer/lsan/lsan_common.cc
+++ b/libsanitizer/lsan/lsan_common.cc
@@ -136,6 +136,8 @@ static inline bool CanBeAHeapPointer(uptr p) {
return ((p >> 47) == 0);
#elif defined(__mips64)
return ((p >> 40) == 0);
+#elif defined(__loongarch64)
+ return ((p >> 40) == 0);
#elif defined(__aarch64__)
unsigned runtimeVMA =
(MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1);
diff --git a/libsanitizer/sanitizer_common/Makefile.am b/libsanitizer/sanitizer_common/Makefile.am
index 246985b99..3b39f5bb0 100644
--- a/libsanitizer/sanitizer_common/Makefile.am
+++ b/libsanitizer/sanitizer_common/Makefile.am
@@ -71,7 +71,7 @@ sanitizer_common_files = \
libsanitizer_common_la_SOURCES = $(sanitizer_common_files)
-EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S
+EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S sanitizer_linux_loongarch64.S
libsanitizer_common_la_LIBADD = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
libsanitizer_common_la_DEPENDENCIES = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in
index b0f5ac25a..023f633f7 100644
--- a/libsanitizer/sanitizer_common/Makefile.in
+++ b/libsanitizer/sanitizer_common/Makefile.in
@@ -355,7 +355,7 @@ sanitizer_common_files = \
sanitizer_win.cc
libsanitizer_common_la_SOURCES = $(sanitizer_common_files)
-EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S
+EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S sanitizer_linux_loongarch64.S
libsanitizer_common_la_LIBADD = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
libsanitizer_common_la_DEPENDENCIES = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
@@ -467,6 +467,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_libcdep.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_mips64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_loongarch64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_s390.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_x86_64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac.Plo@am__quote@
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
index 6fd5ef742..f55759106 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
@@ -2295,7 +2295,8 @@ POST_SYSCALL(ni_syscall)(long res) {}
PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
#if !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
- defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__))
+ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \
+ defined(__loongarch64))
if (data) {
if (request == ptrace_setregs) {
PRE_READ((void *)data, struct_user_regs_struct_sz);
@@ -2316,7 +2317,8 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {
#if !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
- defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__))
+ defined(__powerpc64__) || defined(__aarch64__) || defined(__s390__) || \
+ defined(__loongarch64))
if (res >= 0 && data) {
// Note that this is different from the interceptor in
// sanitizer_common_interceptors.inc.
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc
index 2826cc89e..003c38b4f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc
@@ -12,6 +12,10 @@
#include "sanitizer_platform.h"
+#if defined(__loongarch__)
+#define __ARCH_WANT_RENAMEAT 1
+#endif
+
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
#include "sanitizer_common.h"
@@ -127,7 +131,7 @@ const int FUTEX_WAKE = 1;
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
#endif
-#if defined(__x86_64__) || SANITIZER_MIPS64
+#if defined(__x86_64__) || SANITIZER_MIPS64 || SANITIZER_LOONGARCH64
extern "C" {
extern void internal_sigreturn();
}
@@ -802,7 +806,7 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
// Invokes sigaction via a raw syscall with a restorer, but does not support
// all platforms yet.
// We disable for Go simply because we have not yet added to buildgo.sh.
-#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO
+#if (defined(__x86_64__) || SANITIZER_MIPS64 || SANITIZER_LOONGARCH64) && !SANITIZER_GO
int internal_sigaction_syscall(int signum, const void *act, void *oldact) {
if (act == nullptr)
return internal_sigaction_norestorer(signum, act, oldact);
@@ -980,6 +984,8 @@ uptr GetMaxVirtualAddress() {
return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1;
# elif defined(__mips64)
return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
+# elif defined(__loongarch64)
+ return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
# elif defined(__s390x__)
return (1ULL << 53) - 1; // 0x001fffffffffffffUL;
# else
@@ -1247,6 +1253,61 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
: "memory", "$29" );
return res;
}
+#elif defined(__loongarch__) && SANITIZER_LINUX
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+ int *parent_tidptr, void *newtls, int *child_tidptr) {
+ long long res;
+ if (!fn || !child_stack)
+ return -EINVAL;
+ CHECK_EQ(0, (uptr)child_stack % 16);
+ child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
+ ((unsigned long long *)child_stack)[0] = (uptr)fn;
+ ((unsigned long long *)child_stack)[1] = (uptr)arg;
+
+ register int __flags __asm__("r4") = flags;
+ register void *__child_stack __asm__("r5") = child_stack;
+ register int *__parent_tidptr __asm__("r6") = parent_tidptr;
+ register void *__newtls __asm__("r7") = newtls;
+ register int *__child_tidptr __asm__("r8") = child_tidptr;
+
+ __asm__ __volatile__(
+ /* $a0 = syscall($a7 = SYSCALL(clone),
+ * $a0 = flags,
+ * $a1 = child_stack,
+ * $a2 = parent_tidptr,
+ * $a3 = new_tls,
+ * $a4 = child_tyidptr)
+ */
+
+ /* Do the system call */
+ "addi.d $a7, $r0, %1\n"
+ "syscall 0\n"
+
+ "move %0, $a0"
+ : "=r"(res)
+ : "i"(__NR_clone),
+ "r"(__flags), "r"(__child_stack), "r"(__parent_tidptr), "r"(__newtls), "r"(__child_tidptr)
+ :"memory" );
+ if (res != 0) {
+ return res;
+ }
+ __asm__ __volatile__ (
+ /* In the child, now. Call "fn(arg)". */
+ "ld.d $a6, $sp, 0\n"
+ "ld.d $a0, $sp, 8\n"
+
+ "jirl $r1, $a6, 0\n"
+
+ /* Call _exit($v0) */
+ "addi.d $a7, $r0, %1\n"
+ "syscall 0\n"
+
+ "move %0, $a0"
+ : "=r"(res)
+ : "i"(__NR_exit)
+ :"r1", "memory");
+ return res;
+}
#elif defined(__aarch64__)
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr) {
@@ -1676,6 +1737,30 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
u64 esr;
if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN;
return esr & ESR_ELx_WNR ? WRITE : READ;
+#elif defined(__loongarch__)
+ uint32_t *exception_source;
+ uint32_t faulty_instruction;
+ uint32_t op_code;
+
+ exception_source = (uint32_t *)ucontext->uc_mcontext.__pc;
+ faulty_instruction = (uint32_t)(*exception_source);
+
+ op_code = (faulty_instruction >> 22) & 0x3ff;
+ switch (op_code) {
+ case 0xa0: //ld.b
+ case 0xa1: //ld.h
+ case 0xa2: //ld.w
+ case 0xa3: //ld.d
+ return SignalContext::READ;
+ case 0xa4:
+ case 0xa5:
+ case 0xa6:
+ return SignalContext::WRITE;
+ case 0xa8:
+ case 0xa9:
+ return SignalContext::READ;
+ }
+ return SignalContext::UNKNOWN;
#else
(void)ucontext;
return UNKNOWN; // FIXME: Implement.
@@ -1763,6 +1848,11 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
*pc = ucontext->uc_mcontext.pc;
*bp = ucontext->uc_mcontext.gregs[30];
*sp = ucontext->uc_mcontext.gregs[29];
+#elif defined(__loongarch__)
+ ucontext_t *ucontext = (ucontext_t*)context;
+ *pc = ucontext->uc_mcontext.__pc;
+ *bp = ucontext->uc_mcontext.__gregs[22];
+ *sp = ucontext->uc_mcontext.__gregs[3];
#elif defined(__s390__)
ucontext_t *ucontext = (ucontext_t*)context;
# if defined(__s390x__)
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.h b/libsanitizer/sanitizer_common/sanitizer_linux.h
index 910703d8b..600d2b382 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.h
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.h
@@ -52,14 +52,14 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
// (like the process-wide error reporting SEGV handler) must use
// internal_sigaction instead.
int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
-#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO
+#if (defined(__x86_64__) || SANITIZER_MIPS64 || SANITIZER_LOONGARCH64) && !SANITIZER_GO
// Uses a raw system call to avoid interceptors.
int internal_sigaction_syscall(int signum, const void *act, void *oldact);
#endif
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \
|| defined(__powerpc64__) || defined(__s390__) || defined(__i386__) \
- || defined(__arm__)
+ || defined(__arm__) || defined(__loongarch__)
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr);
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc
index 3b1a2174c..43551c0d1 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -196,7 +196,7 @@ void InitTlsSize() { }
#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \
|| defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) \
- || defined(__arm__)) && SANITIZER_LINUX && !SANITIZER_ANDROID
+ || defined(__arm__) || defined(__loongarch__)) && SANITIZER_LINUX && !SANITIZER_ANDROID
// sizeof(struct pthread) from glibc.
static atomic_uintptr_t kThreadDescriptorSize;
@@ -251,6 +251,9 @@ uptr ThreadDescriptorSize() {
if (val)
atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
return val;
+#elif defined(__loongarch64)
+ val = 1776;
+ return val;
#elif defined(__aarch64__)
// The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22.
val = 1776;
@@ -274,12 +277,14 @@ uptr ThreadSelfOffset() {
return kThreadSelfOffset;
}
-#if defined(__mips__) || defined(__powerpc64__)
+#if defined(__mips__) || defined(__powerpc64__) || defined(__loongarch__)
// TlsPreTcbSize includes size of struct pthread_descr and size of tcb
// head structure. It lies before the static tls blocks.
static uptr TlsPreTcbSize() {
# if defined(__mips__)
const uptr kTcbHead = 16; // sizeof (tcbhead_t)
+# elif defined(__loongarch__)
+ const uptr kTcbHead = 16; // sizeof (tcbhead_t)
# elif defined(__powerpc64__)
const uptr kTcbHead = 88; // sizeof (tcbhead_t)
# endif
@@ -308,6 +313,10 @@ uptr ThreadSelf() {
rdhwr %0,$29;\
.set pop" : "=r" (thread_pointer));
descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize();
+# elif defined(__loongarch__)
+ uptr thread_pointer;
+ asm("or %0,$r2,$r0" : "=r" (thread_pointer));
+ descr_addr = thread_pointer - TlsPreTcbSize();
# elif defined(__aarch64__) || defined(__arm__)
descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer()) -
ThreadDescriptorSize();
@@ -360,7 +369,7 @@ static void GetTls(uptr *addr, uptr *size) {
*addr -= *size;
*addr += ThreadDescriptorSize();
# elif defined(__mips__) || defined(__aarch64__) || defined(__powerpc64__) \
- || defined(__arm__)
+ || defined(__arm__) || defined(__loongarch__)
*addr = ThreadSelf();
*size = GetTlsSize();
# else
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_loongarch64.S b/libsanitizer/sanitizer_common/sanitizer_linux_loongarch64.S
new file mode 100644
index 000000000..245816e60
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_loongarch64.S
@@ -0,0 +1,22 @@
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+
+// Avoid being marked as needing an executable stack:
+#if defined(__linux__) && defined(__ELF__)
+.section .note.GNU-stack,"",%progbits
+#endif
+
+// Further contents are loongarch64 only:
+#if defined(__linux__) && defined(__loongarch64)
+
+.section .text
+.globl internal_sigreturn
+.type internal_sigreturn, @function
+internal_sigreturn:
+
+ li.d $r11,139 // #139 is for SYS_rt_sigreturn
+ syscall 0
+
+.size internal_sigreturn, .-internal_sigreturn
+
+#endif // defined(__linux__) && defined(__loongarch64)
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h
index 1eb4d0c61..6d91863a5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform.h
@@ -187,7 +187,7 @@
#ifndef SANITIZER_CAN_USE_ALLOCATOR64
# if (SANITIZER_ANDROID && defined(__aarch64__)) || SANITIZER_FUCHSIA
# define SANITIZER_CAN_USE_ALLOCATOR64 1
-# elif defined(__mips64) || defined(__aarch64__)
+# elif defined(__mips64) || defined(__aarch64__) || defined(__loongarch64)
# define SANITIZER_CAN_USE_ALLOCATOR64 0
# else
# define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64)
@@ -197,7 +197,7 @@
// The range of addresses which can be returned my mmap.
// FIXME: this value should be different on different platforms. Larger values
// will still work but will consume more memory for TwoLevelByteMap.
-#if defined(__mips__)
+#if defined(__mips__) || defined(__loongarch__)
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
#elif defined(__aarch64__)
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
@@ -209,7 +209,7 @@
// the upstream linux community for all new ports. Other ports may still
// use legacy syscalls.
#ifndef SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
-# if defined(__aarch64__) && SANITIZER_LINUX
+# if (defined(__aarch64__) || defined(__loongarch64)) && SANITIZER_LINUX
# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 1
# else
# define SANITIZER_USES_CANONICAL_LINUX_SYSCALLS 0
@@ -241,6 +241,21 @@
# define HAVE_TIRPC_RPC_XDR_H 0
#endif
+#if defined(__loongarch__)
+# define SANITIZER_LOONGARCH 1
+# if defined(__loongarch64)
+# define SANITIZER_LOONGARCH32 0
+# define SANITIZER_LOONGARCH64 1
+# else
+# define SANITIZER_LOONGARCH32 1
+# define SANITIZER_LOONGARCH64 0
+# endif
+#else
+# define SANITIZER_LOONGARCH 0
+# define SANITIZER_LOONGARCH32 0
+# define SANITIZER_LOONGARCH64 0
+#endif
+
/// \macro MSC_PREREQ
/// \brief Is the compiler MSVC of at least the specified version?
/// The common \param version values to check for are:
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
index b9eb09ad3..e8f8cfedb 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
@@ -205,7 +205,7 @@
#if SI_LINUX_NOT_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
- defined(__s390__))
+ defined(__s390__) || defined(__loongarch__))
#define SANITIZER_INTERCEPT_PTRACE 1
#else
#define SANITIZER_INTERCEPT_PTRACE 0
@@ -382,7 +382,7 @@
#define SANITIZER_INTERCEPT_PVALLOC \
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA)
#define SANITIZER_INTERCEPT_CFREE \
- (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA)
+ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA && !SANITIZER_LOONGARCH)
#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC)
#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC)
#define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
index 23a014823..cf71e922e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
@@ -64,7 +64,7 @@ namespace __sanitizer {
#if !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__aarch64__)\
&& !defined(__mips__) && !defined(__s390__)\
- && !defined(__sparc__)
+ && !defined(__sparc__) && !defined(__loongarch__)
COMPILER_CHECK(struct___old_kernel_stat_sz == sizeof(struct __old_kernel_stat));
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
index 5c720b2e7..e0225c4a9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -115,7 +115,8 @@
#if SANITIZER_LINUX || SANITIZER_FREEBSD
# include <utime.h>
# include <sys/ptrace.h>
-# if defined(__mips64) || defined(__aarch64__) || defined(__arm__)
+# if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \
+ defined(__loongarch64)
# include <asm/ptrace.h>
# ifdef __arm__
typedef struct user_fpregs elf_fpregset_t;
@@ -153,7 +154,7 @@ typedef struct user_fpregs elf_fpregset_t;
#include <sys/shm.h>
#include <sys/statvfs.h>
#include <sys/timex.h>
-#if defined(__mips64)
+#if defined(__mips64) || defined(__loongarch64)
# include <sys/procfs.h>
#endif
#include <sys/user.h>
@@ -253,10 +254,11 @@ namespace __sanitizer {
// has been removed from glibc 2.28.
#if defined(__aarch64__) || defined(__s390x__) || defined (__mips64) \
|| defined(__powerpc64__) || defined(__arch64__) || defined(__sparcv9) \
- || defined(__x86_64__)
+ || defined(__x86_64__) || defined(__loongarch64)
#define SIZEOF_STRUCT_USTAT 32
#elif defined(__arm__) || defined(__i386__) || defined(__mips__) \
- || defined(__powerpc__) || defined(__s390__) || defined(__sparc__)
+ || defined(__powerpc__) || defined(__s390__) || defined(__sparc__) \
+ || defined(__loongarch__)
#define SIZEOF_STRUCT_USTAT 20
#else
#error Unknown size of struct ustat
@@ -326,27 +328,31 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
- defined(__s390__))
+ defined(__s390__) || defined(__loongarch64))
#if defined(__mips64) || defined(__powerpc64__) || defined(__arm__)
unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs);
unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t);
#elif defined(__aarch64__)
unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs);
unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state);
+#elif defined(__loongarch64)
+ unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs);
+ unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fp_state);
#elif defined(__s390__)
unsigned struct_user_regs_struct_sz = sizeof(struct _user_regs_struct);
unsigned struct_user_fpregs_struct_sz = sizeof(struct _user_fpregs_struct);
#else
unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct);
unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct);
-#endif // __mips64 || __powerpc64__ || __aarch64__
+#endif // __mips64 || __powerpc64__ || __aarch64__ || __loongarch64
#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \
- defined(__aarch64__) || defined(__arm__) || defined(__s390__)
+ defined(__aarch64__) || defined(__arm__) || defined(__s390__) || \
+ defined(__loongarch64)
unsigned struct_user_fpxregs_struct_sz = 0;
#else
unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);
#endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__ || __arm__
-// || __s390__
+// || __s390__ || __loongarch64
#ifdef __arm__
unsigned struct_user_vfpregs_struct_sz = ARM_VFPREGS_SIZE;
#else
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
index 9c1429623..0020448cc 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -77,6 +77,9 @@ namespace __sanitizer {
#elif defined(__aarch64__)
const unsigned struct_kernel_stat_sz = 128;
const unsigned struct_kernel_stat64_sz = 104;
+#elif defined(__loongarch__)
+ const unsigned struct_kernel_stat_sz = 128;
+ const unsigned struct_kernel_stat64_sz = 128;
#elif defined(__powerpc__) && !defined(__powerpc64__)
const unsigned struct_kernel_stat_sz = 72;
const unsigned struct_kernel_stat64_sz = 104;
@@ -659,7 +662,7 @@ namespace __sanitizer {
#if SANITIZER_FREEBSD
typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
-#elif defined(__mips__)
+#elif defined(__mips__) || defined(__loongarch__)
struct __sanitizer_kernel_sigset_t {
uptr sig[2];
};
@@ -827,7 +830,7 @@ namespace __sanitizer {
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \
- defined(__s390__))
+ defined(__s390__) || defined(__loongarch64))
extern unsigned struct_user_regs_struct_sz;
extern unsigned struct_user_fpregs_struct_sz;
extern unsigned struct_user_fpxregs_struct_sz;
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
index 2de585c32..ca79b289d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
@@ -18,7 +18,7 @@ namespace __sanitizer {
uptr StackTrace::GetNextInstructionPc(uptr pc) {
#if defined(__mips__)
return pc + 8;
-#elif defined(__powerpc__)
+#elif defined(__powerpc__) || defined(__loongarch__)
return pc + 4;
#else
return pc + 1;
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
index 31e99f6b9..3affe4eb7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
@@ -17,7 +17,8 @@ namespace __sanitizer {
static const u32 kStackTraceMax = 256;
-#if SANITIZER_LINUX && (defined(__sparc__) || defined(__mips__))
+#if SANITIZER_LINUX && (defined(__sparc__) || defined(__mips__)) || \
+ (SANITIZER_LINUX && defined(__loongarch__))
# define SANITIZER_CAN_FAST_UNWIND 0
#elif SANITIZER_WINDOWS
# define SANITIZER_CAN_FAST_UNWIND 0
@@ -74,7 +75,7 @@ uptr StackTrace::GetPreviousInstructionPc(uptr pc) {
// Cancel Thumb bit.
pc = pc & (~1);
#endif
-#if defined(__powerpc__) || defined(__powerpc64__)
+#if defined(__powerpc__) || defined(__powerpc64__) || defined(__loongarch__)
// PCs are always 4 byte aligned.
return pc - 4;
#elif defined(__sparc__) || defined(__mips__)
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
index d746fa540..4c183efc4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
@@ -15,13 +15,17 @@
#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \
defined(__aarch64__) || defined(__powerpc64__) || \
defined(__s390__) || defined(__i386__) || \
- defined(__arm__))
+ defined(__arm__) || defined(__loongarch__))
#include "sanitizer_stoptheworld.h"
#include "sanitizer_platform_limits_posix.h"
#include "sanitizer_atomic.h"
+#if defined(__loongarch__)
+#include <sys/ucontext.h>
+#endif
+
#include <errno.h>
#include <sched.h> // for CLONE_* definitions
#include <stddef.h>
@@ -35,7 +39,7 @@
# include <asm/ptrace.h>
#endif
#include <sys/user.h> // for user_regs_struct
-#if SANITIZER_ANDROID && SANITIZER_MIPS
+#if SANITIZER_ANDROID && SANITIZER_MIPS || SANITIZER_LOONGARCH
# include <asm/reg.h> // for mips SP register in sys/user.h
#endif
#include <sys/wait.h> // for signal-related stuff
@@ -483,8 +487,14 @@ typedef pt_regs regs_struct;
#elif defined(__mips__)
typedef struct user regs_struct;
+#elif defined(__loongarch__)
+typedef struct user_regs_struct regs_struct;
+#define ARCH_IOVEC_FOR_GETREGSET
+
# if SANITIZER_ANDROID
# define REG_SP regs[EF_R29]
+# elif SANITIZER_LOONGARCH
+# define REG_SP gpr[3]
# else
# define REG_SP regs[EF_REG29]
# endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc
index ebf5ec094..c7cdf37df 100644
--- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc
@@ -81,6 +81,8 @@ void DTLS_Destroy() {
// "Dynamic thread vector pointers point 0x8000 past the start of each
// TLS block."
static const uptr kDtvOffset = 0x8000;
+#elif defined(__loongarch__)
+static const uptr kDtvOffset = 0x800;
#else
static const uptr kDtvOffset = 0;
#endif
diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am
index 753cb8f4f..ac5ae4117 100644
--- a/libsanitizer/tsan/Makefile.am
+++ b/libsanitizer/tsan/Makefile.am
@@ -50,7 +50,7 @@ tsan_files = \
tsan_sync.cc
libtsan_la_SOURCES = $(tsan_files)
-EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S
+EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S rtl_loongarch64.S
libtsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(TSAN_TARGET_DEPENDENT_OBJECTS)
libtsan_la_DEPENDENCIES = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/interception/libinterception.la $(TSAN_TARGET_DEPENDENT_OBJECTS)
if LIBBACKTRACE_SUPPORTED
diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in
index 629056bf1..6a3477b99 100644
--- a/libsanitizer/tsan/Makefile.in
+++ b/libsanitizer/tsan/Makefile.in
@@ -358,7 +358,7 @@ tsan_files = \
tsan_sync.cc
libtsan_la_SOURCES = $(tsan_files)
-EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S
+EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S rtl_loongarch64.S
libtsan_la_LIBADD = \
$(top_builddir)/sanitizer_common/libsanitizer_common.la \
$(top_builddir)/interception/libinterception.la \
@@ -512,6 +512,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_aarch64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_amd64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_mips64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_loongarch64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_mutex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_ppc64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_proc.Plo@am__quote@
diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cc
index 15f20d4b6..c6959862b 100644
--- a/libsanitizer/tsan/tsan_interceptors.cc
+++ b/libsanitizer/tsan/tsan_interceptors.cc
@@ -71,7 +71,8 @@ struct ucontext_t {
};
#endif
-#if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1
+#if defined(__x86_64__) || defined(__mips__) || SANITIZER_PPC64V1 \
+ || defined(__loongarch__)
#define PTHREAD_ABI_BASE "GLIBC_2.3.2"
#elif defined(__aarch64__) || SANITIZER_PPC64V2
#define PTHREAD_ABI_BASE "GLIBC_2.17"
@@ -500,6 +501,8 @@ static void LongJmp(ThreadState *thr, uptr *env) {
uptr mangled_sp = env[13];
# elif defined(__mips64)
uptr mangled_sp = env[1];
+#elif defined(__loongarch64)
+ uptr mangled_sp = env[1];
# else
uptr mangled_sp = env[6];
# endif
diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h
index 44a3ea991..a50dc6dbe 100644
--- a/libsanitizer/tsan/tsan_platform.h
+++ b/libsanitizer/tsan/tsan_platform.h
@@ -129,6 +129,44 @@ struct Mapping {
static const uptr kVdsoBeg = 0x7000000000000000ull;
};
+#elif defined(__loongarch64)
+/*
+ * TODO same as mips64 and need to change in the future
+C/C++ on linux/loongarch64 (40-bit VMA)
+0000 0000 00 - 0100 0000 00: - (4 GB)
+0100 0000 00 - 0200 0000 00: main binary (4 GB)
+0200 0000 00 - 2000 0000 00: - (120 GB)
+2000 0000 00 - 4000 0000 00: shadow (128 GB)
+4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB)
+5000 0000 00 - aa00 0000 00: - (360 GB)
+aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB)
+ab00 0000 00 - b000 0000 00: - (20 GB)
+b000 0000 00 - b200 0000 00: traces (8 GB)
+b200 0000 00 - fe00 0000 00: - (304 GB)
+fe00 0000 00 - ff00 0000 00: heap (4 GB)
+ff00 0000 00 - ff80 0000 00: - (2 GB)
+ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB)
+*/
+struct Mapping {
+ static const uptr kMetaShadowBeg = 0x4000000000ull;
+ static const uptr kMetaShadowEnd = 0x5000000000ull;
+ static const uptr kTraceMemBeg = 0xb000000000ull;
+ static const uptr kTraceMemEnd = 0xb200000000ull;
+ static const uptr kShadowBeg = 0x2000000000ull;
+ static const uptr kShadowEnd = 0x4000000000ull;
+ static const uptr kHeapMemBeg = 0xfe00000000ull;
+ static const uptr kHeapMemEnd = 0xff00000000ull;
+ static const uptr kLoAppMemBeg = 0x0100000000ull;
+ static const uptr kLoAppMemEnd = 0x0200000000ull;
+ static const uptr kMidAppMemBeg = 0xaa00000000ull;
+ static const uptr kMidAppMemEnd = 0xab00000000ull;
+ static const uptr kHiAppMemBeg = 0xff80000000ull;
+ static const uptr kHiAppMemEnd = 0xffffffffffull;
+ static const uptr kAppMemMsk = 0xf800000000ull;
+ static const uptr kAppMemXor = 0x0800000000ull;
+ static const uptr kVdsoBeg = 0xfffff00000ull;
+};
+
#elif defined(__aarch64__)
// AArch64 supports multiple VMA which leads to multiple address transformation
// functions. To support these multiple VMAS transformations and mappings TSAN
diff --git a/libsanitizer/tsan/tsan_platform_posix.cc b/libsanitizer/tsan/tsan_platform_posix.cc
index 6e62575f1..e146d04fb 100644
--- a/libsanitizer/tsan/tsan_platform_posix.cc
+++ b/libsanitizer/tsan/tsan_platform_posix.cc
@@ -59,6 +59,9 @@ void InitializeShadowMemory() {
} else {
DCHECK(0);
}
+#elif defined(__loongarch64)
+ const uptr kMadviseRangeBeg = 0xff00000000ull;
+ const uptr kMadviseRangeSize = 0x0100000000ull;
#elif defined(__powerpc64__)
uptr kMadviseRangeBeg = 0;
uptr kMadviseRangeSize = 0;
diff --git a/libsanitizer/tsan/tsan_rtl.cc b/libsanitizer/tsan/tsan_rtl.cc
index 4a1f50061..8f9c48867 100644
--- a/libsanitizer/tsan/tsan_rtl.cc
+++ b/libsanitizer/tsan/tsan_rtl.cc
@@ -224,7 +224,7 @@ static void StartBackgroundThread() {
ctx->background_thread = internal_start_thread(&BackgroundThread, 0);
}
-#ifndef __mips__
+#ifndef __mips__ || defined(__loongarch__)
static void StopBackgroundThread() {
atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed);
internal_join_thread(ctx->background_thread);
@@ -401,6 +401,20 @@ void Initialize(ThreadState *thr) {
OnInitialize();
}
+void MaybeSpawnBackgroundThread() {
+ // On MIPS, TSan initialization is run before
+ // __pthread_initialize_minimal_internal() is finished, so we can not spawn
+ // new threads.
+#if !SANITIZER_GO && !(defined(__mips__) || defined(__loongarch__))
+ static atomic_uint32_t bg_thread = {};
+ if (atomic_load(&bg_thread, memory_order_relaxed) == 0 &&
+ atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) {
+ StartBackgroundThread();
+ SetSandboxingCallback(StopBackgroundThread);
+ }
+#endif
+}
+
int Finalize(ThreadState *thr) {
bool failed = false;
diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h
index 7dd9779e4..6f8800003 100644
--- a/libsanitizer/tsan/tsan_rtl.h
+++ b/libsanitizer/tsan/tsan_rtl.h
@@ -52,7 +52,8 @@ namespace __tsan {
#if !SANITIZER_GO
struct MapUnmapCallback;
-#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__)
+#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) \
+ || defined(__loongarch64)
static const uptr kAllocatorRegionSizeLog = 20;
static const uptr kAllocatorNumRegions =
SANITIZER_MMAP_RANGE_SIZE >> kAllocatorRegionSizeLog;
diff --git a/libsanitizer/tsan/tsan_rtl_loongarch64.S b/libsanitizer/tsan/tsan_rtl_loongarch64.S
new file mode 100644
index 000000000..9331e8afa
--- /dev/null
+++ b/libsanitizer/tsan/tsan_rtl_loongarch64.S
@@ -0,0 +1,156 @@
+.section .text
+
+.hidden __tsan_setjmp
+.comm _ZN14__interception11real_setjmpE,8,8
+.globl setjmp
+.type setjmp, @function
+setjmp:
+
+ # save env parameters
+ addi.d $r3,$r3,-24
+ st.d $r1,$r3,16
+ st.d $r22,$r3,8
+
+ # save jmp_buf
+ st.d $r4,$r3,0
+
+ # obtain $sp
+ add.d $r4,$r0,$r3
+
+ # call tsan interceptor
+ addi.d $r5,$r4,24
+ bl __tsan_setjmp
+
+ # restore jmp_buf
+ ld.d $r4,$r3,0
+
+ # load libc setjmp to r20
+ la $r20,_ZN14__interception11real_setjmpE
+ # restore env parameters
+ ld.d $r22,$r3,8
+ ld.d $r1,$r3,16
+ addi.d $r3,$r3,24
+
+ # tail jump to libc setjmp
+ ld.d $r20,$r20,0
+ jr $r20
+
+.size setjmp, .-setjmp
+
+.hidden __tsan_setjmp
+.globl _setjmp
+.comm _ZN14__interception12real__setjmpE,8,8
+.type _setjmp, @function
+_setjmp:
+
+ # Save env parameters
+ addi.d $r3,$r3,-24
+ st.d $r1,$r3,16
+ st.d $r22,$r3,8
+
+ # save jmp_buf
+ st.d $r4,$r3,0
+
+ # obtain $sp
+ add.d $r4,$r0,$r3
+
+ # call tsan interceptor
+ addi.d $r5,$r4,24
+ bl __tsan_setjmp
+
+ # restore jmp_buf
+ ld.d $r4,$r3,0
+
+ # load libc _setjmp to r20
+ la $r20,_ZN14__interception12real__setjmpE
+
+ # restore env parameters
+ ld.d $r22,$r3,8
+ ld.d $r1,$r3,16
+ addi.d $r3,$r3,24
+
+ # tail jump to libc _setjmp
+ ld.d $r20,$r20,0
+ jr $r20
+
+.size _setjmp, .-_setjmp
+
+.hidden __tsan_setjmp
+.globl sigsetjmp
+.comm _ZN14__interception14real_sigsetjmpE,8,8
+.type sigsetjmp, @function
+sigsetjmp:
+
+ # Save env parameters
+ addi.d $r3,$r3,-32
+ st.d $r1,$r3,24
+ st.d $r22,$r3,16
+
+ # save jmp_buf and savesig
+ st.d $r4,$r3,0
+ st.d $r5,$r3,8
+
+ # obtain $sp
+ add.d $r4,$r0,$r3
+
+ # call tsan interceptor
+ addi.d $r5,$r4,32
+ bl __tsan_setjmp
+
+ # restore jmp_buf and savesig
+ ld.d $r4,$r3,0
+ ld.d $r5,$r3,8
+
+ # load libc sigsetjmp to r20
+ la $r20,_ZN14__interception14real_sigsetjmpE
+
+ # restore env parameters
+ ld.d $r22,$r3,16
+ ld.d $r1,$r3,24
+ addi.d $r3,$r3,32
+
+ # tail jump to libc sigsetjmp
+ ld.d $r20,$r20,0
+ jr $r20
+
+.size sigsetjmp, .-sigsetjmp
+
+.hidden __tsan_setjmp
+.comm _ZN14__interception16real___sigsetjmpE,8,8
+.globl __sigsetjmp
+.type __sigsetjmp, @function
+__sigsetjmp:
+
+ # Save env parameters
+ addi.d $sp,$sp,-32
+ st.d $r1,$r3,24
+ st.d $r22,$r3,16
+
+ # save jmp_buf and savesig
+ st.d $r4,$r3,0
+ st.d $r5,$r3,8
+
+ # obtain $sp
+ add.d $r4,$r0,$r3
+
+ # call tsan interceptor
+ addi.d $r5,$r4,32
+ bl __tsan_setjmp
+
+ # restore jmp_buf and savesig
+ ld.d $r4,$r3,0
+ ld.d $r5,$r3,8
+
+ # load libc __sigsetjmp in r20
+ la $r20,_ZN14__interception16real___sigsetjmpE
+
+ # restore env parameters
+ ld.d $r22,$r3,16
+ ld.d $r1,$r3,24
+ addi.d $r3,$r3,32
+
+ # tail jump to libc __sigsetjmp
+ ld.d $r20,$r20,0
+ jr $r20
+
+.size __sigsetjmp, .-__sigsetjmp
--
2.39.3
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/renbo02/gcc.git
git@gitee.com:renbo02/gcc.git
renbo02
gcc
gcc
a8

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385