forked from OSchip/llvm-project
[lld-macho] Support reading of universal binaries
Differential Revision: https://reviews.llvm.org/D77006
This commit is contained in:
parent
89285a1a97
commit
918948db4d
|
@ -81,7 +81,31 @@ Optional<MemoryBufferRef> macho::readFile(StringRef path) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,9 @@ set(LLD_TEST_DEPS lld)
|
|||
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()
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# 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
|
|
@ -0,0 +1,12 @@
|
|||
# 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:
|
|
@ -0,0 +1,22 @@
|
|||
# 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:
|
Loading…
Reference in New Issue