Update Trac ticket URLs to point to GitLab
[ghc.git] / rts / linker / LoadArchive.c
index 7d9dc22..a92f86f 100644 (file)
@@ -1,6 +1,3 @@
-#include <string.h>
-#include <stddef.h>
-
 #include <Rts.h>
 #include "PathUtils.h"
 
 /* Platform specific headers */
 #if defined(OBJFORMAT_PEi386)
 #  include "linker/PEi386.h"
-#elif defined(darwin_HOST_OS)
+#elif defined(OBJFORMAT_MACHO)
 #  include "linker/MachO.h"
 #  include <regex.h>
 #  include <mach/machine.h>
 #  include <mach-o/fat.h>
+#elif defined(OBJFORMAT_ELF)
+#include "linker/Elf.h"
 #endif
 
+#include <string.h>
+#include <stddef.h>
 #include <ctype.h>
+#include <fs_rts.h>
 
 #define FAIL(...) do {\
    errorBelch("loadArchive: "__VA_ARGS__); \
@@ -29,7 +31,7 @@
 
 #define DEBUG_LOG(...) IF_DEBUG(linker, debugBelch("loadArchive: " __VA_ARGS__))
 
-#if defined(darwin_HOST_OS)
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
 /* Read 4 bytes and convert to host byte order */
 static uint32_t read4Bytes(const char buf[static 4])
 {
@@ -45,12 +47,11 @@ static StgBool loadFatArchive(char tmp[static 20], FILE* f, pathchar* path)
 #elif defined(x86_64_HOST_ARCH)
     const uint32_t mycputype = CPU_TYPE_X86_64;
     const uint32_t mycpusubtype = CPU_SUBTYPE_X86_64_ALL;
-#elif defined(powerpc_HOST_ARCH)
-    const uint32_t mycputype = CPU_TYPE_POWERPC;
-    const uint32_t mycpusubtype = CPU_SUBTYPE_POWERPC_ALL;
-#elif defined(powerpc64_HOST_ARCH)
-    const uint32_t mycputype = CPU_TYPE_POWERPC64;
-    const uint32_t mycpusubtype = CPU_SUBTYPE_POWERPC_ALL;
+#elif defined(aarch64_HOST_ARCH)
+    const uint32_t mycputype = CPU_TYPE_ARM64;
+    const uint32_t mycpusubtype = CPU_SUBTYPE_ARM64_ALL;
+#elif defined(powerpc_HOST_ARCH) || defined(powerpc64_HOST_ARCH)
+#error No Darwin support on PowerPC
 #else
 #error Unknown Darwin architecture
 #endif
@@ -149,7 +150,7 @@ static StgBool checkFatArchive(char magic[static 20], FILE* f, pathchar* path)
 {
     StgBool success;
     success = false;
-#ifdef darwin_HOST_OS
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
     /* Not a standard archive, look for a fat archive magic number: */
     if (read4Bytes(magic) == FAT_MAGIC)
         success = loadFatArchive(magic, f, path);
@@ -256,7 +257,7 @@ static HsInt loadArchive_ (pathchar *path)
     int misalignment = 0;
 
     DEBUG_LOG("start\n");
-    DEBUG_LOG("Loading archive `%" PATH_FMT'\n", path);
+    DEBUG_LOG("Loading archive `%" PATH_FMT "'\n", path);
 
     /* Check that we haven't already loaded this archive.
        Ignore requests to load multiple times */
@@ -341,7 +342,7 @@ static HsInt loadArchive_ (pathchar *path)
             }
         }
 
-#if defined(darwin_HOST_OS)
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
         if (strncmp(fileName, "!<arch>\n", 8) == 0) {
             DEBUG_LOG("found the start of another archive, breaking\n");
             break;
@@ -457,8 +458,11 @@ static HsInt loadArchive_ (pathchar *path)
 
         DEBUG_LOG("Found member file `%s'\n", fileName);
 
+        /* TODO: Stop relying on file extensions to determine input formats.
+                 Instead try to match file headers. See #13103.  */
         isObject = (thisFileNameSize >= 2 && strncmp(fileName + thisFileNameSize - 2, ".o"  , 2) == 0)
-                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".p_o", 4) == 0);
+                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".p_o", 4) == 0)
+                || (thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".obj", 4) == 0);
 
 #if defined(OBJFORMAT_PEi386)
         /*
@@ -472,16 +476,6 @@ static HsInt loadArchive_ (pathchar *path)
         * Linker members (e.g. filename / are skipped since they are not needed)
         */
         isImportLib = thisFileNameSize >= 4 && strncmp(fileName + thisFileNameSize - 4, ".dll", 4) == 0;
-
-        /*
-         * Note [GCC import files (ext .dll.a)]
-         * GCC stores import information in the same binary format
-         * as the object file normally has. The only difference is that
-         * all the information are put in .idata sections. The only real
-         * way to tell if we're dealing with an import lib is by looking
-         * at the file extension.
-         */
-        isImportLib = isImportLib || endsWithPath(path, WSTR(".dll.a"));
 #endif // windows
 
         DEBUG_LOG("\tthisFileNameSize = %d\n", (int)thisFileNameSize);
@@ -492,12 +486,7 @@ static HsInt loadArchive_ (pathchar *path)
 
             DEBUG_LOG("Member is an object file...loading...\n");
 
-#if defined(mingw32_HOST_OS)
-            // TODO: We would like to use allocateExec here, but allocateExec
-            //       cannot currently allocate blocks large enough.
-            image = allocateImageAndTrampolines(path, fileName, f, memberSize,
-                                                isThin);
-#elif defined(darwin_HOST_OS)
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
             if (RTS_LINKER_USE_MMAP)
                 image = mmapForLinker(memberSize, MAP_ANONYMOUS, -1, 0);
             else {
@@ -508,7 +497,7 @@ static HsInt loadArchive_ (pathchar *path)
                 image += misalignment;
             }
 
-#else // not windows or darwin
+#else // not darwin
             image = stgMallocBytes(memberSize, "loadArchive(image)");
 #endif
             if (isThin) {
@@ -532,6 +521,12 @@ static HsInt loadArchive_ (pathchar *path)
 
             oc = mkOc(path, image, memberSize, false, archiveMemberName
                      , misalignment);
+#if defined(OBJFORMAT_MACHO)
+            ocInit_MachO( oc );
+#endif
+#if defined(OBJFORMAT_ELF)
+            ocInit_ELF( oc );
+#endif
 
             stgFree(archiveMemberName);
 
@@ -540,20 +535,8 @@ static HsInt loadArchive_ (pathchar *path)
                 fclose(f);
                 return 0;
             } else {
-#if defined(OBJFORMAT_PEi386)
-                if (isImportLib)
-                {
-                    findAndLoadImportLibrary(oc);
-                    stgFree(oc);
-                    oc = NULL;
-                    break;
-                } else {
-#endif
-                    oc->next = objects;
-                    objects = oc;
-#if defined(OBJFORMAT_PEi386)
-                }
-#endif
+                oc->next = objects;
+                objects = oc;
             }
         }
         else if (isGnuIndex) {