[lld] r221439 - [Mips] Check ELF flags to prevent linking of incompatible files

Simon Atanasyan simon at atanasyan.com
Wed Nov 5 21:53:11 PST 2014


Author: atanasyan
Date: Wed Nov  5 23:53:10 2014
New Revision: 221439

URL: http://llvm.org/viewvc/llvm-project?rev=221439&view=rev
Log:
[Mips] Check ELF flags to prevent linking of incompatible files

1. The path checks ELF header flags to prevent linking of incompatible files.
   For example we do not allow to link files with different ABI, -mnan
   flags, some combination of target CPU etc.
2. The patch merge ELF header flags from input object files to put their
   combination to the generated file. For example, if some input files
   have EF_MIPS_NOREORDER flag we need to put this flag to the output
   file header.

I use the `parseFile()` (not `canParse()`) method because in case of
recognition of incorrect input flags combination we should show detailed
error message and stop the linking process and should not try to use
another `Reader`.

Added:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h
    lld/trunk/test/elf/Mips/e-flags-merge-1.test
    lld/trunk/test/elf/Mips/e-flags-merge-2.test
    lld/trunk/test/elf/Mips/e-flags-merge-3.test
    lld/trunk/test/elf/Mips/e-flags-merge-4.test
    lld/trunk/test/elf/Mips/e-flags-merge-5.test
    lld/trunk/test/elf/Mips/e-flags-merge-6.test
    lld/trunk/test/elf/Mips/e-flags-merge-7.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFReader.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt?rev=221439&r1=221438&r2=221439&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt Wed Nov  5 23:53:10 2014
@@ -1,5 +1,6 @@
 add_lld_library(lldMipsELFTarget
   MipsCtorsOrderPass.cpp
+  MipsELFFlagsMerger.cpp
   MipsLinkingContext.cpp
   MipsRelocationHandler.cpp
   MipsRelocationPass.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h?rev=221439&r1=221438&r2=221439&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h Wed Nov  5 23:53:10 2014
@@ -24,7 +24,8 @@ template <class ELFT>
 class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
 public:
   MipsDynamicLibraryWriter(MipsLinkingContext &ctx,
-                           MipsTargetLayout<ELFT> &layout);
+                           MipsTargetLayout<ELFT> &layout,
+                           MipsELFFlagsMerger &elfFlagsMerger);
 
 protected:
   // Add any runtime files and their atoms to the output
@@ -51,9 +52,11 @@ private:
 
 template <class ELFT>
 MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
-    MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
-    : DynamicLibraryWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
-      _mipsContext(ctx), _mipsTargetLayout(layout) {}
+    MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout,
+    MipsELFFlagsMerger &elfFlagsMerger)
+    : DynamicLibraryWriter<ELFT>(ctx, layout),
+      _writeHelper(ctx, layout, elfFlagsMerger), _mipsContext(ctx),
+      _mipsTargetLayout(layout) {}
 
 template <class ELFT>
 bool MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp?rev=221439&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp Wed Nov  5 23:53:10 2014
