summaryrefslogtreecommitdiff
path: root/rts/linker
diff options
context:
space:
mode:
authorTamar Christina <tamar@zhox.com>2018-10-04 13:50:04 -0400
committerBen Gamari <ben@smart-cactus.org>2018-10-04 22:27:54 -0400
commit98daa34c73ed2a4bccc4cfb6608c6a614da61f8c (patch)
tree0bb50573ed507ee6c85a6ef1557d7df1d78a126e /rts/linker
parentbaec3586576c1eed0d6fab32ef34293484cf5a2e (diff)
downloadhaskell-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
Diffstat (limited to 'rts/linker')
-rw-r--r--rts/linker/PEi386.c35
1 files changed, 22 insertions, 13 deletions
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;