summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamar Christina <tamar@zhox.com>2019-09-08 23:11:19 +0100
committerTamar Christina <tamar@zhox.com>2019-10-20 16:21:10 +0100
commit4b431f334018eaef2cf36de3316025c68c922915 (patch)
tree7f85d5a1a6bc6d39e9a8c51fe33904ff61461a7e
parentc4c9904b324736dc5d190a91418e8d8f564d4104 (diff)
downloadhaskell-4b431f334018eaef2cf36de3316025c68c922915.tar.gz
Windows: Update tarballs to GCC 9.2 and remove MAX_PATH limit.
-rw-r--r--compiler/cbits/genSym.c2
-rw-r--r--configure.ac2
-rw-r--r--docs/users_guide/8.10.1-notes.rst4
-rw-r--r--includes/Rts.h6
-rw-r--r--includes/stg/Types.h9
-rw-r--r--libraries/base/cbits/inputReady.c2
-rwxr-xr-xmk/get-win32-tarballs.sh124
-rw-r--r--mk/win32-tarballs.md5sum63
-rw-r--r--rts/RtsSymbols.c44
-rw-r--r--rts/RtsSymbols.h5
-rw-r--r--rts/linker/PEi386.c10
-rw-r--r--rts/linker/PEi386.h1
-rw-r--r--rts/linker/elf_plt.h4
-rw-r--r--rts/linker/elf_reloc_aarch64.c8
-rw-r--r--rts/linker/elf_reloc_aarch64.h4
-rw-r--r--rts/win32/OSMem.c8
-rw-r--r--rts/win32/OSThreads.c22
-rw-r--r--testsuite/tests/ffi/should_run/T5594_c.c4
-rw-r--r--testsuite/tests/ffi/should_run/ffi002_c.c4
-rw-r--r--testsuite/tests/ffi/should_run/fptr01_c.c5
-rw-r--r--testsuite/tests/ffi/should_run/fptrfail01_c.c5
-rw-r--r--testsuite/tests/rts/linker/linker_error.c2
-rw-r--r--testsuite/tests/rts/linker/linker_unload.c2
-rw-r--r--utils/fs/fs.c299
-rw-r--r--utils/fs/fs.h11
-rw-r--r--utils/ghc-cabal/Main.hs21
26 files changed, 530 insertions, 141 deletions
diff --git a/compiler/cbits/genSym.c b/compiler/cbits/genSym.c
index 769c09358c..ecb318d5a8 100644
--- a/compiler/cbits/genSym.c
+++ b/compiler/cbits/genSym.c
@@ -1,5 +1,5 @@
-#include <assert.h>
#include <Rts.h>
+#include <assert.h>
#include "Unique.h"
static HsInt GenSymCounter = 0;
diff --git a/configure.ac b/configure.ac
index 6fddd04bb0..f1c926903c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -329,7 +329,7 @@ then
if test "$HostArch" = "i386"
then
mingw_arch="i686"
- tarball_dest_dir="mingw-w64/x86"
+ tarball_dest_dir="mingw-w64/i686"
tarball_mingw_dir="mingw32"
else
mingw_arch="x86_64"
diff --git a/docs/users_guide/8.10.1-notes.rst b/docs/users_guide/8.10.1-notes.rst
index 0d7be2e6d8..eb06b02ac8 100644
--- a/docs/users_guide/8.10.1-notes.rst
+++ b/docs/users_guide/8.10.1-notes.rst
@@ -173,6 +173,10 @@ Compiler
implemented correctly, and appears to be largely unused. This flag
will be removed in a later version of GHC.
+- Windows bindist has been updated to GCC 9.2 and binutils 2.32. These binaries have
+ been patched to no longer have have the MAX_PATH limit. Windows users should no longer
+ have any issues with long path names.
+
GHCi
~~~~
diff --git a/includes/Rts.h b/includes/Rts.h
index dd60726c39..256a3e586c 100644
--- a/includes/Rts.h
+++ b/includes/Rts.h
@@ -16,6 +16,12 @@
extern "C" {
#endif
+/* get types from GHC's runtime system */
+#include "ghcconfig.h"
+/* We have to include Types.h before everything else as this defines some
+ macros that will change the behaviour of system headers. */
+#include "stg/Types.h"
+
/* We include windows.h very early, as on Win64 the CONTEXT type has
fields "R8", "R9" and "R10", which goes bad if we've already
#define'd those names for our own purposes (in stg/Regs.h) */
diff --git a/includes/stg/Types.h b/includes/stg/Types.h
index f270686ebc..08ba58c799 100644
--- a/includes/stg/Types.h
+++ b/includes/stg/Types.h
@@ -21,8 +21,15 @@
#pragma once
#if defined(mingw32_HOST_OS)
+# if defined(__USE_MINGW_ANSI_STDIO)
+# if __USE_MINGW_ANSI_STDIO != 1
+# warning "Mismatch between __USE_MINGW_ANSI_STDIO definitions. \
+If using Rts.h make sure it is the first header included."
+# endif
+# else
/* Inform mingw we want the ISO rather than Windows printf format specifiers. */
-#define __USE_MINGW_ANSI_STDIO 1
+# define __USE_MINGW_ANSI_STDIO 1
+#endif
#endif
/* ISO C 99 says:
diff --git a/libraries/base/cbits/inputReady.c b/libraries/base/cbits/inputReady.c
index 8d100e8fbe..7a281d6d90 100644
--- a/libraries/base/cbits/inputReady.c
+++ b/libraries/base/cbits/inputReady.c
@@ -22,10 +22,10 @@
/* select and supporting types is not Posix */
/* #include "PosixSource.h" */
+#include "Rts.h"
#include <limits.h>
#include <stdbool.h>
#include "HsBase.h"
-#include "Rts.h"
#if !defined(_WIN32)
#include <poll.h>
#endif
diff --git a/mk/get-win32-tarballs.sh b/mk/get-win32-tarballs.sh
index fd47232b91..4732ede52d 100755
--- a/mk/get-win32-tarballs.sh
+++ b/mk/get-win32-tarballs.sh
@@ -2,6 +2,7 @@
tarball_dir='ghc-tarballs'
missing_files=0
+pkg_variant="phyx"
# see #12502
if test -z "$FIND"; then FIND="find"; fi
@@ -37,7 +38,7 @@ download_file() {
return
else
echo "Downloading ${description} to ${dest_dir}..."
- $curl_cmd || echo "Checking repo.msys2.org instead of Haskell.org..." && $curl_cmd_bnk || {
+ $curl_cmd || (echo "Checking repo.msys2.org instead of Haskell.org..." && $curl_cmd_bnk) || {
rm -f "${dest_file}"
fail "ERROR: Download failed."
exit 1
@@ -51,11 +52,11 @@ download_file() {
echo "Downloading ${description} (signature) to ${dest_dir}..."
local curl_cmd="curl -f -L ${file_url}.sig -o ${sig_file} --create-dirs -# ${extra_curl_opts}"
if test -n "${backup_url}"; then
- local curl_cmd_bnk="curl -f -L ${backup_url} -o ${sig_file} --create-dirs -# ${extra_curl_opts}"
+ local curl_cmd_bnk="curl -f -L "${backup_url}.sig" -o ${sig_file} --create-dirs -# ${extra_curl_opts}"
else
local curl_cmd_bnk="true"
fi
- $curl_cmd || echo "Checking repo.msys2.org instead of Haskell.org..." && $curl_cmd_bnk || {
+ $curl_cmd || (echo "Checking repo.msys2.org instead of Haskell.org..." && $curl_cmd_bnk) || {
rm -f "${dest_file}.sig"
fail "ERROR: Download failed."
exit 1
@@ -101,26 +102,23 @@ download_tarballs() {
local package_prefix="mingw-w64"
local format_url="/${mingw_arch}/${package_prefix}-${mingw_arch}"
- download_mingw "${format_url}-crt-git-5.0.0.4795.e3d96cb1-1-any.pkg.tar.xz"
- download_mingw "${format_url}-winpthreads-git-5.0.0.4850.d1662dc7-1-any.pkg.tar.xz"
- download_mingw "${format_url}-headers-git-5.0.0.4966.1eee2140-1-any.pkg.tar.xz"
- download_mingw "${format_url}-libwinpthread-git-5.0.0.4850.d1662dc7-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-crt-git-7.0.0.5491.fe45801e-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-winpthreads-git-7.0.0.5480.e14d23be-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-headers-git-7.0.0.5490.9ec54ed1-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-libwinpthread-git-7.0.0.5480.e14d23be-1-any.pkg.tar.xz"
download_mingw "${format_url}-zlib-1.2.8-9-any.pkg.tar.xz"
- download_mingw "${format_url}-isl-0.18-1-any.pkg.tar.xz"
- download_mingw "${format_url}-mpfr-3.1.6-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-isl-0.21-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-mpfr-4.0.2-2-any.pkg.tar.xz"
download_mingw "${format_url}-gmp-6.1.2-1-any.pkg.tar.xz"
- download_mingw "${format_url}-binutils-2.29.1-1-any.pkg.tar.xz"
- download_mingw "${format_url}-libidn2-2.0.4-1-any.pkg.tar.xz"
- download_mingw "${format_url}-gcc-7.2.0-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-binutils-2.32-3-$pkg_variant.pkg.tar.xz"
+ download_mingw "${format_url}-libidn2-2.2.0-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-gcc-9.2.0-1-$pkg_variant.pkg.tar.xz"
+ download_mingw "${format_url}-mpc-1.1.0-1-any.pkg.tar.xz"
+ download_mingw "${format_url}-windows-default-manifest-6.4-3-any.pkg.tar.xz"
# Upstream is unfortunately quite inconsistent in naming
if test "$mingw_arch" != "sources"; then
- download_mingw "${format_url}-mpc-1.0.3-2-any.pkg.tar.xz"
- download_mingw "${format_url}-gcc-libs-7.2.0-1-any.pkg.tar.xz"
- else
- local format_url="${mingw_base_url}/${mingw_arch}/${package_prefix}"
- download_mingw "${format_url}-i686-mpc-1.0.3-2.src.tar.gz"
- download_mingw "${format_url}-x86_64-mpc-1.0.3-2.src.tar.gz"
+ download_mingw "${format_url}-gcc-libs-9.2.0-1-$pkg_variant.pkg.tar.xz"
fi
if ! test "$missing_files" = "0"
@@ -131,7 +129,7 @@ download_tarballs() {
download_i386() {
mingw_arch="i686"
- tarball_dest_dir="mingw-w64/x86"
+ tarball_dest_dir="mingw-w64/i686"
download_tarballs
}
@@ -171,6 +169,54 @@ sync_binaries_and_sources() {
done
}
+patch_single_file () {
+ local patcher_base="$1"
+ local filename=$(readlink -f "$2")
+ local filepath=$(dirname "$filename")
+ local patcher="$patcher_base/iat-patcher.exe"
+ $patcher install "$filename" > /dev/null
+ rm -f "$filename.bak"
+ for file in $patcher_base/*.dll; do cp -f "$file" "${filepath}"; done
+ echo "Patched '$filename'"
+}
+
+patch_tarball () {
+ local tarball_name="$1"
+ local filename=$(basename "$tarball_name")
+ local filepath=$(dirname "$tarball_name")
+ local newfile=`echo "$filepath/$filename" | sed -e 's/-any/-phyx/'`
+ local arch=""
+
+ echo "=> ${filename}"
+
+ case $1 in
+ *x86_64*)
+ arch="x86_64"
+ ;;
+ *i686*)
+ arch="i686"
+ ;;
+ *)
+ echo "unknown architecture detected. Stopping."
+ exit 1
+ ;;
+ esac
+
+ local base="$(pwd)"
+ local patcher_base="$(pwd)/ghc-tarballs/ghc-jailbreak/$arch"
+ local tmpdir="ghc-tarballs/tmpdir"
+ mkdir -p $tmpdir
+ cd $tmpdir
+ tar xJf "$base/$tarball_name"
+ find . -iname "*.exe" -exec bash -c \
+ 'patch_single_file "'"${patcher_base}"'" "$0"' {} \;
+ tar cJf "$base/$newfile" .
+ cd "$base"
+ rm -rf $tmpdir
+ gpg --output "$base/${newfile}.sig" --detach-sig "$base/$newfile"
+ rm -f "$base/$tarball_name"
+}
+
show_hashes_for_binaries() {
$FIND ghc-tarballs/ -iname "*.*" | xargs md5sum | grep -v "\.sig" | sed -s "s/\*//"
}
@@ -182,11 +228,13 @@ usage() {
echo
echo "Where <action> is one of,"
echo ""
- echo " download download the necessary tarballs for the given architecture"
- echo " fetch download the necessary tarballs for the given architecture but doesn't verify their md5."
- echo " verify verify the existence and correctness of the necessary tarballs"
- echo " hash generate md5 hashes for inclusion in win32-tarballs.md5sum"
- echo " sync upload packages downloaded with 'fetch mirror' to haskell.org"
+ echo " download download the necessary tarballs for the given architecture"
+ echo " fetch download the necessary tarballs for the given architecture but doesn't verify their md5."
+ echo " grab download the necessary tarballs using patched toolchains for the given architecture but doesn't verify their md5."
+ echo " verify verify the existence and correctness of the necessary tarballs"
+ echo " patch jailbreak the binaries in the tarballs and remove MAX_PATH limitations."
+ echo " hash generate md5 hashes for inclusion in win32-tarballs.md5sum"
+ echo " sync upload packages downloaded with 'fetch mirror' to haskell.org"
echo ""
echo "and <arch> is one of i386, x86_64,all or mirror (which includes sources)"
}
@@ -199,7 +247,12 @@ case $1 in
;;
fetch)
download=1
+ verify=
+ ;;
+ grab)
+ download=1
verify=0
+ pkg_variant="any"
;;
verify)
download=0
@@ -214,6 +267,28 @@ case $1 in
show_hashes_for_binaries
exit 1
;;
+ # This routine will download the latest ghc-jailbreak and unpack binutils and
+ # the ghc tarballs and patches every .exe in each. Along with this is copies
+ # two dlls in every folder that it patches a .exe in. Afterwards it re-creates
+ # the tarballs and generates a new signature file.
+ patch)
+ export -f patch_tarball
+ export -f patch_single_file
+
+ echo "Downloading ghc-jailbreak..."
+ curl -f -L https://mistuke.blob.core.windows.net/binaries/ghc-jailbreak-0.3.tar.gz \
+ -o ghc-tarballs/ghc-jailbreak/ghc-jailbreak.tar.gz --create-dirs -#
+ tar -C ghc-tarballs/ghc-jailbreak/ -xf ghc-tarballs/ghc-jailbreak/ghc-jailbreak.tar.gz
+
+ find ghc-tarballs/mingw-w64/ \( -iname "*binutils*.tar.xz" \
+ -o -iname "*gcc*.tar.xz" \) \
+ -exec bash -c 'patch_tarball "$0"' {} \;
+
+ rm -rf ghc-tarballs/ghc-jailbreak
+
+ echo "Finished tarball generation, toolchain has been pre-patched."
+ exit 0
+ ;;
*)
usage
exit 1
@@ -236,6 +311,7 @@ case $2 in
download_i386
download_x86_64
verify=0
+ sigs=0
download_sources
show_hashes_for_binaries
;;
diff --git a/mk/win32-tarballs.md5sum b/mk/win32-tarballs.md5sum
index 2c2d3df93a..5d23609de5 100644
--- a/mk/win32-tarballs.md5sum
+++ b/mk/win32-tarballs.md5sum
@@ -1,39 +1,28 @@
-d0b3537c3f56b6f396b3dc23a905d186 ghc-tarballs/mingw-w64/sources/mingw-w64-crt-git-5.0.0.4795.e3d96cb1-1.src.tar.gz
-51d1006727d50a599bf30c34537bb6a9 ghc-tarballs/mingw-w64/sources/mingw-w64-binutils-2.29.1-1.src.tar.gz
-4578c232f7ed327bd6a364737cb018f5 ghc-tarballs/mingw-w64/sources/mingw-w64-gcc-7.2.0-1.src.tar.gz
-b605210c3d1b03092e3b223d1ccf4001 ghc-tarballs/mingw-w64/sources/mingw-w64-gmp-6.1.2-1.src.tar.gz
-1ad83604bb58ecf43f26843975046c1c ghc-tarballs/mingw-w64/sources/mingw-w64-headers-git-5.0.0.4966.1eee2140-1.src.tar.gz
-5c24d319656ed61e517dfa0fee7e475c ghc-tarballs/mingw-w64/sources/mingw-w64-i686-mpc-1.0.3-2.src.tar.gz
-214032557d2474f10c23c33bdaced8e5 ghc-tarballs/mingw-w64/sources/mingw-w64-isl-0.18-1.src.tar.gz
-8c7efe60059c4c80d0d1966c943b5aaa ghc-tarballs/mingw-w64/sources/mingw-w64-libidn2-2.0.4-1.src.tar.gz
-18e9d17e968773c0691c50d9ceeede34 ghc-tarballs/mingw-w64/sources/mingw-w64-mpfr-3.1.6-1.src.tar.gz
-0462bc73a8b15a68dece429f6f33ca81 ghc-tarballs/mingw-w64/sources/mingw-w64-winpthreads-git-5.0.0.4850.d1662dc7-1.src.tar.gz
-d4261042f502998006c57f0e6517998e ghc-tarballs/mingw-w64/sources/mingw-w64-x86_64-mpc-1.0.3-2.src.tar.gz
-534bb4756482f3271308576cdadfe5dc ghc-tarballs/mingw-w64/x86/mingw-w64-i686-crt-git-5.0.0.4795.e3d96cb1-1-any.pkg.tar.xz
-32078e2a67e34ff6c0b1795fe6ed9d36 ghc-tarballs/mingw-w64/sources/mingw-w64-zlib-1.2.8-9.src.tar.gz
-66e4fc3e62c0fa6723c0d27bdb832962 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-binutils-2.29.1-1-any.pkg.tar.xz
-634ad635913713abc0dbcb0ebef8c85b ghc-tarballs/mingw-w64/x86/mingw-w64-i686-gcc-7.2.0-1-any.pkg.tar.xz
-5343540bc6caa7ada564483f3a1fdff7 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-gcc-libs-7.2.0-1-any.pkg.tar.xz
-2f97e71e4ec122151c20350433268d8b ghc-tarballs/mingw-w64/x86/mingw-w64-i686-gmp-6.1.2-1-any.pkg.tar.xz
-07f374e6eb4846169921551ee73103e6 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-headers-git-5.0.0.4966.1eee2140-1-any.pkg.tar.xz
-ac7017bd5d69030cfe76e475e213b43a ghc-tarballs/mingw-w64/x86/mingw-w64-i686-isl-0.18-1-any.pkg.tar.xz
-f758e0d121619b166dbe36060c641767 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-libidn2-2.0.4-1-any.pkg.tar.xz
-3c718f86311bdd8c4438513a0f417391 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-libwinpthread-git-5.0.0.4850.d1662dc7-1-any.pkg.tar.xz
-719e76fa7a54a8676d2e60af3bb13c45 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-mpc-1.0.3-2-any.pkg.tar.xz
-3780a25a6f20eef9b143f47f4b615e39 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-crt-git-5.0.0.4795.e3d96cb1-1-any.pkg.tar.xz
-9d71b5b4698310a6b961a7d9e273a204 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-mpfr-3.1.6-1-any.pkg.tar.xz
-8912539507692ecf3cebcd5405e1a526 ghc-tarballs/mingw-w64/x86/mingw-w64-i686-winpthreads-git-5.0.0.4850.d1662dc7-1-any.pkg.tar.xz
-87c65e9b2930436a75dfd7d459ae98cb ghc-tarballs/mingw-w64/x86/mingw-w64-i686-zlib-1.2.8-9-any.pkg.tar.xz
-a7e26551a47ce247e432d3f3db416f2b ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-binutils-2.29.1-1-any.pkg.tar.xz
-c4ce9e9a696a76a350d6ed4222fe205e ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-gcc-7.2.0-1-any.pkg.tar.xz
-872a54d953e7d9e6f375e3712d540701 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-gcc-libs-7.2.0-1-any.pkg.tar.xz
+8af4600c30671775a1dde3b60fe75854 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-binutils-2.32-3-phyx.pkg.tar.xz
+c442f8999c10a24059a79a0a8974bc46 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-crt-git-7.0.0.5491.fe45801e-1-any.pkg.tar.xz
+dddc20e7431ab369f6e2726feb4f65d1 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-gcc-9.2.0-1-phyx.pkg.tar.xz
+64130e9d870de2292d4627a67fabee51 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-gcc-libs-9.2.0-1-phyx.pkg.tar.xz
+2f97e71e4ec122151c20350433268d8b ghc-tarballs/mingw-w64/i686/mingw-w64-i686-gmp-6.1.2-1-any.pkg.tar.xz
+192a25fe284cf8a78851a673d6ef672a ghc-tarballs/mingw-w64/i686/mingw-w64-i686-headers-git-7.0.0.5490.9ec54ed1-1-any.pkg.tar.xz
+a18983513ec46ff0716dc5742604a78b ghc-tarballs/mingw-w64/i686/mingw-w64-i686-isl-0.21-1-any.pkg.tar.xz
+c8dabb32fabe2492878e070ffad473f0 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-libidn2-2.2.0-1-any.pkg.tar.xz
+d05ca6e90126c17db19a8cd32e7347e8 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-libwinpthread-git-7.0.0.5480.e14d23be-1-any.pkg.tar.xz
+cae596bd144ad70875ef8f21e5bdb77d ghc-tarballs/mingw-w64/i686/mingw-w64-i686-mpc-1.1.0-1-any.pkg.tar.xz
+317a7a490da5c88f63638fbc5461b51e ghc-tarballs/mingw-w64/i686/mingw-w64-i686-mpfr-4.0.2-2-any.pkg.tar.xz
+15a5557d7b321bb26436dcf7adced5b7 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-windows-default-manifest-6.4-3-any.pkg.tar.xz
+beb76cd6141d11c000a1f5ff2ad34971 ghc-tarballs/mingw-w64/i686/mingw-w64-i686-winpthreads-git-7.0.0.5480.e14d23be-1-any.pkg.tar.xz
+87c65e9b2930436a75dfd7d459ae98cb ghc-tarballs/mingw-w64/i686/mingw-w64-i686-zlib-1.2.8-9-any.pkg.tar.xz
+4dca7def5591b8f999e5fa20084cc7a9 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-binutils-2.32-3-phyx.pkg.tar.xz
+d4336ca77b5edf3126a6c1358952567a ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-crt-git-7.0.0.5491.fe45801e-1-any.pkg.tar.xz
+e84e0426204b73af13752b65a035dfc2 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-gcc-9.2.0-1-phyx.pkg.tar.xz
+b6200865004cb558c8f5cd7526975602 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-gcc-libs-9.2.0-1-phyx.pkg.tar.xz
1e1f79abc9fc0534d360c2889b10a9f5 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-gmp-6.1.2-1-any.pkg.tar.xz
-8cce0779e70d5c3ef3564a11fb3bd931 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-headers-git-5.0.0.4966.1eee2140-1-any.pkg.tar.xz
-e1c25a67656e3667847be1f5eba73862 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-isl-0.18-1-any.pkg.tar.xz
-6faaa722dce8af954b30e39c4213d657 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-libidn2-2.0.4-1-any.pkg.tar.xz
-df50f51f32efe8bff7a87f26c6832045 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-libwinpthread-git-5.0.0.4850.d1662dc7-1-any.pkg.tar.xz
-df1a7d4050568d83c265ae78c32ef30b ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-mpc-1.0.3-2-any.pkg.tar.xz
-d15495e807e2a87b917febedbfb3f5b3 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-mpfr-3.1.6-1-any.pkg.tar.xz
-c5ffd1a27eb459242b46d76b066e557e ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-winpthreads-git-5.0.0.4850.d1662dc7-1-any.pkg.tar.xz
+ef6ad2b29b92264c78d7ba6f0a875838 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-headers-git-7.0.0.5490.9ec54ed1-1-any.pkg.tar.xz
+623c059a9691ee7fc74b9e3f89b35782 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-isl-0.21-1-any.pkg.tar.xz
+29a39230c6208366b9d046fbe5bdde6f ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-libidn2-2.2.0-1-any.pkg.tar.xz
+9953a82fd713f0c7ece69d9228238f4d ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-libwinpthread-git-7.0.0.5480.e14d23be-1-any.pkg.tar.xz
+c3aa7f45926edaaafe3bba988e327271 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-mpc-1.1.0-1-any.pkg.tar.xz
+951d8046e65768e00b6dfe1bb6e23016 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-mpfr-4.0.2-2-any.pkg.tar.xz
+8360a1dd2f6f4fd518907530f0839a48 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-windows-default-manifest-6.4-3-any.pkg.tar.xz
+e7cf8d4ac9e9b3f79c16a09413dd1322 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-winpthreads-git-7.0.0.5480.e14d23be-1-any.pkg.tar.xz
60c3a388478f411b7a0908441ebeb537 ghc-tarballs/mingw-w64/x86_64/mingw-w64-x86_64-zlib-1.2.8-9-any.pkg.tar.xz
-b21d1681b61cf7a024e854096285b02e ghc-tarballs/perl/ghc-perl-1.tar.gz
diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c
index e34fcf03f5..4da4258e95 100644
--- a/rts/RtsSymbols.c
+++ b/rts/RtsSymbols.c
@@ -97,6 +97,35 @@
* https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/
* https://sourceforge.net/p/mingw-w64/discussion/723797/thread/55520785/
*/
+/* Note [_iob_func symbol]
+ * ~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * Microsoft in VS2013 to VS2015 transition made a backwards incompatible change
+ * to the stdio function __iob_func.
+ *
+ * They used to be defined as:
+ *
+ * #define stdin (&__iob_func()[0])
+ * #define stdout (&__iob_func()[1])
+ * #define stderr (&__iob_func()[2])
+ *
+ * whereas now they're defined as:
+ *
+ * #define stdin (__acrt_iob_func(0))
+ * #define stdout (__acrt_iob_func(1))
+ * #define stderr (__acrt_iob_func(2))
+ *
+ * Mingw-w64 followed along with the madness and so we have to deal with both
+ * version of these symbols.
+ *
+ * As such when you mix new and old libraries you get a missing symbols error
+ * for __acrt_iob_func. It then links against the PLT for the function but that
+ * no longer exists. Instead we forward the request for the PLT symbol to the
+ * symbol directly which is defined inline since we're using a newer compiler.
+ *
+ * See also:
+ * https://docs.microsoft.com/en-us/cpp/porting/visual-cpp-change-history-2003-2015?view=vs-2017#stdioh-and-conioh
+ */
#define RTS_MINGW_ONLY_SYMBOLS \
SymI_HasProto(stg_asyncReadzh) \
SymI_HasProto(stg_asyncWritezh) \
@@ -112,7 +141,12 @@
RTS_WIN64_ONLY(SymI_HasProto(__iob_func)) \
/* see Note [Symbols for MinGW's printf] */ \
SymI_HasProto(_lock_file) \
- SymI_HasProto(_unlock_file)
+ SymI_HasProto(_unlock_file) \
+ /* See Note [_iob_func symbol] */ \
+ RTS_WIN64_ONLY(SymI_HasProto_redirect( \
+ __imp___acrt_iob_func, __rts_iob_func, true)) \
+ RTS_WIN32_ONLY(SymI_HasProto_redirect( \
+ __imp____acrt_iob_func, __rts_iob_func, true))
#define RTS_MINGW_COMPAT_SYMBOLS \
SymI_HasProto_deprecated(access) \
@@ -977,7 +1011,7 @@
#define SymE_HasProto(vvv) SymI_HasProto(vvv)
#endif
#define SymI_HasProto(vvv) /**/
-#define SymI_HasProto_redirect(vvv,xxx) /**/
+#define SymI_HasProto_redirect(vvv,xxx,weak) /**/
#define SymI_HasProto_deprecated(vvv) /**/
RTS_SYMBOLS
RTS_RET_SYMBOLS
@@ -1013,9 +1047,9 @@ RTS_LIBFFI_SYMBOLS
// SymI_HasProto_redirect allows us to redirect references to one symbol to
// another symbol. See newCAF/newRetainedCAF/newGCdCAF for an example.
-#define SymI_HasProto_redirect(vvv,xxx) \
- { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
- (void*)(&(xxx)), false },
+#define SymI_HasProto_redirect(vvv,xxx,weak) \
+ { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
+ (void*)(&(xxx)), weak },
// SymI_HasProto_deprecated allows us to redirect references from their deprecated
// names to the undeprecated ones. e.g. access -> _access.
diff --git a/rts/RtsSymbols.h b/rts/RtsSymbols.h
index 650b1f5fed..b17c56e0dd 100644
--- a/rts/RtsSymbols.h
+++ b/rts/RtsSymbols.h
@@ -25,3 +25,8 @@ typedef struct _RtsSymbolVal {
} RtsSymbolVal;
extern RtsSymbolVal rtsSyms[];
+
+/* See Note [_iob_func symbol]. */
+#if defined(mingw32_HOST_OS)
+extern const void* __rts_iob_func;
+#endif
diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
index f2c49f6513..788b239d9f 100644
--- a/rts/linker/PEi386.c
+++ b/rts/linker/PEi386.c
@@ -275,6 +275,12 @@ const int default_alignment = 8;
const int initHeapSizeMB = 15;
static HANDLE code_heap = NULL;
+/* See Note [_iob_func symbol]
+ In order to emulate __iob_func the memory location needs to point the
+ location of the I/O structures in memory. As such we need RODATA to contain
+ the pointer as a redirect. Essentially it's a DATA DLL reference. */
+const void* __rts_iob_func = (void*)&__acrt_iob_func;
+
/* Low Fragmentation Heap, try to prevent heap from increasing in size when
space can simply be reclaimed. These are enums missing from mingw-w64's
headers. */
@@ -758,7 +764,7 @@ pathchar* findSystemLibrary_PEi386( pathchar* dll_name )
HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path)
{
HINSTANCE hDLL = LoadLibraryW(L"Kernel32.DLL");
- LPAddDLLDirectory AddDllDirectory = (LPAddDLLDirectory)GetProcAddress((HMODULE)hDLL, "AddDllDirectory");
+ LPAddDLLDirectory AddDllDirectory = (LPAddDLLDirectory)(void*)GetProcAddress((HMODULE)hDLL, "AddDllDirectory");
HsPtr result = NULL;
@@ -828,7 +834,7 @@ bool removeLibrarySearchPath_PEi386(HsPtr dll_path_index)
if (dll_path_index != NULL) {
HINSTANCE hDLL = LoadLibraryW(L"Kernel32.DLL");
- LPRemoveDLLDirectory RemoveDllDirectory = (LPRemoveDLLDirectory)GetProcAddress((HMODULE)hDLL, "RemoveDllDirectory");
+ LPRemoveDLLDirectory RemoveDllDirectory = (LPRemoveDLLDirectory)(void*)GetProcAddress((HMODULE)hDLL, "RemoveDllDirectory");
if (RemoveDllDirectory) {
result = RemoveDllDirectory(dll_path_index);
diff --git a/rts/linker/PEi386.h b/rts/linker/PEi386.h
index 538f132ab5..4c33dfd4d9 100644
--- a/rts/linker/PEi386.h
+++ b/rts/linker/PEi386.h
@@ -172,5 +172,4 @@ because we have no stdcall convention on 64 bits.
See #9218
*/
-
#include "EndPrivate.h"
diff --git a/rts/linker/elf_plt.h b/rts/linker/elf_plt.h
index 1995d51207..0d99c7e462 100644
--- a/rts/linker/elf_plt.h
+++ b/rts/linker/elf_plt.h
@@ -1,10 +1,10 @@
#pragma once
+#if defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)
+
#include "ghcplatform.h"
#include <LinkerInternals.h>
-#if defined(arm_HOST_ARCH) || defined(aarch64_HOST_ARCH)
-
#include "elf_plt_arm.h"
#include "elf_plt_aarch64.h"
diff --git a/rts/linker/elf_reloc_aarch64.c b/rts/linker/elf_reloc_aarch64.c
index bb15576d06..35cc70b5bc 100644
--- a/rts/linker/elf_reloc_aarch64.c
+++ b/rts/linker/elf_reloc_aarch64.c
@@ -1,3 +1,7 @@
+#if defined(aarch64_HOST_ARCH)
+
+#if defined(OBJFORMAT_ELF)
+
#include <stdlib.h>
#include <assert.h>
#include "elf_compat.h"
@@ -6,10 +10,6 @@
#include "elf_util.h"
#include "elf_plt.h"
-#if defined(aarch64_HOST_ARCH)
-
-#if defined(OBJFORMAT_ELF)
-
#define Page(x) ((x) & ~0xFFF)
typedef uint64_t addr_t;
diff --git a/rts/linker/elf_reloc_aarch64.h b/rts/linker/elf_reloc_aarch64.h
index ac7a90ea16..06b41eff0e 100644
--- a/rts/linker/elf_reloc_aarch64.h
+++ b/rts/linker/elf_reloc_aarch64.h
@@ -1,9 +1,9 @@
#pragma once
-#include "LinkerInternals.h"
-
#if defined(OBJFORMAT_ELF)
+#include "LinkerInternals.h"
+
bool
relocateObjectCodeAarch64(ObjectCode * oc);
diff --git a/rts/win32/OSMem.c b/rts/win32/OSMem.c
index 57997b1ac5..35fe72fd58 100644
--- a/rts/win32/OSMem.c
+++ b/rts/win32/OSMem.c
@@ -41,7 +41,7 @@ static block_rec* free_blocks = NULL;
typedef LPVOID(WINAPI *VirtualAllocExNumaProc)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
/* Cache NUMA API call. */
-VirtualAllocExNumaProc VirtualAllocExNuma;
+VirtualAllocExNumaProc _VirtualAllocExNuma;
void
osMemInit(void)
@@ -52,8 +52,8 @@ osMemInit(void)
/* Resolve and cache VirtualAllocExNuma. */
if (osNumaAvailable() && RtsFlags.GcFlags.numa)
{
- VirtualAllocExNuma = (VirtualAllocExNumaProc)GetProcAddress(GetModuleHandleW(L"kernel32"), "VirtualAllocExNuma");
- if (!VirtualAllocExNuma)
+ _VirtualAllocExNuma = (VirtualAllocExNumaProc)(void*)GetProcAddress(GetModuleHandleW(L"kernel32"), "VirtualAllocExNuma");
+ if (!_VirtualAllocExNuma)
{
sysErrorBelch(
"osBindMBlocksToNode: VirtualAllocExNuma does not exist. How did you get this far?");
@@ -569,7 +569,7 @@ void osBindMBlocksToNode(
On windows also -xb is broken, it does nothing so that can't
be used to tweak it (see #12577). So for now, just let the OS decide.
*/
- temp = VirtualAllocExNuma(
+ temp = _VirtualAllocExNuma(
GetCurrentProcess(),
NULL, // addr? See base memory
size,
diff --git a/rts/win32/OSThreads.c b/rts/win32/OSThreads.c
index c67d621bc2..0942382da2 100644
--- a/rts/win32/OSThreads.c
+++ b/rts/win32/OSThreads.c
@@ -111,7 +111,7 @@ createOSThread (OSThreadId* pId, char *name STG_UNUSED,
HANDLE h;
h = CreateThread ( NULL, /* default security attributes */
0,
- (LPTHREAD_START_ROUTINE)startProc,
+ (LPTHREAD_START_ROUTINE)(void*)startProc,
param,
0,
pId);
@@ -314,7 +314,9 @@ getNumberOfProcessorsGroups (void)
on the API being available. So we'll have to resolve manually. */
HMODULE kernel = GetModuleHandleW(L"kernel32");
- GetGroupCountProc GetActiveProcessorGroupCount = (GetGroupCountProc)GetProcAddress(kernel, "GetActiveProcessorGroupCount");
+ GetGroupCountProc GetActiveProcessorGroupCount
+ = (GetGroupCountProc)(void*)
+ GetProcAddress(kernel, "GetActiveProcessorGroupCount");
n_groups = GetActiveProcessorGroupCount();
IF_DEBUG(scheduler, debugBelch("[*] Number of processor groups detected: %u\n", n_groups));
@@ -348,7 +350,9 @@ getProcessorsDistribution (void)
on the API being available. So we'll have to resolve manually. */
HMODULE kernel = GetModuleHandleW(L"kernel32");
- GetItemCountProc GetActiveProcessorCount = (GetItemCountProc)GetProcAddress(kernel, "GetActiveProcessorCount");
+ GetItemCountProc GetActiveProcessorCount
+ = (GetItemCountProc)(void*)
+ GetProcAddress(kernel, "GetActiveProcessorCount");
if (GetActiveProcessorCount)
{
@@ -449,7 +453,9 @@ getNumberOfProcessors (void)
on the API being available. So we'll have to resolve manually. */
HMODULE kernel = GetModuleHandleW(L"kernel32");
- GetItemCountProc GetActiveProcessorCount = (GetItemCountProc)GetProcAddress(kernel, "GetActiveProcessorCount");
+ GetItemCountProc GetActiveProcessorCount
+ = (GetItemCountProc)(void*)
+ GetProcAddress(kernel, "GetActiveProcessorCount");
if (GetActiveProcessorCount && !nproc)
{
nproc = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
@@ -516,7 +522,9 @@ setThreadAffinity (uint32_t n, uint32_t m) // cap N of M
on the API being available. So we'll have to resolve manually. */
HMODULE kernel = GetModuleHandleW(L"kernel32");
- SetThreadGroupAffinityProc SetThreadGroupAffinity = (SetThreadGroupAffinityProc)GetProcAddress(kernel, "SetThreadGroupAffinity");
+ SetThreadGroupAffinityProc SetThreadGroupAffinity
+ = (SetThreadGroupAffinityProc)(void*)
+ GetProcAddress(kernel, "SetThreadGroupAffinity");
#endif
for (i = 0; i < n_groups; i++)
@@ -564,8 +572,8 @@ interruptOSThread (OSThreadId id)
sysErrorBelch("interruptOSThread: OpenThread");
stg_exit(EXIT_FAILURE);
}
- pCSIO = (PCSIO) GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")),
- "CancelSynchronousIo");
+ pCSIO = (PCSIO)(void*)GetProcAddress(GetModuleHandle(TEXT("Kernel32.dll")),
+ "CancelSynchronousIo");
if ( NULL != pCSIO ) {
pCSIO(hdl);
} else {
diff --git a/testsuite/tests/ffi/should_run/T5594_c.c b/testsuite/tests/ffi/should_run/T5594_c.c
index 9ef22e8efd..bcdb2262f3 100644
--- a/testsuite/tests/ffi/should_run/T5594_c.c
+++ b/testsuite/tests/ffi/should_run/T5594_c.c
@@ -1,8 +1,8 @@
-#include <stdio.h>
#include "T5594_stub.h"
-
#include "HsFFI.h"
+#include <stdio.h>
+
int main(int argc, char *argv[])
{
hs_init(&argc, &argv);
diff --git a/testsuite/tests/ffi/should_run/ffi002_c.c b/testsuite/tests/ffi/should_run/ffi002_c.c
index ccf9ac99cf..5783fba051 100644
--- a/testsuite/tests/ffi/should_run/ffi002_c.c
+++ b/testsuite/tests/ffi/should_run/ffi002_c.c
@@ -1,8 +1,8 @@
-#include <stdio.h>
#include "ffi002_stub.h"
-
#include "HsFFI.h"
+#include <stdio.h>
+
int main(int argc, char *argv[])
{
int i;
diff --git a/testsuite/tests/ffi/should_run/fptr01_c.c b/testsuite/tests/ffi/should_run/fptr01_c.c
index 0a0e1efe1c..07197c4172 100644
--- a/testsuite/tests/ffi/should_run/fptr01_c.c
+++ b/testsuite/tests/ffi/should_run/fptr01_c.c
@@ -1,9 +1,8 @@
-#include <stdio.h>
-
#include "HsFFI.h"
-
#include "fptr01.h"
+#include <stdio.h>
+
void f( HsInt *i )
{
printf( "f%d\n", (int)*i );
diff --git a/testsuite/tests/ffi/should_run/fptrfail01_c.c b/testsuite/tests/ffi/should_run/fptrfail01_c.c
index 070a786e57..c620e7535c 100644
--- a/testsuite/tests/ffi/should_run/fptrfail01_c.c
+++ b/testsuite/tests/ffi/should_run/fptrfail01_c.c
@@ -1,9 +1,8 @@
-#include <stdio.h>
-
#include "HsFFI.h"
-
#include "fptrfail01.h"
+#include <stdio.h>
+
void f( HsInt *i )
{
printf( "f%d\n", (int)*i );
diff --git a/testsuite/tests/rts/linker/linker_error.c b/testsuite/tests/rts/linker/linker_error.c
index 264c95d710..aad83686b0 100644
--- a/testsuite/tests/rts/linker/linker_error.c
+++ b/testsuite/tests/rts/linker/linker_error.c
@@ -1,7 +1,7 @@
#include "ghcconfig.h"
+#include "Rts.h"
#include <stdio.h>
#include <stdlib.h>
-#include "Rts.h"
#if defined(mingw32_HOST_OS)
#include <malloc.h>
#endif
diff --git a/testsuite/tests/rts/linker/linker_unload.c b/testsuite/tests/rts/linker/linker_unload.c
index acf41cb86c..159570314a 100644
--- a/testsuite/tests/rts/linker/linker_unload.c
+++ b/testsuite/tests/rts/linker/linker_unload.c
@@ -1,7 +1,7 @@
#include "ghcconfig.h"
+#include "Rts.h"
#include <stdio.h>
#include <stdlib.h>
-#include "Rts.h"
#include <string.h>
#define ITERATIONS 1000
diff --git a/utils/fs/fs.c b/utils/fs/fs.c
index 6644705ffe..4a761e5f9e 100644
--- a/utils/fs/fs.c
+++ b/utils/fs/fs.c
@@ -1,6 +1,6 @@
/* -----------------------------------------------------------------------------
*
- * (c) Tamar Christina 2018
+ * (c) Tamar Christina 2018-2019
*
* Windows I/O routines for file opening.
*
@@ -24,16 +24,20 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <share.h>
+#include <errno.h>
/* This function converts Windows paths between namespaces. More specifically
It converts an explorer style path into a NT or Win32 namespace.
- This has several caveats but they are caviats that are native to Windows and
+ This has several caveats but they are caveats that are native to Windows and
not POSIX. See
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx.
Anything else such as raw device paths we leave untouched. The main benefit
of doing any of this is that we can break the MAX_PATH restriction and also
- access raw handles that we couldn't before. */
-static wchar_t* __hs_create_device_name (const wchar_t* filename) {
+ access raw handles that we couldn't before.
+
+ The resulting string is dynamically allocated and so callers are expected to
+ free this string. */
+wchar_t* FS(create_device_name) (const wchar_t* filename) {
const wchar_t* win32_dev_namespace = L"\\\\.\\";
const wchar_t* win32_file_namespace = L"\\\\?\\";
const wchar_t* nt_device_namespace = L"\\Device\\";
@@ -57,13 +61,31 @@ static wchar_t* __hs_create_device_name (const wchar_t* filename) {
result[i] = L'\\';
}
+ /* We need to expand dos short paths as well. */
+ DWORD nResult = GetLongPathNameW (result, NULL, 0) + 1;
+ wchar_t* temp = NULL;
+ if (nResult > 1)
+ {
+ temp = _wcsdup (result);
+ free (result);
+ result = malloc (nResult * sizeof (wchar_t));
+ if (GetLongPathNameW (temp, result, nResult) == 0)
+ {
+ result = memcpy (result, temp, wcslen (temp));
+ goto cleanup;
+ }
+ free (temp);
+ }
+
/* Now resolve any . and .. in the path or subsequent API calls may fail since
Win32 will no longer resolve them. */
- DWORD nResult = GetFullPathNameW (result, 0, NULL, NULL) + 1;
- wchar_t *temp = _wcsdup (result);
+ nResult = GetFullPathNameW (result, 0, NULL, NULL) + 1;
+ temp = _wcsdup (result);
+ free (result);
result = malloc (nResult * sizeof (wchar_t));
if (GetFullPathNameW (temp, nResult, result, NULL) == 0)
{
+ result = memcpy (result, temp, wcslen (temp));
goto cleanup;
}
@@ -84,6 +106,7 @@ static wchar_t* __hs_create_device_name (const wchar_t* filename) {
/* Create new string. */
int bLen = wcslen (result) + wcslen (ns) + 1;
temp = _wcsdup (result);
+ free (result);
result = malloc (bLen * sizeof (wchar_t));
if (swprintf (result, bLen, L"%ls%ls", ns, temp) <= 0)
{
@@ -100,23 +123,64 @@ cleanup:
return NULL;
}
-#define HAS_FLAG(a,b) ((a & b) == b)
+static int setErrNoFromWin32Error (void);
+/* Sets errno to the right error value and returns -1 to indicate the failure.
+ This function should only be called when the creation of the fd actually
+ failed and you want to return -1 for the fd. */
+static
+int setErrNoFromWin32Error () {
+ switch (GetLastError()) {
+ case ERROR_SUCCESS:
+ errno = 0;
+ break;
+ case ERROR_ACCESS_DENIED:
+ case ERROR_FILE_READ_ONLY:
+ errno = EACCES;
+ break;
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_PATH_NOT_FOUND:
+ errno = ENOENT;
+ break;
+ case ERROR_FILE_EXISTS:
+ errno = EEXIST;
+ break;
+ case ERROR_NOT_ENOUGH_MEMORY:
+ case ERROR_OUTOFMEMORY:
+ errno = ENOMEM;
+ break;
+ case ERROR_INVALID_HANDLE:
+ errno = EBADF;
+ break;
+ case ERROR_INVALID_FUNCTION:
+ errno = EFAULT;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ return -1;
+}
+
+
+#define HAS_FLAG(a,b) (((a) & (b)) == (b))
int FS(swopen) (const wchar_t* filename, int oflag, int shflag, int pmode)
{
/* Construct access mode. */
+ /* https://docs.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants */
DWORD dwDesiredAccess = 0;
if (HAS_FLAG (oflag, _O_RDONLY))
- dwDesiredAccess |= GENERIC_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES;
+ dwDesiredAccess |= GENERIC_READ;
if (HAS_FLAG (oflag, _O_RDWR))
- dwDesiredAccess |= GENERIC_WRITE | GENERIC_READ | FILE_READ_DATA |
- FILE_WRITE_DATA | FILE_READ_ATTRIBUTES |
- FILE_WRITE_ATTRIBUTES;
- if (HAS_FLAG (oflag, _O_WRONLY))
- dwDesiredAccess|= GENERIC_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES;
+ dwDesiredAccess |= GENERIC_WRITE | GENERIC_READ;
+ if (HAS_FLAG (oflag, _O_WRONLY))
+ dwDesiredAccess |= GENERIC_WRITE;
+ if (HAS_FLAG (oflag, _O_APPEND))
+ dwDesiredAccess |= FILE_APPEND_DATA;
/* Construct shared mode. */
- DWORD dwShareMode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
+ /* https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants */
+ DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
if (HAS_FLAG (shflag, _SH_DENYRW))
dwShareMode &= ~(FILE_SHARE_READ | FILE_SHARE_WRITE);
if (HAS_FLAG (shflag, _SH_DENYWR))
@@ -138,21 +202,33 @@ int FS(swopen) (const wchar_t* filename, int oflag, int shflag, int pmode)
}
/* Create file disposition. */
- DWORD dwCreationDisposition = OPEN_EXISTING;
- if (HAS_FLAG (oflag, _O_CREAT))
- dwCreationDisposition = OPEN_ALWAYS;
+ /* https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea */
+ DWORD dwCreationDisposition = 0;
if (HAS_FLAG (oflag, (_O_CREAT | _O_EXCL)))
- dwCreationDisposition = CREATE_NEW;
- if (HAS_FLAG (oflag, _O_TRUNC) && !HAS_FLAG (oflag, _O_CREAT))
- dwCreationDisposition = TRUNCATE_EXISTING;
+ dwCreationDisposition |= CREATE_NEW;
+ else if (HAS_FLAG (oflag, _O_TRUNC | _O_CREAT))
+ dwCreationDisposition |= CREATE_ALWAYS;
+ else if (HAS_FLAG (oflag, _O_TRUNC) && !HAS_FLAG (oflag, O_RDONLY))
+ dwCreationDisposition |= TRUNCATE_EXISTING;
+ else if (HAS_FLAG (oflag, _O_APPEND | _O_CREAT))
+ dwCreationDisposition |= OPEN_ALWAYS;
+ else if (HAS_FLAG (oflag, _O_APPEND))
+ dwCreationDisposition |= OPEN_EXISTING;
+ else if (HAS_FLAG (oflag, _O_CREAT))
+ dwCreationDisposition |= OPEN_ALWAYS;
+ else
+ dwCreationDisposition |= OPEN_EXISTING;
/* Set file access attributes. */
DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
if (HAS_FLAG (oflag, _O_RDONLY))
dwFlagsAndAttributes |= 0; /* No special attribute. */
- if (HAS_FLAG (oflag, (_O_CREAT | _O_TEMPORARY)))
- dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
- if (HAS_FLAG (oflag, (_O_CREAT | _O_SHORT_LIVED)))
+ if (HAS_FLAG (oflag, _O_TEMPORARY))
+ {
+ dwFlagsAndAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
+ dwShareMode |= FILE_SHARE_DELETE;
+ }
+ if (HAS_FLAG (oflag, _O_SHORT_LIVED))
dwFlagsAndAttributes |= FILE_ATTRIBUTE_TEMPORARY;
if (HAS_FLAG (oflag, _O_RANDOM))
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
@@ -162,6 +238,11 @@ int FS(swopen) (const wchar_t* filename, int oflag, int shflag, int pmode)
if (dwFlagsAndAttributes != FILE_ATTRIBUTE_NORMAL)
dwFlagsAndAttributes &= ~FILE_ATTRIBUTE_NORMAL;
+ /* Ensure we have shared read for files which are opened read-only. */
+ if (HAS_FLAG (dwCreationDisposition, OPEN_EXISTING)
+ && ((dwDesiredAccess & (GENERIC_WRITE|GENERIC_READ)) == GENERIC_READ))
+ dwShareMode |= FILE_SHARE_READ;
+
/* Set security attributes. */
SECURITY_ATTRIBUTES securityAttributes;
ZeroMemory (&securityAttributes, sizeof(SECURITY_ATTRIBUTES));
@@ -169,41 +250,39 @@ int FS(swopen) (const wchar_t* filename, int oflag, int shflag, int pmode)
securityAttributes.lpSecurityDescriptor = NULL;
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
- wchar_t* _filename = __hs_create_device_name (filename);
+ wchar_t* _filename = FS(create_device_name) (filename);
if (!_filename)
return -1;
HANDLE hResult
= CreateFileW (_filename, dwDesiredAccess, dwShareMode, &securityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
free (_filename);
if (INVALID_HANDLE_VALUE == hResult)
- return -1;
+ return setErrNoFromWin32Error ();
/* Now we have a Windows handle, we have to convert it to an FD and apply
the remaining flags. */
const int flag_mask = _O_APPEND | _O_RDONLY | _O_TEXT | _O_WTEXT;
int fd = _open_osfhandle ((intptr_t)hResult, oflag & flag_mask);
if (-1 == fd)
- return -1;
+ return setErrNoFromWin32Error ();
/* Finally we can change the mode to the requested one. */
const int mode_mask = _O_TEXT | _O_BINARY | _O_U16TEXT | _O_U8TEXT | _O_WTEXT;
if ((oflag & mode_mask) && (-1 == _setmode (fd, oflag & mode_mask)))
- return -1;
+ return setErrNoFromWin32Error ();
return fd;
}
-FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode)
+int FS(translate_mode) (const wchar_t* mode)
{
- int shflag = 0;
- int pmode = 0;
- int oflag = 0;
-
+ int oflag = 0;
int len = wcslen (mode);
int i;
- #define IS_EXT(X) ((i < (len - 1)) && mode[i] == X)
+ #define IS_EXT(X) ((i < (len - 1)) && mode[i+1] == X)
for (i = 0; i < len; i++)
{
@@ -261,7 +340,19 @@ FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode)
}
#undef IS_EXT
+ return oflag;
+}
+
+FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode)
+{
+ int shflag = 0;
+ int pmode = 0;
+ int oflag = FS(translate_mode) (mode);
+
int fd = FS(swopen) (filename, oflag, shflag, pmode);
+ if (fd < 0)
+ return NULL;
+
FILE* file = _wfdopen (fd, mode);
return file;
}
@@ -281,8 +372,150 @@ FILE *FS(fopen) (const char* filename, const char* mode)
FILE *result = FS(fwopen) (w_filename, w_mode);
free (w_filename);
free (w_mode);
+
+ return result;
+}
+
+int FS(sopen) (const char* filename, int oflag, int shflag, int pmode)
+{
+ size_t len = mbstowcs (NULL, filename, 0);
+ wchar_t *w_filename = malloc (sizeof (wchar_t) * (len + 1));
+ mbstowcs (w_filename, filename, len);
+ w_filename[len] = L'\0';
+
+ int result = FS(swopen) (w_filename, oflag, shflag, pmode);
+ free (w_filename);
+
+ return result;
+}
+
+int FS(_stat) (const char *path, struct _stat *buffer)
+{
+ size_t len = mbstowcs (NULL, path, 0);
+ wchar_t *w_path = malloc (sizeof (wchar_t) * (len + 1));
+ mbstowcs (w_path, path, len);
+ w_path[len] = L'\0';
+
+ int result = FS(_wstat) (w_path, buffer);
+ free (w_path);
+
return result;
}
+
+int FS(_stat64) (const char *path, struct __stat64 *buffer)
+{
+ size_t len = mbstowcs (NULL, path, 0);
+ wchar_t *w_path = malloc (sizeof (wchar_t) * (len + 1));
+ mbstowcs (w_path, path, len);
+ w_path[len] = L'\0';
+
+ int result = FS(_wstat64) (w_path, buffer);
+ free (w_path);
+
+ return result;
+}
+
+static __time64_t ftToPosix(FILETIME ft)
+{
+ /* takes the last modified date. */
+ LARGE_INTEGER date, adjust;
+ date.HighPart = ft.dwHighDateTime;
+ date.LowPart = ft.dwLowDateTime;
+
+ /* 100-nanoseconds = milliseconds * 10000. */
+ /* A UNIX timestamp contains the number of seconds from Jan 1, 1970, while the
+ FILETIME documentation says: Contains a 64-bit value representing the
+ number of 100-nanosecond intervals since January 1, 1601 (UTC).
+
+ Between Jan 1, 1601 and Jan 1, 1970 there are 11644473600 seconds */
+ adjust.QuadPart = 11644473600000 * 10000;
+
+ /* removes the diff between 1970 and 1601. */
+ date.QuadPart -= adjust.QuadPart;
+
+ /* converts back from 100-nanoseconds to seconds. */
+ return (__time64_t)date.QuadPart / 10000000;
+}
+
+int FS(_wstat) (const wchar_t *path, struct _stat *buffer)
+{
+ ZeroMemory (buffer, sizeof (struct _stat));
+ wchar_t* _path = FS(create_device_name) (path);
+ if (!_path)
+ return -1;
+
+ /* Construct shared mode. */
+ DWORD dwShareMode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
+ DWORD dwDesiredAccess = FILE_READ_ATTRIBUTES;
+ DWORD dwFlagsAndAttributes = FILE_FLAG_BACKUP_SEMANTICS;
+ DWORD dwCreationDisposition = OPEN_EXISTING;
+
+ SECURITY_ATTRIBUTES securityAttributes;
+ ZeroMemory (&securityAttributes, sizeof(SECURITY_ATTRIBUTES));
+ securityAttributes.bInheritHandle = false;
+ securityAttributes.lpSecurityDescriptor = NULL;
+ securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+
+ HANDLE hResult
+ = CreateFileW (_path, dwDesiredAccess, dwShareMode, &securityAttributes,
+ dwCreationDisposition, dwFlagsAndAttributes, NULL);
+
+ if (INVALID_HANDLE_VALUE == hResult)
+ {
+ free (_path);
+ return setErrNoFromWin32Error ();
+ }
+
+ WIN32_FILE_ATTRIBUTE_DATA finfo;
+ ZeroMemory (&finfo, sizeof (WIN32_FILE_ATTRIBUTE_DATA));
+ if(!GetFileAttributesExW (_path, GetFileExInfoStandard, &finfo))
+ {
+ free (_path);
+ CloseHandle (hResult);
+ return setErrNoFromWin32Error ();
+ }
+
+ unsigned short mode = _S_IREAD;
+
+ if (finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ mode |= (_S_IFDIR | _S_IEXEC);
+ else
+ {
+ mode |= _S_IFREG;
+ DWORD type;
+ if (GetBinaryTypeW (_path, &type))
+ mode |= _S_IEXEC;
+ }
+
+ if (!(finfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
+ mode |= _S_IWRITE;
+
+ buffer->st_mode = mode;
+ buffer->st_nlink = 1;
+ buffer->st_size = ((uint64_t)finfo.nFileSizeHigh << 32) + finfo.nFileSizeLow;
+ buffer->st_atime = ftToPosix (finfo.ftLastAccessTime);
+ buffer->st_mtime = buffer->st_ctime = ftToPosix (finfo.ftLastWriteTime);
+ free (_path);
+ CloseHandle (hResult);
+ return 0;
+}
+
+int FS(_wstat64) (const wchar_t *path, struct __stat64 *buffer)
+{
+ struct _stat buf;
+ ZeroMemory (buffer, sizeof (struct __stat64));
+
+ int result = FS(_wstat) (path, &buf);
+
+ buffer->st_mode = buf.st_mode;
+ buffer->st_nlink = 1;
+ buffer->st_size = buf.st_size;
+ buffer->st_atime = buf.st_atime;
+ buffer->st_mtime = buf.st_mtime;
+
+ return result;
+}
+
#else
FILE *FS(fopen) (const char* filename, const char* mode)
{
diff --git a/utils/fs/fs.h b/utils/fs/fs.h
index ab2eded2a1..3931e6e03e 100644
--- a/utils/fs/fs.h
+++ b/utils/fs/fs.h
@@ -1,6 +1,6 @@
/* -----------------------------------------------------------------------------
*
- * (c) Tamar Christina 2018
+ * (c) Tamar Christina 2018-2019
*
* Windows I/O routines for file opening.
*
@@ -25,11 +25,18 @@
#if defined(_WIN32)
#include <wchar.h>
-
+wchar_t* FS(create_device_name) (const wchar_t*);
+int FS(translate_mode) (const wchar_t*);
int FS(swopen) (const wchar_t* filename, int oflag,
int shflag, int pmode);
+int FS(sopen) (const char* filename, int oflag,
+ int shflag, int pmode);
FILE *FS(fwopen) (const wchar_t* filename, const wchar_t* mode);
FILE *FS(fopen) (const char* filename, const char* mode);
+int FS(_stat) (const char *path, struct _stat *buffer);
+int FS(_stat64) (const char *path, struct __stat64 *buffer);
+int FS(_wstat) (const wchar_t *path, struct _stat *buffer);
+int FS(_wstat64) (const wchar_t *path, struct __stat64 *buffer);
#else
FILE *FS(fopen) (const char* filename, const char* mode);
diff --git a/utils/ghc-cabal/Main.hs b/utils/ghc-cabal/Main.hs
index 5827331c9c..0962f9ccde 100644
--- a/utils/ghc-cabal/Main.hs
+++ b/utils/ghc-cabal/Main.hs
@@ -385,7 +385,23 @@ generate directory distdir config_args
fixupRtsLibName x = x
transitiveDepNames = map (display . packageName) transitive_dep_ids
- libraryDirs = forDeps Installed.libraryDirs
+ -- Note [Msys2 path translation bug].
+ -- Msys2 has an annoying bug in their path conversion code.
+ -- Officially anything starting with a drive letter should not be
+ -- subjected to path translations, however it seems to only consider
+ -- E:\\ and E:// to be Windows paths. Mixed mode paths such as E:/
+ -- that are produced here get corrupted.
+ --
+ -- Tamar@Rage /t/translate> ./a.exe -optc-I"E://ghc-dev/msys64/"
+ -- path: -optc-IE://ghc-dev/msys64/
+ -- Tamar@Rage /t/translate> ./a.exe -optc-I"E:ghc-dev/msys64/"
+ -- path: -optc-IE:ghc-dev/msys64/
+ -- Tamar@Rage /t/translate> ./a.exe -optc-I"E:\ghc-dev/msys64/"
+ -- path: -optc-IE:\ghc-dev/msys64/
+ --
+ -- As such, let's just normalize the filepaths which is a good thing
+ -- to do anyway.
+ libraryDirs = map normalise $ forDeps Installed.libraryDirs
-- The mkLibraryRelDir function is a bit of a hack.
-- Ideally it should be handled in the makefiles instead.
mkLibraryRelDir "rts" = "rts/dist/build"
@@ -402,7 +418,8 @@ generate directory distdir config_args
injectDistInstall x | takeBaseName x == "include" = [x, takeDirectory x ++ "/dist-install/build/" ++ takeBaseName x]
injectDistInstall x = [x]
- wrappedIncludeDirs <- wrap $ concatMap injectDistInstall $ forDeps Installed.includeDirs
+ -- See Note [Msys2 path translation bug].
+ wrappedIncludeDirs <- wrap $ map normalise $ concatMap injectDistInstall $ forDeps Installed.includeDirs
let variablePrefix = directory ++ '_':distdir
mods = map display modules