if (read32be(&hdr->magic) != MachO::FAT_MAGIC)
return mbref;
- error("TODO: Add support for universal binaries");
+ // Object files and archive files may be fat files, which contains
+ // multiple real files for different CPU ISAs. Here, we search for a
+ // file that matches with the current link target and returns it as
+ // a MemoryBufferRef.
+ auto *arch = reinterpret_cast<const MachO::fat_arch *>(buf + sizeof(*hdr));
+
+ for (uint32_t i = 0, n = read32be(&hdr->nfat_arch); i < n; ++i) {
+ if (reinterpret_cast<const char *>(arch + i + 1) >
+ buf + mbref.getBufferSize()) {
+ error(path + ": fat_arch struct extends beyond end of file");
+ return None;
+ }
+
+ if (read32be(&arch[i].cputype) != target->cpuType ||
+ read32be(&arch[i].cpusubtype) != target->cpuSubtype)
+ continue;
+
+ uint32_t offset = read32be(&arch[i].offset);
+ uint32_t size = read32be(&arch[i].size);
+ if (offset + size > mbref.getBufferSize())
+ error(path + ": slice extends beyond end of file");
+ return MemoryBufferRef(StringRef(buf + offset, size), path.copy(bAlloc));
+ }
+
+ error("unable to find matching architecture in " + path);
return None;
}
if (NOT LLD_BUILT_STANDALONE)
list(APPEND LLD_TEST_DEPS
FileCheck count llc llvm-ar llvm-as llvm-bcanalyzer llvm-config llvm-cvtres
- llvm-dis llvm-dwarfdump llvm-lib llvm-mc llvm-nm llvm-objcopy llvm-objdump
- llvm-pdbutil llvm-readelf llvm-readobj not obj2yaml opt yaml2obj
+ llvm-dis llvm-dwarfdump llvm-lib llvm-lipo llvm-mc llvm-nm llvm-objcopy
+ llvm-objdump llvm-pdbutil llvm-readelf llvm-readobj not obj2yaml opt
+ yaml2obj
)
endif()
--- /dev/null
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=i386-apple-darwin %s -o %t.i386.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.x86_64.o
+# RUN: llvm-lipo %t.i386.o %t.x86_64.o -create -o %t.fat.o
+# RUN: lld -flavor darwinnew -arch x86_64 -o /dev/null %t.fat.o
+
+# RUN: llvm-lipo %t.i386.o -create -o %t.noarch.o
+# RUN: not lld -flavor darwinnew -arch x86_64 -o /dev/null %t.noarch.o 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.noarch.o
+# CHECK: error: unable to find matching architecture in [[FILE]]
+
+.text
+.global _main
+_main:
+ mov $0, %eax
+ ret
--- /dev/null
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.o
+# RUN: not lld -flavor darwinnew -arch x86_64 -o /dev/null %t.o 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.o
+# CHECK: error: [[FILE]]: fat_arch struct extends beyond end of file
+
+!fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 2
+FatArchs:
+Slices:
--- /dev/null
+# REQUIRES: x86
+# RUN: yaml2obj %s -o %t.o
+# RUN: not lld -flavor darwinnew -arch x86_64 -o /dev/null %t.o 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.o
+# CHECK: error: [[FILE]]: slice extends beyond end of file
+
+!fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 2
+FatArchs:
+ - cputype: 0x01000007
+ cpusubtype: 0x00000003
+ offset: 0x0000000000001000
+ size: 0
+ align: 12
+ - cputype: 0x00000007
+ cpusubtype: 0x00000003
+ offset: 0x000000000000B000
+ size: 0
+ align: 12
+Slices: