diff options
| author | Pete Cooper <peter_cooper@apple.com> | 2016-01-14 23:25:06 +0000 |
|---|---|---|
| committer | Pete Cooper <peter_cooper@apple.com> | 2016-01-14 23:25:06 +0000 |
| commit | 99f3b9494b985d25642cd29a8ac24dc060cc0c9c (patch) | |
| tree | 6227689dfc91099c72f5d429e7df49339f63533c | |
| parent | 784b5e3ff0b44ae7048b9b154d9ae119a9a5cb1a (diff) | |
| download | bcm5719-llvm-99f3b9494b985d25642cd29a8ac24dc060cc0c9c.tar.gz bcm5719-llvm-99f3b9494b985d25642cd29a8ac24dc060cc0c9c.zip | |
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
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/File.h | 8 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp | 24 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 4 | ||||
| -rw-r--r-- | lld/test/mach-o/error-simulator-vs-macosx.yaml | 30 |
4 files changed, 66 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index f283a8f4533..24e042ed3b5 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 e5bc077c30e..c129e9e529c 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<MachOFile>(&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 f9499b60321..827dca86959 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<const SimpleDefinedAtom*>(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 00000000000..bd62db39fcc --- /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 |

