Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/Target.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Target.cpp ---------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Machine-specific things, such as applying relocations, creation of
10
// GOT or PLT entries, etc., are handled in this file.
11
//
12
// Refer the ELF spec for the single letter variables, S, A or P, used
13
// in this file.
14
//
15
// Some functions defined in this file has "relaxTls" as part of their names.
16
// They do peephole optimization for TLS variables by rewriting instructions.
17
// They are not part of the ABI but optional optimization, so you can skip
18
// them if you are not interested in how TLS variables are optimized.
19
// See the following paper for the details.
20
//
21
//   Ulrich Drepper, ELF Handling For Thread-Local Storage
22
//   http://www.akkadia.org/drepper/tls.pdf
23
//
24
//===----------------------------------------------------------------------===//
25
26
#include "Target.h"
27
#include "InputFiles.h"
28
#include "OutputSections.h"
29
#include "SymbolTable.h"
30
#include "Symbols.h"
31
#include "lld/Common/ErrorHandler.h"
32
#include "llvm/Object/ELF.h"
33
34
using namespace llvm;
35
using namespace llvm::object;
36
using namespace llvm::ELF;
37
using namespace lld;
38
using namespace lld::elf;
39
40
const TargetInfo *elf::target;
41
42
1.95k
std::string lld::toString(RelType type) {
43
1.95k
  StringRef s = getELFRelocationTypeName(elf::config->emachine, type);
44
1.95k
  if (s == "Unknown")
45
0
    return ("Unknown (" + Twine(type) + ")").str();
46
1.95k
  return s;
47
1.95k
}
48
49
5.60k
TargetInfo *elf::getTarget() {
50
5.60k
  switch (config->emachine) {
51
5.60k
  case EM_386:
52
287
  case EM_IAMCU:
53
287
    return getX86TargetInfo();
54
287
  case EM_AARCH64:
55
247
    return getAArch64TargetInfo();
56
287
  case EM_AMDGPU:
57
18
    return getAMDGPUTargetInfo();
58
325
  case EM_ARM:
59
325
    return getARMTargetInfo();
60
287
  case EM_AVR:
61
0
    return getAVRTargetInfo();
62
287
  case EM_HEXAGON:
63
8
    return getHexagonTargetInfo();
64
398
  case EM_MIPS:
65
398
    switch (config->ekind) {
66
398
    case ELF32LEKind:
67
48
      return getMipsTargetInfo<ELF32LE>();
68
398
    case ELF32BEKind:
69
253
      return getMipsTargetInfo<ELF32BE>();
70
398
    case ELF64LEKind:
71
6
      return getMipsTargetInfo<ELF64LE>();
72
398
    case ELF64BEKind:
73
91
      return getMipsTargetInfo<ELF64BE>();
74
398
    default:
75
0
      llvm_unreachable("unsupported MIPS target");
76
0
    }
77
2
  case EM_MSP430:
78
2
    return getMSP430TargetInfo();
79
62
  case EM_PPC:
80
62
    return getPPCTargetInfo();
81
307
  case EM_PPC64:
82
307
    return getPPC64TargetInfo();
83
180
  case EM_RISCV:
84
180
    return getRISCVTargetInfo();
85
2
  case EM_SPARCV9:
86
2
    return getSPARCV9TargetInfo();
87
3.76k
  case EM_X86_64:
88
3.76k
    return getX86_64TargetInfo();
89
0
  }
90
0
  llvm_unreachable("unknown target machine");
91
0
}
92
93
1.91k
template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
94
1.98k
  for (InputSectionBase *d : inputSections) {
95
1.98k
    auto *isec = cast<InputSection>(d);
96
1.98k
    if (!isec->getParent())
97
2
      continue;
98
1.97k
99
1.97k
    uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
100
1.97k
    if (isecLoc <= loc && 
loc < isecLoc + isec->getSize()1.97k
)
101
1.91k
      return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
102
1.97k
  }
103
1.91k
  
return {}2
;
104
1.91k
}
Target.cpp:lld::elf::ErrorPlace getErrPlace<llvm::object::ELFType<(llvm::support::endianness)1, false> >(unsigned char const*)
Line
Count
Source
93
15
template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
94
18
  for (InputSectionBase *d : inputSections) {
95
18
    auto *isec = cast<InputSection>(d);
96
18
    if (!isec->getParent())
97
0
      continue;
98
18
99
18
    uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
100
18
    if (isecLoc <= loc && loc < isecLoc + isec->getSize())
101
15
      return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
102
18
  }
103
15
  
return {}0
;
104
15
}
Target.cpp:lld::elf::ErrorPlace getErrPlace<llvm::object::ELFType<(llvm::support::endianness)0, false> >(unsigned char const*)
Line
Count
Source
93
3
template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
94
3
  for (InputSectionBase *d : inputSections) {
95
3
    auto *isec = cast<InputSection>(d);
96
3
    if (!isec->getParent())
97
0
      continue;
98
3
99
3
    uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
100
3
    if (isecLoc <= loc && loc < isecLoc + isec->getSize())
101
3
      return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
102
3
  }
