]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/ELF/Arch/MipsArchTree.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r308421, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / ELF / Arch / MipsArchTree.cpp
1 //===- MipsArchTree.cpp --------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===---------------------------------------------------------------------===//
9 //
10 // This file contains a helper function for the Writer.
11 //
12 //===---------------------------------------------------------------------===//
13
14 #include "Error.h"
15 #include "InputFiles.h"
16 #include "SymbolTable.h"
17 #include "Writer.h"
18
19 #include "llvm/BinaryFormat/ELF.h"
20 #include "llvm/Object/ELF.h"
21 #include "llvm/Support/MipsABIFlags.h"
22
23 using namespace llvm;
24 using namespace llvm::object;
25 using namespace llvm::ELF;
26
27 using namespace lld;
28 using namespace lld::elf;
29
30 namespace {
31 struct ArchTreeEdge {
32   uint32_t Child;
33   uint32_t Parent;
34 };
35
36 struct FileFlags {
37   StringRef Filename;
38   uint32_t Flags;
39 };
40 } // namespace
41
42 static StringRef getAbiName(uint32_t Flags) {
43   switch (Flags) {
44   case 0:
45     return "n64";
46   case EF_MIPS_ABI2:
47     return "n32";
48   case EF_MIPS_ABI_O32:
49     return "o32";
50   case EF_MIPS_ABI_O64:
51     return "o64";
52   case EF_MIPS_ABI_EABI32:
53     return "eabi32";
54   case EF_MIPS_ABI_EABI64:
55     return "eabi64";
56   default:
57     return "unknown";
58   }
59 }
60
61 static StringRef getNanName(bool IsNan2008) {
62   return IsNan2008 ? "2008" : "legacy";
63 }
64
65 static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; }
66
67 static void checkFlags(ArrayRef<FileFlags> Files) {
68   uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
69   bool Nan = Files[0].Flags & EF_MIPS_NAN2008;
70   bool Fp = Files[0].Flags & EF_MIPS_FP64;
71
72   for (const FileFlags &F : Files.slice(1)) {
73     uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
74     if (ABI != ABI2)
75       error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" +
76             getAbiName(ABI2) + "': " + F.Filename);
77
78     bool Nan2 = F.Flags & EF_MIPS_NAN2008;
79     if (Nan != Nan2)
80       error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" +
81             getNanName(Nan2) + ": " + F.Filename);
82
83     bool Fp2 = F.Flags & EF_MIPS_FP64;
84     if (Fp != Fp2)
85       error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" +
86             getFpName(Fp2) + ": " + F.Filename);
87   }
88 }
89
90 static uint32_t getMiscFlags(ArrayRef<FileFlags> Files) {
91   uint32_t Ret = 0;
92   for (const FileFlags &F : Files)
93     Ret |= F.Flags &
94            (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
95             EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
96   return Ret;
97 }
98
99 static uint32_t getPicFlags(ArrayRef<FileFlags> Files) {
100   // Check PIC/non-PIC compatibility.
101   bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
102   for (const FileFlags &F : Files.slice(1)) {
103     bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
104     if (IsPic && !IsPic2)
105       warn("linking abicalls code with non-abicalls file: " + F.Filename);
106     if (!IsPic && IsPic2)
107       warn("linking non-abicalls code with abicalls file: " + F.Filename);
108   }
109
110   // Compute the result PIC/non-PIC flag.
111   uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
112   for (const FileFlags &F : Files.slice(1))
113     Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
114
115   // PIC code is inherently CPIC and may not set CPIC flag explicitly.
116   if (Ret & EF_MIPS_PIC)
117     Ret |= EF_MIPS_CPIC;
118   return Ret;
119 }
120
121 static ArchTreeEdge ArchTree[] = {
122     // MIPS32R6 and MIPS64R6 are not compatible with other extensions
123     // MIPS64R2 extensions.
124     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2},
125     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, EF_MIPS_ARCH_64R2},
126     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, EF_MIPS_ARCH_64R2},
127     {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, EF_MIPS_ARCH_64R2},
128     // MIPS64 extensions.
129     {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, EF_MIPS_ARCH_64},
130     {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, EF_MIPS_ARCH_64},
131     {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64},
132     // MIPS V extensions.
133     {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5},
134     // R5000 extensions.
135     {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400},
136     // MIPS IV extensions.
137     {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, EF_MIPS_ARCH_4},
138     {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, EF_MIPS_ARCH_4},
139     {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4},
140     // VR4100 extensions.
141     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
142     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
143     // MIPS III extensions.
144     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, EF_MIPS_ARCH_3},
145     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, EF_MIPS_ARCH_3},
146     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, EF_MIPS_ARCH_3},
147     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, EF_MIPS_ARCH_3},
148     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, EF_MIPS_ARCH_3},
149     {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, EF_MIPS_ARCH_3},
150     {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3},
151     // MIPS32 extensions.
152     {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32},
153     // MIPS II extensions.
154     {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2},
155     {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2},
156     // MIPS I extensions.
157     {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, EF_MIPS_ARCH_1},
158     {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
159 };
160
161 static bool isArchMatched(uint32_t New, uint32_t Res) {
162   if (New == Res)
163     return true;
164   if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, Res))
165     return true;
166   if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, Res))
167     return true;
168   for (const auto &Edge : ArchTree) {
169     if (Res == Edge.Child) {
170       Res = Edge.Parent;
171       if (Res == New)
172         return true;
173     }
174   }
175   return false;
176 }
177
178 static StringRef getMachName(uint32_t Flags) {
179   switch (Flags & EF_MIPS_MACH) {
180   case EF_MIPS_MACH_NONE:
181     return "";
182   case EF_MIPS_MACH_3900:
183     return "r3900";
184   case EF_MIPS_MACH_4010:
185     return "r4010";
186   case EF_MIPS_MACH_4100:
187     return "r4100";
188   case EF_MIPS_MACH_4650:
189     return "r4650";
190   case EF_MIPS_MACH_4120:
191     return "r4120";
192   case EF_MIPS_MACH_4111:
193     return "r4111";
194   case EF_MIPS_MACH_5400:
195     return "vr5400";
196   case EF_MIPS_MACH_5900:
197     return "vr5900";
198   case EF_MIPS_MACH_5500:
199     return "vr5500";
200   case EF_MIPS_MACH_9000:
201     return "rm9000";
202   case EF_MIPS_MACH_LS2E:
203     return "loongson2e";
204   case EF_MIPS_MACH_LS2F:
205     return "loongson2f";
206   case EF_MIPS_MACH_LS3A:
207     return "loongson3a";
208   case EF_MIPS_MACH_OCTEON:
209     return "octeon";
210   case EF_MIPS_MACH_OCTEON2:
211     return "octeon2";
212   case EF_MIPS_MACH_OCTEON3:
213     return "octeon3";
214   case EF_MIPS_MACH_SB1:
215     return "sb1";
216   case EF_MIPS_MACH_XLR:
217     return "xlr";
218   default:
219     return "unknown machine";
220   }
221 }
222
223 static StringRef getArchName(uint32_t Flags) {
224   StringRef S = getMachName(Flags);
225   if (!S.empty())
226     return S;
227
228   switch (Flags & EF_MIPS_ARCH) {
229   case EF_MIPS_ARCH_1:
230     return "mips1";
231   case EF_MIPS_ARCH_2:
232     return "mips2";
233   case EF_MIPS_ARCH_3:
234     return "mips3";
235   case EF_MIPS_ARCH_4:
236     return "mips4";
237   case EF_MIPS_ARCH_5:
238     return "mips5";
239   case EF_MIPS_ARCH_32:
240     return "mips32";
241   case EF_MIPS_ARCH_64:
242     return "mips64";
243   case EF_MIPS_ARCH_32R2:
244     return "mips32r2";
245   case EF_MIPS_ARCH_64R2:
246     return "mips64r2";
247   case EF_MIPS_ARCH_32R6:
248     return "mips32r6";
249   case EF_MIPS_ARCH_64R6:
250     return "mips64r6";
251   default:
252     return "unknown arch";
253   }
254 }
255
256 // There are (arguably too) many MIPS ISAs out there. Their relationships
257 // can be represented as a forest. If all input files have ISAs which
258 // reachable by repeated proceeding from the single child to the parent,
259 // these input files are compatible. In that case we need to return "highest"
260 // ISA. If there are incompatible input files, we show an error.
261 // For example, mips1 is a "parent" of mips2 and such files are compatible.
262 // Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32
263 // are incompatible because nor mips3 is a parent for misp32, nor mips32
264 // is a parent for mips3.
265 static uint32_t getArchFlags(ArrayRef<FileFlags> Files) {
266   uint32_t Ret = Files[0].Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
267
268   for (const FileFlags &F : Files.slice(1)) {
269     uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
270
271     // Check ISA compatibility.
272     if (isArchMatched(New, Ret))
273       continue;
274     if (!isArchMatched(Ret, New)) {
275       error("target ISA '" + getArchName(Ret) + "' is incompatible with '" +
276             getArchName(New) + "': " + F.Filename);
277       return 0;
278     }
279     Ret = New;
280   }
281   return Ret;
282 }
283
284 template <class ELFT> uint32_t elf::getMipsEFlags() {
285   std::vector<FileFlags> V;
286   for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
287     V.push_back({F->getName(), F->getObj().getHeader()->e_flags});
288   if (V.empty())
289     return 0;
290   checkFlags(V);
291   return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
292 }
293
294 static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
295   if (FpA == FpB)
296     return 0;
297   if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
298     return 1;
299   if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
300       FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
301     return 1;
302   if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
303     return -1;
304   if (FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
305       FpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
306       FpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
307     return 1;
308   return -1;
309 }
310
311 static StringRef getMipsFpAbiName(uint8_t FpAbi) {
312   switch (FpAbi) {
313   case Mips::Val_GNU_MIPS_ABI_FP_ANY:
314     return "any";
315   case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
316     return "-mdouble-float";
317   case Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
318     return "-msingle-float";
319   case Mips::Val_GNU_MIPS_ABI_FP_SOFT:
320     return "-msoft-float";
321   case Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
322     return "-mips32r2 -mfp64 (old)";
323   case Mips::Val_GNU_MIPS_ABI_FP_XX:
324     return "-mfpxx";
325   case Mips::Val_GNU_MIPS_ABI_FP_64:
326     return "-mgp32 -mfp64";
327   case Mips::Val_GNU_MIPS_ABI_FP_64A:
328     return "-mgp32 -mfp64 -mno-odd-spreg";
329   default:
330     return "unknown";
331   }
332 }
333
334 uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
335                               StringRef FileName) {
336   if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
337     return NewFlag;
338   if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
339     error("target floating point ABI '" + getMipsFpAbiName(OldFlag) +
340           "' is incompatible with '" + getMipsFpAbiName(NewFlag) +
341           "': " + FileName);
342   return OldFlag;
343 }
344
345 template <class ELFT> static bool isN32Abi(const InputFile *F) {
346   if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
347     return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
348   return false;
349 }
350
351 bool elf::isMipsN32Abi(const InputFile *F) {
352   switch (Config->EKind) {
353   case ELF32LEKind:
354     return isN32Abi<ELF32LE>(F);
355   case ELF32BEKind:
356     return isN32Abi<ELF32BE>(F);
357   case ELF64LEKind:
358     return isN32Abi<ELF64LE>(F);
359   case ELF64BEKind:
360     return isN32Abi<ELF64BE>(F);
361   default:
362     llvm_unreachable("unknown Config->EKind");
363   }
364 }
365
366 template uint32_t elf::getMipsEFlags<ELF32LE>();
367 template uint32_t elf::getMipsEFlags<ELF32BE>();
368 template uint32_t elf::getMipsEFlags<ELF64LE>();
369 template uint32_t elf::getMipsEFlags<ELF64BE>();