From 99f3b9494b985d25642cd29a8ac24dc060cc0c9c Mon Sep 17 00:00:00 2001 From: Pete Cooper Date: Thu, 14 Jan 2016 23:25:06 +0000 Subject: [PATCH] Check for mismatched arch and OS when linking MachO files. This patch makes use of the handleLoadedFile hook added in r257814. That method is used to check the arch and the OS of the files we are linking against the arch and OS on the context. The first test to use this ensures that we do not try to combine i386 Mac OS code with i386 simulator code. llvm-svn: 257837 --- lld/lib/ReaderWriter/MachO/File.h | 8 +++++ .../MachO/MachOLinkingContext.cpp | 24 +++++++++++++++ .../MachO/MachONormalizedFileToAtoms.cpp | 4 +++ .../mach-o/error-simulator-vs-macosx.yaml | 30 +++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 lld/test/mach-o/error-simulator-vs-macosx.yaml 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