@@ -0,0 +1,87 @@
+//===- lib/ReaderWriter/ELF/MipsELFFlagsMerger.cpp ------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsELFFlagsMerger.h"
+#include "lld/Core/Error.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lld;
+using namespace lld::elf;
+
+MipsELFFlagsMerger::MipsELFFlagsMerger() : _flags(0) {}
+
+uint32_t MipsELFFlagsMerger::getMergedELFFlags() const { return _flags; }
+
+std::error_code MipsELFFlagsMerger::merge(uint8_t newClass, uint32_t newFlags) {
+  // Reject 64-bit binaries.
+  if (newClass != llvm::ELF::ELFCLASS32)
+    return make_dynamic_error_code(
+        Twine("Bitness is incompatible with that of the selected target"));
+
+  // We support the only ABI - O32 ...
+  uint32_t abi = newFlags & llvm::ELF::EF_MIPS_ABI;
+  if (abi != llvm::ELF::EF_MIPS_ABI_O32)
+    return make_dynamic_error_code(Twine("Unsupported ABI"));
+
+  // ... and reduced set of architectures ...
+  uint32_t newArch = newFlags & llvm::ELF::EF_MIPS_ARCH;
+  switch (newArch) {
+  case llvm::ELF::EF_MIPS_ARCH_1:
+  case llvm::ELF::EF_MIPS_ARCH_2:
+  case llvm::ELF::EF_MIPS_ARCH_32:
+  case llvm::ELF::EF_MIPS_ARCH_32R2:
+  case llvm::ELF::EF_MIPS_ARCH_32R6:
+    break;
+  default:
+    return make_dynamic_error_code(Twine("Unsupported architecture"));
+  }
+
+  // ... and still do not support MIPS-16 extension.
+  if (newFlags & llvm::ELF::EF_MIPS_ARCH_ASE_M16)
+    return make_dynamic_error_code(Twine("Unsupported extension: MIPS16"));
+
+  std::lock_guard<std::mutex> lock(_mutex);
+
+  // If the old set of flags is empty, use the new one as a result.
+  if (!_flags) {
+    _flags = newFlags;
+    return std::error_code();
+  }
+
+  // Check PIC / CPIC flags compatibility.
+  uint32_t newPic =
+      newFlags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC);
+  uint32_t oldPic = _flags & (llvm::ELF::EF_MIPS_PIC | llvm::ELF::EF_MIPS_CPIC);
+
+  if ((newPic != 0) != (oldPic != 0))
+    llvm::errs() << "lld warning: linking abicalls and non-abicalls files\n";
+
+  if (newPic != 0)
+    _flags |= llvm::ELF::EF_MIPS_CPIC;
+  if (!(newPic & llvm::ELF::EF_MIPS_PIC))
+    _flags &= ~llvm::ELF::EF_MIPS_PIC;
+
+  // Check mixing -mnan=2008 / -mnan=legacy modules.
+  if ((newFlags & llvm::ELF::EF_MIPS_NAN2008) !=
+      (_flags & llvm::ELF::EF_MIPS_NAN2008))
+    return make_dynamic_error_code(
+        Twine("Linking -mnan=2008 and -mnan=legacy modules"));
+
+  // Set the "largest" ISA.
+  uint32_t oldArch = _flags & llvm::ELF::EF_MIPS_ARCH;
+  _flags |= std::max(newArch, oldArch);
+
+  _flags |= newFlags & llvm::ELF::EF_MIPS_NOREORDER;
+  _flags |= newFlags & llvm::ELF::EF_MIPS_MICROMIPS;
+  _flags |= newFlags & llvm::ELF::EF_MIPS_NAN2008;
+
+  return std::error_code();
+}

Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h?rev=221439&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.h Wed Nov  5 23:53:10 2014
@@ -0,0 +1,34 @@
+//===- lib/ReaderWriter/ELF/MipsELFFlagsMerger.h --------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FLAGS_MERGER_H
+#define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_FLAGS_MERGER_H
+
+#include <mutex>
+
+namespace lld {
+namespace elf {
+
+class MipsELFFlagsMerger {
+public:
+  MipsELFFlagsMerger();
+
+  uint32_t getMergedELFFlags() const;
+
+  /// \brief Merge saved ELF header flags and the new set of flags.
+  std::error_code merge(uint8_t newClass, uint32_t newFlags);
+
+private:
+  std::mutex _mutex;
+  uint32_t _flags;
+};
+
+} // namespace elf
+} // namespace lld
+
+#endif

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFReader.h?rev=221439&r1=221438&r2=221439&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFReader.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFReader.h Wed Nov  5 23:53:10 2014
@@ -11,6 +11,7 @@
 
 #include "ELFReader.h"
 #include "MipsELFFile.h"
