summaryrefslogtreecommitdiff
path: root/rts/linker
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-07-13 11:07:40 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-07-16 23:50:36 -0400
commitfbb171100f1d5bd9e78cbb9072fb48d3422458a5 (patch)
treee2afd57f088141c5f14a900bd99699aef238c864 /rts/linker
parentd161e6bc606d7ec86f6d910a9f744ff513fd6df6 (diff)
downloadhaskell-fbb171100f1d5bd9e78cbb9072fb48d3422458a5.tar.gz
rts/linker/MachO: Introduce finalizer support
Diffstat (limited to 'rts/linker')
-rw-r--r--rts/linker/MachO.c29
-rw-r--r--rts/linker/MachO.h1
2 files changed, 30 insertions, 0 deletions
diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c
index 3145e40e03..a9b5f0c712 100644
--- a/rts/linker/MachO.c
+++ b/rts/linker/MachO.c
@@ -1641,6 +1641,35 @@ ocRunInit_MachO ( ObjectCode *oc )
return 1;
}
+int
+ocRunFini_MachO ( ObjectCode *oc )
+{
+ if (NULL == oc->info->segCmd) {
+ barf("ocRunInit_MachO: no segment load command");
+ }
+
+ for (int i = 0; i < oc->n_sections; i++) {
+ IF_DEBUG(linker, debugBelch("ocRunFini_MachO: checking section %d\n", i));
+
+ if (oc->sections[i].kind == SECTIONKIND_FINI_ARRAY) {
+ IF_DEBUG(linker, debugBelch("ocRunFini_MachO: running mod fini functions\n"));
+
+ void *fini_startC = oc->sections[i].start;
+ fini_t *fini = (fini_t*)fini_startC;
+ fini_t *fini_end = (fini_t*)((uint8_t*)fini_startC
+ + oc->sections[i].info->macho_section->size);
+
+ for (int pn = 0; fini < fini_end; fini++, pn++) {
+ IF_DEBUG(linker, debugBelch("ocRunFini_MachO: function pointer %d at %p to %p\n",
+ pn, (void *) fini, (void *) *fini));
+ (*fini)();
+ }
+ }
+ }
+
+ return 1;
+}
+
/*
* Figure out by how much to shift the entire Mach-O file in memory
* when loading so that its single segment ends up 16-byte-aligned
diff --git a/rts/linker/MachO.h b/rts/linker/MachO.h
index f55f68ddc8..4af3532b8d 100644
--- a/rts/linker/MachO.h
+++ b/rts/linker/MachO.h
@@ -12,6 +12,7 @@ int ocBuildSegments_MachO ( ObjectCode* oc );
int ocGetNames_MachO ( ObjectCode* oc );
int ocResolve_MachO ( ObjectCode* oc );
int ocRunInit_MachO ( ObjectCode* oc );
+int ocRunFini_MachO ( ObjectCode* oc );
int machoGetMisalignment ( FILE * );
int ocAllocateExtras_MachO ( ObjectCode* oc );