1 //===- lib/ReaderWriter/ELF/MipsELFFlagsMerger.cpp ------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MipsELFFlagsMerger.h"
11 #include "lld/Core/Error.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/Support/ELF.h"
14 #include "llvm/Support/raw_ostream.h"
17 using namespace lld::elf;
18 using namespace llvm::ELF;
20 struct MipsISATreeEdge {
25 static MipsISATreeEdge isaTree[] = {
26 // MIPS32R6 and MIPS64R6 are not compatible with other extensions
29 {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64},
31 {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5},
32 // MIPS IV extensions.
33 {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4},
34 // MIPS III extensions.
35 {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3},
37 {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32},
38 // MIPS II extensions.
39 {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2},
40 {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2},
42 {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
45 static bool matchMipsISA(unsigned base, unsigned ext) {
48 if (base == EF_MIPS_ARCH_32 && matchMipsISA(EF_MIPS_ARCH_64, ext))
50 if (base == EF_MIPS_ARCH_32R2 && matchMipsISA(EF_MIPS_ARCH_64R2, ext))
52 for (const auto &edge : isaTree) {
53 if (ext == edge.child) {
62 MipsELFFlagsMerger::MipsELFFlagsMerger(bool is64Bits)
63 : _is64Bit(is64Bits), _flags(0) {}
65 uint32_t MipsELFFlagsMerger::getMergedELFFlags() const { return _flags; }
67 std::error_code MipsELFFlagsMerger::merge(uint8_t newClass, uint32_t newFlags) {
69 if (_is64Bit != (newClass == ELFCLASS64))
70 return make_dynamic_error_code(
71 Twine("Bitness is incompatible with that of the selected target"));
73 // We support two ABI: O32 and N64. The last one does not have
74 // the corresponding ELF flag.
75 uint32_t inAbi = newFlags & EF_MIPS_ABI;
76 uint32_t supportedAbi = _is64Bit ? 0 : uint32_t(EF_MIPS_ABI_O32);
77 if (inAbi != supportedAbi)
78 return make_dynamic_error_code(Twine("Unsupported ABI"));
80 // ... and reduced set of architectures ...
81 uint32_t newArch = newFlags & EF_MIPS_ARCH;
90 case EF_MIPS_ARCH_32R2:
91 case EF_MIPS_ARCH_64R2:
92 case EF_MIPS_ARCH_32R6:
93 case EF_MIPS_ARCH_64R6:
96 return make_dynamic_error_code(Twine("Unsupported instruction set"));
99 // ... and still do not support MIPS-16 extension.
100 if (newFlags & EF_MIPS_ARCH_ASE_M16)
101 return make_dynamic_error_code(Twine("Unsupported extension: MIPS16"));
103 // PIC code is inherently CPIC and may not set CPIC flag explicitly.
104 // Ensure that this flag will exist in the linked file.
105 if (newFlags & EF_MIPS_PIC)
106 newFlags |= EF_MIPS_CPIC;
108 std::lock_guard<std::mutex> lock(_mutex);
110 // If the old set of flags is empty, use the new one as a result.
113 return std::error_code();
116 // Check PIC / CPIC flags compatibility.
117 uint32_t newPic = newFlags & (EF_MIPS_PIC | EF_MIPS_CPIC);
118 uint32_t oldPic = _flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
120 if ((newPic != 0) != (oldPic != 0))
121 llvm::errs() << "lld warning: linking abicalls and non-abicalls files\n";
123 if (!(newPic & EF_MIPS_PIC))
124 _flags &= ~EF_MIPS_PIC;
126 _flags |= EF_MIPS_CPIC;
128 // Check mixing -mnan=2008 / -mnan=legacy modules.
129 if ((newFlags & EF_MIPS_NAN2008) != (_flags & EF_MIPS_NAN2008))
130 return make_dynamic_error_code(
131 Twine("Linking -mnan=2008 and -mnan=legacy modules"));
133 // Check ISA compatibility and update the extension flag.
134 uint32_t oldArch = _flags & EF_MIPS_ARCH;
135 if (!matchMipsISA(newArch, oldArch)) {
136 if (!matchMipsISA(oldArch, newArch))
137 return make_dynamic_error_code(
138 Twine("Linking modules with incompatible ISA"));
139 _flags &= ~EF_MIPS_ARCH;
143 _flags |= newFlags & EF_MIPS_NOREORDER;
144 _flags |= newFlags & EF_MIPS_MICROMIPS;
145 _flags |= newFlags & EF_MIPS_NAN2008;
146 _flags |= newFlags & EF_MIPS_32BITMODE;
148 return std::error_code();