[lld] r226253 - [Mips] Allow linking object files with MIPS32 and MIPS64 instructions

Simon Atanasyan simon at atanasyan.com
Fri Jan 16 00:57:09 PST 2015


Author: atanasyan
Date: Fri Jan 16 02:57:08 2015
New Revision: 226253

URL: http://llvm.org/viewvc/llvm-project?rev=226253&view=rev
Log:
[Mips] Allow linking object files with MIPS32 and MIPS64 instructions

If object files satisfy O32 ABI they can be linked together even if some
of them contains MIPS64 or MIPS64R2 instructions.

Added:
    lld/trunk/test/elf/Mips/e-flags-merge-8.test
    lld/trunk/test/elf/Mips/e-flags-merge-9.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp
    lld/trunk/test/elf/Mips/e-flags-merge-1.test

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp?rev=226253&r1=226252&r2=226253&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFlagsMerger.cpp Fri Jan 16 02:57:08 2015
@@ -15,6 +15,47 @@
 
 using namespace lld;
 using namespace lld::elf;
+using namespace llvm::ELF;
+
+struct MipsISATreeEdge {
+  unsigned child;
+  unsigned parent;
+};
+
+static MipsISATreeEdge isaTree[] = {
+    // MIPS64 extensions.
+    {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64},
+    // MIPS V extensions.
+    {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5},
+    // MIPS IV extensions.
+    {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4},
+    // MIPS III extensions.
+    {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3},
+    // MIPS32 extensions.
+    {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32},
+    // MIPS II extensions.
+    {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2},
+    {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2},
+    // MIPS I extensions.
+    {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
+};
+
+static bool matchMipsISA(unsigned base, unsigned ext) {
+  if (base == ext)
+    return true;
+  if (base == EF_MIPS_ARCH_32 && matchMipsISA(EF_MIPS_ARCH_64, ext))
+    return true;
+  if (base == EF_MIPS_ARCH_32R2 && matchMipsISA(EF_MIPS_ARCH_64R2, ext))
+    return true;
+  for (const auto &edge : isaTree) {
+    if (ext == edge.child) {
+      ext = edge.parent;
+      if (ext == base)
+        return true;
+    }
+  }
+  return false;
+}
 
 MipsELFFlagsMerger::MipsELFFlagsMerger() : _flags(0) {}
 
@@ -36,12 +77,16 @@ std::error_code MipsELFFlagsMerger::merg
   switch (newArch) {
   case llvm::ELF::EF_MIPS_ARCH_1:
   case llvm::ELF::EF_MIPS_ARCH_2:
+  case llvm::ELF::EF_MIPS_ARCH_3:
+  case llvm::ELF::EF_MIPS_ARCH_4:
+  case llvm::ELF::EF_MIPS_ARCH_5:
   case llvm::ELF::EF_MIPS_ARCH_32:
+  case llvm::ELF::EF_MIPS_ARCH_64:
   case llvm::ELF::EF_MIPS_ARCH_32R2:
-  case llvm::ELF::EF_MIPS_ARCH_32R6:
+  case llvm::ELF::EF_MIPS_ARCH_64R2:
     break;
   default:
-    return make_dynamic_error_code(Twine("Unsupported architecture"));
+    return make_dynamic_error_code(Twine("Unsupported instruction set"));
   }
 
   // ... and still do not support MIPS-16 extension.
@@ -80,13 +125,20 @@ std::error_code MipsELFFlagsMerger::merg
     return make_dynamic_error_code(
         Twine("Linking -mnan=2008 and -mnan=legacy modules"));
 
-  // Set the "largest" ISA.
+  // Check ISA compatibility and update the extension flag.
   uint32_t oldArch = _flags & llvm::ELF::EF_MIPS_ARCH;
-  _flags |= std::max(newArch, oldArch);
+  if (!matchMipsISA(newArch, oldArch)) {
+    if (!matchMipsISA(oldArch, newArch))
+      return make_dynamic_error_code(
+          Twine("Linking modules with icompatible ISA"));
+    _flags &= ~EF_MIPS_ARCH;
+    _flags |= newArch;
+  }
 
   _flags |= newFlags & llvm::ELF::EF_MIPS_NOREORDER;
   _flags |= newFlags & llvm::ELF::EF_MIPS_MICROMIPS;
   _flags |= newFlags & llvm::ELF::EF_MIPS_NAN2008;
+  _flags |= newFlags & llvm::ELF::EF_MIPS_32BITMODE;
 
   return std::error_code();
 }

Modified: 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=226253&r1=226252&r2=226253&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-1.test (original)
+++ lld/trunk/test/elf/Mips/e-flags-merge-1.test Fri Jan 16 02:57:08 2015
@@ -5,24 +5,11 @@
 # 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: yaml2obj -format=elf -docnum 2 %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
@@ -36,69 +23,6 @@ FileHeader:
 
 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

Added: lld/trunk/test/elf/Mips/e-flags-merge-8.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-8.test?rev=226253&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-8.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-8.test Fri Jan 16 02:57:08 2015
@@ -0,0 +1,65 @@
+# Check that LLD links files with mips32 and mips64 instructions
+# if all these files satisfy O32 ABI.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-32.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-64.o
+# RUN: yaml2obj -format=elf -docnum 3 %s > %t-64r2.o
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-32.o %t-64.o %t-64r2.o
+# RUN: llvm-readobj -file-headers %t.so | FileCheck %s
+
+# CHECK:      Flags [ (0x80001100)
+# CHECK-NEXT:   EF_MIPS_32BITMODE (0x100)
+# CHECK-NEXT:   EF_MIPS_ABI_O32 (0x1000)
+# CHECK-NEXT:   EF_MIPS_ARCH_64R2 (0x80000000)
+# CHECK-NEXT: ]
+
+
+# 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:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_64, EF_MIPS_32BITMODE]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+
+# 64r2.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_64R2, EF_MIPS_32BITMODE]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+...

Added: lld/trunk/test/elf/Mips/e-flags-merge-9.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/e-flags-merge-9.test?rev=226253&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/e-flags-merge-9.test (added)
+++ lld/trunk/test/elf/Mips/e-flags-merge-9.test Fri Jan 16 02:57:08 2015
@@ -0,0 +1,43 @@
+# Check that LLD shows an error and does not link files with mips32r2
+# and mips64 instructions sets.
+
+# RUN: yaml2obj -format=elf -docnum 1 %s > %t-32r2.o
+# RUN: yaml2obj -format=elf -docnum 2 %s > %t-64.o
+
+# RUN: not lld -flavor gnu -target mipsel -shared -o %t.so \
+# RUN:         %t-32r2.o %t-64.o 2>&1 | FileCheck %s
+
+# CHECK: Linking modules with icompatible ISA
+
+# 32r2.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
+
+# 64.o
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_MIPS
+  Flags:           [EF_MIPS_ABI_O32, EF_MIPS_ARCH_64, EF_MIPS_32BITMODE]
+
+Sections:
+  - Name:          .text
+    Type:          SHT_PROGBITS
+    Flags:         [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:  0x04
+    Size:          0x04
+...





More information about the llvm-commits mailing list