Coverage Report

Created: 2017-09-21 03:39

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/ELF/Arch/MipsArchTree.cpp
Line
Count
Source (jump to first uncovered line)
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
0
static StringRef getAbiName(uint32_t Flags) {
43
0
  switch (Flags) {
44
0
  case 0:
45
0
    return "n64";
46
0
  case EF_MIPS_ABI2:
47
0
    return "n32";
48
0
  case EF_MIPS_ABI_O32:
49
0
    return "o32";
50
0
  case EF_MIPS_ABI_O64:
51
0
    return "o64";
52
0
  case EF_MIPS_ABI_EABI32:
53
0
    return "eabi32";
54
0
  case EF_MIPS_ABI_EABI64:
55
0
    return "eabi64";
56
0
  default:
57
0
    return "unknown";
58
0
  }
59
0
}
60
61
4
static StringRef getNanName(bool IsNan2008) {
62
4
  return IsNan2008 ? 
"2008"2
:
"legacy"2
;
63
4
}
64
65
0
static StringRef getFpName(bool IsFp64) 
{ return IsFp64 ? 0
"64"0
:
"32"0
; }
66
67
134
static void checkFlags(ArrayRef<FileFlags> Files) {
68
134
  uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
69
134
  bool Nan = Files[0].Flags & EF_MIPS_NAN2008;
70
134
  bool Fp = Files[0].Flags & EF_MIPS_FP64;
71
134
72
37
  for (const FileFlags &F : Files.slice(1)) {
73
37
    uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
74
37
    if (ABI != ABI2)
75
0
      error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" +
76
0
            getAbiName(ABI2) + "': " + F.Filename);
77
37
78
37
    bool Nan2 = F.Flags & EF_MIPS_NAN2008;
79
37
    if (Nan != Nan2)
80
2
      error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" +
81
2
            getNanName(Nan2) + ": " + F.Filename);
82
37
83
37
    bool Fp2 = F.Flags & EF_MIPS_FP64;
84
37
    if (Fp != Fp2)
85
0
      error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" +
86
0
            getFpName(Fp2) + ": " + F.Filename);
87
37
  }
