summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-02-05 23:12:07 -0500
committerBen Gamari <ben@smart-cactus.org>2022-02-09 18:35:01 -0500
commitadebbabb925760e8bc617c0ce692bdc902fbff18 (patch)
tree57124025bdd8ad13b110c02481a21da3eccd377f
parentd9b0c1b2a30556aea8e4bf0a8648dd1d32a656fa (diff)
downloadhaskell-adebbabb925760e8bc617c0ce692bdc902fbff18.tar.gz
rts/linker: Catch archives masquerading as object files
-rw-r--r--rts/Linker.c11
-rw-r--r--rts/LinkerInternals.h4
-rw-r--r--rts/linker/LoadArchive.c20
3 files changed, 33 insertions, 2 deletions
diff --git a/rts/Linker.c b/rts/Linker.c
index 4a57c2aed4..4241235e67 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -1395,7 +1395,7 @@ preloadObjectFile (pathchar *path)
image = stgMallocBytes(fileSize, "loadObj(image)");
-#endif
+#endif /* !defined(darwin_HOST_OS) */
int n;
n = fread ( image, 1, fileSize, f );
@@ -1440,6 +1440,15 @@ static HsInt loadObj_ (pathchar *path)
return 1; // success
}
+ if (isArchive(path)) {
+ if (loadArchive_(path)) {
+ return 1; // success
+ } else {
+ IF_DEBUG(linker,
+ debugBelch("tried and failed to load %" PATH_FMT " as an archive\n", path));
+ }
+ }
+
ObjectCode *oc = preloadObjectFile(path);
if (oc == NULL) return 0;
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index 5c24f3cbaf..8177a0fd03 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -432,6 +432,10 @@ pathchar*
resolveSymbolAddr (pathchar* buffer, int size,
SymbolAddr* symbol, uintptr_t* top);
+/* defined in LoadArchive.c */
+bool isArchive (pathchar *path);
+HsInt loadArchive_ (pathchar *path);
+
/*************************************************
* Various bits of configuration
*************************************************/
diff --git a/rts/linker/LoadArchive.c b/rts/linker/LoadArchive.c
index 99e405db22..86fa5cb94b 100644
--- a/rts/linker/LoadArchive.c
+++ b/rts/linker/LoadArchive.c
@@ -241,7 +241,7 @@ lookupGNUArchiveIndex(int gnuFileIndexSize, char **fileName_,
return true;
}
-static HsInt loadArchive_ (pathchar *path)
+HsInt loadArchive_ (pathchar *path)
{
char *image = NULL;
HsInt retcode = 0;
@@ -632,3 +632,21 @@ HsInt loadArchive (pathchar *path)
RELEASE_LOCK(&linker_mutex);
return r;
}
+
+bool isArchive (pathchar *path)
+{
+ static const char ARCHIVE_HEADER[] = "!<arch>\n";
+ char buffer[10];
+ FILE *f = pathopen(path, WSTR("rb"));
+ if (f == NULL) {
+ return false;
+ }
+
+ size_t ret = fread(buffer, 1, sizeof(buffer), f);
+ if (ret < sizeof(buffer)) {
+ return false;
+ }
+ fclose(f);
+ return strncmp(ARCHIVE_HEADER, buffer, sizeof(ARCHIVE_HEADER)-1) == 0;
+}
+