From fb4ad967fe2461dbff93b4a2a38212ee40ea4ef5 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Sat, 7 Jun 2025 10:03:27 +0800 Subject: [PATCH] LoongArch: fix sanitizer and gcc_except_table --- 0001-LoongArch-Fix-sanitizer.patch | 348 ++++++++++++++++++ ...-the-cached-value-of-the-gcc_except_.patch | 77 ++++ gcc.spec | 9 +- 3 files changed, 433 insertions(+), 1 deletion(-) create mode 100644 0001-LoongArch-Fix-sanitizer.patch create mode 100644 except-Don-t-use-the-cached-value-of-the-gcc_except_.patch diff --git a/0001-LoongArch-Fix-sanitizer.patch b/0001-LoongArch-Fix-sanitizer.patch new file mode 100644 index 0000000..3ffe83a --- /dev/null +++ b/0001-LoongArch-Fix-sanitizer.patch @@ -0,0 +1,348 @@ +From 5c2fd630f27927acb7c64cfeb010ccf7c2c13ddb Mon Sep 17 00:00:00 2001 +From: Peng Fan +Date: Sat, 7 Jun 2025 01:30:06 +0000 +Subject: [PATCH 1/2] LoongArch: Fix sanitizer + +--- + .../sanitizer_common/sanitizer_common.h | 2 +- + .../sanitizer_common/sanitizer_linux.cpp | 30 +++++----- + .../sanitizer_linux_libcdep.cpp | 2 +- + .../sanitizer_common/sanitizer_platform.h | 4 +- + .../sanitizer_platform_interceptors.h | 2 +- + .../sanitizer_platform_limits_posix.cpp | 2 +- + .../sanitizer_platform_limits_posix.h | 2 +- + .../sanitizer_symbolizer_libcdep.cpp | 2 +- + ...ommon_interceptors_vfork_loongarch64.inc.S | 57 ------------------- + libsanitizer/tsan/tsan_platform.h | 41 ++++--------- + 10 files changed, 35 insertions(+), 109 deletions(-) + delete mode 100644 libsanitizer/sanitizer_common_interceptors_vfork_loongarch64.inc.S + +diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h +index 5f68e4994..8d7d08360 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_common.h ++++ b/libsanitizer/sanitizer_common/sanitizer_common.h +@@ -766,7 +766,7 @@ inline const char *ModuleArchToString(ModuleArch arch) { + return "armv7k"; + case kModuleArchARM64: + return "arm64"; +- case kModuleArchLoongArch64: ++ case kModuleArchLoongArch64: + return "loongarch64"; + case kModuleArchRISCV64: + return "riscv64"; +diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cpp b/libsanitizer/sanitizer_common/sanitizer_linux.cpp +index a3c90bca9..1e9eece27 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_linux.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_linux.cpp +@@ -30,7 +30,7 @@ + #include + #endif + +-#if SANITIZER_LINUX && defined(__loongarch__) ++#if SANITIZER_LINUX && defined(__loongarch__) + # include + #endif + +@@ -184,7 +184,7 @@ ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); } + # include "sanitizer_syscall_linux_arm.inc" + # elif SANITIZER_LINUX && defined(__hexagon__) + # include "sanitizer_syscall_linux_hexagon.inc" +-# elif SANITIZER_LINUX && SANITIZER_LOONGARCH64 ++# elif SANITIZER_LINUX && SANITIZER_LOONGARCH64 + # include "sanitizer_syscall_linux_loongarch64.inc" + # else + # include "sanitizer_syscall_generic.inc" +@@ -364,7 +364,7 @@ uptr internal_stat(const char *path, void *buf) { + #if SANITIZER_FREEBSD + return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0); + #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +-# if SANITIZER_LINUX && defined(__loongarch__) ++# if SANITIZER_LINUX && defined(__loongarch__) + struct statx bufx; + int res = internal_syscall(SYSCALL(statx), AT_FDCWD, (uptr)path, + AT_NO_AUTOMOUNT, STATX_BASIC_STATS, (uptr)&bufx); +@@ -397,7 +397,7 @@ uptr internal_lstat(const char *path, void *buf) { + return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, + AT_SYMLINK_NOFOLLOW); + #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +-# if SANITIZER_LINUX && defined(__loongarch__) ++# if SANITIZER_LINUX && defined(__loongarch__) + struct statx bufx; + int res = internal_syscall(SYSCALL(statx), AT_FDCWD, (uptr)path, + AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT, +@@ -434,7 +434,7 @@ uptr internal_fstat(fd_t fd, void *buf) { + int res = internal_syscall(SYSCALL(fstat), fd, &kbuf); + kernel_stat_to_stat(&kbuf, (struct stat *)buf); + return res; +-# elif SANITIZER_LINUX && defined(__loongarch__) ++# elif SANITIZER_LINUX && defined(__loongarch__) + struct statx bufx; + int res = internal_syscall(SYSCALL(statx), fd, "", AT_EMPTY_PATH, + STATX_BASIC_STATS, (uptr)&bufx); +@@ -1317,9 +1317,9 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + if (!fn || !child_stack) + return -EINVAL; +- ++ + CHECK_EQ(0, (uptr)child_stack % 16); +- ++ + register int res __asm__("$a0"); + register int __flags __asm__("$a0") = flags; + register void *__stack __asm__("$a1") = child_stack; +@@ -1329,24 +1329,24 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + register int (*__fn)(void *) __asm__("$a5") = fn; + register void *__arg __asm__("$a6") = arg; + register int nr_clone __asm__("$a7") = __NR_clone; +- ++ + __asm__ __volatile__( + "syscall 0\n" +- ++ + // if ($a0 != 0) + // return $a0; + "bnez $a0, 1f\n" +- ++ + // In the child, now. Call "fn(arg)". + "move $a0, $a6\n" + "jirl $ra, $a5, 0\n" +- ++ + // Call _exit($a0). + "addi.d $a7, $zero, %9\n" + "syscall 0\n" +- ++ + "1:\n" +- ++ + : "=r"(res) + : "0"(__flags), "r"(__stack), "r"(__ptid), "r"(__ctid), "r"(__tls), + "r"(__fn), "r"(__arg), "r"(nr_clone), "i"(__NR_exit) +@@ -1967,7 +1967,7 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { + u64 esr; + if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN; + return esr & ESR_ELx_WNR ? WRITE : READ; +-#elif defined(__loongarch__) ++#elif defined(__loongarch__) + u32 flags = ucontext->uc_mcontext.__flags; + if (flags & SC_ADDRERR_RD) + return SignalContext::READ; +@@ -2228,7 +2228,7 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { + *pc = ucontext->uc_mcontext.pc; + *bp = ucontext->uc_mcontext.r30; + *sp = ucontext->uc_mcontext.r29; +-# elif defined(__loongarch__) ++# elif defined(__loongarch__) + ucontext_t *ucontext = (ucontext_t *)context; + *pc = ucontext->uc_mcontext.__pc; + *bp = ucontext->uc_mcontext.__gregs[22]; +diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +index 0fc1d2d44..474272ec7 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp +@@ -263,7 +263,7 @@ static uptr ThreadDescriptorSizeFallback() { + #elif defined(__mips__) + // TODO(sagarthakur): add more values as per different glibc versions. + val = FIRST_32_SECOND_64(1152, 1776); +-#elif SANITIZER_LOONGARCH64 ++#elif SANITIZER_LOONGARCH64 + val = 1856; // from glibc 2.36 + #elif SANITIZER_RISCV64 + int major; +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h +index ed2d47ddf..ef9d71278 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform.h ++++ b/libsanitizer/sanitizer_common/sanitizer_platform.h +@@ -225,9 +225,9 @@ + #define SANITIZER_RISCV64 0 + #endif + +-#if defined(__loongarch_lp64) ++#if defined(__loongarch_lp64) + # define SANITIZER_LOONGARCH64 1 +-#else ++#else + # define SANITIZER_LOONGARCH64 0 + #endif + +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +index 14610f2df..426745fb3 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +@@ -271,7 +271,7 @@ + #if SI_LINUX_NOT_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__s390__) || SANITIZER_RISCV64) ++ defined(__s390__) || SANITIZER_RISCV64 || defined(__loongarch__)) + #define SANITIZER_INTERCEPT_PTRACE 1 + #else + #define SANITIZER_INTERCEPT_PTRACE 0 +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +index f5d775839..89d935a1d 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp +@@ -248,7 +248,7 @@ namespace __sanitizer { + defined(__powerpc__) || defined(__s390__) || defined(__sparc__) || \ + defined(__hexagon__) + # define SIZEOF_STRUCT_USTAT 20 +-# elif defined(__loongarch__) ++# elif defined(__loongarch__) + // Not used. The minimum Glibc version available for LoongArch is 2.36 + // so ustat() wrapper is already gone. + # define SIZEOF_STRUCT_USTAT 0 +diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +index f50827d9a..2279238e0 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h ++++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +@@ -99,7 +99,7 @@ const unsigned struct_kernel_stat64_sz = 144; + const unsigned struct___old_kernel_stat_sz = 0; + const unsigned struct_kernel_stat_sz = 64; + const unsigned struct_kernel_stat64_sz = 104; +-# elif defined(__loongarch__) ++# elif defined(__loongarch__) + const unsigned struct_kernel_stat_sz = 128; + const unsigned struct_kernel_stat64_sz = 0; + #elif SANITIZER_RISCV64 +diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +index 1b6c0d5c0..bc24430d8 100644 +--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp ++++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp +@@ -261,7 +261,7 @@ class LLVMSymbolizerProcess final : public SymbolizerProcess { + const char* const kSymbolizerArch = "--default-arch=i386"; + #elif SANITIZER_RISCV64 + const char *const kSymbolizerArch = "--default-arch=riscv64"; +-#elif SANITIZER_LOONGARCH64 ++#elif SANITIZER_LOONGARCH64 + const char *const kSymbolizerArch = "--default-arch=loongarch64"; + #elif defined(__aarch64__) + const char* const kSymbolizerArch = "--default-arch=arm64"; +diff --git a/libsanitizer/sanitizer_common_interceptors_vfork_loongarch64.inc.S b/libsanitizer/sanitizer_common_interceptors_vfork_loongarch64.inc.S +deleted file mode 100644 +index dae72b5ac..000000000 +--- a/libsanitizer/sanitizer_common_interceptors_vfork_loongarch64.inc.S ++++ /dev/null +@@ -1,57 +0,0 @@ +-#if defined(__loongarch64) && defined(__linux__) +- +-#include "sanitizer_common/sanitizer_asm.h" +- +-ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) +-ASM_HIDDEN(_ZN14__interception10real_vforkE) +- +-.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 +diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h +index 0ec562dac..6ed65b81f 100644 +--- a/libsanitizer/tsan/tsan_platform.h ++++ b/libsanitizer/tsan/tsan_platform.h +@@ -98,42 +98,25 @@ struct Mapping48AddressSpace { + 7fff 0000 0000 - 7fff 8000 0000: - + 7fff 8000 0000 - 8000 0000 0000: modules and main thread stack + */ +-// struct MappingLoongArch64_47 { +-// static const uptr kMetaShadowBeg = 0x300000000000ull; +-// static const uptr kMetaShadowEnd = 0x340000000000ull; +-// static const uptr kShadowBeg = 0x010000000000ull; +-// static const uptr kShadowEnd = 0x100000000000ull; +-// static const uptr kHeapMemBeg = 0x7ffe00000000ull; +-// static const uptr kHeapMemEnd = 0x7fff00000000ull; +-// static const uptr kLoAppMemBeg = 0x000000004000ull; +-// static const uptr kLoAppMemEnd = 0x008000000000ull; +-// static const uptr kMidAppMemBeg = 0x555500000000ull; +-// static const uptr kMidAppMemEnd = 0x555600000000ull; +-// static const uptr kHiAppMemBeg = 0x7fff80000000ull; +-// static const uptr kHiAppMemEnd = 0x800000000000ull; +-// static const uptr kShadowMsk = 0x780000000000ull; +-// static const uptr kShadowXor = 0x040000000000ull; +-// static const uptr kShadowAdd = 0x000000000000ull; +-// static const uptr kVdsoBeg = 0x7fffffffc000ull; +-// }; + struct MappingLoongArch64_47 { +- static const uptr kMetaShadowBeg = 0x300000000000ull; +- static const uptr kMetaShadowEnd = 0x340000000000ull; +- static const uptr kShadowBeg = 0x010000000000ull; +- static const uptr kShadowEnd = 0x100000000000ull; +- static const uptr kHeapMemBeg = 0x7ffe00000000ull; +- static const uptr kHeapMemEnd = 0x7fff00000000ull; + static const uptr kLoAppMemBeg = 0x000000004000ull; + static const uptr kLoAppMemEnd = 0x008000000000ull; ++ static const uptr kShadowBeg = 0x010000000000ull; ++ static const uptr kShadowEnd = 0x200000000000ull; ++ static const uptr kMetaShadowBeg = 0x300000000000ull; ++ static const uptr kMetaShadowEnd = 0x340000000000ull; + static const uptr kMidAppMemBeg = 0x555500000000ull; + static const uptr kMidAppMemEnd = 0x555600000000ull; +- static const uptr kHiAppMemBeg = 0x7fff80000000ull; +- static const uptr kHiAppMemEnd = 0x800000000000ull; + static const uptr kTraceMemBeg = 0x600000000000ull; + static const uptr kTraceMemEnd = 0x620000000000ull; +- static const uptr kShadowMsk = 0x780000000000ull; +- static const uptr kShadowXor = 0x040000000000ull; +- static const uptr kShadowAdd = 0x000000000000ull; ++ static const uptr kHeapMemBeg = 0x7ffe00000000ull; ++ static const uptr kHeapMemEnd = 0x7fff00000000ull; ++ static const uptr kHiAppMemBeg = 0x7fff80000000ull; ++ static const uptr kHiAppMemEnd = 0x800000000000ull; ++ ++ static const uptr kShadowMsk = 0x780000000000ull; ++ static const uptr kShadowXor = 0x040000000000ull; ++ static const uptr kShadowAdd = 0x000000000000ull; + static const uptr kVdsoBeg = 0x7fffffffc000ull; + }; + +-- +2.41.0 + diff --git a/except-Don-t-use-the-cached-value-of-the-gcc_except_.patch b/except-Don-t-use-the-cached-value-of-the-gcc_except_.patch new file mode 100644 index 0000000..14f240e --- /dev/null +++ b/except-Don-t-use-the-cached-value-of-the-gcc_except_.patch @@ -0,0 +1,77 @@ +From db34c7838f3379549e087ef05f017943db34298b Mon Sep 17 00:00:00 2001 +From: Andrew Pinski +Date: Fri, 28 Mar 2025 17:25:56 -0700 +Subject: [PATCH 2/2] except: Don't use the cached value of the + gcc_except_table section for comdat functions [PR119507] + +This has been broken since GCC started to put the comdat functions' gcc_except_table into their +own section; r0-118218-g3e6011cfebedfb. What would happen is after a non-comdat function is processed, +the cached value would always be used even for comdat function. Instead we should create a new +section for comdat functions. + +OK? Bootstrapped and tested on x86_64-linux-gnu. + + PR middle-end/119507 + +gcc/ChangeLog: + + * except.cc (switch_to_exception_section): Don't use the cached section if + the current function is in comdat. + +gcc/testsuite/ChangeLog: + + * g++.dg/eh/pr119507.C: New test. + +Signed-off-by: Andrew Pinski +--- + gcc/except.cc | 9 ++++++++- + gcc/testsuite/g++.dg/eh/pr119507.C | 17 +++++++++++++++++ + 2 files changed, 25 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/g++.dg/eh/pr119507.C + +diff --git a/gcc/except.cc b/gcc/except.cc +index b94de4255..8714c1be8 100644 +--- a/gcc/except.cc ++++ b/gcc/except.cc +@@ -2906,7 +2906,14 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname)) + { + section *s; + +- if (exception_section) ++ if (exception_section ++ /* Don't use the cached section for comdat if it will be different. */ ++#ifdef HAVE_LD_EH_GC_SECTIONS ++ && !(targetm_common.have_named_sections ++ && DECL_COMDAT_GROUP (current_function_decl) ++ && HAVE_COMDAT_GROUP) ++#endif ++ ) + s = exception_section; + else + { +diff --git a/gcc/testsuite/g++.dg/eh/pr119507.C b/gcc/testsuite/g++.dg/eh/pr119507.C +new file mode 100644 +index 000000000..50afa75a4 +--- /dev/null ++++ b/gcc/testsuite/g++.dg/eh/pr119507.C +@@ -0,0 +1,17 @@ ++// { dg-do compile { target comdat_group } } ++// Force off function sections ++// Force on exceptions ++// { dg-options "-fno-function-sections -fexceptions" } ++// PR middle-end/119507 ++ ++ ++inline int comdat() { try { throw 1; } catch (int) { return 1; } return 0; } ++int another_func_with_exception() { try { throw 1; } catch (int) { return 1; } return 0; } ++inline int comdat1() { try { throw 1; } catch (int) { return 1; } return 0; } ++int foo() { return comdat() + comdat1(); } ++ ++// Make sure the gcc puts the exception table for both comdat and comdat1 in their own section ++// { dg-final { scan-assembler-times ".section\[\t \]\[^\n\]*.gcc_except_table._Z6comdatv" 1 } } ++// { dg-final { scan-assembler-times ".section\[\t \]\[^\n\]*.gcc_except_table._Z7comdat1v" 1 } } ++// There should be 3 exception tables, ++// { dg-final { scan-assembler-times ".section\[\t \]\[^\n\]*.gcc_except_table" 3 } } +-- +2.41.0 + diff --git a/gcc.spec b/gcc.spec index 544945d..0d8a830 100644 --- a/gcc.spec +++ b/gcc.spec @@ -1,4 +1,4 @@ -%define anolis_release 12 +%define anolis_release 13 %global DATE 20221121 %global gitrev b3f5a0d53b84ed27cf00cfa2b9c3e2c78935c07d @@ -132,6 +132,7 @@ Patch100: gcc12-fortran-fdec-duplicates.patch Patch101: gcc12-fortran-flogical-as-integer.patch Patch102: gcc12-fortran-fdec-override-kind.patch Patch103: gcc12-fortran-fdec-non-logical-if.patch +Patch104: except-Don-t-use-the-cached-value-of-the-gcc_except_.patch # Part 3000 ~ 4999 Patch3001: loongarch-add-alternatives-for-idiv-insns-to-improve.patch @@ -456,6 +457,7 @@ Patch3319: 0189-LoongArch-fix-building-errors.patch Patch3320: 0190-tree-optimization-110702-avoid-zero-based-memory-ref.patch Patch3321: 0191-LoongArch-Change-OSDIR-for-distribution.patch Patch3322: Fix-indentation-and-numbering-errors.diff +Patch3323: 0001-LoongArch-Fix-sanitizer.patch # Part 5000 ~ 5999 Patch5001: HYGON-0001-arch-support-for-hygon.patch @@ -1008,6 +1010,7 @@ The %{name}-doc package contains documentation files for %{name}. %patch101 -p1 %patch102 -p1 %patch103 -p1 +%patch104 -p1 %ifarch loongarch64 %patch3001 -p1 %patch3002 -p1 @@ -1331,6 +1334,7 @@ The %{name}-doc package contains documentation files for %{name}. %patch3320 -p1 %patch3321 -p1 %patch3322 -p1 +%patch3323 -p1 %endif %ifarch x86_64 %patch5001 -p1 @@ -2850,6 +2854,9 @@ end %changelog +* Sat Jun 7 2025 Peng Fan - 12.3.0-13 +- Fix sanitizer and gcc_except_table + * Tue Jun 3 2025 zhoujiajia111 -12.3.0-12 - Provide tar package using download file -- Gitee