[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