diff options
Diffstat (limited to 'rts')
-rw-r--r-- | rts/RtsSymbols.c | 44 | ||||
-rw-r--r-- | rts/RtsSymbols.h | 5 | ||||
-rw-r--r-- | rts/linker/PEi386.c | 10 | ||||
-rw-r--r-- | rts/linker/PEi386.h | 1 | ||||
-rw-r--r-- | rts/linker/elf_plt.h | 4 | ||||
-rw-r--r-- | rts/linker/elf_reloc_aarch64.c | 8 | ||||
-rw-r--r-- | rts/linker/elf_reloc_aarch64.h | 4 | ||||
-rw-r--r-- | rts/win32/OSMem.c | 8 | ||||
-rw-r--r-- | rts/win32/OSThreads.c | 22 |
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 { |