X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FLinker.c;h=33daea3ab3d5f147227ea67a9f6358d8535183ab;hb=43e5415176ae4f37462999e636f8e23c90689d2c;hp=cfec769776ff15e624148957cfe6147fb938fce3;hpb=b8384ce5da4738c0a6d3eaf11de03cab3ddd3cd6;p=ghc-hetmet.git diff --git a/rts/Linker.c b/rts/Linker.c index cfec769..33daea3 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -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;incmds;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;