diff options
| author | Tamar Christina <tamar@zhox.com> | 2018-10-04 13:50:04 -0400 |
|---|---|---|
| committer | Ben Gamari <ben@smart-cactus.org> | 2018-10-04 22:27:54 -0400 |
| commit | 98daa34c73ed2a4bccc4cfb6608c6a614da61f8c (patch) | |
| tree | 0bb50573ed507ee6c85a6ef1557d7df1d78a126e | |
| parent | baec3586576c1eed0d6fab32ef34293484cf5a2e (diff) | |
| download | haskell-98daa34c73ed2a4bccc4cfb6608c6a614da61f8c.tar.gz | |
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
| -rw-r--r-- | rts/Linker.c | 6 | ||||
| -rw-r--r-- | rts/linker/PEi386.c | 35 |
2 files changed, 28 insertions, 13 deletions
diff --git a/rts/Linker.c b/rts/Linker.c index a1de6a7a14..826269738b 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 4dbb6291f9..ab4583da7c 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; |
