summaryrefslogtreecommitdiff
path: root/rts/Linker.c
diff options
context:
space:
mode:
Diffstat (limited to 'rts/Linker.c')
-rw-r--r--rts/Linker.c576
1 files changed, 307 insertions, 269 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index 1b91e2f3d7..682e5db600 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -111,6 +111,7 @@
#elif defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
# define OBJFORMAT_PEi386
# include <windows.h>
+# include <shfolder.h> /* SHGetFolderPathW */
# include <math.h>
#elif defined(darwin_HOST_OS)
# define OBJFORMAT_MACHO
@@ -162,7 +163,7 @@ Mutex linker_mutex;
* This protects unloaded_objects. We have a separate mutex for this, because
* the GC needs to access unloaded_objects in checkUnload, while the linker only
* needs to access unloaded_objects in unloadObj(), so this allows most linker
- * operations proceed concurrently with the GC.
+ * operations proceed concurrently with the GC.
*/
Mutex linker_unloaded_mutex;
#endif
@@ -227,7 +228,10 @@ static int ocGetNames_PEi386 ( ObjectCode* oc );
static int ocResolve_PEi386 ( ObjectCode* oc );
static int ocRunInit_PEi386 ( ObjectCode* oc );
static void *lookupSymbolInDLLs ( unsigned char *lbl );
-static void zapTrailingAtSign ( unsigned char *sym );
+/* See Note [mingw-w64 name decoration scheme] */
+#ifndef x86_64_HOST_ARCH
+ static void zapTrailingAtSign ( unsigned char *sym );
+#endif
static char *allocateImageAndTrampolines (
pathchar* arch_name, char* member_name,
#if defined(x86_64_HOST_ARCH)
@@ -509,7 +513,6 @@ typedef struct _RtsSymbolVal {
SymI_HasProto(strcpy) \
SymI_HasProto(strncpy) \
SymI_HasProto(abort) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_alloca)) \
SymI_HasProto(isxdigit) \
SymI_HasProto(isupper) \
SymI_HasProto(ispunct) \
@@ -560,251 +563,239 @@ typedef struct _RtsSymbolVal {
SymI_HasProto(rts_InstallConsoleEvent) \
SymI_HasProto(rts_ConsoleHandlerDone) \
SymI_NeedsProto(mktime) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_imp___timezone)) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_imp___tzname)) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_imp__tzname)) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_imp___iob)) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_imp___osver)) \
SymI_NeedsProto(localtime) \
SymI_NeedsProto(gmtime) \
SymI_NeedsProto(opendir) \
SymI_NeedsProto(readdir) \
SymI_NeedsProto(rewinddir) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_imp____mb_cur_max)) \
- RTS_WIN32_ONLY(SymI_NeedsProto(_imp___pctype)) \
- RTS_WIN32_ONLY(SymI_NeedsProto(__chkstk)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp___iob_func)) \
+ RTS_WIN32_ONLY(SymI_NeedsProto(__chkstk_ms)) \
RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_localeconv)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_islower)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_isspace)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_isxdigit)) \
- RTS_WIN64_ONLY(SymI_HasProto(close)) \
- RTS_WIN64_ONLY(SymI_HasProto(read)) \
- RTS_WIN64_ONLY(SymI_HasProto(dup)) \
- RTS_WIN64_ONLY(SymI_HasProto(dup2)) \
- RTS_WIN64_ONLY(SymI_HasProto(write)) \
+ SymI_NeedsProto(localeconv) \
+ SymI_HasProto(close) \
+ SymI_HasProto(read) \
+ SymI_HasProto(dup) \
+ SymI_HasProto(dup2) \
+ SymI_HasProto(write) \
SymI_NeedsProto(getpid) \
- RTS_WIN64_ONLY(SymI_HasProto(access)) \
+ SymI_HasProto(access) \
SymI_HasProto(chmod) \
- RTS_WIN64_ONLY(SymI_HasProto(creat)) \
- RTS_WIN64_ONLY(SymI_HasProto(umask)) \
+ SymI_HasProto(creat) \
+ SymI_HasProto(umask) \
SymI_HasProto(unlink) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__errno)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(ftruncate64)) \
- RTS_WIN64_ONLY(SymI_HasProto(setmode)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__wstat64)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__fstat64)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__wsopen)) \
+ SymI_HasProto(_errno) \
+ SymI_NeedsProto(ftruncate64) \
+ SymI_HasProto(setmode) \
+ SymI_HasProto(_wstat64) \
+ SymI_HasProto(_fstat64) \
+ SymI_HasProto(_wsopen) \
+ RTS_WIN32_ONLY(SymI_HasProto(_imp___environ)) \
RTS_WIN64_ONLY(SymI_HasProto(__imp__environ)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetFileAttributesA)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetFileInformationByHandle)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetFileType)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetLastError)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_QueryPerformanceFrequency)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_QueryPerformanceCounter)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetTickCount)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_WaitForSingleObject)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_PeekConsoleInputA)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_ReadConsoleInputA)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_PeekNamedPipe)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__isatty)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_select)) \
- RTS_WIN64_ONLY(SymI_HasProto(isatty)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__get_osfhandle)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetConsoleMode)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SetConsoleMode)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_FlushConsoleInputBuffer)) \
- RTS_WIN64_ONLY(SymI_HasProto(free)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(raise)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(_getpid)) \
- RTS_WIN64_ONLY(SymI_HasProto(getc)) \
- RTS_WIN64_ONLY(SymI_HasProto(ungetc)) \
- RTS_WIN64_ONLY(SymI_HasProto(puts)) \
- RTS_WIN64_ONLY(SymI_HasProto(putc)) \
- RTS_WIN64_ONLY(SymI_HasProto(putchar)) \
- RTS_WIN64_ONLY(SymI_HasProto(fputc)) \
- RTS_WIN64_ONLY(SymI_HasProto(fread)) \
- RTS_WIN64_ONLY(SymI_HasProto(fwrite)) \
- RTS_WIN64_ONLY(SymI_HasProto(ferror)) \
- RTS_WIN64_ONLY(SymI_HasProto(printf)) \
- RTS_WIN64_ONLY(SymI_HasProto(fprintf)) \
- RTS_WIN64_ONLY(SymI_HasProto(sprintf)) \
- RTS_WIN64_ONLY(SymI_HasProto(vsprintf)) \
- RTS_WIN64_ONLY(SymI_HasProto(sscanf)) \
- RTS_WIN64_ONLY(SymI_HasProto(ldexp)) \
- RTS_WIN64_ONLY(SymI_HasProto(strlen)) \
- RTS_WIN64_ONLY(SymI_HasProto(strnlen)) \
- RTS_WIN64_ONLY(SymI_HasProto(strchr)) \
- RTS_WIN64_ONLY(SymI_HasProto(strtol)) \
- RTS_WIN64_ONLY(SymI_HasProto(strerror)) \
- RTS_WIN64_ONLY(SymI_HasProto(memchr)) \
- RTS_WIN64_ONLY(SymI_HasProto(memcmp)) \
- RTS_WIN64_ONLY(SymI_HasProto(wcscpy)) \
- RTS_WIN64_ONLY(SymI_HasProto(wcslen)) \
- RTS_WIN64_ONLY(SymI_HasProto(_lseeki64)) \
- RTS_WIN64_ONLY(SymI_HasProto(_wchmod)) \
- RTS_WIN64_ONLY(SymI_HasProto(closesocket)) \
- RTS_WIN64_ONLY(SymI_HasProto(send)) \
- RTS_WIN64_ONLY(SymI_HasProto(recv)) \
- RTS_WIN64_ONLY(SymI_HasProto(bsearch)) \
- RTS_WIN64_ONLY(SymI_HasProto(CommandLineToArgvW)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateBitmap)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateBitmapIndirect)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateCompatibleBitmap)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateDIBPatternBrushPt)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateDIBitmap)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetBitmapDimensionEx)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetBitmapDimensionEx)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetStockObject)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetObjectW)) \
- RTS_WIN64_ONLY(SymI_HasProto(DeleteObject)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetDIBits)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetDIBits)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateSolidBrush)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateHatchBrush)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreatePatternBrush)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateFontW)) \
- RTS_WIN64_ONLY(SymI_HasProto(AngleArc)) \
- RTS_WIN64_ONLY(SymI_HasProto(Arc)) \
- RTS_WIN64_ONLY(SymI_HasProto(ArcTo)) \
- RTS_WIN64_ONLY(SymI_HasProto(BeginPath)) \
- RTS_WIN64_ONLY(SymI_HasProto(BitBlt)) \
- RTS_WIN64_ONLY(SymI_HasProto(CancelDC)) \
- RTS_WIN64_ONLY(SymI_HasProto(Chord)) \
- RTS_WIN64_ONLY(SymI_HasProto(CloseFigure)) \
- RTS_WIN64_ONLY(SymI_HasProto(CombineRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateCompatibleDC)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateEllipticRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateEllipticRgnIndirect)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreatePen)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreatePolygonRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateRectRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateRectRgnIndirect)) \
- RTS_WIN64_ONLY(SymI_HasProto(CreateRoundRectRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(DeleteDC)) \
- RTS_WIN64_ONLY(SymI_HasProto(Ellipse)) \
- RTS_WIN64_ONLY(SymI_HasProto(EndPath)) \
- RTS_WIN64_ONLY(SymI_HasProto(EqualRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(ExtSelectClipRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(FillPath)) \
- RTS_WIN64_ONLY(SymI_HasProto(FillRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(FlattenPath)) \
- RTS_WIN64_ONLY(SymI_HasProto(FrameRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetArcDirection)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetBkColor)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetBkMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetBrushOrgEx)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetCurrentObject)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetDCOrgEx)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetGraphicsMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetMiterLimit)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetPolyFillMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetRgnBox)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetStretchBltMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetTextAlign)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetTextCharacterExtra)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetTextColor)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetTextExtentPoint32W)) \
- RTS_WIN64_ONLY(SymI_HasProto(InvertRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(LineTo)) \
- RTS_WIN64_ONLY(SymI_HasProto(MaskBlt)) \
- RTS_WIN64_ONLY(SymI_HasProto(MoveToEx)) \
- RTS_WIN64_ONLY(SymI_HasProto(OffsetRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(PaintRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(PathToRegion)) \
- RTS_WIN64_ONLY(SymI_HasProto(Pie)) \
- RTS_WIN64_ONLY(SymI_HasProto(PlgBlt)) \
- RTS_WIN64_ONLY(SymI_HasProto(PolyBezier)) \
- RTS_WIN64_ONLY(SymI_HasProto(PolyBezierTo)) \
- RTS_WIN64_ONLY(SymI_HasProto(Polygon)) \
- RTS_WIN64_ONLY(SymI_HasProto(Polyline)) \
- RTS_WIN64_ONLY(SymI_HasProto(PolylineTo)) \
- RTS_WIN64_ONLY(SymI_HasProto(PtInRegion)) \
- RTS_WIN64_ONLY(SymI_HasProto(Rectangle)) \
- RTS_WIN64_ONLY(SymI_HasProto(RectInRegion)) \
- RTS_WIN64_ONLY(SymI_HasProto(RestoreDC)) \
- RTS_WIN64_ONLY(SymI_HasProto(RoundRect)) \
- RTS_WIN64_ONLY(SymI_HasProto(SaveDC)) \
- RTS_WIN64_ONLY(SymI_HasProto(SelectClipPath)) \
- RTS_WIN64_ONLY(SymI_HasProto(SelectClipRgn)) \
- RTS_WIN64_ONLY(SymI_HasProto(SelectObject)) \
- RTS_WIN64_ONLY(SymI_HasProto(SelectPalette)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetArcDirection)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetBkColor)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetBkMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetBrushOrgEx)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetGraphicsMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetMiterLimit)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetPolyFillMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetStretchBltMode)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetTextAlign)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetTextCharacterExtra)) \
- RTS_WIN64_ONLY(SymI_HasProto(SetTextColor)) \
- RTS_WIN64_ONLY(SymI_HasProto(StretchBlt)) \
- RTS_WIN64_ONLY(SymI_HasProto(StrokeAndFillPath)) \
- RTS_WIN64_ONLY(SymI_HasProto(StrokePath)) \
- RTS_WIN64_ONLY(SymI_HasProto(TextOutW)) \
- RTS_WIN64_ONLY(SymI_HasProto(timeGetTime)) \
- RTS_WIN64_ONLY(SymI_HasProto(WidenPath)) \
- RTS_WIN64_ONLY(SymI_HasProto(GetFileSecurityW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegCloseKey)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegConnectRegistryW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegCreateKeyExW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegCreateKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegDeleteKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegDeleteValueW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegEnumKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegEnumValueW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegFlushKey)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegLoadKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegNotifyChangeKeyValue)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegOpenKeyExW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegOpenKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegQueryInfoKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegQueryValueExW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegQueryValueW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegReplaceKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegRestoreKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegSaveKeyW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegSetValueExW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegSetValueW)) \
- RTS_WIN64_ONLY(SymI_HasProto(RegUnLoadKeyW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(SHGetFolderPathW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SetWindowLongPtrW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetWindowLongPtrW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_MenuItemFromPoint)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_ChildWindowFromPoint)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_ChildWindowFromPointEx)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DeleteObject)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_UnmapViewOfFile)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CloseHandle)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_FreeLibrary)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetMessageW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_TranslateMessage)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DispatchMessageW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DefWindowProcW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetDIBits)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GlobalAlloc)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GlobalFree)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreateFileW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_WriteFile)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreateCompatibleBitmap)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SelectObject)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_Polygon)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_FormatMessageW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__localtime64)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__tzname)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__timezone)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreatePipe)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_SetHandleInformation)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetStdHandle)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetCurrentProcess)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_DuplicateHandle)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_CreateProcessW)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_TerminateProcess)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp__open_osfhandle)) \
- RTS_WIN64_ONLY(SymI_NeedsProto(__imp_GetExitCodeProcess)) \
+ RTS_WIN32_ONLY(SymI_HasProto(_imp___iob)) \
+ RTS_WIN64_ONLY(SymI_HasProto(__iob_func)) \
+ SymI_HasProto(GetFileAttributesA) \
+ SymI_HasProto(GetFileInformationByHandle) \
+ SymI_HasProto(GetFileType) \
+ SymI_HasProto(GetLastError) \
+ SymI_HasProto(QueryPerformanceFrequency) \
+ SymI_HasProto(QueryPerformanceCounter) \
+ SymI_HasProto(GetTickCount) \
+ SymI_HasProto(WaitForSingleObject) \
+ SymI_HasProto(PeekConsoleInputA) \
+ SymI_HasProto(ReadConsoleInputA) \
+ SymI_HasProto(PeekNamedPipe) \
+ SymI_HasProto(select) \
+ SymI_HasProto(isatty) \
+ SymI_HasProto(_get_osfhandle) \
+ SymI_HasProto(GetConsoleMode) \
+ SymI_HasProto(SetConsoleMode) \
+ SymI_HasProto(FlushConsoleInputBuffer) \
+ SymI_HasProto(free) \
+ SymI_NeedsProto(raise) \
+ SymI_NeedsProto(_getpid) \
+ SymI_HasProto(getc) \
+ SymI_HasProto(ungetc) \
+ SymI_HasProto(puts) \
+ SymI_HasProto(putc) \
+ SymI_HasProto(putchar) \
+ SymI_HasProto(fputc) \
+ SymI_HasProto(fread) \
+ SymI_HasProto(fwrite) \
+ SymI_HasProto(ferror) \
+ SymI_HasProto(printf) \
+ SymI_HasProto(fprintf) \
+ SymI_HasProto(sprintf) \
+ SymI_HasProto(vsprintf) \
+ SymI_HasProto(sscanf) \
+ SymI_HasProto(ldexp) \
+ SymI_HasProto(strlen) \
+ SymI_HasProto(strnlen) \
+ SymI_HasProto(strchr) \
+ SymI_HasProto(strtol) \
+ SymI_HasProto(strerror) \
+ SymI_HasProto(memchr) \
+ SymI_HasProto(memcmp) \
+ SymI_HasProto(wcscpy) \
+ SymI_HasProto(wcslen) \
+ SymI_HasProto(_lseeki64) \
+ SymI_HasProto(_wchmod) \
+ SymI_HasProto(closesocket) \
+ SymI_HasProto(send) \
+ SymI_HasProto(recv) \
+ SymI_HasProto(bsearch) \
+ SymI_HasProto(CommandLineToArgvW) \
+ SymI_HasProto(CreateBitmap) \
+ SymI_HasProto(CreateBitmapIndirect) \
+ SymI_HasProto(CreateCompatibleBitmap) \
+ SymI_HasProto(CreateDIBPatternBrushPt) \
+ SymI_HasProto(CreateDIBitmap) \
+ SymI_HasProto(SetBitmapDimensionEx) \
+ SymI_HasProto(GetBitmapDimensionEx) \
+ SymI_HasProto(GetStockObject) \
+ SymI_HasProto(GetObjectW) \
+ SymI_HasProto(DeleteObject) \
+ SymI_HasProto(SetDIBits) \
+ SymI_HasProto(GetDIBits) \
+ SymI_HasProto(CreateSolidBrush) \
+ SymI_HasProto(CreateHatchBrush) \
+ SymI_HasProto(CreatePatternBrush) \
+ SymI_HasProto(CreateFontW) \
+ SymI_HasProto(AngleArc) \
+ SymI_HasProto(Arc) \
+ SymI_HasProto(ArcTo) \
+ SymI_HasProto(BeginPath) \
+ SymI_HasProto(BitBlt) \
+ SymI_HasProto(CancelDC) \
+ SymI_HasProto(Chord) \
+ SymI_HasProto(CloseFigure) \
+ SymI_HasProto(CombineRgn) \
+ SymI_HasProto(CreateCompatibleDC) \
+ SymI_HasProto(CreateEllipticRgn) \
+ SymI_HasProto(CreateEllipticRgnIndirect) \
+ SymI_HasProto(CreatePen) \
+ SymI_HasProto(CreatePolygonRgn) \
+ SymI_HasProto(CreateRectRgn) \
+ SymI_HasProto(CreateRectRgnIndirect) \
+ SymI_HasProto(CreateRoundRectRgn) \
+ SymI_HasProto(DeleteDC) \
+ SymI_HasProto(Ellipse) \
+ SymI_HasProto(EndPath) \
+ SymI_HasProto(EqualRgn) \
+ SymI_HasProto(ExtSelectClipRgn) \
+ SymI_HasProto(FillPath) \
+ SymI_HasProto(FillRgn) \
+ SymI_HasProto(FlattenPath) \
+ SymI_HasProto(FrameRgn) \
+ SymI_HasProto(GetArcDirection) \
+ SymI_HasProto(GetBkColor) \
+ SymI_HasProto(GetBkMode) \
+ SymI_HasProto(GetBrushOrgEx) \
+ SymI_HasProto(GetCurrentObject) \
+ SymI_HasProto(GetDCOrgEx) \
+ SymI_HasProto(GetGraphicsMode) \
+ SymI_HasProto(GetMiterLimit) \
+ SymI_HasProto(GetPolyFillMode) \
+ SymI_HasProto(GetRgnBox) \
+ SymI_HasProto(GetStretchBltMode) \
+ SymI_HasProto(GetTextAlign) \
+ SymI_HasProto(GetTextCharacterExtra) \
+ SymI_HasProto(GetTextColor) \
+ SymI_HasProto(GetTextExtentPoint32W) \
+ SymI_HasProto(InvertRgn) \
+ SymI_HasProto(LineTo) \
+ SymI_HasProto(MaskBlt) \
+ SymI_HasProto(MoveToEx) \
+ SymI_HasProto(OffsetRgn) \
+ SymI_HasProto(PaintRgn) \
+ SymI_HasProto(PathToRegion) \
+ SymI_HasProto(Pie) \
+ SymI_HasProto(PlgBlt) \
+ SymI_HasProto(PolyBezier) \
+ SymI_HasProto(PolyBezierTo) \
+ SymI_HasProto(Polygon) \
+ SymI_HasProto(Polyline) \
+ SymI_HasProto(PolylineTo) \
+ SymI_HasProto(PtInRegion) \
+ SymI_HasProto(Rectangle) \
+ SymI_HasProto(RectInRegion) \
+ SymI_HasProto(RestoreDC) \
+ SymI_HasProto(RoundRect) \
+ SymI_HasProto(SaveDC) \
+ SymI_HasProto(SelectClipPath) \
+ SymI_HasProto(SelectClipRgn) \
+ SymI_HasProto(SelectObject) \
+ SymI_HasProto(SelectPalette) \
+ SymI_HasProto(SetArcDirection) \
+ SymI_HasProto(SetBkColor) \
+ SymI_HasProto(SetBkMode) \
+ SymI_HasProto(SetBrushOrgEx) \
+ SymI_HasProto(SetGraphicsMode) \
+ SymI_HasProto(SetMiterLimit) \
+ SymI_HasProto(SetPolyFillMode) \
+ SymI_HasProto(SetStretchBltMode) \
+ SymI_HasProto(SetTextAlign) \
+ SymI_HasProto(SetTextCharacterExtra) \
+ SymI_HasProto(SetTextColor) \
+ SymI_HasProto(StretchBlt) \
+ SymI_HasProto(StrokeAndFillPath) \
+ SymI_HasProto(StrokePath) \
+ SymI_HasProto(TextOutW) \
+ SymI_HasProto(timeGetTime) \
+ SymI_HasProto(WidenPath) \
+ SymI_HasProto(GetFileSecurityW) \
+ SymI_HasProto(RegCloseKey) \
+ SymI_HasProto(RegConnectRegistryW) \
+ SymI_HasProto(RegCreateKeyExW) \
+ SymI_HasProto(RegCreateKeyW) \
+ SymI_HasProto(RegDeleteKeyW) \
+ SymI_HasProto(RegDeleteValueW) \
+ SymI_HasProto(RegEnumKeyW) \
+ SymI_HasProto(RegEnumValueW) \
+ SymI_HasProto(RegFlushKey) \
+ SymI_HasProto(RegLoadKeyW) \
+ SymI_HasProto(RegNotifyChangeKeyValue) \
+ SymI_HasProto(RegOpenKeyExW) \
+ SymI_HasProto(RegOpenKeyW) \
+ SymI_HasProto(RegQueryInfoKeyW) \
+ SymI_HasProto(RegQueryValueExW) \
+ SymI_HasProto(RegQueryValueW) \
+ SymI_HasProto(RegReplaceKeyW) \
+ SymI_HasProto(RegRestoreKeyW) \
+ SymI_HasProto(RegSaveKeyW) \
+ SymI_HasProto(RegSetValueExW) \
+ SymI_HasProto(RegSetValueW) \
+ SymI_HasProto(RegUnLoadKeyW) \
+ SymI_HasProto(SHGetFolderPathW) \
+ RTS_WIN32_ONLY(SymI_HasProto(SetWindowLongW)) \
+ RTS_WIN32_ONLY(SymI_HasProto(GetWindowLongW)) \
+ RTS_WIN64_ONLY(SymI_HasProto(SetWindowLongPtrW)) \
+ RTS_WIN64_ONLY(SymI_HasProto(GetWindowLongPtrW)) \
+ SymI_HasProto(MenuItemFromPoint) \
+ SymI_HasProto(ChildWindowFromPoint) \
+ SymI_HasProto(ChildWindowFromPointEx) \
+ SymI_HasProto(UnmapViewOfFile) \
+ SymI_HasProto(CloseHandle) \
+ SymI_HasProto(FreeLibrary) \
+ SymI_HasProto(GetMessageW) \
+ SymI_HasProto(TranslateMessage) \
+ SymI_HasProto(DispatchMessageW) \
+ SymI_HasProto(DefWindowProcW) \
+ SymI_HasProto(GlobalAlloc) \
+ SymI_HasProto(GlobalFree) \
+ SymI_HasProto(CreateFileW) \
+ SymI_HasProto(WriteFile) \
+ SymI_HasProto(FormatMessageW) \
+ SymI_NeedsProto(_localtime64) \
+ SymI_NeedsProto(_tzname) \
+ SymI_NeedsProto(_timezone) \
+ SymI_HasProto(CreatePipe) \
+ SymI_HasProto(SetHandleInformation) \
+ SymI_HasProto(GetStdHandle) \
+ SymI_HasProto(GetCurrentProcess) \
+ SymI_HasProto(DuplicateHandle) \
+ SymI_HasProto(CreateProcessW) \
+ SymI_HasProto(TerminateProcess) \
+ SymI_HasProto(_open_osfhandle) \
+ SymI_HasProto(GetExitCodeProcess) \
RTS_MINGW_GETTIMEOFDAY_SYM \
SymI_NeedsProto(closedir)
@@ -2111,14 +2102,10 @@ static void* lookupSymbol_ (char *lbl)
# elif defined(OBJFORMAT_PEi386)
void* sym;
- sym = lookupSymbolInDLLs((unsigned char*)lbl);
- if (sym != NULL) {
- return sym;
- };
-
- // Also try looking up the symbol without the @N suffix. Some
- // DLLs have the suffixes on their symbols, some don't.
- zapTrailingAtSign ( (unsigned char*)lbl );
+/* See Note [mingw-w64 name decoration scheme] */
+#ifndef x86_64_HOST_ARCH
+ zapTrailingAtSign ( (unsigned char*)lbl );
+#endif
sym = lookupSymbolInDLLs((unsigned char*)lbl);
return sym; // might be NULL if not found
@@ -2401,6 +2388,7 @@ void freeObjectCode (ObjectCode *oc)
stgFree(ia);
ia = ia_next;
}
+ indirects = NULL;
#endif
@@ -3770,6 +3758,7 @@ typedef
/* From PE spec doc, section 4.1 */
#define MYIMAGE_SCN_CNT_CODE 0x00000020
#define MYIMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define MYIMAGE_SCN_LNK_COMDAT 0x00001000
#define MYIMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
/* From PE spec doc, section 5.2.1 */
@@ -3994,6 +3983,8 @@ findPEi386SectionCalled ( ObjectCode* oc, UChar* name, UChar* strtab )
return NULL;
}
+/* See Note [mingw-w64 name decoration scheme] */
+#ifndef x86_64_HOST_ARCH
static void
zapTrailingAtSign ( UChar* sym )
{
@@ -4008,6 +3999,30 @@ zapTrailingAtSign ( UChar* sym )
if (j > 0 && sym[j] == '@' && j != i) sym[j] = 0;
# undef my_isdigit
}
+#endif
+
+/* See Note [mingw-w64 name decoration scheme] */
+#ifndef x86_64_HOST_ARCH
+#define STRIP_LEADING_UNDERSCORE 1
+#else
+#define STRIP_LEADING_UNDERSCORE 0
+#endif
+
+/*
+ Note [mingw-w64 name decoration scheme]
+
+ What's going on with name decoration? Well, original code
+ have some crufty and ad-hocish paths related mostly to very old
+ mingw gcc/binutils/runtime combinations. Now mingw-w64 offers pretty
+ uniform and MS-compatible decoration scheme across its tools and runtime.
+
+ The scheme is pretty straightforward: on 32 bit objects symbols are exported
+ with underscore prepended (and @ + stack size suffix appended for stdcall
+ functions), on 64 bits no underscore is prepended and no suffix is appended
+ because we have no stdcall convention on 64 bits.
+
+ See #9218
+*/
static void *
lookupSymbolInDLLs ( UChar *lbl )
@@ -4018,17 +4033,10 @@ lookupSymbolInDLLs ( UChar *lbl )
for (o_dll = opened_dlls; o_dll != NULL; o_dll = o_dll->next) {
/* debugBelch("look in %ls for %s\n", o_dll->name, lbl); */
- if (lbl[0] == '_') {
- /* HACK: if the name has an initial underscore, try stripping
- it off & look that up first. I've yet to verify whether there's
- a Rule that governs whether an initial '_' *should always* be
- stripped off when mapping from import lib name to the DLL name.
- */
- sym = GetProcAddress(o_dll->instance, (char*)(lbl+1));
- if (sym != NULL) {
- /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
- return sym;
- }
+ sym = GetProcAddress(o_dll->instance, (char*)(lbl+STRIP_LEADING_UNDERSCORE));
+ if (sym != NULL) {
+ /*debugBelch("found %s in %s\n", lbl+1,o_dll->name);*/
+ return sym;
}
/* Ticket #2283.
@@ -4039,7 +4047,7 @@ lookupSymbolInDLLs ( UChar *lbl )
the same semantics as in __imp_foo = GetProcAddress(..., "foo")
*/
if (sym == NULL && strncmp ((const char*)lbl, "__imp_", 6) == 0) {
- sym = GetProcAddress(o_dll->instance, (char*)(lbl+6));
+ sym = GetProcAddress(o_dll->instance, (char*)(lbl+6+STRIP_LEADING_UNDERSCORE));
if (sym != NULL) {
IndirectAddr* ret;
ret = stgMallocBytes( sizeof(IndirectAddr), "lookupSymbolInDLLs" );
@@ -4048,7 +4056,7 @@ lookupSymbolInDLLs ( UChar *lbl )
indirects = ret;
IF_DEBUG(linker,
debugBelch("warning: %s from %S is linked instead of %s",
- (char*)(lbl+6), o_dll->name, (char*)lbl));
+ (char*)(lbl+6+STRIP_LEADING_UNDERSCORE), o_dll->name, (char*)lbl));
return (void*) & ret->addr;
}
}
@@ -4374,11 +4382,14 @@ ocGetNames_PEi386 ( ObjectCode* oc )
kind = SECTIONKIND_CODE_OR_RODATA;
# endif
- if (0==strcmp(".text",(char*)secname) ||
- 0==strcmp(".text.startup",(char*)secname) ||
+ if (0==strcmp(".text",(char*)secname) ||
+ 0==strcmp(".text.startup",(char*)secname) ||
0==strcmp(".text.unlikely", (char*)secname) ||
- 0==strcmp(".rdata",(char*)secname)||
- 0==strcmp(".eh_frame", (char*)secname)||
+ 0==strncmp(".text$",(char*)secname, 6) ||
+ /* See Note [.rdata section group] */
+ (0==strncmp(".rdata",(char*)secname, 6) &&
+ 0!=strcmp(".rdata$zzz", (char*)secname)) ||
+ 0==strcmp(".eh_frame", (char*)secname) ||
0==strcmp(".rodata",(char*)secname))
kind = SECTIONKIND_CODE_OR_RODATA;
if (0==strcmp(".data",(char*)secname) ||
@@ -4406,6 +4417,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
&& 0!= strncmp(".debug", (char*)secname, 6)
/* ignore unknown section that appeared in gcc 3.4.5(?) */
&& 0!= strcmp(".reloc", (char*)secname)
+ /* See Note [.rdata section group] */
&& 0 != strcmp(".rdata$zzz", (char*)secname)
/* ignore linker directive sections */
&& 0 != strcmp(".drectve", (char*)secname)
@@ -4427,6 +4439,24 @@ ocGetNames_PEi386 ( ObjectCode* oc )
stgFree(secname);
}
+/*
+ Note [.rdata section group]
+
+ Most of the sections .rdata group section we want to load
+ and consider a SECTIONKIND_CODE_OR_RODATA section.
+ With the exception of .rdata$zzz which is just a section
+ containing the GCC version:
+
+ Contents of section .rdata$zzz:
+ 0000 4743433a 20285265 76332c20 4275696c GCC: (Rev3, Buil
+ 0010 74206279 204d5359 53322070 726f6a65 t by MSYS2 proje
+ 0020 63742920 352e322e 30000000 00000000 ct) 5.2.0.......
+
+ Because we're inspecting the group members one by one, we shouldn't
+ consider this code since we can't load it. Instead consider it an OTHER
+ section.
+*/
+
/* Copy exported symbols into the ObjectCode. */
oc->n_symbols = hdr->NumberOfSymbols;
@@ -4445,8 +4475,8 @@ ocGetNames_PEi386 ( ObjectCode* oc )
addr = NULL;
- if (symtab_i->StorageClass == MYIMAGE_SYM_CLASS_EXTERNAL
- && symtab_i->SectionNumber != MYIMAGE_SYM_UNDEFINED) {
+ HsBool isWeak = HS_BOOL_FALSE;
+ if (symtab_i->SectionNumber != MYIMAGE_SYM_UNDEFINED) {
/* This symbol is global and defined, viz, exported */
/* for MYIMAGE_SYMCLASS_EXTERNAL
&& !MYIMAGE_SYM_UNDEFINED,
@@ -4457,9 +4487,17 @@ ocGetNames_PEi386 ( ObjectCode* oc )
= (COFF_section*) myindex ( sizeof_COFF_section,
sectab,
symtab_i->SectionNumber-1 );
- addr = ((UChar*)(oc->image))
- + (sectabent->PointerToRawData
- + symtab_i->Value);
+ if (symtab_i->StorageClass == MYIMAGE_SYM_CLASS_EXTERNAL
+ || ( symtab_i->StorageClass == MYIMAGE_SYM_CLASS_STATIC
+ && sectabent->Characteristics & MYIMAGE_SCN_LNK_COMDAT)
+ ) {
+ addr = ((UChar*)(oc->image))
+ + (sectabent->PointerToRawData
+ + symtab_i->Value);
+ if (sectabent->Characteristics & MYIMAGE_SCN_LNK_COMDAT) {
+ isWeak = HS_BOOL_TRUE;
+ }
+ }
}
else
if (symtab_i->SectionNumber == MYIMAGE_SYM_UNDEFINED
@@ -4482,7 +4520,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
/* cstring_from_COFF_symbol_name always succeeds. */
oc->symbols[i] = (char*)sname;
if (! ghciInsertSymbolTable(oc->fileName, symhash, (char*)sname, addr,
- HS_BOOL_FALSE, oc)) {
+ isWeak, oc)) {
return 0;
}
} else {