summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPete Cooper <peter_cooper@apple.com>2016-01-14 23:25:06 +0000
committerPete Cooper <peter_cooper@apple.com>2016-01-14 23:25:06 +0000
commit99f3b9494b985d25642cd29a8ac24dc060cc0c9c (patch)
tree6227689dfc91099c72f5d429e7df49339f63533c
parent784b5e3ff0b44ae7048b9b154d9ae119a9a5cb1a (diff)
downloadbcm5719-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.h8
-rw-r--r--lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp24
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp4
-rw-r--r--lld/test/mach-o/error-simulator-vs-macosx.yaml30
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
OpenPOWER on IntegriCloud