103
3
  
return {}0
;
104
3
}
Target.cpp:lld::elf::ErrorPlace getErrPlace<llvm::object::ELFType<(llvm::support::endianness)1, true> >(unsigned char const*)
Line
Count
Source
93
78
template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
94
140
  for (InputSectionBase *d : inputSections) {
95
140
    auto *isec = cast<InputSection>(d);
96
140
    if (!isec->getParent())
97
2
      continue;
98
138
99
138
    uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
100
138
    if (isecLoc <= loc && 
loc < isecLoc + isec->getSize()135
)
101
76
      return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
102
138
  }
103
78
  
return {}2
;
104
78
}
Target.cpp:lld::elf::ErrorPlace getErrPlace<llvm::object::ELFType<(llvm::support::endianness)0, true> >(unsigned char const*)
Line
Count
Source
93
1.81k
template <class ELFT> static ErrorPlace getErrPlace(const uint8_t *loc) {
94
1.81k
  for (InputSectionBase *d : inputSections) {
95
1.81k
    auto *isec = cast<InputSection>(d);
96
1.81k
    if (!isec->getParent())
97
0
      continue;
98
1.81k
99
1.81k
    uint8_t *isecLoc = Out::bufferStart + isec->getParent()->offset + isec->outSecOff;
100
1.81k
    if (isecLoc <= loc && loc < isecLoc + isec->getSize())
101
1.81k
      return {isec, isec->template getLocation<ELFT>(loc - isecLoc) + ": "};
102
1.81k
  }
103
1.81k
  
return {}0
;
104
1.81k
}
105
106
1.91k
ErrorPlace elf::getErrorPlace(const uint8_t *loc) {
107
1.91k
  switch (config->ekind) {
108
1.91k
  case ELF32LEKind:
109
15
    return getErrPlace<ELF32LE>(loc);
110
1.91k
  case ELF32BEKind:
111
3
    return getErrPlace<ELF32BE>(loc);
112
1.91k
  case ELF64LEKind:
113
78
    return getErrPlace<ELF64LE>(loc);
114
1.91k
  case ELF64BEKind:
115
1.81k
    return getErrPlace<ELF64BE>(loc);
116
1.91k
  default:
117
0
    llvm_unreachable("unknown ELF type");
118
1.91k
  }
119
1.91k
}
120
121
2.86k
TargetInfo::~TargetInfo() {}
122
123
2
int64_t TargetInfo::getImplicitAddend(const uint8_t *buf, RelType type) const {
124
2
  return 0;
125
2
}
126
127
199
bool TargetInfo::usesOnlyLowPageBits(RelType type) const { return false; }
128
129
bool TargetInfo::needsThunk(RelExpr expr, RelType type, const InputFile *file,
130
0
                            uint64_t branchAddr, const Symbol &s) const {
131
0
  return false;
132
0
}
133
134
bool TargetInfo::adjustPrologueForCrossSplitStack(uint8_t *loc, uint8_t *end,
135
0
                                                  uint8_t stOther) const {
136
0
  llvm_unreachable("Target doesn't support split stacks.");
137
0
}
138
139
61
bool TargetInfo::inBranchRange(RelType type, uint64_t src, uint64_t dst) const {
140
61
  return true;
141
61
}
142
143
45
void TargetInfo::writeIgotPlt(uint8_t *buf, const Symbol &s) const {
144
45
  writeGotPlt(buf, s);
145
45
}
146
147
RelExpr TargetInfo::adjustRelaxExpr(RelType type, const uint8_t *data,
148
9
                                    RelExpr expr) const {
149
9
  return expr;
150
9
}
151
152
0
void TargetInfo::relaxGot(uint8_t *loc, RelType type, uint64_t val) const {
153
0
  llvm_unreachable("Should not have claimed to be relaxable");
154
0
}
155
156
void TargetInfo::relaxTlsGdToLe(uint8_t *loc, RelType type,
157
0
                                uint64_t val) const {
158
0
  llvm_unreachable("Should not have claimed to be relaxable");
159
0
}
160
161
void TargetInfo::relaxTlsGdToIe(uint8_t *loc, RelType type,
162
0
                                uint64_t val) const {
163
0
  llvm_unreachable("Should not have claimed to be relaxable");
164
0
}
165
166
void TargetInfo::relaxTlsIeToLe(uint8_t *loc, RelType type,
167
0
                                uint64_t val) const {
168
0
  llvm_unreachable("Should not have claimed to be relaxable");
169
0
}
170
171
void TargetInfo::relaxTlsLdToLe(uint8_t *loc, RelType type,
172
0
                                uint64_t val) const {
173
0
  llvm_unreachable("Should not have claimed to be relaxable");
174
0
}
175
176
4.51k
uint64_t TargetInfo::getImageBase() const {
177
4.51k
  // Use -image-base if set. Fall back to the target default if not.
178
4.51k
  if (config->imageBase)
179
16
    return *config->imageBase;
180
4.49k
  return config->isPic ? 
01.79k
:
defaultImageBase2.70k
;
181
4.49k
}