From c123e0f14ab73976a36c651d47d134f249413f29 Mon Sep 17 00:00:00 2001 From: Geod24 Date: Sat, 4 Jan 2020 01:08:28 +0900 Subject: main/gcc: Fix D language support on non-x86_64 While some basic functions were working, some C definitions in Druntime were wrong, which led to wrong compilation when trying to bootstrap other packages on x86, ARM and AArch64. Additionally, s390x didn't seem to pick the dependency on the C runtime, and needed an extra dependency on libucontext-dev (not to mention a few fixes to C definitions, like other archs). Finally, 404-dlang-zlib.patch contains a fix that was done in 2.077.0, but is needed for another Alpine package to work on all platforms. While not required to fix platform support, it fixes #11125. --- main/gcc/402-dlang-stat.patch | 448 ++++++++++++++++++++++++++++++++++++++++++ main/gcc/403-dlang-ibmz.patch | 137 +++++++++++++ main/gcc/404-dlang-zlib.patch | 411 ++++++++++++++++++++++++++++++++++++++ main/gcc/APKBUILD | 14 +- 4 files changed, 1007 insertions(+), 3 deletions(-) create mode 100644 main/gcc/402-dlang-stat.patch create mode 100644 main/gcc/403-dlang-ibmz.patch create mode 100644 main/gcc/404-dlang-zlib.patch (limited to 'main') diff --git a/main/gcc/402-dlang-stat.patch b/main/gcc/402-dlang-stat.patch new file mode 100644 index 00000000000..faf4ed731f8 --- /dev/null +++ b/main/gcc/402-dlang-stat.patch @@ -0,0 +1,448 @@ +diff -Nurp a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d +--- a/libphobos/libdruntime/core/sys/posix/fcntl.d 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/libdruntime/core/sys/posix/fcntl.d 2020-01-01 00:00:00.000000000 +0900 +@@ -779,7 +779,102 @@ else version (CRuntime_Bionic) + } + else version (CRuntime_Musl) + { +- enum { ++ version (X86_64) ++ { ++ enum ++ { ++ O_DIRECTORY = 0x010000, // octal 0200000 ++ O_NOFOLLOW = 0x020000, // octal 0400000 ++ O_DIRECT = 0x004000, // octal 040000 ++ O_LARGEFILE = 0, ++ O_TMPFILE = 0x410000, // octal 020200000 ++ ++ F_GETLK = 5, ++ F_SETLK = 6, ++ F_SETLKW = 7, ++ } ++ } ++ // Note: Definitions for i386 are in arch/generic/bits/fcntl.h ++ else version (X86) ++ { ++ enum ++ { ++ O_DIRECTORY = 0x010000, // octal 0200000 ++ O_NOFOLLOW = 0x020000, // octal 0400000 ++ O_DIRECT = 0x004000, // octal 040000 ++ O_LARGEFILE = 0x008000, // octal 0100000 ++ O_TMPFILE = 0x410000, // octal 020200000 ++ ++ F_GETLK = 12, ++ F_SETLK = 13, ++ F_SETLKW = 14, ++ } ++ } ++ else version (ARM) ++ { ++ enum ++ { ++ O_DIRECTORY = 0x004000, // octal 040000 ++ O_NOFOLLOW = 0x008000, // octal 0100000 ++ O_DIRECT = 0x010000, // octal 0200000 ++ O_LARGEFILE = 0x020000, // octal 0400000 ++ O_TMPFILE = 0x404000, // octal 020040000 ++ ++ F_GETLK = 12, ++ F_SETLK = 13, ++ F_SETLKW = 14, ++ } ++ } ++ else version (AArch64) ++ { ++ enum ++ { ++ O_DIRECTORY = 0x004000, // octal 040000 ++ O_NOFOLLOW = 0x008000, // octal 0100000 ++ O_DIRECT = 0x010000, // octal 0200000 ++ O_LARGEFILE = 0x020000, // octal 0400000 ++ O_TMPFILE = 0x404000, // octal 020040000 ++ ++ F_GETLK = 5, ++ F_SETLK = 6, ++ F_SETLKW = 7, ++ } ++ } ++ else version (SystemZ) ++ { ++ enum ++ { ++ O_DIRECTORY = 0x010000, // octal 0200000 ++ O_NOFOLLOW = 0x020000, // octal 0400000 ++ O_DIRECT = 0x004000, // octal 040000 ++ O_LARGEFILE = 0x008000, // octal 0100000 ++ O_TMPFILE = 0x410000, // octal 020200000 ++ ++ F_GETLK = 5, ++ F_SETLK = 6, ++ F_SETLKW = 7, ++ } ++ } ++ else version (PPC64) ++ { ++ enum ++ { ++ O_DIRECTORY = 0x004000, // octal 040000 ++ O_NOFOLLOW = 0x008000, // octal 0100000 ++ O_DIRECT = 0x020000, // octal 0400000 ++ O_LARGEFILE = 0x010000, // octal 0200000 ++ O_TMPFILE = 0x410000, // octal 020200000 ++ ++ F_GETLK = 5, ++ F_SETLK = 6, ++ F_SETLKW = 7, ++ } ++ } ++ else ++ static assert(0, "Platform not supported"); ++ ++ enum ++ { + O_CREAT = 0x40, // octal 0100 + O_EXCL = 0x80, // octal 0200 + O_NOCTTY = 0x100, // octal 0400 +@@ -790,16 +885,11 @@ else version (CRuntime_Musl) + O_DSYNC = 0x1000, // octal 010000 + O_SYNC = 0x101000, // octal 04010000 + O_RSYNC = O_SYNC, +- O_DIRECTORY = 0x10000, +- O_NOFOLLOW = 0x20000, + O_CLOEXEC = 0x80000, + + O_ASYNC = 0x2000, +- O_DIRECT = 0x4000, +- O_LARGEFILE = 0, + O_NOATIME = 0x40000, + O_PATH = 0x200000, +- O_TMPFILE = 0x410000, + O_NDELAY = O_NONBLOCK, + O_SEARCH = O_PATH, + O_EXEC = O_PATH, +@@ -809,19 +899,19 @@ else version (CRuntime_Musl) + O_WRONLY = 01, + O_RDWR = 02, + } +- enum { ++ enum ++ { + F_DUPFD = 0, + F_GETFD = 1, + F_SETFD = 2, + F_GETFL = 3, + F_SETFL = 4, +- F_GETLK = 5, +- F_SETLK = 6, +- F_SETLKW = 7, ++ // F_GETLK, F_SETLK, F_SETLKW are arch-specific + F_SETOWN = 8, + F_GETOWN = 9, + } +- enum { ++ enum ++ { + F_RDLCK = 0, + F_WRLCK = 1, + F_UNLCK = 2, +diff -Nurp a/libphobos/libdruntime/core/sys/posix/semaphore.d b/libphobos/libdruntime/core/sys/posix/semaphore.d +--- a/libphobos/libdruntime/core/sys/posix/semaphore.d 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/libdruntime/core/sys/posix/semaphore.d 2020-01-01 00:00:00.000000000 +0900 +@@ -143,8 +143,10 @@ else version (CRuntime_Bionic) + else version (CRuntime_Musl) + { + struct sem_t { +- int[4*long.sizeof/int.sizeof] __val; ++ int[4*c_long.sizeof/int.sizeof] __val; + } ++ ++ enum SEM_FAILED = (sem_t*).init; + } + else version (CRuntime_UClibc) + { +diff -Nurp a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d +--- a/libphobos/libdruntime/core/sys/posix/sys/stat.d 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d 2020-01-01 00:00:00.000000000 +0900 +@@ -1587,31 +1587,225 @@ else version (CRuntime_Musl) + S_ISGID = 0x400, // octal 02000 + S_ISVTX = 0x200, // octal 01000 + } +- struct stat_t { +- dev_t st_dev; +- ino_t st_ino; +- nlink_t st_nlink; +- +- mode_t st_mode; +- uid_t st_uid; +- gid_t st_gid; +- uint __pad0; +- dev_t st_rdev; +- off_t st_size; +- blksize_t st_blksize; +- blkcnt_t st_blocks; +- +- timespec st_atim; +- timespec st_mtim; +- timespec st_ctim; +- extern(D) @safe @property inout pure nothrow +- { +- ref inout(time_t) st_atime() return { return st_atim.tv_sec; } +- ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } +- ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ version (ARM) ++ { ++ struct stat_t ++ { ++ dev_t st_dev; ++ int __st_dev_padding; ++ c_long __st_ino_truncated; ++ mode_t st_mode; ++ nlink_t st_nlink; ++ ++ uid_t st_uid; ++ gid_t st_gid; ++ dev_t st_rdev; ++ int __st_rdev_padding; ++ off_t st_size; ++ blksize_t st_blksize; ++ blkcnt_t st_blocks; ++ ++ timespec st_atim; ++ timespec st_mtim; ++ timespec st_ctim; ++ ino_t st_ino; ++ ++ extern(D) @safe @property inout pure nothrow ++ { ++ ref inout(time_t) st_atime() return { return st_atim.tv_sec; } ++ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ++ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ } ++ } ++ } ++ else version (AArch64) ++ { ++ struct stat_t ++ { ++ dev_t st_dev; ++ ino_t st_ino; ++ mode_t st_mode; ++ nlink_t st_nlink; ++ ++ uid_t st_uid; ++ gid_t st_gid; ++ dev_t st_rdev; ++ c_ulong __pad; ++ off_t st_size; ++ blksize_t st_blksize; ++ int __pad2; ++ blkcnt_t st_blocks; ++ ++ timespec st_atim; ++ timespec st_mtim; ++ timespec st_ctim; ++ uint[2] __unused; ++ ++ extern(D) @safe @property inout pure nothrow ++ { ++ ref inout(time_t) st_atime() return { return st_atim.tv_sec; } ++ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ++ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ } ++ } ++ } ++ else version (X86_64) ++ { ++ struct stat_t ++ { ++ dev_t st_dev; ++ ino_t st_ino; ++ nlink_t st_nlink; ++ ++ mode_t st_mode; ++ uid_t st_uid; ++ gid_t st_gid; ++ uint __pad0; ++ dev_t st_rdev; ++ off_t st_size; ++ blksize_t st_blksize; ++ blkcnt_t st_blocks; ++ ++ timespec st_atim; ++ timespec st_mtim; ++ timespec st_ctim; ++ ++ c_long[3] __unused; ++ ++ extern(D) @safe @property inout pure nothrow ++ { ++ ref inout(time_t) st_atime() return { return st_atim.tv_sec; } ++ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ++ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ } ++ } ++ } ++ else version (X86) ++ { ++ struct stat_t ++ { ++ dev_t st_dev; ++ int __st_dev_padding; ++ c_long __st_ino_truncated; ++ mode_t st_mode; ++ nlink_t st_nlink; ++ ++ uid_t st_uid; ++ gid_t st_gid; ++ dev_t st_rdev; ++ int __st_rdev_padding; ++ off_t st_size; ++ blksize_t st_blksize; ++ blkcnt_t st_blocks; ++ ++ timespec st_atim; ++ timespec st_mtim; ++ timespec st_ctim; ++ ino_t st_ino; ++ ++ extern(D) @safe @property inout pure nothrow ++ { ++ ref inout(time_t) st_atime() return { return st_atim.tv_sec; } ++ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ++ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ } + } +- long[3] __unused; + } ++ else version (MIPS64) ++ { ++ struct stat_t ++ { ++ dev_t st_dev; ++ int[3] __pad1; ++ ino_t st_ino; ++ mode_t st_mode; ++ nlink_t st_nlink; ++ ++ uid_t st_uid; ++ gid_t st_gid; ++ dev_t st_rdev; ++ uint[2] __pad2; ++ off_t st_size; ++ int __pad3; ++ ++ timespec st_atim; ++ timespec st_mtim; ++ timespec st_ctim; ++ blksize_t st_blksize; ++ uint __pad4; ++ blkcnt_t st_blocks; ++ int[14] __pad5; ++ ++ extern(D) @safe @property inout pure nothrow ++ { ++ ref inout(time_t) st_atime() return { return st_atim.tv_sec; } ++ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ++ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ } ++ } ++ } ++ else version (PPC64) ++ { ++ struct stat_t ++ { ++ dev_t st_dev; ++ ino_t st_ino; ++ nlink_t st_nlink; ++ mode_t st_mode; ++ ++ uid_t st_uid; ++ gid_t st_gid; ++ dev_t st_rdev; ++ off_t st_size; ++ blksize_t st_blksize; ++ blkcnt_t st_blocks; ++ ++ timespec st_atim; ++ timespec st_mtim; ++ timespec st_ctim; ++ c_ulong[3] __unused; ++ ++ extern(D) @safe @property inout pure nothrow ++ { ++ ref inout(time_t) st_atime() return { return st_atim.tv_sec; } ++ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ++ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ } ++ } ++ } ++ else version (SystemZ) ++ { ++ struct stat_t ++ { ++ dev_t st_dev; ++ ino_t st_ino; ++ nlink_t st_nlink; ++ mode_t st_mode; ++ ++ uid_t st_uid; ++ gid_t st_gid; ++ dev_t st_rdev; ++ off_t st_size; ++ ++ timespec st_atim; ++ timespec st_mtim; ++ timespec st_ctim; ++ ++ blksize_t st_blksize; ++ blkcnt_t st_blocks; ++ c_ulong[3] __unused; ++ ++ extern(D) @safe @property inout pure nothrow ++ { ++ ref inout(time_t) st_atime() return { return st_atim.tv_sec; } ++ ref inout(time_t) st_mtime() return { return st_mtim.tv_sec; } ++ ref inout(time_t) st_ctime() return { return st_ctim.tv_sec; } ++ } ++ } ++ } ++ else ++ static assert("Unsupported platform"); ++ + private + { + extern (D) bool S_ISTYPE( mode_t mode, uint mask ) +diff -Nurp a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d +--- a/libphobos/libdruntime/core/sys/posix/sys/types.d 2020-01-08 00:00:00.000000000 +0900 ++++ b/libphobos/libdruntime/core/sys/posix/sys/types.d 2020-01-08 00:00:00.000000000 +0900 +@@ -112,8 +112,26 @@ version (CRuntime_Glibc) + } + else version (CRuntime_Musl) + { +- alias c_long blksize_t; +- alias c_ulong nlink_t; ++ version (AArch64) ++ { ++ alias int blksize_t; ++ alias uint nlink_t; ++ } ++ else version (MIPS64) ++ { ++ alias c_long blksize_t; ++ alias uint nlink_t; ++ } ++ else version (RISCV64) ++ { ++ alias int blksize_t; ++ alias uint nlink_t; ++ } ++ else ++ { ++ alias c_long blksize_t; ++ alias c_ulong nlink_t; ++ } + alias long dev_t; + alias long blkcnt_t; + alias ulong ino_t; diff --git a/main/gcc/403-dlang-ibmz.patch b/main/gcc/403-dlang-ibmz.patch new file mode 100644 index 00000000000..f6f9a2ce0ca --- /dev/null +++ b/main/gcc/403-dlang-ibmz.patch @@ -0,0 +1,137 @@ +diff -Nurp a/libphobos/libdruntime/gcc/sections/elf_shared.d b/libphobos/libdruntime/gcc/sections/elf_shared.d +--- a/libphobos/libdruntime/gcc/sections/elf_shared.d 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/libdruntime/gcc/sections/elf_shared.d 2020-01-01 00:00:00.000000000 +0900 +@@ -1084,7 +1084,9 @@ void[] getTLSRange(size_t mod, size_t sz) nothrow @nogc + + // base offset + auto ti = tls_index(mod, 0); +- version (IBMZ_Any) ++ version (CRuntime_Musl) ++ return (__tls_get_addr(&ti)-TLS_DTV_OFFSET)[0 .. sz]; ++ else version (IBMZ_Any) + { + auto idx = cast(void *)__tls_get_addr_internal(&ti) + + cast(ulong)__builtin_thread_pointer(); +diff -Nurp a/libphobos/configure.ac b/libphobos/configure.ac +--- a/libphobos/configure.ac 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/configure.ac 2020-01-01 00:00:00.000000000 +0900 +@@ -140,6 +140,14 @@ case ${host} in + esac + AC_MSG_RESULT($LIBPHOBOS_SUPPORTED) + ++AC_MSG_CHECKING([if target needs to link in swapcontext]) ++AC_MSG_RESULT($LIBDRUNTIME_NEEDS_UCONTEXT) ++AS_IF([test "x$LIBDRUNTIME_NEEDS_UCONTEXT" = xyes], [ ++ AC_SEARCH_LIBS([swapcontext], [c ucontext], [], [ ++ AC_MSG_ERROR([[can't find library providing swapcontext]]) ++ ]) ++]) ++ + # Decide if it's usable. + case $LIBPHOBOS_SUPPORTED:$enable_libphobos in + *:no) use_libphobos=no ;; +diff -Nurp a/libphobos/configure.tgt b/libphobos/configure.tgt +--- a/libphobos/configure.tgt 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/configure.tgt 2020-01-01 00:00:00.000000000 +0900 +@@ -22,6 +22,13 @@ + # Disable the libphobos or libdruntime components on untested or known + # broken systems. More targets shall be added after testing. + LIBPHOBOS_SUPPORTED=no ++ ++# Check if we require 'ucontext' or if we have a custom solution. ++# Most platform uses a custom assembly solution for context switches, ++# see `core.thread` and grep for `AsmExternal`. ++# Definitions are in config/ARCH/ ++LIBPHOBOS_NEEDS_UCONTEXT=no ++ + case "${target}" in + aarch64*-*-linux*) + LIBPHOBOS_SUPPORTED=yes +@@ -37,6 +44,7 @@ case "${target}" in + ;; + s390*-linux*) + LIBPHOBOS_SUPPORTED=yes ++ LIBDRUNTIME_NEEDS_UCONTEXT=yes + ;; + x86_64-*-kfreebsd*-gnu | i?86-*-kfreebsd*-gnu) + LIBPHOBOS_SUPPORTED=yes +diff -Nurp a/libphobos/configure b/libphobos/configure +--- a/libphobos/configure 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/configure 2020-01-01 00:00:00.000000000 +0900 +@@ -13955,6 +13955,76 @@ esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBPHOBOS_SUPPORTED" >&5 + $as_echo "$LIBPHOBOS_SUPPORTED" >&6; } + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if target needs to link in swapcontext" >&5 ++$as_echo_n "checking if target needs to link in swapcontext... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBDRUNTIME_NEEDS_UCONTEXT" >&5 ++$as_echo "$LIBDRUNTIME_NEEDS_UCONTEXT" >&6; } ++if test "x$LIBDRUNTIME_NEEDS_UCONTEXT" = xyes; then : ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing swapcontext" >&5 ++$as_echo_n "checking for library containing swapcontext... " >&6; } ++if ${ac_cv_search_swapcontext+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_func_search_save_LIBS=$LIBS ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char swapcontext (); ++int ++main () ++{ ++return swapcontext (); ++ ; ++ return 0; ++} ++_ACEOF ++for ac_lib in '' c ucontext; do ++ if test -z "$ac_lib"; then ++ ac_res="none required" ++ else ++ ac_res=-l$ac_lib ++ LIBS="-l$ac_lib $ac_func_search_save_LIBS" ++ fi ++ if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_search_swapcontext=$ac_res ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext ++ if ${ac_cv_search_swapcontext+:} false; then : ++ break ++fi ++done ++if ${ac_cv_search_swapcontext+:} false; then : ++ ++else ++ ac_cv_search_swapcontext=no ++fi ++rm conftest.$ac_ext ++LIBS=$ac_func_search_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_swapcontext" >&5 ++$as_echo "$ac_cv_search_swapcontext" >&6; } ++ac_res=$ac_cv_search_swapcontext ++if test "$ac_res" != no; then : ++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ++ ++else ++ ++ as_fn_error $? "can't find library providing swapcontext" "$LINENO" 5 ++ ++fi ++ ++ ++fi ++ ++ + # Decide if it's usable. + case $LIBPHOBOS_SUPPORTED:$enable_libphobos in + *:no) use_libphobos=no ;; diff --git a/main/gcc/404-dlang-zlib.patch b/main/gcc/404-dlang-zlib.patch new file mode 100644 index 00000000000..4c453258dc7 --- /dev/null +++ b/main/gcc/404-dlang-zlib.patch @@ -0,0 +1,411 @@ +diff -Nurp a/libphobos/src/std/zlib.d b/libphobos/src/std/zlib.d +--- a/libphobos/src/std/zlib.d 2020-01-01 00:00:00.000000000 +0900 ++++ b/libphobos/src/std/zlib.d 2020-01-01 00:00:00.000000000 +0900 +@@ -1,7 +1,7 @@ + // Written in the D programming language. + + /** +- * Compress/decompress data using the $(HTTP www._zlib.net, _zlib library). ++ * Compress/decompress data using the $(HTTP www.zlib.net, zlib library). + * + * Examples: + * +@@ -43,12 +43,12 @@ + * References: + * $(HTTP en.wikipedia.org/wiki/Zlib, Wikipedia) + * +- * Copyright: Copyright Digital Mars 2000 - 2011. ++ * Copyright: Copyright The D Language Foundation 2000 - 2011. + * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). + * Authors: $(HTTP digitalmars.com, Walter Bright) +- * Source: $(PHOBOSSRC std/_zlib.d) ++ * Source: $(PHOBOSSRC std/zlib.d) + */ +-/* Copyright Digital Mars 2000 - 2011. ++/* Copyright The D Language Foundation 2000 - 2011. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) +@@ -75,9 +75,9 @@ enum + + class ZlibException : Exception + { +- this(int errnum) +- { string msg; +- ++ private static string getmsg(int errnum) nothrow @nogc pure @safe ++ { ++ string msg; + switch (errnum) + { + case Z_STREAM_END: msg = "stream end"; break; +@@ -90,7 +90,12 @@ class ZlibException : Exception + case Z_VERSION_ERROR: msg = "version error"; break; + default: msg = "unknown error"; break; + } +- super(msg); ++ return msg; ++ } ++ ++ this(int errnum) ++ { ++ super(getmsg(errnum)); + } + } + +@@ -104,7 +109,7 @@ class ZlibException : Exception + * buf = buffer containing input data + * + * Returns: +- * A $(D uint) checksum for the provided input data and starting checksum ++ * A `uint` checksum for the provided input data and starting checksum + * + * See_Also: + * $(LINK http://en.wikipedia.org/wiki/Adler-32) +@@ -147,7 +152,7 @@ uint adler32(uint adler, const(void)[] b + * buf = buffer containing input data + * + * Returns: +- * A $(D uint) checksum for the provided input data and starting checksum ++ * A `uint` checksum for the provided input data and starting checksum + * + * See_Also: + * $(LINK http://en.wikipedia.org/wiki/Cyclic_redundancy_check) +@@ -191,13 +196,14 @@ uint crc32(uint crc, const(void)[] buf) + ubyte[] compress(const(void)[] srcbuf, int level) + in + { +- assert(-1 <= level && level <= 9); ++ assert(-1 <= level && level <= 9, "Compression level needs to be within [-1, 9]."); + } +-body ++do + { + import core.memory : GC; ++ import std.array : uninitializedArray; + auto destlen = srcbuf.length + ((srcbuf.length + 1023) / 1024) + 12; +- auto destbuf = new ubyte[destlen]; ++ auto destbuf = uninitializedArray!(ubyte[])(destlen); + auto err = etc.c.zlib.compress2(destbuf.ptr, &destlen, cast(ubyte *) srcbuf.ptr, srcbuf.length, level); + if (err) + { +@@ -276,7 +282,7 @@ void[] uncompress(const(void)[] srcbuf, + throw new ZlibException(err); + } + } +- assert(0); ++ assert(0, "Unreachable code"); + } + + @system unittest +@@ -370,9 +376,9 @@ class Compress + this(int level, HeaderFormat header = HeaderFormat.deflate) + in + { +- assert(1 <= level && level <= 9); ++ assert(1 <= level && level <= 9, "Legal compression level are in [1, 9]."); + } +- body ++ do + { + this.level = level; + this.gzip = header == HeaderFormat.gzip; +@@ -406,6 +412,7 @@ class Compress + const(void)[] compress(const(void)[] buf) + { + import core.memory : GC; ++ import std.array : uninitializedArray; + int err; + ubyte[] destbuf; + +@@ -420,7 +427,7 @@ class Compress + inited = 1; + } + +- destbuf = new ubyte[zs.avail_in + buf.length]; ++ destbuf = uninitializedArray!(ubyte[])(zs.avail_in + buf.length); + zs.next_out = destbuf.ptr; + zs.avail_out = to!uint(destbuf.length); + +@@ -461,9 +468,10 @@ class Compress + void[] flush(int mode = Z_FINISH) + in + { +- assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH); ++ assert(mode == Z_FINISH || mode == Z_SYNC_FLUSH || mode == Z_FULL_FLUSH, ++ "Mode must be either Z_FINISH, Z_SYNC_FLUSH or Z_FULL_FLUSH."); + } +- body ++ do + { + import core.memory : GC; + ubyte[] destbuf; +@@ -523,6 +531,7 @@ class UnCompress + z_stream zs; + int inited; + int done; ++ bool inputEnded; + size_t destbufsize; + + HeaderFormat format; +@@ -571,16 +580,16 @@ class UnCompress + const(void)[] uncompress(const(void)[] buf) + in + { +- assert(!done); ++ assert(!done, "Buffer has been flushed."); + } +- body ++ do + { ++ if (inputEnded || !buf.length) ++ return null; ++ + import core.memory : GC; ++ import std.array : uninitializedArray; + int err; +- ubyte[] destbuf; +- +- if (buf.length == 0) +- return null; + + if (!inited) + { +@@ -598,26 +607,152 @@ class UnCompress + + if (!destbufsize) + destbufsize = to!uint(buf.length) * 2; +- destbuf = new ubyte[zs.avail_in * 2 + destbufsize]; +- zs.next_out = destbuf.ptr; +- zs.avail_out = to!uint(destbuf.length); +- +- if (zs.avail_in) +- buf = zs.next_in[0 .. zs.avail_in] ~ cast(ubyte[]) buf; ++ auto destbuf = uninitializedArray!(ubyte[])(destbufsize); ++ size_t destFill; + + zs.next_in = cast(ubyte*) buf.ptr; + zs.avail_in = to!uint(buf.length); + +- err = inflate(&zs, Z_NO_FLUSH); +- if (err != Z_STREAM_END && err != Z_OK) ++ while (true) + { +- GC.free(destbuf.ptr); +- error(err); ++ auto oldAvailIn = zs.avail_in; ++ ++ zs.next_out = destbuf[destFill .. $].ptr; ++ zs.avail_out = to!uint(destbuf.length - destFill); ++ ++ err = inflate(&zs, Z_NO_FLUSH); ++ if (err == Z_STREAM_END) ++ { ++ inputEnded = true; ++ break; ++ } ++ else if (err != Z_OK) ++ { ++ GC.free(destbuf.ptr); ++ error(err); ++ } ++ else if (!zs.avail_in) ++ break; ++ ++ /* ++ According to the zlib manual inflate() stops when either there's ++ no more data to uncompress or the output buffer is full ++ So at this point, the output buffer is too full ++ */ ++ ++ destFill = destbuf.length; ++ ++ if (destbuf.capacity) ++ { ++ if (destbuf.length < destbuf.capacity) ++ destbuf.length = destbuf.capacity; ++ else ++ { ++ auto newLength = GC.extend(destbuf.ptr, destbufsize, destbufsize); ++ ++ if (newLength && destbuf.length < destbuf.capacity) ++ destbuf.length = destbuf.capacity; ++ else ++ destbuf.length += destbufsize; ++ } ++ } ++ else ++ destbuf.length += destbufsize; + } ++ + destbuf.length = destbuf.length - zs.avail_out; + return destbuf; + } + ++ // Test for issues 3191 and 9505 ++ @system unittest ++ { ++ import std.algorithm.comparison; ++ import std.array; ++ import std.file; ++ import std.zlib; ++ ++ // Data that can be easily compressed ++ ubyte[1024] originalData; ++ ++ // This should yield a compression ratio of at least 1/2 ++ auto compressedData = compress(originalData, 9); ++ assert(compressedData.length < originalData.length / 2, ++ "The compression ratio is too low to accurately test this situation"); ++ ++ auto chunkSize = compressedData.length / 4; ++ assert(chunkSize < compressedData.length, ++ "The length of the compressed data is too small to accurately test this situation"); ++ ++ auto decompressor = new UnCompress(); ++ ubyte[originalData.length] uncompressedData; ++ ubyte[] reusedBuf; ++ int progress; ++ ++ reusedBuf.length = chunkSize; ++ ++ for (int i = 0; i < compressedData.length; i += chunkSize) ++ { ++ auto len = min(chunkSize, compressedData.length - i); ++ // simulate reading from a stream in small chunks ++ reusedBuf[0 .. len] = compressedData[i .. i + len]; ++ ++ // decompress using same input buffer ++ auto chunk = decompressor.uncompress(reusedBuf); ++ assert(progress + chunk.length <= originalData.length, ++ "The uncompressed result is bigger than the original data"); ++ ++ uncompressedData[progress .. progress + chunk.length] = cast(const ubyte[]) chunk[]; ++ progress += chunk.length; ++ } ++ ++ auto chunk = decompressor.flush(); ++ assert(progress + chunk.length <= originalData.length, ++ "The uncompressed result is bigger than the original data"); ++ ++ uncompressedData[progress .. progress + chunk.length] = cast(const ubyte[]) chunk[]; ++ progress += chunk.length; ++ ++ assert(progress == originalData.length, ++ "The uncompressed and the original data sizes differ"); ++ assert(originalData[] == uncompressedData[], ++ "The uncompressed and the original data differ"); ++ } ++ ++ @system unittest ++ { ++ ubyte[1024] invalidData; ++ auto decompressor = new UnCompress(); ++ ++ try ++ { ++ auto uncompressedData = decompressor.uncompress(invalidData); ++ } ++ catch (ZlibException e) ++ { ++ assert(e.msg == "data error"); ++ return; ++ } ++ ++ assert(false, "Corrupted data didn't result in an error"); ++ } ++ ++ @system unittest ++ { ++ ubyte[2014] originalData = void; ++ auto compressedData = compress(originalData, 9); ++ ++ auto decompressor = new UnCompress(); ++ auto uncompressedData = decompressor.uncompress(compressedData ~ cast(ubyte[]) "whatever"); ++ ++ assert(originalData.length == uncompressedData.length, ++ "The uncompressed and the original data sizes differ"); ++ assert(originalData[] == uncompressedData[], ++ "The uncompressed and the original data differ"); ++ assert(!decompressor.uncompress("whatever").length, ++ "Compression continued after the end"); ++ } ++ + /** + * Decompress and return any remaining data. + * The returned data should be appended to that returned by uncompress(). +@@ -626,48 +761,39 @@ class UnCompress + void[] flush() + in + { +- assert(!done); ++ assert(!done, "Buffer has been flushed before."); + } + out + { +- assert(done); ++ assert(done, "Flushing failed."); + } +- body ++ do + { +- import core.memory : GC; +- ubyte[] extra; +- ubyte[] destbuf; +- int err; +- + done = 1; +- if (!inited) +- return null; ++ return null; ++ } + +- L1: +- destbuf = new ubyte[zs.avail_in * 2 + 100]; +- zs.next_out = destbuf.ptr; +- zs.avail_out = to!uint(destbuf.length); ++ /// Returns true if all input data has been decompressed and no further data ++ /// can be decompressed (inflate() returned Z_STREAM_END) ++ @property bool empty() const ++ { ++ return inputEnded; ++ } + +- err = etc.c.zlib.inflate(&zs, Z_NO_FLUSH); +- if (err == Z_OK && zs.avail_out == 0) +- { +- extra ~= destbuf; +- goto L1; +- } +- if (err != Z_STREAM_END) +- { +- GC.free(destbuf.ptr); +- if (err == Z_OK) +- err = Z_BUF_ERROR; +- error(err); +- } +- destbuf = destbuf.ptr[0 .. zs.next_out - destbuf.ptr]; +- err = etc.c.zlib.inflateEnd(&zs); +- inited = 0; +- if (err) +- error(err); +- if (extra.length) +- destbuf = extra ~ destbuf; +- return destbuf; ++ /// ++ @system unittest ++ { ++ // some random data ++ ubyte[1024] originalData = void; ++ ++ // append garbage data (or don't, this works in both cases) ++ auto compressedData = cast(ubyte[]) compress(originalData) ~ cast(ubyte[]) "whatever"; ++ ++ auto decompressor = new UnCompress(); ++ auto uncompressedData = decompressor.uncompress(compressedData); ++ ++ assert(uncompressedData[] == originalData[], ++ "The uncompressed and the original data differ"); ++ assert(decompressor.empty, "The UnCompressor reports not being done"); + } + } diff --git a/main/gcc/APKBUILD b/main/gcc/APKBUILD index 0fbdd567f07..7b78c281624 100644 --- a/main/gcc/APKBUILD +++ b/main/gcc/APKBUILD @@ -6,7 +6,7 @@ pkgver=9.2.0 [ "$CHOST" != "$CTARGET" ] && _target="-$CTARGET_ARCH" || _target="" pkgname="$pkgname$_target" -pkgrel=4 +pkgrel=5 pkgdesc="The GNU Compiler Collection" url="https://gcc.gnu.org" arch="all" @@ -126,6 +126,7 @@ fi if $LANG_D; then subpackages="$subpackages libgphobos::$CTARGET_ARCH gcc-gdc$_target:gdc" _languages="$_languages,d" + [ "$CTARGET_ARCH" == "s390x" ] && makedepends_build="$makedepends_build libucontext-dev" fi if $LANG_OBJC; then subpackages="$subpackages libobjc::$CTARGET_ARCH gcc-objc$_target:objc" @@ -186,6 +187,9 @@ source="https://gcc.gnu.org/pub/gcc/releases/gcc-${_pkgbase:-$pkgver}/gcc-${_pkg 400-dlang-phobos.patch 401-dlang-32bits.patch + 402-dlang-stat.patch + 403-dlang-ibmz.patch + 404-dlang-zlib.patch " # gcc-4.8-build-args.patch @@ -497,7 +501,8 @@ libgphobos() { gdc() { pkgdesc="GCC-based D language compiler" - depends="gcc=$_gccrel libgphobos=$_gccrel" + depends="gcc=$_gccrel libgphobos=$_gccrel musl-dev" + [ "$CTARGET_ARCH" == "s390x" ] && depends="$depends libucontext-dev" mkdir -p "$subpkgdir"/$_gcclibdir/include/d/ \ "$subpkgdir"/usr/lib \ @@ -631,4 +636,7 @@ f4ef08454e28c8732db69115e4998ec153399e8d229dd27f923dbdcf57b68128a65640d026cc7f45 17e0faeef742d32d57a070d983480367dd28cd28d47a8966ce327afdff3a38ea76803a833c90aff7d3a93aa66dae76c9be47b2408500913b40571af25b85aca7 0016-invalid_tls_model.patch e9fef7677f9541848cd1df0bf3c330f06f1369bdf1d228238b7f1d03d8f2c4be07fd62be503b7bf72b6b1e2d4e404ddd957157b56b8050e3657820ade77491aa gcc10-pr91920.patch 38772c5b0905455a44c43d6ef7e5f140530006e2bde9f5ffd6b569c7cf9633992515f666b486d7a78c30ab8da99b92b2775c90fde47821ae542ef1c49dc405df 400-dlang-phobos.patch -84bdbdfcb972161765b81220ea2e80e83c32f3ab27596b77eb451d8cac4bd6312210df468581c2b0e1363f5e3b31654e369c47ae84c907f3b54a1786d7c17830 401-dlang-32bits.patch" +84bdbdfcb972161765b81220ea2e80e83c32f3ab27596b77eb451d8cac4bd6312210df468581c2b0e1363f5e3b31654e369c47ae84c907f3b54a1786d7c17830 401-dlang-32bits.patch +9d73f21eaa2458d28a144dd0e5478ed52763a4d8bbf62084b607db52bce1e2242f773c853fc34e6aae2d53c4124948139954627064e850e9dabaddaef5cb9d69 402-dlang-stat.patch +fd056014d0c6f627108d7387bfe46b5fb66786a16fa964da55b0442658b1c8e9e903c641a9e3233000ef37691e32ea4fef22029ab5eba217ccbc8bd5941e81ae 403-dlang-ibmz.patch +ddb3ca26b5e55f6d376036c2ed87959770bfb72d1175d0dba332f705edf6817806d53765c838ff670472a16ab175bd1ce88946c19d83f9d5e53ff2b4d3558dfb 404-dlang-zlib.patch" -- cgit v1.2.3