in rts/linker/LoadArchive.c [41:105]
static StgBool loadFatArchive(char tmp[static 20], FILE* f, pathchar* path)
{
uint32_t nfat_arch, nfat_offset, cputype, cpusubtype;
#if defined(i386_HOST_ARCH)
const uint32_t mycputype = CPU_TYPE_X86;
const uint32_t mycpusubtype = CPU_SUBTYPE_X86_ALL;
#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(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
nfat_arch = read4Bytes(tmp + 4);
DEBUG_LOG("found a fat archive containing %d architectures\n", nfat_arch);
nfat_offset = 0;
for (uint32_t i = 0; i < nfat_arch; i++) {
/* search for the right arch */
int n = fread(tmp, 1, 12, f);
if (n != 12) {
errorBelch("Failed reading arch from `%" PATH_FMT "'", path);
return false;
}
cputype = read4Bytes(tmp);
cpusubtype = read4Bytes(tmp + 4);
if (cputype == mycputype && cpusubtype == mycpusubtype) {
DEBUG_LOG("found my archive in a fat archive\n");
nfat_offset = read4Bytes(tmp + 8);
break;
}
}
if (nfat_offset == 0) {
errorBelch("Fat archive contains %d architectures, "
"but none of them are compatible with the host",
(int)nfat_arch);
return false;
} else {
/* Seek to the correct architecture */
int n = fseek(f, nfat_offset, SEEK_SET);
if (n != 0) {
errorBelch("Failed to seek to arch in `%" PATH_FMT "'", path);
return false;
}
/* Read the header */
n = fread(tmp, 1, 8, f);
if (n != 8) {
errorBelch("Failed reading header from `%" PATH_FMT "'", path);
return false;
}
/* Check the magic number */
if (strncmp(tmp, "!<arch>\n", 8) != 0) {
errorBelch("couldn't find archive in `%" PATH_FMT "'"
"at offset %d", path, nfat_offset);
return false;
}
}
return true;
}