diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index f283a8f4533a..24e042ed3b53 100644 --- a/lld/lib/ReaderWriter/MachO/File.h +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -188,6 +188,12 @@ public: visitor(offAndAtom.atom, offAndAtom.offset); } + MachOLinkingContext::Arch arch() const { return _arch; } + void setArch(MachOLinkingContext::Arch arch) { _arch = arch; } + + MachOLinkingContext::OS OS() const { return _os; } + void setOS(MachOLinkingContext::OS os) { _os = os; } + /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const File *F) { return F->kind() == File::kindMachObject; @@ -226,6 +232,8 @@ private: MachOLinkingContext *_ctx; SectionToAtoms _sectionAtoms; NameToAtom _undefAtoms; + MachOLinkingContext::Arch _arch = MachOLinkingContext::arch_unknown; + MachOLinkingContext::OS _os = MachOLinkingContext::OS::unknown; }; class MachODylibFile : public SharedLibraryFile { diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index e5bc077c30e0..c129e9e529c0 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -35,6 +35,7 @@ #endif using lld::mach_o::ArchHandler; +using lld::mach_o::MachOFile; using lld::mach_o::MachODylibFile; using namespace llvm::MachO; @@ -991,6 +992,29 @@ void MachOLinkingContext::finalizeInputFiles() { } std::error_code MachOLinkingContext::handleLoadedFile(File &file) { + auto *machoFile = dyn_cast(&file); + if (!machoFile) + return std::error_code(); + + // Check that the arch of the context matches that of the file. + // Also set the arch of the context if it didn't have one. + if (_arch == arch_unknown) { + _arch = machoFile->arch(); + } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) { + // Archs are different. + return make_dynamic_error_code(file.path() + + Twine(" cannot be linked due to incompatible architecture")); + } + + // Check that the OS of the context matches that of the file. + // Also set the OS of the context if it didn't have one. + if (_os == OS::unknown) { + _os = machoFile->OS(); + } else if (machoFile->OS() != OS::unknown && machoFile->OS() != _os) { + // OSes are different. + return make_dynamic_error_code(file.path() + + Twine(" cannot be linked due to incompatible operating systems")); + } return std::error_code(); } diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index f9499b603214..827dca869596 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -992,6 +992,10 @@ normalizedObjectToAtoms(MachOFile *file, handler->kindArch()); } + // Cache some attributes on the file for use later. + file->setArch(normalizedFile.arch); + file->setOS(normalizedFile.os); + // Sort references in each atom to their canonical order. for (const DefinedAtom* defAtom : file->defined()) { reinterpret_cast(defAtom)->sortReferences(); diff --git a/lld/test/mach-o/error-simulator-vs-macosx.yaml b/lld/test/mach-o/error-simulator-vs-macosx.yaml new file mode 100644 index 000000000000..bd62db39fccb --- /dev/null +++ b/lld/test/mach-o/error-simulator-vs-macosx.yaml @@ -0,0 +1,30 @@ +# RUN: lld -flavor darwin -arch i386 -macosx_version_min 10.8 %s %p/Inputs/hello-world-x86.yaml -o %t && llvm-nm -m %t | FileCheck %s +# RUN: not lld -flavor darwin -arch i386 -ios_simulator_version_min 5.0 %s %p/Inputs/hello-world-x86.yaml -o %t 2>&1 | FileCheck %s --check-prefix=ERROR +# +# Test that i386 can link with a macos version but gives an error with a simululator version. +# + +--- !mach-o +arch: x86 +OS: Mac OS X +file-type: MH_OBJECT +flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ] +sections: + - segment: __TEXT + section: __text + type: S_REGULAR + attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ] + address: 0x0000000000000000 + content: [ 0x90 ] +global-symbols: + - name: _main + type: N_SECT + scope: [ N_EXT ] + sect: 1 + value: 0x0000000000000000 +... + +# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main +# CHECK: (undefined) external dyld_stub_binder (from libSystem) + +# ERROR: cannot be linked due to incompatible operating systems