[commit: ghc] ghc-7.8: linker: Fix indirect calls for x86_64 windows (#2283) (38b3e7b)
git at git.haskell.org
git at git.haskell.org
Sat Mar 22 19:38:44 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : ghc-7.8
Link : http://ghc.haskell.org/trac/ghc/changeset/38b3e7b7df8ffdedb626b40ad9437aeaacc8024f/ghc
>---------------------------------------------------------------
commit 38b3e7b7df8ffdedb626b40ad9437aeaacc8024f
Author: Kyrill Briantsev <kyrab at mail.ru>
Date: Fri Mar 21 05:42:48 2014 -0500
linker: Fix indirect calls for x86_64 windows (#2283)
Signed-off-by: Austin Seipp <austin at well-typed.com>
(cherry picked from commit 7a1c85113dd082153cc07f4792216beaf34daeeb)
>---------------------------------------------------------------
38b3e7b7df8ffdedb626b40ad9437aeaacc8024f
rts/Linker.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/rts/Linker.c b/rts/Linker.c
index 8f57873..814f930 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1718,6 +1718,18 @@ typedef
/* A list thereof. */
static OpenedDLL* opened_dlls = NULL;
+
+/* A record for storing indirectly linked functions from DLLs. */
+typedef
+ struct _IndirectAddr {
+ void* addr;
+ struct _IndirectAddr* next;
+ }
+ IndirectAddr;
+
+/* A list thereof. */
+static IndirectAddr* indirects = NULL;
+
#endif
# if defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO)
@@ -2189,6 +2201,15 @@ void freeObjectCode (ObjectCode *oc)
stgFree(oc->image);
#else
VirtualFree(oc->image - PEi386_IMAGE_OFFSET, 0, MEM_RELEASE);
+
+ IndirectAddr *ia, *ia_next;
+ ia = indirects;
+ while (ia != NULL) {
+ ia_next = ia->next;
+ stgFree(ia);
+ ia = ia_next;
+ }
+
#endif
#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
@@ -3698,15 +3719,20 @@ lookupSymbolInDLLs ( UChar *lbl )
Long description: http://support.microsoft.com/kb/132044
tl;dr:
If C/C++ compiler sees __declspec(dllimport) ... foo ...
- it generates call __imp_foo, and __imp_foo here has exactly
+ it generates call *__imp_foo, and __imp_foo here has exactly
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));
if (sym != NULL) {
+ IndirectAddr* ret;
+ ret = stgMallocBytes( sizeof(IndirectAddr), "lookupSymbolInDLLs" );
+ ret->addr = sym;
+ ret->next = indirects;
+ indirects = ret;
errorBelch("warning: %s from %S is linked instead of %s",
(char*)(lbl+6), o_dll->name, (char*)lbl);
- return sym;
+ return (void*) & ret->addr;
}
}
More information about the ghc-commits
mailing list