Index: test/tools/llvm-lipo/Inputs/armv7m-slice.yaml =================================================================== --- test/tools/llvm-lipo/Inputs/armv7m-slice.yaml +++ test/tools/llvm-lipo/Inputs/armv7m-slice.yaml @@ -0,0 +1,9 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACE + cputype: 0x0000000C + cpusubtype: 0x0000000F + filetype: 0x00000001 + ncmds: 0 + sizeofcmds: 0 + flags: 0x00002000 Index: test/tools/llvm-lipo/create-arch.test =================================================================== --- test/tools/llvm-lipo/create-arch.test +++ test/tools/llvm-lipo/create-arch.test @@ -1,5 +1,6 @@ # RUN: yaml2obj %p/Inputs/i386-slice.yaml > %t-i386.o # RUN: yaml2obj %p/Inputs/x86_64-slice.yaml > %t-x86_64.o +# RUN: yaml2obj %p/Inputs/armv7m-slice.yaml >%t-armv7m.o # RUN: llvm-lipo %t-i386.o %t-x86_64.o -create -output %t-universal.o # RUN: llvm-lipo %t-i386.o -arch x86_64 %t-x86_64.o -create -output %t-universal-1.o @@ -9,9 +10,14 @@ # # RUN: not llvm-lipo -arch armv7 %t-i386.o -arch x86_64 %t-x86_64.o -create -output /dev/null 2>&1 | FileCheck --check-prefix=ARCH_NOT_MATCHED %s # ARCH_NOT_MATCHED: error: specified architecture: armv7 for file: {{.*}} does not match the file's architecture (i386) -# -# # RUN: not llvm-lipo -arch i3866 %t-32.o -create -o /dev/null 2>&1 | FileCheck --check-prefix=INVALID_ARCH %s + +# RUN: not llvm-lipo -arch i3866 %t-32.o -create -o /dev/null 2>&1 | FileCheck --check-prefix=INVALID_ARCH %s # INVALID_ARCH: error: Invalid architecture: i3866 # # RUN: not llvm-lipo -arch i386 %t-33.o -create -o /dev/null 2>&1 | FileCheck --check-prefix=INVALID_FILE %s # INVALID_FILE: {{[nN]}}o such file or directory +# +# Verify that -arch accepts the mismatch of cpusubtypes if the cputypes match. +# RUN: llvm-lipo -arch armv7 %t-armv7m.o -create -output %t-universal-3.o +# RUN: llvm-lipo -arch armv7m %t-armv7m.o -create -output %t-universal-4.o +# RUN: cmp %t-universal-3.o %t-universal-4.o Index: tools/llvm-lipo/llvm-lipo.cpp =================================================================== --- tools/llvm-lipo/llvm-lipo.cpp +++ tools/llvm-lipo/llvm-lipo.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/WithColor.h" +#include "llvm/TextAPI/MachO/Architecture.h" using namespace llvm; using namespace llvm::object; @@ -438,14 +439,19 @@ if (!B->isArchive() && !B->isMachO() && !B->isMachOUniversalBinary()) reportError("File " + IF.FileName + " has unsupported binary format"); if (IF.ArchType && (B->isMachO() || B->isArchive())) { - const auto ArchType = - B->isMachO() ? Slice(cast(B)).getArchString() - : Slice(cast(B)).getArchString(); - if (Triple(*IF.ArchType).getArch() != Triple(ArchType).getArch()) + const auto S = B->isMachO() ? Slice(cast(B)) + : Slice(cast(B)); + const auto SpecifiedCPUType = + MachO::getCPUTypeFromArchitecture( + MachO::mapToArchitecture(Triple(*IF.ArchType))) + .first; + // For compatibility with cctools' lipo + // the comparison is relaxed just to checking cpu types. + if (S.getCPUType() != SpecifiedCPUType) reportError("specified architecture: " + *IF.ArchType + " for file: " + B->getFileName() + - " does not match the file's architecture (" + ArchType + - ")"); + " does not match the file's architecture (" + + S.getArchString() + ")"); } InputBinaries.push_back(std::move(*BinaryOrErr)); }