summaryrefslogtreecommitdiff
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
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
-rw-r--r--rts/Linker.c6
-rw-r--r--rts/linker/PEi386.c35
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;