Bump version to 7.1
[ghc-hetmet.git] / rts / Linker.c
index cfec769..33daea3 100644 (file)
@@ -1663,8 +1663,16 @@ loadArchive( char *path )
    int imageSize;
    FILE *f;
    int n;
-   char tmp[16];
+   size_t fileNameSize;
+   char *file;
+   size_t fileSize;
    int isObject;
+   char tmp[12];
+
+   IF_DEBUG(linker, debugBelch("loadArchive `%s'\n", path));
+
+   fileSize = 32;
+   file = stgMallocBytes(fileSize, "loadArchive(file)");
 
    f = fopen(path, "rb");
    if (!f)
@@ -1675,7 +1683,7 @@ loadArchive( char *path )
        barf("loadArchive: Not an archive: `%s'", path);
 
    while(1) {
-       n = fread ( tmp, 1, 16, f );
+       n = fread ( file, 1, 16, f );
        if (n != 16) {
            if (feof(f)) {
                break;
@@ -1684,14 +1692,6 @@ loadArchive( char *path )
                barf("loadArchive: Failed reading file name from `%s'", path);
            }
        }
-       /* Ignore special files */
-       if ((0 == strncmp(tmp, "/               ", 16)) ||
-           (0 == strncmp(tmp, "//              ", 16))) {
-           isObject = 0;
-       }
-       else {
-           isObject = 1;
-       }
        n = fread ( tmp, 1, 12, f );
        if (n != 12)
            barf("loadArchive: Failed reading mod time from `%s'", path);
@@ -1715,6 +1715,35 @@ loadArchive( char *path )
        if (strncmp(tmp, "\x60\x0A", 2) != 0)
            barf("loadArchive: Failed reading magic from `%s' at %ld. Got %c%c", path, ftell(f), tmp[0], tmp[1]);
 
+       /* Check for BSD-variant large filenames */
+       if (0 == strncmp(file, "#1/", 3)) {
+           file[16] = '\0';
+           for (n = 3; isdigit(file[n]); n++);
+           file[n] = '\0';
+           fileNameSize = atoi(file + 3);
+           imageSize -= fileNameSize;
+           if (fileNameSize > fileSize) {
+               /* Double it to avoid potentially continually
+                  increasing it by 1 */
+               fileSize = fileNameSize * 2;
+               file = stgReallocBytes(file, fileSize, "loadArchive(file)");
+           }
+           n = fread ( file, 1, fileNameSize, f );
+           if (n != (int)fileNameSize)
+               barf("loadArchive: Failed reading filename from `%s'", path);
+       }
+       else {
+           fileNameSize = 16;
+       }
+
+       isObject = 0;
+       for (n = 0; n < (int)fileNameSize - 1; n++) {
+           if ((file[n] == '.') && (file[n + 1] == 'o')) {
+               isObject = 1;
+               break;
+           }
+       }
+
        if (isObject) {
            /* We can't mmap from the archive directly, as object
               files need to be 8-byte aligned but files in .ar
@@ -1734,13 +1763,14 @@ loadArchive( char *path )
 #endif
                     );
            if (0 == loadOc(oc)) {
+               stgFree(file);
                return 0;
            }
        }
        else {
            n = fseek(f, imageSize, SEEK_CUR);
            if (n != 0)
-               barf("loadArchive: error whilst seeking to %d in `%s'",
+               barf("loadArchive: error whilst seeking by %d in `%s'",
                     imageSize, path);
        }
        /* .ar files are 2-byte aligned */
@@ -1759,6 +1789,7 @@ loadArchive( char *path )
 
    fclose(f);
 
+   stgFree(file);
    return 1;
 }
 #else
@@ -1889,6 +1920,8 @@ static HsInt
 loadOc( ObjectCode* oc ) {
    int r;
 
+   IF_DEBUG(linker, debugBelch("loadOc\n"));
+
 #  if defined(OBJFORMAT_MACHO) && (defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH))
    r = ocAllocateSymbolExtras_MachO ( oc );
    if (!r) {
@@ -4830,6 +4863,8 @@ static int ocGetNames_MachO(ObjectCode* oc)
     char    *commonStorage = NULL;
     unsigned long commonCounter;
 
+    IF_DEBUG(linker,debugBelch("ocGetNames_MachO\n"));
+
     for(i=0;i<header->ncmds;i++)
     {
        if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64)
@@ -4919,6 +4954,7 @@ static int ocGetNames_MachO(ObjectCode* oc)
                         ; // weak definition, and we already have a definition
                     else
                     {
+                            IF_DEBUG(linker,debugBelch("Adding symbol 1 %s\n", nm));
                             ghciInsertStrHashTable(oc->fileName, symhash, nm,
                                                     image
                                                     + sections[nlist[i].n_sect-1].offset
@@ -4945,6 +4981,7 @@ static int ocGetNames_MachO(ObjectCode* oc)
 
                nlist[i].n_value = commonCounter;
 
+            IF_DEBUG(linker,debugBelch("Adding symbol 2 %s\n", nm));
                ghciInsertStrHashTable(oc->fileName, symhash, nm,
                                       (void*)commonCounter);
                oc->symbols[curSymbol++] = nm;