+#include "MipsELFFlagsMerger.h"
 
 namespace lld {
 namespace elf {
@@ -39,18 +40,48 @@ struct MipsDynamicFileCreateELFTraits {
 
 class MipsELFObjectReader
     : public ELFObjectReader<Mips32ElELFType, MipsELFFileCreateTraits> {
+  typedef ELFObjectReader<Mips32ElELFType, MipsELFFileCreateTraits>
+      BaseReaderType;
+
 public:
-  MipsELFObjectReader(bool atomizeStrings)
-      : ELFObjectReader<Mips32ElELFType, MipsELFFileCreateTraits>(
-            atomizeStrings, llvm::ELF::EM_MIPS) {}
+  MipsELFObjectReader(MipsELFFlagsMerger &flagMerger, bool atomizeStrings)
+      : BaseReaderType(atomizeStrings, llvm::ELF::EM_MIPS),
+        _flagMerger(flagMerger) {}
+
+  std::error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const Registry &registry,
+            std::vector<std::unique_ptr<File>> &result) const override {
+    auto &hdr = *elfHeader(*mb);
+    if (std::error_code ec = _flagMerger.merge(hdr.getFileClass(), hdr.e_flags))
+      return ec;
+    return BaseReaderType::parseFile(mb, registry, result);
+  }
+
+private:
+  MipsELFFlagsMerger &_flagMerger;
 };
 
 class MipsELFDSOReader
     : public ELFDSOReader<Mips32ElELFType, MipsDynamicFileCreateELFTraits> {
+  typedef ELFDSOReader<Mips32ElELFType, MipsDynamicFileCreateELFTraits>
+      BaseReaderType;
+
 public:
-  MipsELFDSOReader(bool useUndefines)
-      : ELFDSOReader<Mips32ElELFType, MipsDynamicFileCreateELFTraits>(
-            useUndefines, llvm::ELF::EM_MIPS) {}
+  MipsELFDSOReader(MipsELFFlagsMerger &flagMerger, bool useUndefines)
+      : BaseReaderType(useUndefines, llvm::ELF::EM_MIPS),
+        _flagMerger(flagMerger) {}
+
+  std::error_code
+  parseFile(std::unique_ptr<MemoryBuffer> &mb, const Registry &registry,
+            std::vector<std::unique_ptr<File>> &result) const override {
+    auto &hdr = *elfHeader(*mb);
+    if (std::error_code ec = _flagMerger.merge(hdr.getFileClass(), hdr.e_flags))
+      return ec;
+    return BaseReaderType::parseFile(mb, registry, result);
+  }
+
+private:
+  MipsELFFlagsMerger &_flagMerger;
 };
 
 } // namespace elf

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h?rev=221439&r1=221438&r2=221439&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h Wed Nov  5 23:53:10 2014
@@ -9,6 +9,7 @@
 #ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
 #define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
 
+#include "MipsELFFlagsMerger.h"
 #include "MipsLinkingContext.h"
 #include "OutputELFWriter.h"
 
@@ -21,8 +22,10 @@ template <class ELFT> class MipsTargetLa
 
 template <typename ELFT> class MipsELFWriter {
 public:
-  MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout)
-      : _ctx(ctx), _targetLayout(targetLayout) {}
+  MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
+                MipsELFFlagsMerger &elfFlagsMerger)
+      : _ctx(ctx), _targetLayout(targetLayout),
+        _elfFlagsMerger(elfFlagsMerger) {}
 
   void setELFHeader(ELFHeader<ELFT> &elfHeader) {
     elfHeader.e_version(1);
@@ -33,13 +36,7 @@ public:
     else
       elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0);
 
-    // FIXME (simon): Read elf flags from all inputs, check compatibility,
-    // merge them and write result here.
-    uint32_t flags = llvm::ELF::EF_MIPS_NOREORDER | llvm::ELF::EF_MIPS_ABI_O32 |
-                     llvm::ELF::EF_MIPS_CPIC | llvm::ELF::EF_MIPS_ARCH_32R2;
-    if (_ctx.getOutputELFType() == llvm::ELF::ET_DYN)
-      flags |= EF_MIPS_PIC;
-    elfHeader.e_flags(flags);
+    elfHeader.e_flags(_elfFlagsMerger.getMergedELFFlags());
   }
 
   void finalizeMipsRuntimeAtomValues() {
@@ -74,6 +71,7 @@ public:
 private:
   MipsLinkingContext &_ctx;
   MipsTargetLayout<ELFT> &_targetLayout;
+  MipsELFFlagsMerger &_elfFlagsMerger;
 
   void setAtomValue(StringRef name, uint64_t value) {
     auto atom = _targetLayout.findAbsoluteAtom(name);

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=221439&r1=221438&r2=221439&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h Wed Nov  5 23:53:10 2014
@@ -22,7 +22,8 @@ template <typename ELFT> class MipsTarge
 template <class ELFT>
 class MipsExecutableWriter : public ExecutableWriter<ELFT> {
 public:
-  MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout);
+  MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout,
+                       MipsELFFlagsMerger &elfFlagsMerger);
 
 protected:
   void buildDynamicSymbolTable(const File &file) override;
@@ -50,10 +51,12 @@ private:
 };
 
 template <class ELFT>
-MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &ctx,
-                                                 MipsTargetLayout<ELFT> &layout)
-    : ExecutableWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
-      _mipsContext(ctx), _mipsTargetLayout(layout) {}
+MipsExecutableWriter<ELFT>::MipsExecutableWriter(
+    MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout,
+    MipsELFFlagsMerger &elfFlagsMerger)
+    : ExecutableWriter<ELFT>(ctx, layout),
+      _writeHelper(ctx, layout, elfFlagsMerger), _mipsContext(ctx),
+      _mipsTargetLayout(layout) {}
 
 template <class ELFT>
 void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=221439&r1=221438&r2=221439&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Wed Nov  5 23:53:10 2014
@@ -27,11 +27,12 @@ MipsTargetHandler::MipsTargetHandler(Mip
 std::unique_ptr<Writer> MipsTargetHandler::getWriter() {
   switch (_ctx.getOutputELFType()) {
   case llvm::ELF::ET_EXEC:
-    return std::unique_ptr<Writer>(
-        new MipsExecutableWriter<Mips32ElELFType>(_ctx, *_targetLayout));
+    return std::unique_ptr<Writer>(new MipsExecutableWriter<Mips32ElELFType>(
+        _ctx, *_targetLayout, _elfFlagsMerger));
   case llvm::ELF::ET_DYN:
     return std::unique_ptr<Writer>(
-        new MipsDynamicLibraryWriter<Mips32ElELFType>(_ctx, *_targetLayout));
+        new MipsDynamicLibraryWriter<Mips32ElELFType>(_ctx, *_targetLayout,
+                                                      _elfFlagsMerger));
   case llvm::ELF::ET_REL:
     llvm_unreachable("TODO: support -r mode");
   default:

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=221439&r1=221438&r2=221439&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Wed Nov  5 23:53:10 2014
@@ -10,6 +10,7 @@
 #define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
 
 #include "DefaultTargetHandler.h"
+#include "MipsELFFlagsMerger.h"
 #include "MipsELFReader.h"
 #include "MipsLinkingContext.h"
 #include "MipsRelocationHandler.h"
@@ -108,11 +109,13 @@ public:
   }
 
   std::unique_ptr<Reader> getObjReader(bool atomizeStrings) override {
-    return std::unique_ptr<Reader>(new MipsELFObjectReader(atomizeStrings));
+    return std::unique_ptr<Reader>(
+        new MipsELFObjectReader(_elfFlagsMerger, atomizeStrings));
   }
 
   std::unique_ptr<Reader> getDSOReader(bool useShlibUndefines) override {
-    return std::unique_ptr<Reader>(new MipsELFDSOReader(useShlibUndefines));
+    return std::unique_ptr<Reader>(
+        new MipsELFDSOReader(_elfFlagsMerger, useShlibUndefines));
   }
 
   const MipsTargetRelocationHandler &getRelocationHandler() const override {
@@ -126,6 +129,7 @@ public:
 private:
   static const Registry::KindStrings kindStrings[];
   MipsLinkingContext &_ctx;
+  MipsELFFlagsMerger _elfFlagsMerger;
   std::unique_ptr<MipsRuntimeFile<Mips32ElELFType>> _runtimeFile;
   std::unique_ptr<MipsTargetLayout<Mips32ElELFType>> _targetLayout;
   std::unique_ptr<MipsTargetRelocationHandler> _relocationHandler;

Added: lld/trunk/test/elf/Mips/e-flags-merge-1.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-1.test?rev=221439&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-1.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-1.test Wed Nov  5 23:53:10 2014
@@ -0,0 +1,132 @@
+# Check that the linker shows an error when object file has missed
+# or unsupported ABI and ARCH flags or unsupported ASE flags.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-no-abi.o
+# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-no-abi.o 2>&1 | \
+# RUN:   FileCheck -check-prefix=INVALID-ABI %s
+
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-arch3.o
+# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-arch3.o 2>&1 | \
+# RUN:   FileCheck -check-prefix=INVALID-ARCH %s
+
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-arch4.o
+# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-arch4.o 2>&1 | \
+# RUN:   FileCheck -check-prefix=INVALID-ARCH %s
+
+# RUN: yaml2obj -format=elf -docnum 4 %s > %t-arch64.o
+# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-arch64.o 2>&1 | \
+# RUN:   FileCheck -check-prefix=INVALID-ARCH %s
+
+# RUN: yaml2obj -format=elf -docnum 5 %s > %t-mips16.o
+# RUN: not lld -flavor gnu -target mipsel -e T -o %t.exe %t-mips16.o 2>&1 | \
+# RUN:   FileCheck -check-prefix=MIPS16 %s
+
+# INVALID-ABI: Unsupported ABI
+# INVALID-ARCH: Unsupported architecture
+# MIPS16: Unsupported extension: MIPS16
+
+# no-abi.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           []
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T
+      Section:     .text
+
+# arch3.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_3]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T
+      Section:     .text
+
+# arch4.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_4]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T
+      Section:     .text
+
+# arch64.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_64]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T
+      Section:     .text
+
+# mips16.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_ARCH_ASE_M16]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T
+      Section:     .text
+...

Added: lld/trunk/test/elf/Mips/e-flags-merge-2.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-2.test?rev=221439&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-2.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-2.test Wed Nov  5 23:53:10 2014
@@ -0,0 +1,35 @@
+# Check that the linker copies ELF header flags from the single input object
+# file to the generated executable
+
+# RUN: yaml2obj -format=elf %s > %t.o
+# RUN: lld -flavor gnu -target mipsel -e T -o %t.exe %t.o
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
+
+# CHECK:      Flags [ (0x52001001)
+# CHECK-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# CHECK-NEXT:   EF_MIPS_ARCH_32 (0x50000000)
+# CHECK-NEXT:   EF_MIPS_MICROMIPS (0x2000000)
+# CHECK-NEXT:   EF_MIPS_NOREORDER (0x1)
+# CHECK-NEXT: ]
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32,
+                    EF_MIPS_NOREORDER, EF_MIPS_MICROMIPS]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T
+      Section:     .text
+...

Added: lld/trunk/test/elf/Mips/e-flags-merge-3.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-3.test?rev=221439&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-3.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-3.test Wed Nov  5 23:53:10 2014
@@ -0,0 +1,133 @@
+# Check PIC/CPIC flags merging in case of multiple input objects.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-none.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-cpic.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-pic.o
+# RUN: yaml2obj -format=elf -docnum 4 %s > %t-both.o
+
+# RUN: lld -flavor gnu -target mipsel -e T1 -o %t-abi1.exe \
+# RUN:     %t-none.o %t-pic.o 2>&1 | FileCheck -check-prefix=ABI-CALLS-WARN %s
+# RUN: llvm-readobj -file-headers %t-abi1.exe \
+# RUN:              | FileCheck -check-prefix=ABI-CALLS1 %s
+
+# RUN: lld -flavor gnu -target mipsel -e T1 -o %t-abi2.exe \
+# RUN:     %t-cpic.o %t-none.o 2>&1 | FileCheck -check-prefix=ABI-CALLS-WARN %s
+# RUN: llvm-readobj -file-headers %t-abi2.exe \
+# RUN:              | FileCheck -check-prefix=ABI-CALLS2 %s
+
+# RUN: lld -flavor gnu -target mipsel -e T2 -o %t-cpic.exe %t-cpic.o %t-pic.o
+# RUN: llvm-readobj -file-headers %t-cpic.exe | FileCheck -check-prefix=CPIC %s
+
+# RUN: lld -flavor gnu -target mipsel -e T3 -o %t-both.exe %t-pic.o %t-both.o
+# RUN: llvm-readobj -file-headers %t-both.exe | FileCheck -check-prefix=BOTH %s
+
+# ABI-CALLS-WARN: lld warning: linking abicalls and non-abicalls files
+
+# ABI-CALLS1:      Flags [ (0x50001000)
+# ABI-CALLS1-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# ABI-CALLS1-NEXT:   EF_MIPS_ARCH_32 (0x50000000)
+# ABI-CALLS1-NEXT: ]
+
+# ABI-CALLS2:      Flags [ (0x50001004)
+# ABI-CALLS2-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# ABI-CALLS2-NEXT:   EF_MIPS_ARCH_32 (0x50000000)
+# ABI-CALLS2-NEXT:   EF_MIPS_CPIC (0x4)
+# ABI-CALLS2-NEXT: ]
+
+# CPIC:      Flags [ (0x50001004)
+# CPIC-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# CPIC-NEXT:   EF_MIPS_ARCH_32 (0x50000000)
+# CPIC-NEXT:   EF_MIPS_CPIC (0x4)
+# CPIC-NEXT: ]
+
+# BOTH:      Flags [ (0x50001006)
+# BOTH-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# BOTH-NEXT:   EF_MIPS_ARCH_32 (0x50000000)
+# BOTH-NEXT:   EF_MIPS_CPIC (0x4)
+# BOTH-NEXT:   EF_MIPS_PIC (0x2)
+# BOTH-NEXT: ]
+
+# none.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T1
+      Section:     .text
+
+# cpic.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_CPIC]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T2
+      Section:     .text
+
+# pic.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_PIC]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T3
+      Section:     .text
+
+# both.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_CPIC, EF_MIPS_PIC]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+Symbols:
+  Global:
+    - Name:        T4
+      Section:     .text
+...

Added: lld/trunk/test/elf/Mips/e-flags-merge-4.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-4.test?rev=221439&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-4.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-4.test Wed Nov  5 23:53:10 2014
@@ -0,0 +1,65 @@
+# Check ELF flags merging.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-none.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-noreorder.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-micro.o
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so \
+# RUN:     %t-none.o %t-noreorder.o %t-micro.o
+# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
+
+# CHECK:      Flags [ (0x52001001)
+# CHECK-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# CHECK-NEXT:   EF_MIPS_ARCH_32 (0x50000000)
+# CHECK-NEXT:   EF_MIPS_MICROMIPS (0x2000000)
+# CHECK-NEXT:   EF_MIPS_NOREORDER (0x1)
+# CHECK-NEXT: ]
+
+# none.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# noreorder.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_NOREORDER]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# micro.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_MICROMIPS]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+...

Added: lld/trunk/test/elf/Mips/e-flags-merge-5.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-5.test?rev=221439&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-5.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-5.test Wed Nov  5 23:53:10 2014
@@ -0,0 +1,42 @@
+# Check that LLD does not allow to mix 32 and 64-bit MIPS object files.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-32.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-64.o
+
+# RUN: not lld -flavor gnu -target mipsel -shared -o %t.so \
+# RUN:         %t-32.o %t-64.o 2>&1 | FileCheck %s
+
+# CHECK: Bitness is incompatible with that of the selected target
+
+# 32.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# 64.o
+---
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ARCH_64]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+...