88
134
}
89
90
134
static uint32_t getMiscFlags(ArrayRef<FileFlags> Files) {
91
134
  uint32_t Ret = 0;
92
134
  for (const FileFlags &F : Files)
93
171
    Ret |= F.Flags &
94
171
           (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
95
171
            EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
96
134
  return Ret;
97
134
}
98
99
134
static uint32_t getPicFlags(ArrayRef<FileFlags> Files) {
100
134
  // Check PIC/non-PIC compatibility.
101
134
  bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
102
37
  for (const FileFlags &F : Files.slice(1)) {
103
37
    bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
104
37
    if (
IsPic && 37
!IsPic237
)
105
0
      warn("linking abicalls code with non-abicalls file: " + F.Filename);
106
37
    if (
!IsPic && 37
IsPic20
)
107
0
      warn("linking non-abicalls code with abicalls file: " + F.Filename);
108
37
  }
109
134
110
134
  // Compute the result PIC/non-PIC flag.
111
134
  uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
112
134
  for (const FileFlags &F : Files.slice(1))
113
37
    Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
114
134
115
134
  // PIC code is inherently CPIC and may not set CPIC flag explicitly.
116
134
  if (Ret & EF_MIPS_PIC)
117
19
    Ret |= EF_MIPS_CPIC;
118
134
  return Ret;
119
134
}
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
44
static bool isArchMatched(uint32_t New, uint32_t Res) {
162
44
  if (New == Res)
163
33
    return true;
164
11
  
if (11
New == EF_MIPS_ARCH_32 && 11
isArchMatched(EF_MIPS_ARCH_64, Res)2
)
165
0
    return true;
166
11
  
if (11
New == EF_MIPS_ARCH_32R2 && 11
isArchMatched(EF_MIPS_ARCH_64R2, Res)1
)
167
0
    return true;
168
11
  
for (const auto &Edge : ArchTree) 11
{
169
263
    if (
Res == Edge.Child263
) {
170
28
      Res = Edge.Parent;
171
28
      if (Res == New)
172
2
        return true;
173
9
    }
174
263
  }
175
9
  return false;
176
9
}
177
178
4
static StringRef getMachName(uint32_t Flags) {
179
4
  switch (Flags & EF_MIPS_MACH) {
180
3
  case EF_MIPS_MACH_NONE:
181
3
    return "";
182
0
  case EF_MIPS_MACH_3900:
183
0
    return "r3900";
184
0
  case EF_MIPS_MACH_4010:
185
0
    return "r4010";
186
0
  case EF_MIPS_MACH_4100:
187
0
    return "r4100";
188
0
  case EF_MIPS_MACH_4650:
189
0
    return "r4650";
190
0
  case EF_MIPS_MACH_4120:
191
0
    return "r4120";
192
0
  case EF_MIPS_MACH_4111:
193
0
    return "r4111";
194
0
  case EF_MIPS_MACH_5400:
195
0
    return "vr5400";
196
0
  case EF_MIPS_MACH_5900:
197
0
    return "vr5900";
198
0
  case EF_MIPS_MACH_5500:
199
0
    return "vr5500";
200
0
  case EF_MIPS_MACH_9000:
201
0
    return "rm9000";
202
0
  case EF_MIPS_MACH_LS2E:
203
0
    return "loongson2e";
204
0
  case EF_MIPS_MACH_LS2F:
205
0
    return "loongson2f";
206
0
  case EF_MIPS_MACH_LS3A:
207
0
    return "loongson3a";
208
1
  case EF_MIPS_MACH_OCTEON:
209
1
    return "octeon";
210
0
  case EF_MIPS_MACH_OCTEON2:
211
0
    return "octeon2";
212
0
  case EF_MIPS_MACH_OCTEON3:
213
0
    return "octeon3";
214
0
  case EF_MIPS_MACH_SB1:
215
0
    return "sb1";
216
0
  case EF_MIPS_MACH_XLR:
217
0
    return "xlr";
218
0
  default:
219
0
    return "unknown machine";
220
0
  }
221
0
}
222
223
4
static StringRef getArchName(uint32_t Flags) {
224
4
  StringRef S = getMachName(Flags);
225
4
  if (!S.empty())
226
1
    return S;
227
3
228
3
  switch (Flags & EF_MIPS_ARCH) {
229
0
  case EF_MIPS_ARCH_1:
230
0
    return "mips1";
231
0
  case EF_MIPS_ARCH_2:
232
0
    return "mips2";
233
1
  case EF_MIPS_ARCH_3:
234
1
    return "mips3";
235
0
  case EF_MIPS_ARCH_4:
236
0
    return "mips4";
237
0
  case EF_MIPS_ARCH_5:
238
0
    return "mips5";
239
1
  case EF_MIPS_ARCH_32:
240
1
    return "mips32";
241
0
  case EF_MIPS_ARCH_64:
242
0
    return "mips64";
243
0
  case EF_MIPS_ARCH_32R2:
244
0
    return "mips32r2";
245
0
  case EF_MIPS_ARCH_64R2:
246
0
    return "mips64r2";
247
0
  case EF_MIPS_ARCH_32R6:
248
0
    return "mips32r6";
249
1
  case EF_MIPS_ARCH_64R6:
250
1
    return "mips64r6";
251
0
  default:
252
0
    return "unknown arch";
253
0
  }
254
0
}
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
134
static uint32_t getArchFlags(ArrayRef<FileFlags> Files) {
266
134
  uint32_t Ret = Files[0].Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
267
134
268
37
  for (const FileFlags &F : Files.slice(1)) {
269
37
    uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
270
37
271
37
    // Check ISA compatibility.
272
37
    if (isArchMatched(New, Ret))
273
33
      continue;
274
4
    
if (4
!isArchMatched(Ret, New)4
) {
275
2
      error("target ISA '" + getArchName(Ret) + "' is incompatible with '" +
276
2
            getArchName(New) + "': " + F.Filename);
277
2
      return 0;
278
2
    }
279
2
    Ret = New;
280
2
  }
281
132
  return Ret;
282
134
}
283
284
135
template <class ELFT> uint32_t elf::getMipsEFlags() {
285
135
  std::vector<FileFlags> V;
286
135
  for (InputFile *F : ObjectFiles)
287
171
    V.push_back(
288
171
        {F->getName(), cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
289
135
  if (V.empty())
290
1
    return 0;
291
134
  checkFlags(V);
292
134
  return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
293
134
}
unsigned int lld::elf::getMipsEFlags<llvm::object::ELFType<(llvm::support::endianness)1, false> >()
Line
Count
Source
284
14
template <class ELFT> uint32_t elf::getMipsEFlags() {
285
14
  std::vector<FileFlags> V;
286
14
  for (InputFile *F : ObjectFiles)
287
15
    V.push_back(
288
15
        {F->getName(), cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
289
14
  if (V.empty())
290
0
    return 0;
291
14
  checkFlags(V);
292
14
  return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
293
14
}
unsigned int lld::elf::getMipsEFlags<llvm::object::ELFType<(llvm::support::endianness)0, false> >()
Line
Count
Source
284
91
template <class ELFT> uint32_t elf::getMipsEFlags() {
285
91
  std::vector<FileFlags> V;
286
91
  for (InputFile *F : ObjectFiles)
287
120
    V.push_back(
288
120
        {F->getName(), cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
289
91
  if (V.empty())
290
1
    return 0;
291
90
  checkFlags(V);
292
90
  return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
293
90
}
unsigned int lld::elf::getMipsEFlags<llvm::object::ELFType<(llvm::support::endianness)1, true> >()
Line
Count
Source
284
2
template <class ELFT> uint32_t elf::getMipsEFlags() {
285
2
  std::vector<FileFlags> V;
286
2
  for (InputFile *F : ObjectFiles)
287
2
    V.push_back(
288
2
        {F->getName(), cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
289
2
  if (V.empty())
290
0
    return 0;
291
2
  checkFlags(V);
292
2
  return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
293
2
}
unsigned int lld::elf::getMipsEFlags<llvm::object::ELFType<(llvm::support::endianness)0, true> >()
Line
Count
Source
284
28
template <class ELFT> uint32_t elf::getMipsEFlags() {
285
28
  std::vector<FileFlags> V;
286
28
  for (InputFile *F : ObjectFiles)
287
34
    V.push_back(
288
34
        {F->getName(), cast<ObjFile<ELFT>>(F)->getObj().getHeader()->e_flags});
289
28
  if (V.empty())
290
0
    return 0;
291
28
  checkFlags(V);
292
28
  return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
293
28
}
294
295
174
static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
296
174
  if (FpA == FpB)
297
37
    return 0;
298
137
  
if (137
FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY137
)
299
135
    return 1;
300
2
  
if (2
FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
301
0
      FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
302
0
    return 1;
303
2
  
if (2
FpB != Mips::Val_GNU_MIPS_ABI_FP_XX2
)
304
2
    return -1;
305
0
  
if (0
FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
306
0
      FpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
307
0
      FpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
308
0
    return 1;
309
0
  return -1;
310
0
}
311
312
2
static StringRef getMipsFpAbiName(uint8_t FpAbi) {
313
2
  switch (FpAbi) {
314
0
  case Mips::Val_GNU_MIPS_ABI_FP_ANY:
315
0
    return "any";
316
1
  case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
317
1
    return "-mdouble-float";
318
0
  case Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
319
0
    return "-msingle-float";
320
0
  case Mips::Val_GNU_MIPS_ABI_FP_SOFT:
321
0
    return "-msoft-float";
322
0
  case Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
323
0
    return "-mips32r2 -mfp64 (old)";
324
0
  case Mips::Val_GNU_MIPS_ABI_FP_XX:
325
0
    return "-mfpxx";
326
1
  case Mips::Val_GNU_MIPS_ABI_FP_64:
327
1
    return "-mgp32 -mfp64";
328
0
  case Mips::Val_GNU_MIPS_ABI_FP_64A:
329
0
    return "-mgp32 -mfp64 -mno-odd-spreg";
330
0
  default:
331
0
    return "unknown";
332
0
  }
333
0
}
334
335
uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
336
173
                              StringRef FileName) {
337
173
  if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
338
172
    return NewFlag;
339
1
  
if (1
compareMipsFpAbi(OldFlag, NewFlag) < 01
)
340
1
    error("target floating point ABI '" + getMipsFpAbiName(OldFlag) +
341
1
          "' is incompatible with '" + getMipsFpAbiName(NewFlag) +
342
1
          "': " + FileName);
343
173
  return OldFlag;
344
173
}
345
346
336
template <class ELFT> static bool isN32Abi(const InputFile *F) {
347
336
  if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
348
336
    return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
349
0
  return false;
350
0
}
MipsArchTree.cpp:bool isN32Abi<llvm::object::ELFType<(llvm::support::endianness)1, false> >(lld::elf::InputFile const*)
Line
Count
Source
346
30
template <class ELFT> static bool isN32Abi(const InputFile *F) {
347
30
  if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
348
30
    return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
349
0
  return false;
350
0
}
MipsArchTree.cpp:bool isN32Abi<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::InputFile const*)
Line
Count
Source
346
237
template <class ELFT> static bool isN32Abi(const InputFile *F) {
347
237
  if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
348
237
    return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
349
0
  return false;
350
0
}
MipsArchTree.cpp:bool isN32Abi<llvm::object::ELFType<(llvm::support::endianness)1, true> >(lld::elf::InputFile const*)
Line
Count
Source
346
3
template <class ELFT> static bool isN32Abi(const InputFile *F) {
347
3
  if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
348
3
    return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
349
0
  return false;
350
0
}
MipsArchTree.cpp:bool isN32Abi<llvm::object::ELFType<(llvm::support::endianness)0, true> >(lld::elf::InputFile const*)
Line
Count
Source
346
66
template <class ELFT> static bool isN32Abi(const InputFile *F) {
347
66
  if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
348
66
    return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
349
0
  return false;
350
0
}
351
352
336
bool elf::isMipsN32Abi(const InputFile *F) {
353
336
  switch (Config->EKind) {
354
30
  case ELF32LEKind:
355
30
    return isN32Abi<ELF32LE>(F);
356
237
  case ELF32BEKind:
357
237
    return isN32Abi<ELF32BE>(F);
358
3
  case ELF64LEKind:
359
3
    return isN32Abi<ELF64LE>(F);
360
66
  case ELF64BEKind:
361
66
    return isN32Abi<ELF64BE>(F);
362
0
  default:
363
0
    llvm_unreachable("unknown Config->EKind");
364
0
  }
365
0
}
366
367
template uint32_t elf::getMipsEFlags<ELF32LE>();
368
template uint32_t elf::getMipsEFlags<ELF32BE>();
369
template uint32_t elf::getMipsEFlags<ELF64LE>();
370
template uint32_t elf::getMipsEFlags<ELF64BE>();