From a59f75b1951100a667db155a279f0a3cf6236c9a Mon Sep 17 00:00:00 2001
From: maqi <maqi@uniontech.com>
Date: Thu, 16 Jan 2025 17:05:35 +0800
Subject: [PATCH] add sw_64 support

---
 config.guess                    |  3 +++
 config.sub                      |  1 +
 src/base/basictypes.h           |  2 ++
 src/base/linuxthreads.cc        |  2 +-
 src/getpc-inl.h                 | 16 +++++++++++++++-
 src/stacktrace.cc               | 19 +++++++++++++++++++
 src/stacktrace_generic_fp-inl.h |  2 ++
 src/tcmalloc.cc                 |  1 +
 8 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/config.guess b/config.guess
index 7f76b62..fd3524f 100755
--- a/config.guess
+++ b/config.guess
@@ -1143,6 +1143,9 @@ EOF
     sparc:Linux:*:* | sparc64:Linux:*:*)
 	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
 	;;
+    sw_64*:Linux:*:*)
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     tile*:Linux:*:*)
 	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
 	;;
diff --git a/config.sub b/config.sub
index dba16e8..c6a3b0b 100755
--- a/config.sub
+++ b/config.sub
@@ -1267,6 +1267,7 @@ case $cpu-$vendor in
 			| sparclite \
 			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
 			| spu \
+ 			| sw_64 \
 			| tahoe \
 			| thumbv7* \
 			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
diff --git a/src/base/basictypes.h b/src/base/basictypes.h
index 1f3b47b..595013f 100644
--- a/src/base/basictypes.h
+++ b/src/base/basictypes.h
@@ -386,6 +386,8 @@ class AssignAttributeStartEnd {
 #   define CACHELINE_ALIGNED __attribute__((aligned(64)))
 # elif defined(__loongarch64)
 #   define CACHELINE_ALIGNED __attribute__((aligned(64)))
+# elif defined(__sw_64)
+#   define CACHELINE_ALIGNED __attribute__((aligned(64)))
 # else
 #   error Could not determine cache line length - unknown architecture
 # endif
diff --git a/src/base/linuxthreads.cc b/src/base/linuxthreads.cc
index d477385..e6602ce 100644
--- a/src/base/linuxthreads.cc
+++ b/src/base/linuxthreads.cc
@@ -158,7 +158,7 @@ static int local_clone (int (*fn)(void *), void *arg) {
     clone_stack_size = ~clone_stack_size + 1;
   }
 
-#if defined(__i386__) || defined(__x86_64__) || defined(__riscv) || defined(__arm__) || defined(__aarch64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__riscv) || defined(__arm__) || defined(__aarch64__) || defined(__sw_64__)
   // Sanity check code above. We know that those arch-es grow stack to
   // lower addresses.
   CHECK(grows_to_low);
diff --git a/src/getpc-inl.h b/src/getpc-inl.h
index 615e238..404fae6 100644
--- a/src/getpc-inl.h
+++ b/src/getpc-inl.h
@@ -119,6 +119,18 @@ struct get_4e9b682d<U, P, void_t<decltype(((U*){})->uc_mcontext.__pc)>> : public
   }
 };
 
+// Linux/sw_64
+template <class U, class P, class = void>
+struct get_4a81fbc6 : public P {
+};
+template <class U, class P>
+struct get_4a81fbc6<U, P, void_t<decltype(((U*){})->uc_mcontext.sc_pc)>> : public P {
+  static void* Get(const U* uc) {
+    // Linux/sw_64
+    return (void*)(uc->uc_mcontext.sc_pc);
+  }
+};
+
 // Linux/{mips,aarch64}
 template <class U, class P, class = void>
 struct get_b94b7246 : public P {
@@ -378,8 +390,10 @@ inline void* RawUCToPC(const ucontext_t* uc) {
   using g_d0eeceae = get_d0eeceae<ucontext_t, g_a81f6801>;
   // Linux/{mips,aarch64}
   using g_b94b7246 = get_b94b7246<ucontext_t, g_d0eeceae>;
+  // Linux/sw_64
+  using g_4a81fbc6 = get_4a81fbc6<ucontext_t, g_b94b7246>;
   // Linux/loongarch64
-  using g_4e9b682d = get_4e9b682d<ucontext_t, g_b94b7246>;
+  using g_4e9b682d = get_4e9b682d<ucontext_t, g_4a81fbc6>;
   // Linux/ia64
   using g_8fda99d3 = get_8fda99d3<ucontext_t, g_4e9b682d>;
   // Linux/amd64 (with #ifdef REG_RIP)
diff --git a/src/stacktrace.cc b/src/stacktrace.cc
index b1fd04b..500cffb 100644
--- a/src/stacktrace.cc
+++ b/src/stacktrace.cc
@@ -144,6 +144,25 @@ struct GetStackImplementation {
 #define HAVE_GST_generic_fp_unsafe
 #endif
 
+#if defined(__GNUC__) && defined(__sw_64__)
+#define STACKTRACE_INL_HEADER "stacktrace_generic_fp-inl.h"
+#define GST_SUFFIX generic_fp
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_generic_fp
+
+#undef TCMALLOC_UNSAFE_GENERIC_FP_STACKTRACE
+#define TCMALLOC_UNSAFE_GENERIC_FP_STACKTRACE 1
+
+#define STACKTRACE_INL_HEADER "stacktrace_generic_fp-inl.h"
+#define GST_SUFFIX generic_fp_unsafe
+#include "stacktrace_impl_setup-inl.h"
+#undef GST_SUFFIX
+#undef STACKTRACE_INL_HEADER
+#define HAVE_GST_generic_fp_unsafe
+#endif
+
 #if defined(__ppc__) || defined(__PPC__)
 #if defined(__linux__)
 #define STACKTRACE_INL_HEADER "stacktrace_powerpc-linux-inl.h"
diff --git a/src/stacktrace_generic_fp-inl.h b/src/stacktrace_generic_fp-inl.h
index 12f93bb..e2da11b 100644
--- a/src/stacktrace_generic_fp-inl.h
+++ b/src/stacktrace_generic_fp-inl.h
@@ -319,6 +319,8 @@ static int GET_STACK_TRACE_OR_FRAMES {
 #elif __linux__ && __arm__
     // Note: arm's frame pointer support is borked in recent GCC-s.
     SETUP_FRAME(&uc->uc_mcontext.arm_pc, uc->uc_mcontext.arm_fp);
+#elif __linux__ && __sw_64__
+    SETUP_FRAME(&uc->uc_mcontext.sc_pc,uc->uc_mcontext.sc_regs[15]);
 #elif __linux__ && __i386__
     SETUP_FRAME(&uc->uc_mcontext.gregs[REG_EIP], uc->uc_mcontext.gregs[REG_EBP]);
 #elif __linux__ && __x86_64__
diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc
index dcb9460..740171b 100644
--- a/src/tcmalloc.cc
+++ b/src/tcmalloc.cc
@@ -171,6 +171,7 @@ DECLARE_int64(tcmalloc_heap_limit_mb);
 // jump. I am not able to reproduce that anymore.
 #if !defined(__i386__) && !defined(__x86_64__) && \
     !defined(__ppc__) && !defined(__PPC__) && \
+    !defined(__sw_64__) && \
     !defined(__aarch64__) && !defined(__mips__) && !defined(__arm__) && !defined(__loongarch64)
 #undef TCMALLOC_NO_ALIASES
 #define TCMALLOC_NO_ALIASES
-- 
2.33.0
