summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
Diffstat (limited to 'rts')
-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
9 files changed, 79 insertions, 27 deletions
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 {