summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rts/Linker.c9
-rw-r--r--rts/linker/LoadArchive.c3
-rw-r--r--rts/linker/MachO.c81
-rw-r--r--rts/linker/MachO.h4
4 files changed, 93 insertions, 4 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index 87f1eebf04..529af9ac9a 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1186,6 +1186,10 @@ void freeObjectCode (ObjectCode *oc)
}
#endif
+#if defined(OBJECTFORMAT_MACHO)
+ ocDeinit_MachO(oc);
+#endif
+
stgFree(oc->fileName);
stgFree(oc->archiveMemberName);
@@ -1389,6 +1393,11 @@ preloadObjectFile (pathchar *path)
oc = mkOc(path, image, fileSize, true, NULL, misalignment);
+#ifdef OBJFORMAT_MACHO
+ if (ocVerifyImage_MachO( oc ))
+ ocInit_MachO( oc );
+#endif
+
return oc;
}
diff --git a/rts/linker/LoadArchive.c b/rts/linker/LoadArchive.c
index f9997cf598..a33c00da3e 100644
--- a/rts/linker/LoadArchive.c
+++ b/rts/linker/LoadArchive.c
@@ -538,6 +538,9 @@ static HsInt loadArchive_ (pathchar *path)
oc = mkOc(path, image, memberSize, false, archiveMemberName
, misalignment);
+#ifdef OBJFORMAT_MACHO
+ ocInit_MachO( oc );
+#endif
stgFree(archiveMemberName);
diff --git a/rts/linker/MachO.c b/rts/linker/MachO.c
index 55b2bf1ebc..13508fac70 100644
--- a/rts/linker/MachO.c
+++ b/rts/linker/MachO.c
@@ -1,6 +1,6 @@
#include "Rts.h"
-#ifdef darwin_HOST_OS
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
#include "RtsUtils.h"
#include "GetEnv.h"
@@ -17,7 +17,7 @@
#include <mach-o/nlist.h>
#include <mach-o/reloc.h>
-#if defined(HAVE_SYS_MMAN_H)
+#if defined(HAVE_SYS_MMAN_H) && RTS_LINKER_USE_MMAP
# include <sys/mman.h>
#endif
@@ -46,6 +46,77 @@
#define nlist nlist_64
#endif
+/*
+ * Initialize some common data in the object code so we don't have to
+ * continuously look up the addresses.
+ */
+void
+ocInit_MachO(ObjectCode * oc)
+{
+ oc->info = (ObjectCodeFormatInfo*)stgCallocBytes(
+ 1, sizeof(ObjectCodeFormatInfo),
+ "ocInit_MachO(ObjectCodeFormatInfo)");
+ oc->info->header = (MachOHeader *) oc->image;
+ oc->info->symCmd = NULL;
+ oc->info->segCmd = NULL;
+ oc->info->dsymCmd = NULL;
+
+ MachOLoadCommand *lc = (MachOLoadCommand*)(oc->image + sizeof(MachOHeader));
+ for(size_t i = 0; i < oc->info->header->ncmds; i++) {
+ if (lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64) {
+ oc->info->segCmd = (MachOSegmentCommand*) lc;
+ }
+ else if (lc->cmd == LC_SYMTAB) {
+ oc->info->symCmd = (MachOSymtabCommand*) lc;
+ }
+ else if (lc->cmd == LC_DYSYMTAB) {
+ oc->info->dsymCmd = (MachODsymtabCommand*) lc;
+ }
+ lc = (MachOLoadCommand *) ( ((char*)lc) + lc->cmdsize );
+ }
+ if (NULL == oc->info->segCmd) {
+ barf("ocGetNames_MachO: no segment load command");
+ }
+
+ oc->info->macho_sections = (MachOSection*) (oc->info->segCmd+1);
+ oc->n_sections = oc->info->segCmd->nsects;
+
+ oc->info->nlist = oc->info->symCmd == NULL
+ ? NULL
+ : (MachONList *)(oc->image + oc->info->symCmd->symoff);
+ oc->info->names = oc->image + oc->info->symCmd->stroff;
+
+ /* If we have symbols, allocate and fill the macho_symbols
+ * This will make relocation easier.
+ */
+ oc->info->n_macho_symbols = 0;
+ oc->info->macho_symbols = NULL;
+
+ if(NULL != oc->info->nlist) {
+ oc->info->n_macho_symbols = oc->info->symCmd->nsyms;
+ oc->info->macho_symbols = (MachOSymbol*)stgCallocBytes(
+ oc->info->symCmd->nsyms,
+ sizeof(MachOSymbol),
+ "ocInit_MachO(MachOSymbol)");
+ for(uint32_t i = 0; i < oc->info->symCmd->nsyms; i++) {
+ oc->info->macho_symbols[i].name = oc->info->names
+ + oc->info->nlist[i].n_un.n_strx;
+ oc->info->macho_symbols[i].nlist = &oc->info->nlist[i];
+ /* we don't have an address for this symbol yet; this will be
+ * populated during ocGetNames_MachO. hence addr = NULL
+ */
+ oc->info->macho_symbols[i].addr = NULL;
+ }
+ }
+}
+
+void
+ocDeinit_MachO(ObjectCode * oc) {
+ if(oc->info->n_macho_symbols > 0) {
+ stgFree(oc->info->macho_symbols);
+ }
+ stgFree(oc->info);
+}
static int
resolveImports(
ObjectCode* oc,
@@ -55,6 +126,7 @@ resolveImports(
unsigned long *indirectSyms,
struct nlist *nlist);
+#if NEED_SYMBOL_EXTRAS
#if defined(powerpc_HOST_ARCH)
int
ocAllocateSymbolExtras_MachO(ObjectCode* oc)
@@ -144,6 +216,7 @@ ocAllocateSymbolExtras_MachO(ObjectCode* oc)
#else
#error Unknown MachO architecture
#endif /* HOST_ARCH */
+#endif /* NEED_SYMBOL_EXTRAS */
int
ocVerifyImage_MachO(ObjectCode * oc)
@@ -153,7 +226,7 @@ ocVerifyImage_MachO(ObjectCode * oc)
IF_DEBUG(linker, debugBelch("ocVerifyImage_MachO: start\n"));
-#if x86_64_HOST_ARCH || powerpc64_HOST_ARCH
+#if x86_64_HOST_ARCH || powerpc64_HOST_ARCH || aarch64_HOST_ARCH
if(header->magic != MH_MAGIC_64) {
errorBelch("Could not load image %s: bad magic!\n"
" Expected %08x (64bit), got %08x%s\n",
@@ -1241,4 +1314,4 @@ machoGetMisalignment( FILE * f )
return misalignment ? (16 - misalignment) : 0;
}
-#endif /* darwin_HOST_OS */
+#endif /* darwin_HOST_OS, ios_HOST_OS */
diff --git a/rts/linker/MachO.h b/rts/linker/MachO.h
index 8c7fb1fc1a..9362eb7238 100644
--- a/rts/linker/MachO.h
+++ b/rts/linker/MachO.h
@@ -5,6 +5,10 @@
#include "BeginPrivate.h"
+#include "MachOTypes.h"
+
+void ocInit_MachO ( ObjectCode* oc );
+void ocDeinit_MachO ( ObjectCode* oc );
int ocVerifyImage_MachO ( ObjectCode* oc );
int ocGetNames_MachO ( ObjectCode* oc );
int ocResolve_MachO ( ObjectCode* oc );