From 9852d13a3263e0d163e6cb180d6c3edbd54e5858 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 6 Jul 2024 20:31:50 -0500 Subject: system/gcc: Add sanitizer support Based-ish on Chimera's patches, but a bit more thorough. * 32-bit ports don't have liblsan or libtsan. * We can't dep on utmps-dev for utmpx, so hard-code size. The size is the same on all six arches per my testing. --- system/gcc/APKBUILD | 34 ++++++++++- system/gcc/sanitation.patch | 141 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 system/gcc/sanitation.patch diff --git a/system/gcc/APKBUILD b/system/gcc/APKBUILD index 38372feb0..b349cf43d 100644 --- a/system/gcc/APKBUILD +++ b/system/gcc/APKBUILD @@ -32,6 +32,7 @@ LIBGOMP=true LIBGCC=true LIBATOMIC=true LIBITM=true +LIBSANITIZER=true if [ "$CHOST" != "$CTARGET" ]; then if [ "$BOOTSTRAP" = nolibc ]; then @@ -48,6 +49,7 @@ if [ "$CHOST" != "$CTARGET" ]; then LIBGOMP=false LIBATOMIC=false LIBITM=false + LIBSANITIZER=false # reset target flags (should be set in crosscreate abuild) # fixup flags. seems gcc treats CPPFLAGS as global without @@ -109,6 +111,7 @@ esac $LIBATOMIC && subpackages="$subpackages libatomic::$CTARGET_ARCH" $LIBGCC && subpackages="$subpackages libgcc::$CTARGET_ARCH" $LIBQUADMATH && subpackages="$subpackages libquadmath::$CTARGET_ARCH" +$LIBSANITIZER && subpackages="$subpackages libsanitizer::$CTARGET_ARCH" if $LIBGOMP; then depends="$depends libgomp=$_gccrel" subpackages="$subpackages libgomp::$CTARGET_ARCH" @@ -176,11 +179,12 @@ source="https://ftp.gnu.org/gnu/gcc/gcc-$pkgver/gcc-$pkgver.tar.xz 336-gccgo-mmap64.patch 341-gccgo-libucontext-stack.patch 342-gccgo-reflect-underscore.patch + libgo-musl-1.2.3.patch add-classic_table-support.patch gcc-5.4.0-locale.patch - libgo-musl-1.2.3.patch + sanitation.patch match-split.patch insn-split.patch @@ -245,7 +249,6 @@ build() { case "$CTARGET_LIBC" in musl) - _libc_configure="--disable-libsanitizer" _symvers="--disable-symvers" export libat_cv_have_ifunc=no export ac_cv_type_off64_t=no @@ -263,6 +266,7 @@ build() { $LIBGOMP || _bootstrap_configure="$_bootstrap_configure --disable-libgomp" $LIBATOMIC || _bootstrap_configure="$_bootstrap_configure --disable-libatomic" $LIBITM || _bootstrap_configure="$_bootstrap_configure --disable-libitm" + $LIBSANITIZER || _bootstrap_configure="$_bootstrap_configure --disable-libsanitizer" $LIBQUADMATH || _arch_configure="$_arch_configure --disable-libquadmath" msg "Building the following:" @@ -500,6 +504,29 @@ libquadmath() { mv "$pkgdir"/usr/lib/libquadmath.so.* "$subpkgdir"/usr/lib/ } +libsanitizer() { + pkgdesc="Runtime code linting libraries for GCC" + depends= + + # https://github.com/google/sanitizers/issues/794 + # https://reviews.llvm.org/D28609 ("ported to GCC") + case $CTARGET_ARCH in + pmmx|x86|i528|armel|armhf|armv7|m68k|mips32|mips32el|ppc) + sanitizer_extras="";; + *) + sanitizer_extras="lsan tsan";; + esac + + mkdir -p "$subpkgdir"/usr/lib + for san in asan sanitizer ubsan ${sanitizer_extras}; do + mv "$pkgdir"/usr/lib/lib${san}* "$subpkgdir"/usr/lib/ + done + + mkdir -p "$subpkgdir"/$_gcclibdir/include + mv "$pkgdir"/$_gcclibdir/include/sanitizer \ + "$subpkgdir"/$_gcclibdir/include/ +} + gfortran() { pkgdesc="GNU Fortran Compiler" depends="gcc=$_gccrel libgfortran=$_gccrel" @@ -576,8 +603,9 @@ dc03c7b660f0142aa16e78e4e50581c883f6632f4794131f1131e0dc8fd500ba5d6a0046a36dc621 5ead34140ff01e2918554c9c3f8378fe02cdf41f5b965053c126238dc157a1e2558d58465395b750e85b1d7167c4fc79d8a7f34894146507d7366d79a69d4ee7 336-gccgo-mmap64.patch 3cbe5e879902a73121b22d903be605c7100e607864b0e305d6825a4083502fbe94be9a4166fb833b28e5d18cd7548f317719e28e3579194ea3e1b626450c943b 341-gccgo-libucontext-stack.patch 76d141a9e245595eab66cc4ddbfda57330790e04960de5d1c4e1e97efb52291d18087840f7494c0310afc3f093e1fad8c6070928f489c97201f32782f67559fd 342-gccgo-reflect-underscore.patch +fa59b0fb081d97f8f63506b8793699588a95c602b5d468140eb1e80456597e52e1cc45dc0b234ac8e60e2b0cd606d94d111c8b0ae64c0a2be1bc1b8a184ceb93 libgo-musl-1.2.3.patch 1860593584f629d24d5b6db14b0a3412e9f93449b663aaa4981301a0923db0159314905e694f27366fbfef72dce06636ab6df86862b7e9e9564847e03bee82c1 add-classic_table-support.patch a09b3181002798d1b17b8374eba6bec18e67d4d4f30677311c330b599e231e97cf02c1b9b79c0829952f5027016e01146743b665b19558ed2693c60a567823fb gcc-5.4.0-locale.patch -fa59b0fb081d97f8f63506b8793699588a95c602b5d468140eb1e80456597e52e1cc45dc0b234ac8e60e2b0cd606d94d111c8b0ae64c0a2be1bc1b8a184ceb93 libgo-musl-1.2.3.patch +dba5fdaf253a44f4239151cff8bcfc676264f2fac535d05f82ac7d7e965e272b724067a364521da1eeca3cff1d499f6e1eafa483ff3b3c2ede9fcd90be368e36 sanitation.patch ff6159633f04d26eadc79895dc24ccb46671a04fdc728cbbac86964a14ce17e2e51cd7668947dfe06b9168bb9b8575a80955012e5f51295ea02f4f3169e07541 match-split.patch ee626cbe4bdda5b868980c86ca066d33167d06517db676e43d0719c4ad7d11e99b3a0151927f15c93ab89f6c76dd12bd48d402d25771fa3fd175273248824eda insn-split.patch" diff --git a/system/gcc/sanitation.patch b/system/gcc/sanitation.patch new file mode 100644 index 000000000..7dcdb0b65 --- /dev/null +++ b/system/gcc/sanitation.patch @@ -0,0 +1,141 @@ +--- gcc-13.3.0/libsanitizer/sanitizer_common/sanitizer_linux.cpp.old 2024-05-21 07:47:42.000000000 +0000 ++++ gcc-13.3.0/libsanitizer/sanitizer_common/sanitizer_linux.cpp 2024-06-20 23:28:49.290053800 +0000 +@@ -82,6 +82,10 @@ + # include + #endif + ++#if SANITIZER_LINUX && defined(__powerpc__) ++# include ++#endif ++ + #if SANITIZER_FREEBSD + #include + #include +@@ -277,7 +281,7 @@ + return res; + } + +-#if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC) && SANITIZER_LINUX ++#if (!SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_SPARC) && SANITIZER_LINUX && defined(__glibc__) + static void stat64_to_stat(struct stat64 *in, struct stat *out) { + internal_memset(out, 0, sizeof(*out)); + out->st_dev = in->st_dev; +@@ -384,11 +388,8 @@ + return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, + 0); + # else +- struct stat64 buf64; +- int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, +- (uptr)&buf64, 0); +- stat64_to_stat(&buf64, (struct stat *)buf); +- return res; ++ return internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, (uptr)buf, ++ 0); + # endif + # else + struct stat64 buf64; +@@ -416,11 +417,8 @@ + return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, + AT_SYMLINK_NOFOLLOW); + # else +- struct stat64 buf64; +- int res = internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, +- (uptr)&buf64, AT_SYMLINK_NOFOLLOW); +- stat64_to_stat(&buf64, (struct stat *)buf); +- return res; ++ return internal_syscall(SYSCALL(fstatat64), AT_FDCWD, (uptr)path, (uptr)buf, ++ AT_SYMLINK_NOFOLLOW); + # endif + # else + struct stat64 buf64; +@@ -448,10 +446,7 @@ + return internal_syscall(SYSCALL(fstat), fd, (uptr)buf); + # endif + #else +- struct stat64 buf64; +- int res = internal_syscall(SYSCALL(fstat64), fd, &buf64); +- stat64_to_stat(&buf64, (struct stat *)buf); +- return res; ++ return internal_syscall(SYSCALL(fstat64), fd, (uptr)buf); + #endif + } + +@@ -871,7 +866,9 @@ + #endif + + #if SANITIZER_LINUX +-#define SA_RESTORER 0x04000000 ++# ifndef SA_RESTORER ++# define SA_RESTORER 0x04000000 ++# endif + // Doesn't set sa_restorer if the caller did not set it, so use with caution + //(see below). + int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { +@@ -2173,11 +2170,11 @@ + *bp = ucontext->uc_mcontext.mc_frame[31]; + # else + ucontext_t *ucontext = (ucontext_t*)context; +- *pc = ucontext->uc_mcontext.regs->nip; +- *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; ++ *pc = ucontext->uc_mcontext.gregs[PT_NIP]; ++ *sp = ucontext->uc_mcontext.gregs[PT_R1]; + // The powerpc{,64}-linux ABIs do not specify r31 as the frame + // pointer, but GCC always uses r31 when we need a frame pointer. +- *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; ++ *bp = ucontext->uc_mcontext.gregs[PT_R31]; + # endif + #elif defined(__sparc__) + #if defined(__arch64__) || defined(__sparcv9) +--- gcc-13.3.0/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp.old 2024-06-20 14:03:27.437916098 -0500 ++++ gcc-13.3.0/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp 2024-07-09 03:28:44.101087267 -0500 +@@ -51,7 +51,7 @@ + #include + #include + #include +-#if !SANITIZER_APPLE ++#if HAVE_UTMP_H + #include + #endif + +@@ -62,7 +62,6 @@ + #if !SANITIZER_ANDROID + #include + #include +-#include + #endif + + #if SANITIZER_LINUX +@@ -94,7 +93,7 @@ + # include + # include + # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ +- defined(__hexagon__) || SANITIZER_RISCV64 ++ defined(__hexagon__) || defined(__powerpc__) || SANITIZER_RISCV64 + # include + # ifdef __arm__ + typedef struct user_fpregs elf_fpregset_t; +@@ -313,11 +312,11 @@ + int shmctl_shm_stat = (int)SHM_STAT; + #endif + +-#if !SANITIZER_APPLE && !SANITIZER_FREEBSD ++#if HAVE_UTMP_H + unsigned struct_utmp_sz = sizeof(struct utmp); + #endif + #if !SANITIZER_ANDROID +- unsigned struct_utmpx_sz = sizeof(struct utmpx); ++ unsigned struct_utmpx_sz = 400; + #endif + + int map_fixed = MAP_FIXED; +--- gcc-13.3.0/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp.old 2024-05-21 02:47:42.000000000 -0500 ++++ gcc-13.3.0/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp 2024-06-20 16:23:27.115377319 -0500 +@@ -31,7 +31,7 @@ + #include // for pid_t + #include // for iovec + #include // for NT_PRSTATUS +-#if (defined(__aarch64__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID ++#if (defined(__aarch64__) || defined(__powerpc__) || SANITIZER_RISCV64) && !SANITIZER_ANDROID + // GLIBC 2.20+ sys/user does not include asm/ptrace.h + # include + #endif -- cgit v1.2.3-70-g09d2