Added: lld/trunk/test/elf/Mips/e-flags-merge-6.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-6.test?rev=221439&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-6.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-6.test Wed Nov  5 23:53:10 2014
@@ -0,0 +1,80 @@
+# Check selecting ELF header ARCH flag.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-m1.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-m2.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-m32.o
+# RUN: yaml2obj -format=elf -docnum 4 %s > %t-m32r2.o
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so \
+# RUN:     %t-m32.o %t-m2.o %t-m32r2.o %t-m1.o
+# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
+
+# CHECK:      Flags [ (0x70001000)
+# CHECK-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# CHECK-NEXT:   EF_MIPS_ARCH_32R2 (0x70000000)
+# CHECK-NEXT: ]
+
+# m1.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_1]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# m2.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_2]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# m32.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# m32r2.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+...

Added: lld/trunk/test/elf/Mips/e-flags-merge-7.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-7.test?rev=221439&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-7.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-7.test Wed Nov  5 23:53:10 2014
@@ -0,0 +1,42 @@
+# Check that LLD does not allow to mix nan2008 and legacy MIPS object files.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-2008.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-legacy.o
+
+# RUN: not lld -flavor gnu -target mipsel -shared -o %t.so \
+# RUN:         %t-2008.o %t-legacy.o 2>&1 | FileCheck %s
+
+# CHECK: Linking -mnan=2008 and -mnan=legacy modules
+
+# 2008.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_NAN2008]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# legacy.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+...





More information about the llvm-commits mailing list