From e46d939c0fe1ec0db13ba154dd92d690d907378f Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Fri, 13 Jan 2023 14:17:07 -0800 Subject: [PATCH] [lld-macho] Improve invalid fat binary warning This nearly mirrors ld64's error for this case: ld: warning: ignoring file path/to/file, file is universal (armv7,arm64) but does not contain the x86_64 architecture: path/to/file Differential Revision: https://reviews.llvm.org/D141729 --- lld/MachO/InputFiles.cpp | 12 ++++++++++-- lld/test/MachO/fat-arch.s | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index 50c6987..e128910 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -223,7 +223,11 @@ std::optional macho::readFile(StringRef path) { // 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. const auto *arch = reinterpret_cast(buf + sizeof(*hdr)); + auto getArchName = [](uint32_t cpuType, uint32_t cpuSubtype) { + return getArchitectureName(getArchitectureFromCpuType(cpuType, cpuSubtype)); + }; + std::vector archs; for (uint32_t i = 0, n = read32be(&hdr->nfat_arch); i < n; ++i) { if (reinterpret_cast(arch + i + 1) > buf + mbref.getBufferSize()) { @@ -238,8 +242,10 @@ std::optional macho::readFile(StringRef path) { // FIXME: LD64 has a more complex fallback logic here. // Consider implementing that as well? if (cpuType != static_cast(target->cpuType) || - cpuSubtype != target->cpuSubtype) + cpuSubtype != target->cpuSubtype) { + archs.emplace_back(getArchName(cpuType, cpuSubtype)); continue; + } uint32_t offset = read32be(&arch[i].offset); uint32_t size = read32be(&arch[i].size); @@ -251,7 +257,9 @@ std::optional macho::readFile(StringRef path) { path.copy(bAlloc)); } - warn("unable to find matching architecture in " + path); + auto targetArchName = getArchName(target->cpuType, target->cpuSubtype); + warn(path + ": ignoring file because it is universal (" + join(archs, ",") + + ") but does not contain the " + targetArchName + " architecture"); return std::nullopt; } diff --git a/lld/test/MachO/fat-arch.s b/lld/test/MachO/fat-arch.s index dd6b61b..59b82cd 100644 --- a/lld/test/MachO/fat-arch.s +++ b/lld/test/MachO/fat-arch.s @@ -11,7 +11,11 @@ # RUN: llvm-lipo %t.i386.o -create -o %t.noarch.o # RUN: not %no-fatal-warnings-lld -o /dev/null %t.noarch.o 2>&1 | \ # RUN: FileCheck %s -DFILE=%t.noarch.o -# CHECK: warning: unable to find matching architecture in [[FILE]] +# CHECK: warning: [[FILE]]: ignoring file because it is universal (i386) but does not contain the x86_64 architecture + +# RUN: not %lld -arch arm64 -o /dev/null %t.fat.o 2>&1 | \ +# RUN: FileCheck --check-prefix=CHECK-FAT %s -DFILE=%t.fat.o +# CHECK-FAT: error: [[FILE]]: ignoring file because it is universal (i386,x86_64) but does not contain the arm64 architecture ## Validates that we read the cpu-subtype correctly from a fat exec. # RUN: %lld -o %t.x86_64.out %t.x86_64.o -- 2.7.4