[lld] r212072 - [mach-o] improve errors when mixing architectures

Nick Kledzik kledzik at apple.com
Mon Jun 30 15:57:33 PDT 2014


Author: kledzik
Date: Mon Jun 30 17:57:33 2014
New Revision: 212072

URL: http://llvm.org/viewvc/llvm-project?rev=212072&view=rev
Log:
[mach-o] improve errors when mixing architectures

Added:
    lld/trunk/test/mach-o/wrong-arch-error.yaml
Modified:
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=212072&r1=212071&r2=212072&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Mon Jun 30 17:57:33 2014
@@ -275,7 +275,12 @@ normalizedFromAtoms(const lld::File &ato
 
 /// Class for interfacing mach-o yaml files into generic yaml parsing
 class MachOYamlIOTaggedDocumentHandler : public YamlIOTaggedDocumentHandler {
+public:
+  MachOYamlIOTaggedDocumentHandler(MachOLinkingContext::Arch arch)
+    : _arch(arch) { }
   bool handledDocTag(llvm::yaml::IO &io, const lld::File *&file) const override;
+private:
+  const MachOLinkingContext::Arch _arch;
 };
 
 } // namespace mach_o

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp?rev=212072&r1=212071&r2=212072&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp Mon Jun 30 17:57:33 2014
@@ -142,7 +142,10 @@ readBinary(std::unique_ptr<MemoryBuffer>
       fa++;
     }
     if (!foundArch) {
-      return make_error_code(llvm::errc::executable_format_error);
+      return make_dynamic_error_code(Twine("file does not contain required"
+                                    " architecture ("
+                                    + MachOLinkingContext::nameFromArch(arch)
+                                    + ")" ));
     }
     objSize = readBigEndian(fa->size);
     uint32_t offset = readBigEndian(fa->offset);
@@ -191,8 +194,15 @@ readBinary(std::unique_ptr<MemoryBuffer>
   if (lcRange.end() > (start + objSize))
     return make_error_code(llvm::errc::executable_format_error);
 
-  // Normalize architecture
+  // Get architecture from mach_header.
   f->arch = MachOLinkingContext::archFromCpuType(smh->cputype, smh->cpusubtype);
+  if (f->arch != arch) {
+    return make_dynamic_error_code(Twine("file is wrong architecture. Expected "
+                                  "(" + MachOLinkingContext::nameFromArch(arch)
+                                  + ") found ("
+                                  + MachOLinkingContext::nameFromArch(f->arch)
+                                  + ")" ));
+  }
   bool isBigEndianArch = MachOLinkingContext::isBigEndian(f->arch);
   // Copy file type and flags
   f->fileType = HeaderFileType(smh->filetype);
@@ -393,23 +403,10 @@ public:
   bool canParse(file_magic magic, StringRef ext,
                 const MemoryBuffer &mb) const override {
     if (magic != llvm::sys::fs::file_magic::macho_object &&
+        magic != llvm::sys::fs::file_magic::macho_universal_binary &&
         magic != llvm::sys::fs::file_magic::macho_dynamically_linked_shared_lib)
       return false;
-    if (mb.getBufferSize() < 32)
-      return false;
-    const char *start = mb.getBufferStart();
-    const mach_header *mh = reinterpret_cast<const mach_header *>(start);
-    const bool swap = (mh->magic == llvm::MachO::MH_CIGAM) ||
-                      (mh->magic == llvm::MachO::MH_CIGAM_64);
-    const uint32_t filesCpuType = read32(swap, mh->cputype);
-    const uint32_t filesCpuSubtype = read32(swap, mh->cpusubtype);
-    if (filesCpuType != MachOLinkingContext::cpuTypeFromArch(_arch))
-      return false;
-    if (filesCpuSubtype != MachOLinkingContext::cpuSubtypeFromArch(_arch))
-      return false;
-
-    // Is mach-o file with correct cpu type/subtype.
-    return true;
+    return (mb.getBufferSize() > 32);
   }
 
   std::error_code
@@ -458,7 +455,7 @@ void Registry::addSupportMachOObjects(St
     llvm_unreachable("mach-o arch not supported");
   }
   add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
-                               new mach_o::MachOYamlIOTaggedDocumentHandler()));
+                           new mach_o::MachOYamlIOTaggedDocumentHandler(arch)));
 }
 
 } // namespace lld

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp?rev=212072&r1=212071&r2=212072&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp Mon Jun 30 17:57:33 2014
@@ -651,8 +651,16 @@ bool MachOYamlIOTaggedDocumentHandler::h
   // Step 2: parse normalized mach-o struct into atoms.
   ErrorOr<std::unique_ptr<lld::File>> foe = normalizedToAtoms(nf, info->_path,
                                                               true);
-
+  if (nf.arch != _arch) {
+    io.setError(Twine("file is wrong architecture. Expected ("
+                      + MachOLinkingContext::nameFromArch(_arch)
+                      + ") found ("
+                      + MachOLinkingContext::nameFromArch(nf.arch)
+                      + ")"));
+    return false;
+  }
   info->_normalizeMachOFile = nullptr;
+
   if (foe) {
     // Transfer ownership to "out" File parameter.
     std::unique_ptr<lld::File> f = std::move(foe.get());

Added: lld/trunk/test/mach-o/wrong-arch-error.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/wrong-arch-error.yaml?rev=212072&view=auto
==============================================================================
--- lld/trunk/test/mach-o/wrong-arch-error.yaml (added)
+++ lld/trunk/test/mach-o/wrong-arch-error.yaml Mon Jun 30 17:57:33 2014
@@ -0,0 +1,49 @@
+# RUN: not lld -flavor darwin -arch x86_64 -r %s 2> %t.err
+# RUN: FileCheck %s < %t.err
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [  ]
+has-UUID:        false
+OS:              unknown
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0xCC ]
+
+global-symbols:
+  - name:            _foo
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+
+--- !mach-o
+arch:            x86
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+has-UUID:        false
+OS:              unknown
+sections:
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    alignment:       4
+    address:         0x0000000000000000
+    content:         [ 0xC3 ]
+
+global-symbols:
+  - name:            _bar
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+...
+
+
+# CHECK:       wrong architecture





More information about the llvm-commits mailing list