[commit: ghc] master: Fix PE linker wibbles (98daa34)

git at git.haskell.org git at git.haskell.org
Fri Oct 5 03:35:21 UTC 2018


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/98daa34c73ed2a4bccc4cfb6608c6a614da61f8c/ghc

>---------------------------------------------------------------

commit 98daa34c73ed2a4bccc4cfb6608c6a614da61f8c
Author: Tamar Christina <tamar at zhox.com>
Date:   Thu Oct 4 13:50:04 2018 -0400

    Fix PE linker wibbles
    
    Fix some various issues that popped up because the linker now doesn't
    load import libraries for longer than it needs to.
    
    These are all use after free issues.
    
    Test Plan: ./validate
    
    Reviewers: bgamari, erikd, simonmar
    
    Reviewed By: bgamari
    
    Subscribers: simonpj, rwbarton, carter
    
    Differential Revision: https://phabricator.haskell.org/D5175


>---------------------------------------------------------------

98daa34c73ed2a4bccc4cfb6608c6a614da61f8c
 rts/Linker.c        |  6 ++++++
 rts/linker/PEi386.c | 35 ++++++++++++++++++++++-------------
 2 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/rts/Linker.c b/rts/Linker.c
index a1de6a7..8262697 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1235,6 +1235,12 @@ void freeObjectCode (ObjectCode *oc)
 * Sets the initial status of a fresh ObjectCode
 */
 static void setOcInitialStatus(ObjectCode* oc) {
+    /* If a target has requested the ObjectCode not to be resolved then
+       honor this requests.  Usually this means the ObjectCode has not been
+       initialized and can't be.  */
+    if (oc->status == OBJECT_DONT_RESOLVE)
+      return;
+
     if (oc->archiveMemberName == NULL) {
         oc->status = OBJECT_NEEDED;
     } else {
diff --git a/rts/linker/PEi386.c b/rts/linker/PEi386.c
index 4dbb629..ab4583d 100644
--- a/rts/linker/PEi386.c
+++ b/rts/linker/PEi386.c
@@ -414,12 +414,11 @@ void freePreloadObjectFile_PEi386(ObjectCode *oc)
         oc->image = NULL;
     }
 
-    if (oc->info->image) {
-        HeapFree(code_heap, 0, oc->info->image);
-        oc->info->image = NULL;
-    }
-
     if (oc->info) {
+        if (oc->info->image) {
+            HeapFree(code_heap, 0, oc->info->image);
+            oc->info->image = NULL;
+        }
         if (oc->info->ch_info)
            stgFree (oc->info->ch_info);
         stgFree (oc->info);
@@ -447,15 +446,15 @@ static void releaseOcInfo(ObjectCode* oc) {
         oc->info = NULL;
     }
     for (int i = 0; i < oc->n_sections; i++){
-        Section section = oc->sections[i];
-        if (section.info) {
-            stgFree (section.info->name);
-            if (section.info->relocs) {
-                stgFree (section.info->relocs);
-                section.info->relocs = NULL;
+        Section *section = &oc->sections[i];
+        if (section->info) {
+            stgFree (section->info->name);
+            if (section->info->relocs) {
+                stgFree (section->info->relocs);
+                section->info->relocs = NULL;
             }
-            stgFree (section.info);
-            section.info = NULL;
+            stgFree (section->info);
+            section->info = NULL;
         }
     }
 }
@@ -1161,6 +1160,11 @@ ocVerifyImage_PEi386 ( ObjectCode* oc )
 {
    COFF_HEADER_INFO *info = getHeaderInfo (oc);
 
+   /* If the header could not be read, then don't process the ObjectCode.
+      This the case when the ObjectCode has been partially freed.  */
+   if (!info)
+     return false;
+
    uint32_t i, noRelocs;
    COFF_section* sectab;
    COFF_symbol*  symtab;
@@ -1530,6 +1534,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
           stgFree (oc->image);
           oc->image = NULL;
           releaseOcInfo (oc);
+          oc->status = OBJECT_DONT_RESOLVE;
           return true;
       }
 
@@ -1831,6 +1836,10 @@ ocResolve_PEi386 ( ObjectCode* oc )
    uint8_t symbol[1000];
    /* debugBelch("resolving for %s\n", oc->fileName); */
 
+   /* Such libraries have been partially freed and can't be resolved.  */
+   if (oc->status == OBJECT_DONT_RESOLVE)
+     return 1;
+
    COFF_HEADER_INFO *info = oc->info->ch_info;
    uint32_t numberOfSections = info->numberOfSections;
 



More information about the ghc-commits mailing list