Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/Arch/Mips.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MIPS.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
#include "InputFiles.h"
10
#include "OutputSections.h"
11
#include "Symbols.h"
12
#include "SyntheticSections.h"
13
#include "Target.h"
14
#include "Thunks.h"
15
#include "lld/Common/ErrorHandler.h"
16
#include "llvm/Object/ELF.h"
17
#include "llvm/Support/Endian.h"
18
19
using namespace llvm;
20
using namespace llvm::object;
21
using namespace llvm::support::endian;
22
using namespace llvm::ELF;
23
using namespace lld;
24
using namespace lld::elf;
25
26
namespace {
27
template <class ELFT> class MIPS final : public TargetInfo {
28
public:
29
  MIPS();
30
  uint32_t calcEFlags() const override;
31
  RelExpr getRelExpr(RelType type, const Symbol &s,
32
                     const uint8_t *loc) const override;
33
  int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
34
  RelType getDynRel(RelType type) const override;
35
  void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
36
  void writePltHeader(uint8_t *buf) const override;
37
  void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
38
                int32_t index, unsigned relOff) const override;
39
  bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
40
                  uint64_t branchAddr, const Symbol &s) const override;
41
  void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
42
  bool usesOnlyLowPageBits(RelType type) const override;
43
};
44
} // namespace
45
46
200
template <class ELFT> MIPS<ELFT>::MIPS() {
47
200
  gotPltHeaderEntriesNum = 2;
48
200
  defaultMaxPageSize = 65536;
49
200
  gotBaseSymInGotPlt = false;
50
200
  pltEntrySize = 16;
51
200
  pltHeaderSize = 32;
52
200
  copyRel = R_MIPS_COPY;
53
200
  noneRel = R_MIPS_NONE;
54
200
  pltRel = R_MIPS_JUMP_SLOT;
55
200
  needsThunks = true;
56
200
57
200
  // Set `sigrie 1` as a trap instruction.
58
200
  write32(trapInstr.data(), 0x04170001);
59
200
60
200
  if (ELFT::Is64Bits) {
61
49
    relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
49
    symbolicRel = R_MIPS_64;
63
49
    tlsGotRel = R_MIPS_TLS_TPREL64;
64
49
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
65
49
    tlsOffsetRel = R_MIPS_TLS_DTPREL64;
66
151
  } else {
67
151
    relativeRel = R_MIPS_REL32;
68
151
    symbolicRel = R_MIPS_32;
69
151
    tlsGotRel = R_MIPS_TLS_TPREL32;
70
151
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
71
151
    tlsOffsetRel = R_MIPS_TLS_DTPREL32;
72
151
  }
73
200
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::MIPS()
Line
Count
Source
46
24
template <class ELFT> MIPS<ELFT>::MIPS() {
47
24
  gotPltHeaderEntriesNum = 2;
48
24
  defaultMaxPageSize = 65536;
49
24
  gotBaseSymInGotPlt = false;
50
24
  pltEntrySize = 16;
51
24
  pltHeaderSize = 32;
52
24
  copyRel = R_MIPS_COPY;
53
24
  noneRel = R_MIPS_NONE;
54
24
  pltRel = R_MIPS_JUMP_SLOT;
55
24
  needsThunks = true;
56
24
57
24
  // Set `sigrie 1` as a trap instruction.
58
24
  write32(trapInstr.data(), 0x04170001);
59
24
60
24
  if (ELFT::Is64Bits) {
61
0
    relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
0
    symbolicRel = R_MIPS_64;
63
0
    tlsGotRel = R_MIPS_TLS_TPREL64;
64
0
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
65
0
    tlsOffsetRel = R_MIPS_TLS_DTPREL64;
66
24
  } else {
67
24
    relativeRel = R_MIPS_REL32;
68
24
    symbolicRel = R_MIPS_32;
69
24
    tlsGotRel = R_MIPS_TLS_TPREL32;
70
24
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
71
24
    tlsOffsetRel = R_MIPS_TLS_DTPREL32;
72
24
  }
73
24
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::MIPS()
Line
Count
Source
46
127
template <class ELFT> MIPS<ELFT>::MIPS() {
47
127
  gotPltHeaderEntriesNum = 2;
48
127
  defaultMaxPageSize = 65536;
49
127
  gotBaseSymInGotPlt = false;
50
127
  pltEntrySize = 16;
51
127
  pltHeaderSize = 32;
52
127
  copyRel = R_MIPS_COPY;
53
127
  noneRel = R_MIPS_NONE;
54
127
  pltRel = R_MIPS_JUMP_SLOT;
55
127
  needsThunks = true;
56
127
57
127
  // Set `sigrie 1` as a trap instruction.
58
127
  write32(trapInstr.data(), 0x04170001);
59
127
60
127
  if (ELFT::Is64Bits) {
61
0
    relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
0
    symbolicRel = R_MIPS_64;
63
0
    tlsGotRel = R_MIPS_TLS_TPREL64;
64
0
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
65
0
    tlsOffsetRel = R_MIPS_TLS_DTPREL64;
66
127
  } else {
67
127
    relativeRel = R_MIPS_REL32;
68
127
    symbolicRel = R_MIPS_32;
69
127
    tlsGotRel = R_MIPS_TLS_TPREL32;
70
127
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
71
127
    tlsOffsetRel = R_MIPS_TLS_DTPREL32;
72
127
  }
73
127
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::MIPS()
Line
Count
Source
46
3
template <class ELFT> MIPS<ELFT>::MIPS() {
47
3
  gotPltHeaderEntriesNum = 2;
48
3
  defaultMaxPageSize = 65536;
49
3
  gotBaseSymInGotPlt = false;
50
3
  pltEntrySize = 16;
51
3
  pltHeaderSize = 32;
52
3
  copyRel = R_MIPS_COPY;
53
3
  noneRel = R_MIPS_NONE;
54
3
  pltRel = R_MIPS_JUMP_SLOT;
55
3
  needsThunks = true;
56
3
57
3
  // Set `sigrie 1` as a trap instruction.
58
3
  write32(trapInstr.data(), 0x04170001);
59
3
60
3
  if (ELFT::Is64Bits) {
61
3
    relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
3
    symbolicRel = R_MIPS_64;
63
3
    tlsGotRel = R_MIPS_TLS_TPREL64;
64
3
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
65
3
    tlsOffsetRel = R_MIPS_TLS_DTPREL64;
66
3
  } else {
67
0
    relativeRel = R_MIPS_REL32;
68
0
    symbolicRel = R_MIPS_32;
69
0
    tlsGotRel = R_MIPS_TLS_TPREL32;
70
0
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
71
0
    tlsOffsetRel = R_MIPS_TLS_DTPREL32;
72
0
  }
73
3
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::MIPS()
Line
Count
Source
46
46
template <class ELFT> MIPS<ELFT>::MIPS() {
47
46
  gotPltHeaderEntriesNum = 2;
48
46
  defaultMaxPageSize = 65536;
49
46
  gotBaseSymInGotPlt = false;
50
46
  pltEntrySize = 16;
51
46
  pltHeaderSize = 32;
52
46
  copyRel = R_MIPS_COPY;
53
46
  noneRel = R_MIPS_NONE;
54
46
  pltRel = R_MIPS_JUMP_SLOT;
55
46
  needsThunks = true;
56
46
57
46
  // Set `sigrie 1` as a trap instruction.
58
46
  write32(trapInstr.data(), 0x04170001);
59
46
60
46
  if (ELFT::Is64Bits) {
61
46
    relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
46
    symbolicRel = R_MIPS_64;
63
46
    tlsGotRel = R_MIPS_TLS_TPREL64;
64
46
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
65
46
    tlsOffsetRel = R_MIPS_TLS_DTPREL64;
66
46
  } else {
67
0
    relativeRel = R_MIPS_REL32;
68
0
    symbolicRel = R_MIPS_32;
69
0
    tlsGotRel = R_MIPS_TLS_TPREL32;
70
0
    tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
71
0
    tlsOffsetRel = R_MIPS_TLS_DTPREL32;
72
0
  }
73
46
}
74
75
198
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
76
198
  return calcMipsEFlags<ELFT>();
77
198
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::calcEFlags() const
Line
Count
Source
75
24
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
76
24
  return calcMipsEFlags<ELFT>();
77
24
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::calcEFlags() const
Line
Count
Source
75
126
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
76
126
  return calcMipsEFlags<ELFT>();
77
126
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::calcEFlags() const
Line
Count
Source
75
3
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
76
3
  return calcMipsEFlags<ELFT>();
77
3
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::calcEFlags() const
Line
Count
Source
75
45
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
76
45
  return calcMipsEFlags<ELFT>();
77
45
}
78
79
template <class ELFT>
80
RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
81
10.3k
                               const uint8_t *loc) const {
82
10.3k
  // See comment in the calculateMipsRelChain.
83
10.3k
  if (ELFT::Is64Bits || 
config->mipsN32Abi320
)
84
10.0k
    type &= 0xff;
85
10.3k
86
10.3k
  switch (type) {
87
10.3k
  case R_MIPS_JALR:
88
1
  case R_MICROMIPS_JALR:
89
1
    return R_HINT;
90
28
  case R_MIPS_GPREL16:
91
28
  case R_MIPS_GPREL32:
92
28
  case R_MICROMIPS_GPREL16:
93
28
  case R_MICROMIPS_GPREL7_S2:
94
28
    return R_MIPS_GOTREL;
95
76
  case R_MIPS_26:
96
76
  case R_MICROMIPS_26_S1:
97
76
    return R_PLT;
98
76
  case R_MICROMIPS_PC26_S1:
99
6
    return R_PLT_PC;
100
81
  case R_MIPS_HI16:
101
81
  case R_MIPS_LO16:
102
81
  case R_MIPS_HIGHER:
103
81
  case R_MIPS_HIGHEST:
104
81
  case R_MICROMIPS_HI16:
105
81
  case R_MICROMIPS_LO16:
106
81
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
107
81
    // offset between start of function and 'gp' value which by default
108
81
    // equal to the start of .got section. In that case we consider these
109
81
    // relocations as relative.
110
81
    if (&s == ElfSym::mipsGpDisp)
111
20
      return R_MIPS_GOT_GP_PC;
112
61
    if (&s == ElfSym::mipsLocalGp)
113
2
      return R_MIPS_GOT_GP;
114
59
    LLVM_FALLTHROUGH;
115
94
  case R_MIPS_32:
116
94
  case R_MIPS_64:
117
94
  case R_MIPS_GOT_OFST:
118
94
  case R_MIPS_SUB:
119
94
  case R_MIPS_TLS_DTPREL_HI16:
120
94
  case R_MIPS_TLS_DTPREL_LO16:
121
94
  case R_MIPS_TLS_DTPREL32:
122
94
  case R_MIPS_TLS_DTPREL64:
123
94
  case R_MIPS_TLS_TPREL_HI16:
124
94
  case R_MIPS_TLS_TPREL_LO16:
125
94
  case R_MIPS_TLS_TPREL32:
126
94
  case R_MIPS_TLS_TPREL64:
127
94
  case R_MICROMIPS_TLS_DTPREL_HI16:
128
94
  case R_MICROMIPS_TLS_DTPREL_LO16:
129
94
  case R_MICROMIPS_TLS_TPREL_HI16:
130
94
  case R_MICROMIPS_TLS_TPREL_LO16:
131
94
    return R_ABS;
132
94
  case R_MIPS_PC32:
133
20
  case R_MIPS_PC16:
134
20
  case R_MIPS_PC19_S2:
135
20
  case R_MIPS_PC21_S2:
136
20
  case R_MIPS_PC26_S2:
137
20
  case R_MIPS_PCHI16:
138
20
  case R_MIPS_PCLO16:
139
20
  case R_MICROMIPS_PC7_S1:
140
20
  case R_MICROMIPS_PC10_S1:
141
20
  case R_MICROMIPS_PC16_S1:
142
20
  case R_MICROMIPS_PC18_S3:
143
20
  case R_MICROMIPS_PC19_S2:
144
20
  case R_MICROMIPS_PC23_S2:
145
20
  case R_MICROMIPS_PC21_S1:
146
20
    return R_PC;
147
50
  case R_MIPS_GOT16:
148
50
  case R_MICROMIPS_GOT16:
149
50
    if (s.isLocal())
150
23
      return R_MIPS_GOT_LOCAL_PAGE;
151
27
    LLVM_FALLTHROUGH;
152
10.0k
  case R_MIPS_CALL16:
153
10.0k
  case R_MIPS_GOT_DISP:
154
10.0k
  case R_MIPS_TLS_GOTTPREL:
155
10.0k
  case R_MICROMIPS_CALL16:
156
10.0k
  case R_MICROMIPS_TLS_GOTTPREL:
157
10.0k
    return R_MIPS_GOT_OFF;
158
10.0k
  case R_MIPS_CALL_HI16:
159
16
  case R_MIPS_CALL_LO16:
160
16
  case R_MIPS_GOT_HI16:
161
16
  case R_MIPS_GOT_LO16:
162
16
  case R_MICROMIPS_CALL_HI16:
163
16
  case R_MICROMIPS_CALL_LO16:
164
16
  case R_MICROMIPS_GOT_HI16:
165
16
  case R_MICROMIPS_GOT_LO16:
166
16
    return R_MIPS_GOT_OFF32;
167
16
  case R_MIPS_GOT_PAGE:
168
12
    return R_MIPS_GOT_LOCAL_PAGE;
169
16
  case R_MIPS_TLS_GD:
170
12
  case R_MICROMIPS_TLS_GD:
171
12
    return R_MIPS_TLSGD;
172
12
  case R_MIPS_TLS_LDM:
173
6
  case R_MICROMIPS_TLS_LDM:
174
6
    return R_MIPS_TLSLD;
175
6
  case R_MIPS_NONE:
176
0
    return R_NONE;
177
6
  default:
178
0
    error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
179
0
          ") against symbol " + toString(s));
180
0
    return R_NONE;
181
10.3k
  }
182
10.3k
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getRelExpr(unsigned int, lld::elf::Symbol const&, unsigned char const*) const
Line
Count
Source
81
27
                               const uint8_t *loc) const {
82
27
  // See comment in the calculateMipsRelChain.
83
27
  if (ELFT::Is64Bits || config->mipsN32Abi)
84
0
    type &= 0xff;
85
27
86
27
  switch (type) {
87
27
  case R_MIPS_JALR:
88
1
  case R_MICROMIPS_JALR:
89
1
    return R_HINT;
90
1
  case R_MIPS_GPREL16:
91
1
  case R_MIPS_GPREL32:
92
1
  case R_MICROMIPS_GPREL16:
93
1
  case R_MICROMIPS_GPREL7_S2:
94
1
    return R_MIPS_GOTREL;
95
2
  case R_MIPS_26:
96
2
  case R_MICROMIPS_26_S1:
97
2
    return R_PLT;
98
3
  case R_MICROMIPS_PC26_S1:
99
3
    return R_PLT_PC;
100
4
  case R_MIPS_HI16:
101
4
  case R_MIPS_LO16:
102
4
  case R_MIPS_HIGHER:
103
4
  case R_MIPS_HIGHEST:
104
4
  case R_MICROMIPS_HI16:
105
4
  case R_MICROMIPS_LO16:
106
4
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
107
4
    // offset between start of function and 'gp' value which by default
108
4
    // equal to the start of .got section. In that case we consider these
109
4
    // relocations as relative.
110
4
    if (&s == ElfSym::mipsGpDisp)
111
2
      return R_MIPS_GOT_GP_PC;
112
2
    if (&s == ElfSym::mipsLocalGp)
113
0
      return R_MIPS_GOT_GP;
114
2
    LLVM_FALLTHROUGH;
115
5
  case R_MIPS_32:
116
5
  case R_MIPS_64:
117
5
  case R_MIPS_GOT_OFST:
118
5
  case R_MIPS_SUB:
119
5
  case R_MIPS_TLS_DTPREL_HI16:
120
5
  case R_MIPS_TLS_DTPREL_LO16:
121
5
  case R_MIPS_TLS_DTPREL32:
122
5
  case R_MIPS_TLS_DTPREL64:
123
5
  case R_MIPS_TLS_TPREL_HI16:
124
5
  case R_MIPS_TLS_TPREL_LO16:
125
5
  case R_MIPS_TLS_TPREL32:
126
5
  case R_MIPS_TLS_TPREL64:
127
5
  case R_MICROMIPS_TLS_DTPREL_HI16:
128
5
  case R_MICROMIPS_TLS_DTPREL_LO16:
129
5
  case R_MICROMIPS_TLS_TPREL_HI16:
130
5
  case R_MICROMIPS_TLS_TPREL_LO16:
131
5
    return R_ABS;
132
5
  case R_MIPS_PC32:
133
5
  case R_MIPS_PC16:
134
5
  case R_MIPS_PC19_S2:
135
5
  case R_MIPS_PC21_S2:
136
5
  case R_MIPS_PC26_S2:
137
5
  case R_MIPS_PCHI16:
138
5
  case R_MIPS_PCLO16:
139
5
  case R_MICROMIPS_PC7_S1:
140
5
  case R_MICROMIPS_PC10_S1:
141
5
  case R_MICROMIPS_PC16_S1:
142
5
  case R_MICROMIPS_PC18_S3:
143
5
  case R_MICROMIPS_PC19_S2:
144
5
  case R_MICROMIPS_PC23_S2:
145
5
  case R_MICROMIPS_PC21_S1:
146
5
    return R_PC;
147
7
  case R_MIPS_GOT16:
148
7
  case R_MICROMIPS_GOT16:
149
7
    if (s.isLocal())
150
2
      return R_MIPS_GOT_LOCAL_PAGE;
151
5
    LLVM_FALLTHROUGH;
152
6
  case R_MIPS_CALL16:
153
6
  case R_MIPS_GOT_DISP:
154
6
  case R_MIPS_TLS_GOTTPREL:
155
6
  case R_MICROMIPS_CALL16:
156
6
  case R_MICROMIPS_TLS_GOTTPREL:
157
6
    return R_MIPS_GOT_OFF;
158
6
  case R_MIPS_CALL_HI16:
159
0
  case R_MIPS_CALL_LO16:
160
0
  case R_MIPS_GOT_HI16:
161
0
  case R_MIPS_GOT_LO16:
162
0
  case R_MICROMIPS_CALL_HI16:
163
0
  case R_MICROMIPS_CALL_LO16:
164
0
  case R_MICROMIPS_GOT_HI16:
165
0
  case R_MICROMIPS_GOT_LO16:
166
0
    return R_MIPS_GOT_OFF32;
167
0
  case R_MIPS_GOT_PAGE:
168
0
    return R_MIPS_GOT_LOCAL_PAGE;
169
0
  case R_MIPS_TLS_GD:
170
0
  case R_MICROMIPS_TLS_GD:
171
0
    return R_MIPS_TLSGD;
172
0
  case R_MIPS_TLS_LDM:
173
0
  case R_MICROMIPS_TLS_LDM:
174
0
    return R_MIPS_TLSLD;
175
0
  case R_MIPS_NONE:
176
0
    return R_NONE;
177
0
  default:
178
0
    error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
179
0
          ") against symbol " + toString(s));
180
0
    return R_NONE;
181
27
  }
182
27
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getRelExpr(unsigned int, lld::elf::Symbol const&, unsigned char const*) const
Line
Count
Source
81
293
                               const uint8_t *loc) const {
82
293
  // See comment in the calculateMipsRelChain.
83
293
  if (ELFT::Is64Bits || config->mipsN32Abi)
84
5
    type &= 0xff;
85
293
86
293
  switch (type) {
87
293
  case R_MIPS_JALR:
88
0
  case R_MICROMIPS_JALR:
89
0
    return R_HINT;
90
16
  case R_MIPS_GPREL16:
91
16
  case R_MIPS_GPREL32:
92
16
  case R_MICROMIPS_GPREL16:
93
16
  case R_MICROMIPS_GPREL7_S2:
94
16
    return R_MIPS_GOTREL;
95
72
  case R_MIPS_26:
96
72
  case R_MICROMIPS_26_S1:
97
72
    return R_PLT;
98
72
  case R_MICROMIPS_PC26_S1:
99
3
    return R_PLT_PC;
100
73
  case R_MIPS_HI16:
101
73
  case R_MIPS_LO16:
102
73
  case R_MIPS_HIGHER:
103
73
  case R_MIPS_HIGHEST:
104
73
  case R_MICROMIPS_HI16:
105
73
  case R_MICROMIPS_LO16:
106
73
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
107
73
    // offset between start of function and 'gp' value which by default
108
73
    // equal to the start of .got section. In that case we consider these
109
73
    // relocations as relative.
110
73
    if (&s == ElfSym::mipsGpDisp)
111
18
      return R_MIPS_GOT_GP_PC;
112
55
    if (&s == ElfSym::mipsLocalGp)
113
2
      return R_MIPS_GOT_GP;
114
53
    LLVM_FALLTHROUGH;
115
73
  case R_MIPS_32:
116
73
  case R_MIPS_64:
117
73
  case R_MIPS_GOT_OFST:
118
73
  case R_MIPS_SUB:
119
73
  case R_MIPS_TLS_DTPREL_HI16:
120
73
  case R_MIPS_TLS_DTPREL_LO16:
121
73
  case R_MIPS_TLS_DTPREL32:
122
73
  case R_MIPS_TLS_DTPREL64:
123
73
  case R_MIPS_TLS_TPREL_HI16:
124
73
  case R_MIPS_TLS_TPREL_LO16:
125
73
  case R_MIPS_TLS_TPREL32:
126
73
  case R_MIPS_TLS_TPREL64:
127
73
  case R_MICROMIPS_TLS_DTPREL_HI16:
128
73
  case R_MICROMIPS_TLS_DTPREL_LO16:
129
73
  case R_MICROMIPS_TLS_TPREL_HI16:
130
73
  case R_MICROMIPS_TLS_TPREL_LO16:
131
73
    return R_ABS;
132
73
  case R_MIPS_PC32:
133
14
  case R_MIPS_PC16:
134
14
  case R_MIPS_PC19_S2:
135
14
  case R_MIPS_PC21_S2:
136
14
  case R_MIPS_PC26_S2:
137
14
  case R_MIPS_PCHI16:
138
14
  case R_MIPS_PCLO16:
139
14
  case R_MICROMIPS_PC7_S1:
140
14
  case R_MICROMIPS_PC10_S1:
141
14
  case R_MICROMIPS_PC16_S1:
142
14
  case R_MICROMIPS_PC18_S3:
143
14
  case R_MICROMIPS_PC19_S2:
144
14
  case R_MICROMIPS_PC23_S2:
145
14
  case R_MICROMIPS_PC21_S1:
146
14
    return R_PC;
147
43
  case R_MIPS_GOT16:
148
43
  case R_MICROMIPS_GOT16:
149
43
    if (s.isLocal())
150
21
      return R_MIPS_GOT_LOCAL_PAGE;
151
22
    LLVM_FALLTHROUGH;
152
47
  case R_MIPS_CALL16:
153
47
  case R_MIPS_GOT_DISP:
154
47
  case R_MIPS_TLS_GOTTPREL:
155
47
  case R_MICROMIPS_CALL16:
156
47
  case R_MICROMIPS_TLS_GOTTPREL:
157
47
    return R_MIPS_GOT_OFF;
158
47
  case R_MIPS_CALL_HI16:
159
16
  case R_MIPS_CALL_LO16:
160
16
  case R_MIPS_GOT_HI16:
161
16
  case R_MIPS_GOT_LO16:
162
16
  case R_MICROMIPS_CALL_HI16:
163
16
  case R_MICROMIPS_CALL_LO16:
164
16
  case R_MICROMIPS_GOT_HI16:
165
16
  case R_MICROMIPS_GOT_LO16:
166
16
    return R_MIPS_GOT_OFF32;
167
16
  case R_MIPS_GOT_PAGE:
168
0
    return R_MIPS_GOT_LOCAL_PAGE;
169
16
  case R_MIPS_TLS_GD:
170
7
  case R_MICROMIPS_TLS_GD:
171
7
    return R_MIPS_TLSGD;
172
7
  case R_MIPS_TLS_LDM:
173
4
  case R_MICROMIPS_TLS_LDM:
174
4
    return R_MIPS_TLSLD;
175
4
  case R_MIPS_NONE:
176
0
    return R_NONE;
177
4
  default:
178
0
    error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
179
0
          ") against symbol " + toString(s));
180
0
    return R_NONE;
181
293
  }
182
293
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getRelExpr(unsigned int, lld::elf::Symbol const&, unsigned char const*) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getRelExpr(unsigned int, lld::elf::Symbol const&, unsigned char const*) const
Line
Count
Source
81
10.0k
                               const uint8_t *loc) const {
82
10.0k
  // See comment in the calculateMipsRelChain.
83
10.0k
  if (ELFT::Is64Bits || 
config->mipsN32Abi0
)
84
10.0k
    type &= 0xff;
85
10.0k
86
10.0k
  switch (type) {
87
10.0k
  case R_MIPS_JALR:
88
0
  case R_MICROMIPS_JALR:
89
0
    return R_HINT;
90
11
  case R_MIPS_GPREL16:
91
11
  case R_MIPS_GPREL32:
92
11
  case R_MICROMIPS_GPREL16:
93
11
  case R_MICROMIPS_GPREL7_S2:
94
11
    return R_MIPS_GOTREL;
95
11
  case R_MIPS_26:
96
2
  case R_MICROMIPS_26_S1:
97
2
    return R_PLT;
98
2
  case R_MICROMIPS_PC26_S1:
99
0
    return R_PLT_PC;
100
4
  case R_MIPS_HI16:
101
4
  case R_MIPS_LO16:
102
4
  case R_MIPS_HIGHER:
103
4
  case R_MIPS_HIGHEST:
104
4
  case R_MICROMIPS_HI16:
105
4
  case R_MICROMIPS_LO16:
106
4
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
107
4
    // offset between start of function and 'gp' value which by default
108
4
    // equal to the start of .got section. In that case we consider these
109
4
    // relocations as relative.
110
4
    if (&s == ElfSym::mipsGpDisp)
111
0
      return R_MIPS_GOT_GP_PC;
112
4
    if (&s == ElfSym::mipsLocalGp)
113
0
      return R_MIPS_GOT_GP;
114
4
    LLVM_FALLTHROUGH;
115
16
  case R_MIPS_32:
116
16
  case R_MIPS_64:
117
16
  case R_MIPS_GOT_OFST:
118
16
  case R_MIPS_SUB:
119
16
  case R_MIPS_TLS_DTPREL_HI16:
120
16
  case R_MIPS_TLS_DTPREL_LO16:
121
16
  case R_MIPS_TLS_DTPREL32:
122
16
  case R_MIPS_TLS_DTPREL64:
123
16
  case R_MIPS_TLS_TPREL_HI16:
124
16
  case R_MIPS_TLS_TPREL_LO16:
125
16
  case R_MIPS_TLS_TPREL32:
126
16
  case R_MIPS_TLS_TPREL64:
127
16
  case R_MICROMIPS_TLS_DTPREL_HI16:
128
16
  case R_MICROMIPS_TLS_DTPREL_LO16:
129
16
  case R_MICROMIPS_TLS_TPREL_HI16:
130
16
  case R_MICROMIPS_TLS_TPREL_LO16:
131
16
    return R_ABS;
132
16
  case R_MIPS_PC32:
133
1
  case R_MIPS_PC16:
134
1
  case R_MIPS_PC19_S2:
135
1
  case R_MIPS_PC21_S2:
136
1
  case R_MIPS_PC26_S2:
137
1
  case R_MIPS_PCHI16:
138
1
  case R_MIPS_PCLO16:
139
1
  case R_MICROMIPS_PC7_S1:
140
1
  case R_MICROMIPS_PC10_S1:
141
1
  case R_MICROMIPS_PC16_S1:
142
1
  case R_MICROMIPS_PC18_S3:
143
1
  case R_MICROMIPS_PC19_S2:
144
1
  case R_MICROMIPS_PC23_S2:
145
1
  case R_MICROMIPS_PC21_S1:
146
1
    return R_PC;
147
1
  case R_MIPS_GOT16:
148
0
  case R_MICROMIPS_GOT16:
149
0
    if (s.isLocal())
150
0
      return R_MIPS_GOT_LOCAL_PAGE;
151
0
    LLVM_FALLTHROUGH;
152
10.0k
  case R_MIPS_CALL16:
153
10.0k
  case R_MIPS_GOT_DISP:
154
10.0k
  case R_MIPS_TLS_GOTTPREL:
155
10.0k
  case R_MICROMIPS_CALL16:
156
10.0k
  case R_MICROMIPS_TLS_GOTTPREL:
157
10.0k
    return R_MIPS_GOT_OFF;
158
10.0k
  case R_MIPS_CALL_HI16:
159
0
  case R_MIPS_CALL_LO16:
160
0
  case R_MIPS_GOT_HI16:
161
0
  case R_MIPS_GOT_LO16:
162
0
  case R_MICROMIPS_CALL_HI16:
163
0
  case R_MICROMIPS_CALL_LO16:
164
0
  case R_MICROMIPS_GOT_HI16:
165
0
  case R_MICROMIPS_GOT_LO16:
166
0
    return R_MIPS_GOT_OFF32;
167
12
  case R_MIPS_GOT_PAGE:
168
12
    return R_MIPS_GOT_LOCAL_PAGE;
169
5
  case R_MIPS_TLS_GD:
170
5
  case R_MICROMIPS_TLS_GD:
171
5
    return R_MIPS_TLSGD;
172
5
  case R_MIPS_TLS_LDM:
173
2
  case R_MICROMIPS_TLS_LDM:
174
2
    return R_MIPS_TLSLD;
175
2
  case R_MIPS_NONE:
176
0
    return R_NONE;
177
2
  default:
178
0
    error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
179
0
          ") against symbol " + toString(s));
180
0
    return R_NONE;
181
10.0k
  }
182
10.0k
}
183
184
9
template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
185
9
  if (type == symbolicRel)
186
9
    return type;
187
0
  return R_MIPS_NONE;
188
0
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getDynRel(unsigned int) const
Line
Count
Source
184
2
template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
185
2
  if (type == symbolicRel)
186
2
    return type;
187
0
  return R_MIPS_NONE;
188
0
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getDynRel(unsigned int) const
Line
Count
Source
184
2
template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
185
2
  if (type == symbolicRel)
186
2
    return type;
187
0
  return R_MIPS_NONE;
188
0
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getDynRel(unsigned int) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getDynRel(unsigned int) const
Line
Count
Source
184
5
template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
185
5
  if (type == symbolicRel)
186
5
    return type;
187
0
  return R_MIPS_NONE;
188
0
}
189
190
template <class ELFT>
191
17
void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
192
17
  uint64_t va = in.plt->getVA();
193
17
  if (isMicroMips())
194
6
    va |= 1;
195
17
  write32<ELFT::TargetEndianness>(buf, va);
196
17
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeGotPlt(unsigned char*, lld::elf::Symbol const&) const
Line
Count
Source
191
2
void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
192
2
  uint64_t va = in.plt->getVA();
193
2
  if (isMicroMips())
194
2
    va |= 1;
195
2
  write32<ELFT::TargetEndianness>(buf, va);
196
2
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::writeGotPlt(unsigned char*, lld::elf::Symbol const&) const
Line
Count
Source
191
13
void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
192
13
  uint64_t va = in.plt->getVA();
193
13
  if (isMicroMips())
194
4
    va |= 1;
195
13
  write32<ELFT::TargetEndianness>(buf, va);
196
13
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::writeGotPlt(unsigned char*, lld::elf::Symbol const&) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::writeGotPlt(unsigned char*, lld::elf::Symbol const&) const
Line
Count
Source
191
2
void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
192
2
  uint64_t va = in.plt->getVA();
193
2
  if (isMicroMips())
194
0
    va |= 1;
195
2
  write32<ELFT::TargetEndianness>(buf, va);
196
2
}
197
198
38
template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
199
38
  // The major opcode of a microMIPS instruction needs to appear
200
38
  // in the first 16-bit word (lowest address) for efficient hardware
201
38
  // decode so that it knows if the instruction is 16-bit or 32-bit
202
38
  // as early as possible. To do so, little-endian binaries keep 16-bit
203
38
  // words in a big-endian order. That is why we have to swap these
204
38
  // words to get a correct value.
205
38
  uint32_t v = read32<E>(loc);
206
38
  if (E == support::little)
207
12
    return (v << 16) | (v >> 16);
208
26
  return v;
209
26
}
Mips.cpp:unsigned int readShuffle<(llvm::support::endianness)1>(unsigned char const*)
Line
Count
Source
198
12
template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
199
12
  // The major opcode of a microMIPS instruction needs to appear
200
12
  // in the first 16-bit word (lowest address) for efficient hardware
201
12
  // decode so that it knows if the instruction is 16-bit or 32-bit
202
12
  // as early as possible. To do so, little-endian binaries keep 16-bit
203
12
  // words in a big-endian order. That is why we have to swap these
204
12
  // words to get a correct value.
205
12
  uint32_t v = read32<E>(loc);
206
12
  if (E == support::little)
207
12
    return (v << 16) | (v >> 16);
208
0
  return v;
209
0
}
Mips.cpp:unsigned int readShuffle<(llvm::support::endianness)0>(unsigned char const*)
Line
Count
Source
198
26
template <endianness E> static uint32_t readShuffle(const uint8_t *loc) {
199
26
  // The major opcode of a microMIPS instruction needs to appear
200
26
  // in the first 16-bit word (lowest address) for efficient hardware
201
26
  // decode so that it knows if the instruction is 16-bit or 32-bit
202
26
  // as early as possible. To do so, little-endian binaries keep 16-bit
203
26
  // words in a big-endian order. That is why we have to swap these
204
26
  // words to get a correct value.
205
26
  uint32_t v = read32<E>(loc);
206
26
  if (E == support::little)
207
0
    return (v << 16) | (v >> 16);
208
26
  return v;
209
26
}
210
211
template <endianness E>
212
static void writeValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
213
10.5k
                       uint8_t shift) {
214
10.5k
  uint32_t instr = read32<E>(loc);
215
10.5k
  uint32_t mask = 0xffffffff >> (32 - bitsSize);
216
10.5k
  uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
217
10.5k
  write32<E>(loc, data);
218
10.5k
}
Mips.cpp:void writeValue<(llvm::support::endianness)1>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
213
30
                       uint8_t shift) {
214
30
  uint32_t instr = read32<E>(loc);
215
30
  uint32_t mask = 0xffffffff >> (32 - bitsSize);
216
30
  uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
217
30
  write32<E>(loc, data);
218
30
}
Mips.cpp:void writeValue<(llvm::support::endianness)0>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
213
10.4k
                       uint8_t shift) {
214
10.4k
  uint32_t instr = read32<E>(loc);
215
10.4k
  uint32_t mask = 0xffffffff >> (32 - bitsSize);
216
10.4k
  uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
217
10.4k
  write32<E>(loc, data);
218
10.4k
}
219
220
template <endianness E>
221
static void writeShuffleValue(uint8_t *loc, uint64_t v, uint8_t bitsSize,
222
64
                              uint8_t shift) {
223
64
  // See comments in readShuffle for purpose of this code.
224
64
  uint16_t *words = (uint16_t *)loc;
225
64
  if (E == support::little)
226
22
    std::swap(words[0], words[1]);
227
64
228
64
  writeValue<E>(loc, v, bitsSize, shift);
229
64
230
64
  if (E == support::little)
231
22
    std::swap(words[0], words[1]);
232
64
}
Mips.cpp:void writeShuffleValue<(llvm::support::endianness)1>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
222
22
                              uint8_t shift) {
223
22
  // See comments in readShuffle for purpose of this code.
224
22
  uint16_t *words = (uint16_t *)loc;
225
22
  if (E == support::little)
226
22
    std::swap(words[0], words[1]);
227
22
228
22
  writeValue<E>(loc, v, bitsSize, shift);
229
22
230
22
  if (E == support::little)
231
22
    std::swap(words[0], words[1]);
232
22
}
Mips.cpp:void writeShuffleValue<(llvm::support::endianness)0>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
222
42
                              uint8_t shift) {
223
42
  // See comments in readShuffle for purpose of this code.
224
42
  uint16_t *words = (uint16_t *)loc;
225
42
  if (E == support::little)
226
0
    std::swap(words[0], words[1]);
227
42
228
42
  writeValue<E>(loc, v, bitsSize, shift);
229
42
230
42
  if (E == support::little)
231
0
    std::swap(words[0], words[1]);
232
42
}
233
234
template <endianness E>
235
static void writeMicroRelocation16(uint8_t *loc, uint64_t v, uint8_t bitsSize,
236
5
                                   uint8_t shift) {
237
5
  uint16_t instr = read16<E>(loc);
238
5
  uint16_t mask = 0xffff >> (16 - bitsSize);
239
5
  uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
240
5
  write16<E>(loc, data);
241
5
}
Mips.cpp:void writeMicroRelocation16<(llvm::support::endianness)1>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
236
2
                                   uint8_t shift) {
237
2
  uint16_t instr = read16<E>(loc);
238
2
  uint16_t mask = 0xffff >> (16 - bitsSize);
239
2
  uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
240
2
  write16<E>(loc, data);
241
2
}
Mips.cpp:void writeMicroRelocation16<(llvm::support::endianness)0>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
236
3
                                   uint8_t shift) {
237
3
  uint16_t instr = read16<E>(loc);
238
3
  uint16_t mask = 0xffff >> (16 - bitsSize);
239
3
  uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
240
3
  write16<E>(loc, data);
241
3
}
242
243
15
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
244
15
  const endianness e = ELFT::TargetEndianness;
245
15
  if (isMicroMips()) {
246
6
    uint64_t gotPlt = in.gotPlt->getVA();
247
6
    uint64_t plt = in.plt->getVA();
248
6
    // Overwrite trap instructions written by Writer::writeTrapInstr.
249
6
    memset(buf, 0, pltHeaderSize);
250
6
251
6
    write16<e>(buf, isMipsR6() ? 
0x78602
:
0x79804
); // addiupc v1, (GOTPLT) - .
252
6
    write16<e>(buf + 4, 0xff23);    // lw      $25, 0($3)
253
6
    write16<e>(buf + 8, 0x0535);    // subu16  $2,  $2, $3
254
6
    write16<e>(buf + 10, 0x2525);   // srl16   $2,  $2, 2
255
6
    write16<e>(buf + 12, 0x3302);   // addiu   $24, $2, -2
256
6
    write16<e>(buf + 14, 0xfffe);
257
6
    write16<e>(buf + 16, 0x0dff);   // move    $15, $31
258
6
    if (isMipsR6()) {
259
2
      write16<e>(buf + 18, 0x0f83); // move    $28, $3
260
2
      write16<e>(buf + 20, 0x472b); // jalrc   $25
261
2
      write16<e>(buf + 22, 0x0c00); // nop
262
2
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
263
4
    } else {
264
4
      write16<e>(buf + 18, 0x45f9); // jalrc   $25
265
4
      write16<e>(buf + 20, 0x0f83); // move    $28, $3
266
4
      write16<e>(buf + 22, 0x0c00); // nop
267
4
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
268
4
    }
269
6
    return;
270
6
  }
271
9
272
9
  if (config->mipsN32Abi) {
273
2
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
274
2
    write32<e>(buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
275
2
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
276
2
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
277
2
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
278
2
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
279
7
  } else if (ELFT::Is64Bits) {
280
2
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
281
2
    write32<e>(buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
282
2
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
283
2
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
284
2
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
285
2
    write32<e>(buf + 20, 0x0018c0c2); // srl   $24, $24, 3
286
5
  } else {
287
5
    write32<e>(buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
288
5
    write32<e>(buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
289
5
    write32<e>(buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
290
5
    write32<e>(buf + 12, 0x031cc023); // subu  $24, $24, $28
291
5
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
292
5
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
293
5
  }
294
9
295
9
  uint32_t jalrInst = config->zHazardplt ? 
0x0320fc093
:
0x0320f8096
;
296
9
  write32<e>(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
297
9
  write32<e>(buf + 28, 0x2718fffe); // subu  $24, $24, 2
298
9
299
9
  uint64_t gotPlt = in.gotPlt->getVA();
300
9
  writeValue<e>(buf, gotPlt + 0x8000, 16, 16);
301
9
  writeValue<e>(buf + 4, gotPlt, 16, 0);
302
9
  writeValue<e>(buf + 8, gotPlt, 16, 0);
303
9
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writePltHeader(unsigned char*) const
Line
Count
Source
243
2
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
244
2
  const endianness e = ELFT::TargetEndianness;
245
2
  if (isMicroMips()) {
246
2
    uint64_t gotPlt = in.gotPlt->getVA();
247
2
    uint64_t plt = in.plt->getVA();
248
2
    // Overwrite trap instructions written by Writer::writeTrapInstr.
249
2
    memset(buf, 0, pltHeaderSize);
250
2
251
2
    write16<e>(buf, isMipsR6() ? 
0x78601
:
0x79801
); // addiupc v1, (GOTPLT) - .
252
2
    write16<e>(buf + 4, 0xff23);    // lw      $25, 0($3)
253
2
    write16<e>(buf + 8, 0x0535);    // subu16  $2,  $2, $3
254
2
    write16<e>(buf + 10, 0x2525);   // srl16   $2,  $2, 2
255
2
    write16<e>(buf + 12, 0x3302);   // addiu   $24, $2, -2
256
2
    write16<e>(buf + 14, 0xfffe);
257
2
    write16<e>(buf + 16, 0x0dff);   // move    $15, $31
258
2
    if (isMipsR6()) {
259
1
      write16<e>(buf + 18, 0x0f83); // move    $28, $3
260
1
      write16<e>(buf + 20, 0x472b); // jalrc   $25
261
1
      write16<e>(buf + 22, 0x0c00); // nop
262
1
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
263
1
    } else {
264
1
      write16<e>(buf + 18, 0x45f9); // jalrc   $25
265
1
      write16<e>(buf + 20, 0x0f83); // move    $28, $3
266
1
      write16<e>(buf + 22, 0x0c00); // nop
267
1
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
268
1
    }
269
2
    return;
270
2
  }
271
0
272
0
  if (config->mipsN32Abi) {
273
0
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
274
0
    write32<e>(buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
275
0
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
276
0
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
277
0
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
278
0
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
279
0
  } else if (ELFT::Is64Bits) {
280
0
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
281
0
    write32<e>(buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
282
0
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
283
0
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
284
0
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
285
0
    write32<e>(buf + 20, 0x0018c0c2); // srl   $24, $24, 3
286
0
  } else {
287
0
    write32<e>(buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
288
0
    write32<e>(buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
289
0
    write32<e>(buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
290
0
    write32<e>(buf + 12, 0x031cc023); // subu  $24, $24, $28
291
0
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
292
0
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
293
0
  }
294
0
295
0
  uint32_t jalrInst = config->zHazardplt ? 0x0320fc09 : 0x0320f809;
296
0
  write32<e>(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
297
0
  write32<e>(buf + 28, 0x2718fffe); // subu  $24, $24, 2
298
0
299
0
  uint64_t gotPlt = in.gotPlt->getVA();
300
0
  writeValue<e>(buf, gotPlt + 0x8000, 16, 16);
301
0
  writeValue<e>(buf + 4, gotPlt, 16, 0);
302
0
  writeValue<e>(buf + 8, gotPlt, 16, 0);
303
0
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::writePltHeader(unsigned char*) const
Line
Count
Source
243
11
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
244
11
  const endianness e = ELFT::TargetEndianness;
245
11
  if (isMicroMips()) {
246
4
    uint64_t gotPlt = in.gotPlt->getVA();
247
4
    uint64_t plt = in.plt->getVA();
248
4
    // Overwrite trap instructions written by Writer::writeTrapInstr.
249
4
    memset(buf, 0, pltHeaderSize);
250
4
251
4
    write16<e>(buf, isMipsR6() ? 
0x78601
:
0x79803
); // addiupc v1, (GOTPLT) - .
252
4
    write16<e>(buf + 4, 0xff23);    // lw      $25, 0($3)
253
4
    write16<e>(buf + 8, 0x0535);    // subu16  $2,  $2, $3
254
4
    write16<e>(buf + 10, 0x2525);   // srl16   $2,  $2, 2
255
4
    write16<e>(buf + 12, 0x3302);   // addiu   $24, $2, -2
256
4
    write16<e>(buf + 14, 0xfffe);
257
4
    write16<e>(buf + 16, 0x0dff);   // move    $15, $31
258
4
    if (isMipsR6()) {
259
1
      write16<e>(buf + 18, 0x0f83); // move    $28, $3
260
1
      write16<e>(buf + 20, 0x472b); // jalrc   $25
261
1
      write16<e>(buf + 22, 0x0c00); // nop
262
1
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
263
3
    } else {
264
3
      write16<e>(buf + 18, 0x45f9); // jalrc   $25
265
3
      write16<e>(buf + 20, 0x0f83); // move    $28, $3
266
3
      write16<e>(buf + 22, 0x0c00); // nop
267
3
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
268
3
    }
269
4
    return;
270
4
  }
271
7
272
7
  if (config->mipsN32Abi) {
273
2
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
274
2
    write32<e>(buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
275
2
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
276
2
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
277
2
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
278
2
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
279
5
  } else if (ELFT::Is64Bits) {
280
0
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
281
0
    write32<e>(buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
282
0
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
283
0
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
284
0
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
285
0
    write32<e>(buf + 20, 0x0018c0c2); // srl   $24, $24, 3
286
5
  } else {
287
5
    write32<e>(buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
288
5
    write32<e>(buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
289
5
    write32<e>(buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
290
5
    write32<e>(buf + 12, 0x031cc023); // subu  $24, $24, $28
291
5
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
292
5
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
293
5
  }
294
7
295
7
  uint32_t jalrInst = config->zHazardplt ? 
0x0320fc092
:
0x0320f8095
;
296
7
  write32<e>(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
297
7
  write32<e>(buf + 28, 0x2718fffe); // subu  $24, $24, 2
298
7
299
7
  uint64_t gotPlt = in.gotPlt->getVA();
300
7
  writeValue<e>(buf, gotPlt + 0x8000, 16, 16);
301
7
  writeValue<e>(buf + 4, gotPlt, 16, 0);
302
7
  writeValue<e>(buf + 8, gotPlt, 16, 0);
303
7
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::writePltHeader(unsigned char*) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::writePltHeader(unsigned char*) const
Line
Count
Source
243
2
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
244
2
  const endianness e = ELFT::TargetEndianness;
245
2
  if (isMicroMips()) {
246
0
    uint64_t gotPlt = in.gotPlt->getVA();
247
0
    uint64_t plt = in.plt->getVA();
248
0
    // Overwrite trap instructions written by Writer::writeTrapInstr.
249
0
    memset(buf, 0, pltHeaderSize);
250
0
251
0
    write16<e>(buf, isMipsR6() ? 0x7860 : 0x7980);  // addiupc v1, (GOTPLT) - .
252
0
    write16<e>(buf + 4, 0xff23);    // lw      $25, 0($3)
253
0
    write16<e>(buf + 8, 0x0535);    // subu16  $2,  $2, $3
254
0
    write16<e>(buf + 10, 0x2525);   // srl16   $2,  $2, 2
255
0
    write16<e>(buf + 12, 0x3302);   // addiu   $24, $2, -2
256
0
    write16<e>(buf + 14, 0xfffe);
257
0
    write16<e>(buf + 16, 0x0dff);   // move    $15, $31
258
0
    if (isMipsR6()) {
259
0
      write16<e>(buf + 18, 0x0f83); // move    $28, $3
260
0
      write16<e>(buf + 20, 0x472b); // jalrc   $25
261
0
      write16<e>(buf + 22, 0x0c00); // nop
262
0
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPlt - plt);
263
0
    } else {
264
0
      write16<e>(buf + 18, 0x45f9); // jalrc   $25
265
0
      write16<e>(buf + 20, 0x0f83); // move    $28, $3
266
0
      write16<e>(buf + 22, 0x0c00); // nop
267
0
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPlt - plt);
268
0
    }
269
0
    return;
270
0
  }
271
2
272
2
  if (config->mipsN32Abi) {
273
0
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
274
0
    write32<e>(buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
275
0
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
276
0
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
277
0
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
278
0
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
279
2
  } else if (ELFT::Is64Bits) {
280
2
    write32<e>(buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
281
2
    write32<e>(buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
282
2
    write32<e>(buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
283
2
    write32<e>(buf + 12, 0x030ec023); // subu  $24, $24, $14
284
2
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
285
2
    write32<e>(buf + 20, 0x0018c0c2); // srl   $24, $24, 3
286
2
  } else {
287
0
    write32<e>(buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
288
0
    write32<e>(buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
289
0
    write32<e>(buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
290
0
    write32<e>(buf + 12, 0x031cc023); // subu  $24, $24, $28
291
0
    write32<e>(buf + 16, 0x03e07825); // move  $15, $31
292
0
    write32<e>(buf + 20, 0x0018c082); // srl   $24, $24, 2
293
0
  }
294
2
295
2
  uint32_t jalrInst = config->zHazardplt ? 
0x0320fc091
:
0x0320f8091
;
296
2
  write32<e>(buf + 24, jalrInst); // jalr.hb $25 or jalr $25
297
2
  write32<e>(buf + 28, 0x2718fffe); // subu  $24, $24, 2
298
2
299
2
  uint64_t gotPlt = in.gotPlt->getVA();
300
2
  writeValue<e>(buf, gotPlt + 0x8000, 16, 16);
301
2
  writeValue<e>(buf + 4, gotPlt, 16, 0);
302
2
  writeValue<e>(buf + 8, gotPlt, 16, 0);
303
2
}
304
305
template <class ELFT>
306
void MIPS<ELFT>::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
307
                          uint64_t pltEntryAddr, int32_t index,
308
17
                          unsigned relOff) const {
309
17
  const endianness e = ELFT::TargetEndianness;
310
17
  if (isMicroMips()) {
311
6
    // Overwrite trap instructions written by Writer::writeTrapInstr.
312
6
    memset(buf, 0, pltEntrySize);
313
6
314
6
    if (isMipsR6()) {
315
2
      write16<e>(buf, 0x7840);      // addiupc $2, (GOTPLT) - .
316
2
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
317
2
      write16<e>(buf + 8, 0x0f02);  // move $24, $2
318
2
      write16<e>(buf + 10, 0x4723); // jrc $25 / jr16 $25
319
2
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
320
4
    } else {
321
4
      write16<e>(buf, 0x7900);      // addiupc $2, (GOTPLT) - .
322
4
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
323
4
      write16<e>(buf + 8, 0x4599);  // jrc $25 / jr16 $25
324
4
      write16<e>(buf + 10, 0x0f02); // move $24, $2
325
4
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
326
4
    }
327
6
    return;
328
6
  }
329
11
330
11
  uint32_t loadInst = ELFT::Is64Bits ? 
0xddf900002
:
0x8df900009
;
331
11
  uint32_t jrInst = isMipsR6() ? 
(config->zHazardplt 2
?
0x032004091
:
0x032000091
)
332
11
                               : 
(config->zHazardplt 9
?
0x032004082
:
0x032000087
);
333
11
  uint32_t addInst = ELFT::Is64Bits ? 
0x65f800002
:
0x25f800009
;
334
11
335
11
  write32<e>(buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
336
11
  write32<e>(buf + 4, loadInst);   // l[wd] $25, %lo(.got.plt entry)($15)
337
11
  write32<e>(buf + 8, jrInst);     // jr  $25 / jr.hb $25
338
11
  write32<e>(buf + 12, addInst);   // [d]addiu $24, $15, %lo(.got.plt entry)
339
11
  writeValue<e>(buf, gotPltEntryAddr + 0x8000, 16, 16);
340
11
  writeValue<e>(buf + 4, gotPltEntryAddr, 16, 0);
341
11
  writeValue<e>(buf + 12, gotPltEntryAddr, 16, 0);
342
11
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writePlt(unsigned char*, unsigned long long, unsigned long long, int, unsigned int) const
Line
Count
Source
308
2
                          unsigned relOff) const {
309
2
  const endianness e = ELFT::TargetEndianness;
310
2
  if (isMicroMips()) {
311
2
    // Overwrite trap instructions written by Writer::writeTrapInstr.
312
2
    memset(buf, 0, pltEntrySize);
313
2
314
2
    if (isMipsR6()) {
315
1
      write16<e>(buf, 0x7840);      // addiupc $2, (GOTPLT) - .
316
1
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
317
1
      write16<e>(buf + 8, 0x0f02);  // move $24, $2
318
1
      write16<e>(buf + 10, 0x4723); // jrc $25 / jr16 $25
319
1
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
320
1
    } else {
321
1
      write16<e>(buf, 0x7900);      // addiupc $2, (GOTPLT) - .
322
1
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
323
1
      write16<e>(buf + 8, 0x4599);  // jrc $25 / jr16 $25
324
1
      write16<e>(buf + 10, 0x0f02); // move $24, $2
325
1
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
326
1
    }
327
2
    return;
328
2
  }
329
0
330
0
  uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
331
0
  uint32_t jrInst = isMipsR6() ? (config->zHazardplt ? 0x03200409 : 0x03200009)
332
0
                               : (config->zHazardplt ? 0x03200408 : 0x03200008);
333
0
  uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
334
0
335
0
  write32<e>(buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
336
0
  write32<e>(buf + 4, loadInst);   // l[wd] $25, %lo(.got.plt entry)($15)
337
0
  write32<e>(buf + 8, jrInst);     // jr  $25 / jr.hb $25
338
0
  write32<e>(buf + 12, addInst);   // [d]addiu $24, $15, %lo(.got.plt entry)
339
0
  writeValue<e>(buf, gotPltEntryAddr + 0x8000, 16, 16);
340
0
  writeValue<e>(buf + 4, gotPltEntryAddr, 16, 0);
341
0
  writeValue<e>(buf + 12, gotPltEntryAddr, 16, 0);
342
0
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::writePlt(unsigned char*, unsigned long long, unsigned long long, int, unsigned int) const
Line
Count
Source
308
13
                          unsigned relOff) const {
309
13
  const endianness e = ELFT::TargetEndianness;
310
13
  if (isMicroMips()) {
311
4
    // Overwrite trap instructions written by Writer::writeTrapInstr.
312
4
    memset(buf, 0, pltEntrySize);
313
4
314
4
    if (isMipsR6()) {
315
1
      write16<e>(buf, 0x7840);      // addiupc $2, (GOTPLT) - .
316
1
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
317
1
      write16<e>(buf + 8, 0x0f02);  // move $24, $2
318
1
      write16<e>(buf + 10, 0x4723); // jrc $25 / jr16 $25
319
1
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
320
3
    } else {
321
3
      write16<e>(buf, 0x7900);      // addiupc $2, (GOTPLT) - .
322
3
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
323
3
      write16<e>(buf + 8, 0x4599);  // jrc $25 / jr16 $25
324
3
      write16<e>(buf + 10, 0x0f02); // move $24, $2
325
3
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
326
3
    }
327
4
    return;
328
4
  }
329
9
330
9
  uint32_t loadInst = ELFT::Is64Bits ? 
0xddf900000
: 0x8df90000;
331
9
  uint32_t jrInst = isMipsR6() ? 
(config->zHazardplt 2
?
0x032004091
:
0x032000091
)
332
9
                               : 
(config->zHazardplt 7
?
0x032004081
:
0x032000086
);
333
9
  uint32_t addInst = ELFT::Is64Bits ? 
0x65f800000
: 0x25f80000;
334
9
335
9
  write32<e>(buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
336
9
  write32<e>(buf + 4, loadInst);   // l[wd] $25, %lo(.got.plt entry)($15)
337
9
  write32<e>(buf + 8, jrInst);     // jr  $25 / jr.hb $25
338
9
  write32<e>(buf + 12, addInst);   // [d]addiu $24, $15, %lo(.got.plt entry)
339
9
  writeValue<e>(buf, gotPltEntryAddr + 0x8000, 16, 16);
340
9
  writeValue<e>(buf + 4, gotPltEntryAddr, 16, 0);
341
9
  writeValue<e>(buf + 12, gotPltEntryAddr, 16, 0);
342
9
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::writePlt(unsigned char*, unsigned long long, unsigned long long, int, unsigned int) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::writePlt(unsigned char*, unsigned long long, unsigned long long, int, unsigned int) const
Line
Count
Source
308
2
                          unsigned relOff) const {
309
2
  const endianness e = ELFT::TargetEndianness;
310
2
  if (isMicroMips()) {
311
0
    // Overwrite trap instructions written by Writer::writeTrapInstr.
312
0
    memset(buf, 0, pltEntrySize);
313
0
314
0
    if (isMipsR6()) {
315
0
      write16<e>(buf, 0x7840);      // addiupc $2, (GOTPLT) - .
316
0
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
317
0
      write16<e>(buf + 8, 0x0f02);  // move $24, $2
318
0
      write16<e>(buf + 10, 0x4723); // jrc $25 / jr16 $25
319
0
      relocateOne(buf, R_MICROMIPS_PC19_S2, gotPltEntryAddr - pltEntryAddr);
320
0
    } else {
321
0
      write16<e>(buf, 0x7900);      // addiupc $2, (GOTPLT) - .
322
0
      write16<e>(buf + 4, 0xff22);  // lw $25, 0($2)
323
0
      write16<e>(buf + 8, 0x4599);  // jrc $25 / jr16 $25
324
0
      write16<e>(buf + 10, 0x0f02); // move $24, $2
325
0
      relocateOne(buf, R_MICROMIPS_PC23_S2, gotPltEntryAddr - pltEntryAddr);
326
0
    }
327
0
    return;
328
0
  }
329
2
330
2
  uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 
0x8df900000
;
331
2
  uint32_t jrInst = isMipsR6() ? 
(config->zHazardplt 0
?
0x032004090
:
0x032000090
)
332
2
                               : (config->zHazardplt ? 
0x032004081
:
0x032000081
);
333
2
  uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 
0x25f800000
;
334
2
335
2
  write32<e>(buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
336
2
  write32<e>(buf + 4, loadInst);   // l[wd] $25, %lo(.got.plt entry)($15)
337
2
  write32<e>(buf + 8, jrInst);     // jr  $25 / jr.hb $25
338
2
  write32<e>(buf + 12, addInst);   // [d]addiu $24, $15, %lo(.got.plt entry)
339
2
  writeValue<e>(buf, gotPltEntryAddr + 0x8000, 16, 16);
340
2
  writeValue<e>(buf + 4, gotPltEntryAddr, 16, 0);
341
2
  writeValue<e>(buf + 12, gotPltEntryAddr, 16, 0);
342
2
}
343
344
template <class ELFT>
345
bool MIPS<ELFT>::needsThunk(RelExpr expr, RelType type, const InputFile *file,
346
10.3k
                            uint64_t branchAddr, const Symbol &s) const {
347
10.3k
  // Any MIPS PIC code function is invoked with its address in register $t9.
348
10.3k
  // So if we have a branch instruction from non-PIC code to the PIC one
349
10.3k
  // we cannot make the jump directly and need to create a small stubs
350
10.3k
  // to save the target function address.
351
10.3k
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
352
10.3k
  if (type != R_MIPS_26 && 
type != R_MIPS_PC26_S210.2k
&&
353
10.3k
      
type != R_MICROMIPS_26_S110.2k
&&
type != R_MICROMIPS_PC26_S110.2k
)
354
10.2k
    return false;
355
94
  auto *f = dyn_cast_or_null<ObjFile<ELFT>>(file);
356
94
  if (!f)
357
0
    return false;
358
94
  // If current file has PIC code, LA25 stub is not required.
359
94
  if (f->getObj().getHeader()->e_flags & EF_MIPS_PIC)
360
0
    return false;
361
94
  auto *d = dyn_cast<Defined>(&s);
362
94
  // LA25 is required if target file has PIC code
363
94
  // or target symbol is a PIC symbol.
364
94
  return d && 
isMipsPIC<ELFT>(d)81
;
365
94
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::needsThunk(lld::elf::RelExpr, unsigned int, lld::elf::InputFile const*, unsigned long long, lld::elf::Symbol const&) const
Line
Count
Source
346
18
                            uint64_t branchAddr, const Symbol &s) const {
347
18
  // Any MIPS PIC code function is invoked with its address in register $t9.
348
18
  // So if we have a branch instruction from non-PIC code to the PIC one
349
18
  // we cannot make the jump directly and need to create a small stubs
350
18
  // to save the target function address.
351
18
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
352
18
  if (type != R_MIPS_26 && type != R_MIPS_PC26_S2 &&
353
18
      type != R_MICROMIPS_26_S1 && 
type != R_MICROMIPS_PC26_S116
)
354
13
    return false;
355
5
  auto *f = dyn_cast_or_null<ObjFile<ELFT>>(file);
356
5
  if (!f)
357
0
    return false;
358
5
  // If current file has PIC code, LA25 stub is not required.
359
5
  if (f->getObj().getHeader()->e_flags & EF_MIPS_PIC)
360
0
    return false;
361
5
  auto *d = dyn_cast<Defined>(&s);
362
5
  // LA25 is required if target file has PIC code
363
5
  // or target symbol is a PIC symbol.
364
5
  return d && 
isMipsPIC<ELFT>(d)3
;
365
5
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::needsThunk(lld::elf::RelExpr, unsigned int, lld::elf::InputFile const*, unsigned long long, lld::elf::Symbol const&) const
Line
Count
Source
346
269
                            uint64_t branchAddr, const Symbol &s) const {
347
269
  // Any MIPS PIC code function is invoked with its address in register $t9.
348
269
  // So if we have a branch instruction from non-PIC code to the PIC one
349
269
  // we cannot make the jump directly and need to create a small stubs
350
269
  // to save the target function address.
351
269
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
352
269
  if (type != R_MIPS_26 && 
type != R_MIPS_PC26_S2193
&&
353
269
      
type != R_MICROMIPS_26_S1192
&&
type != R_MICROMIPS_PC26_S1185
)
354
182
    return false;
355
87
  auto *f = dyn_cast_or_null<ObjFile<ELFT>>(file);
356
87
  if (!f)
357
0
    return false;
358
87
  // If current file has PIC code, LA25 stub is not required.
359
87
  if (f->getObj().getHeader()->e_flags & EF_MIPS_PIC)
360
0
    return false;
361
87
  auto *d = dyn_cast<Defined>(&s);
362
87
  // LA25 is required if target file has PIC code
363
87
  // or target symbol is a PIC symbol.
364
87
  return d && 
isMipsPIC<ELFT>(d)78
;
365
87
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::needsThunk(lld::elf::RelExpr, unsigned int, lld::elf::InputFile const*, unsigned long long, lld::elf::Symbol const&) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::needsThunk(lld::elf::RelExpr, unsigned int, lld::elf::InputFile const*, unsigned long long, lld::elf::Symbol const&) const
Line
Count
Source
346
10.0k
                            uint64_t branchAddr, const Symbol &s) const {
347
10.0k
  // Any MIPS PIC code function is invoked with its address in register $t9.
348
10.0k
  // So if we have a branch instruction from non-PIC code to the PIC one
349
10.0k
  // we cannot make the jump directly and need to create a small stubs
350
10.0k
  // to save the target function address.
351
10.0k
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
352
10.0k
  if (type != R_MIPS_26 && 
type != R_MIPS_PC26_S210.0k
&&
353
10.0k
      
type != R_MICROMIPS_26_S110.0k
&&
type != R_MICROMIPS_PC26_S110.0k
)
354
10.0k
    return false;
355
2
  auto *f = dyn_cast_or_null<ObjFile<ELFT>>(file);
356
2
  if (!f)
357
0
    return false;
358
2
  // If current file has PIC code, LA25 stub is not required.
359
2
  if (f->getObj().getHeader()->e_flags & EF_MIPS_PIC)
360
0
    return false;
361
2
  auto *d = dyn_cast<Defined>(&s);
362
2
  // LA25 is required if target file has PIC code
363
2
  // or target symbol is a PIC symbol.
364
2
  return d && 
isMipsPIC<ELFT>(d)0
;
365
2
}
366
367
template <class ELFT>
368
357
int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
369
357
  const endianness e = ELFT::TargetEndianness;
370
357
  switch (type) {
371
357
  case R_MIPS_32:
372
29
  case R_MIPS_GPREL32:
373
29
  case R_MIPS_TLS_DTPREL32:
374
29
  case R_MIPS_TLS_TPREL32:
375
29
    return SignExtend64<32>(read32<e>(buf));
376
64
  case R_MIPS_26:
377
64
    // FIXME (simon): If the relocation target symbol is not a PLT entry
378
64
    // we should use another expression for calculation:
379
64
    // ((A << 2) | (P & 0xf0000000)) >> 2
380
64
    return SignExtend64<28>(read32<e>(buf) << 2);
381
70
  case R_MIPS_GOT16:
382
70
  case R_MIPS_HI16:
383
70
  case R_MIPS_PCHI16:
384
70
    return SignExtend64<16>(read32<e>(buf)) << 16;
385
94
  case R_MIPS_GPREL16:
386
94
  case R_MIPS_LO16:
387
94
  case R_MIPS_PCLO16:
388
94
  case R_MIPS_TLS_DTPREL_HI16:
389
94
  case R_MIPS_TLS_DTPREL_LO16:
390
94
  case R_MIPS_TLS_TPREL_HI16:
391
94
  case R_MIPS_TLS_TPREL_LO16:
392
94
    return SignExtend64<16>(read32<e>(buf));
393
94
  case R_MICROMIPS_GOT16:
394
7
  case R_MICROMIPS_HI16:
395
7
    return SignExtend64<16>(readShuffle<e>(buf)) << 16;
396
9
  case R_MICROMIPS_GPREL16:
397
9
  case R_MICROMIPS_LO16:
398
9
  case R_MICROMIPS_TLS_DTPREL_HI16:
399
9
  case R_MICROMIPS_TLS_DTPREL_LO16:
400
9
  case R_MICROMIPS_TLS_TPREL_HI16:
401
9
  case R_MICROMIPS_TLS_TPREL_LO16:
402
9
    return SignExtend64<16>(readShuffle<e>(buf));
403
9
  case R_MICROMIPS_GPREL7_S2:
404
0
    return SignExtend64<9>(readShuffle<e>(buf) << 2);
405
9
  case R_MIPS_PC16:
406
2
    return SignExtend64<18>(read32<e>(buf) << 2);
407
9
  case R_MIPS_PC19_S2:
408
1
    return SignExtend64<21>(read32<e>(buf) << 2);
409
9
  case R_MIPS_PC21_S2:
410
1
    return SignExtend64<23>(read32<e>(buf) << 2);
411
9
  case R_MIPS_PC26_S2:
412
1
    return SignExtend64<28>(read32<e>(buf) << 2);
413
9
  case R_MIPS_PC32:
414
1
    return SignExtend64<32>(read32<e>(buf));
415
9
  case R_MICROMIPS_26_S1:
416
8
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
417
9
  case R_MICROMIPS_PC7_S1:
418
2
    return SignExtend64<8>(read16<e>(buf) << 1);
419
9
  case R_MICROMIPS_PC10_S1:
420
3
    return SignExtend64<11>(read16<e>(buf) << 1);
421
9
  case R_MICROMIPS_PC16_S1:
422
2
    return SignExtend64<17>(readShuffle<e>(buf) << 1);
423
9
  case R_MICROMIPS_PC18_S3:
424
0
    return SignExtend64<21>(readShuffle<e>(buf) << 3);
425
9
  case R_MICROMIPS_PC19_S2:
426
2
    return SignExtend64<21>(readShuffle<e>(buf) << 2);
427
9
  case R_MICROMIPS_PC21_S1:
428
2
    return SignExtend64<22>(readShuffle<e>(buf) << 1);
429
9
  case R_MICROMIPS_PC23_S2:
430
0
    return SignExtend64<25>(readShuffle<e>(buf) << 2);
431
9
  case R_MICROMIPS_PC26_S1:
432
6
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
433
53
  default:
434
53
    return 0;
435
357
  }
436
357
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getImplicitAddend(unsigned char const*, unsigned int) const
Line
Count
Source
368
27
int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
369
27
  const endianness e = ELFT::TargetEndianness;
370
27
  switch (type) {
371
27
  case R_MIPS_32:
372
4
  case R_MIPS_GPREL32:
373
4
  case R_MIPS_TLS_DTPREL32:
374
4
  case R_MIPS_TLS_TPREL32:
375
4
    return SignExtend64<32>(read32<e>(buf));
376
4
  case R_MIPS_26:
377
0
    // FIXME (simon): If the relocation target symbol is not a PLT entry
378
0
    // we should use another expression for calculation:
379
0
    // ((A << 2) | (P & 0xf0000000)) >> 2
380
0
    return SignExtend64<28>(read32<e>(buf) << 2);
381
6
  case R_MIPS_GOT16:
382
6
  case R_MIPS_HI16:
383
6
  case R_MIPS_PCHI16:
384
6
    return SignExtend64<16>(read32<e>(buf)) << 16;
385
6
  case R_MIPS_GPREL16:
386
2
  case R_MIPS_LO16:
387
2
  case R_MIPS_PCLO16:
388
2
  case R_MIPS_TLS_DTPREL_HI16:
389
2
  case R_MIPS_TLS_DTPREL_LO16:
390
2
  case R_MIPS_TLS_TPREL_HI16:
391
2
  case R_MIPS_TLS_TPREL_LO16:
392
2
    return SignExtend64<16>(read32<e>(buf));
393
2
  case R_MICROMIPS_GOT16:
394
2
  case R_MICROMIPS_HI16:
395
2
    return SignExtend64<16>(readShuffle<e>(buf)) << 16;
396
2
  case R_MICROMIPS_GPREL16:
397
2
  case R_MICROMIPS_LO16:
398
2
  case R_MICROMIPS_TLS_DTPREL_HI16:
399
2
  case R_MICROMIPS_TLS_DTPREL_LO16:
400
2
  case R_MICROMIPS_TLS_TPREL_HI16:
401
2
  case R_MICROMIPS_TLS_TPREL_LO16:
402
2
    return SignExtend64<16>(readShuffle<e>(buf));
403
2
  case R_MICROMIPS_GPREL7_S2:
404
0
    return SignExtend64<9>(readShuffle<e>(buf) << 2);
405
2
  case R_MIPS_PC16:
406
0
    return SignExtend64<18>(read32<e>(buf) << 2);
407
2
  case R_MIPS_PC19_S2:
408
0
    return SignExtend64<21>(read32<e>(buf) << 2);
409
2
  case R_MIPS_PC21_S2:
410
0
    return SignExtend64<23>(read32<e>(buf) << 2);
411
2
  case R_MIPS_PC26_S2:
412
0
    return SignExtend64<28>(read32<e>(buf) << 2);
413
2
  case R_MIPS_PC32:
414
0
    return SignExtend64<32>(read32<e>(buf));
415
2
  case R_MICROMIPS_26_S1:
416
2
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
417
2
  case R_MICROMIPS_PC7_S1:
418
1
    return SignExtend64<8>(read16<e>(buf) << 1);
419
2
  case R_MICROMIPS_PC10_S1:
420
1
    return SignExtend64<11>(read16<e>(buf) << 1);
421
2
  case R_MICROMIPS_PC16_S1:
422
1
    return SignExtend64<17>(readShuffle<e>(buf) << 1);
423
2
  case R_MICROMIPS_PC18_S3:
424
0
    return SignExtend64<21>(readShuffle<e>(buf) << 3);
425
2
  case R_MICROMIPS_PC19_S2:
426
1
    return SignExtend64<21>(readShuffle<e>(buf) << 2);
427
2
  case R_MICROMIPS_PC21_S1:
428
1
    return SignExtend64<22>(readShuffle<e>(buf) << 1);
429
2
  case R_MICROMIPS_PC23_S2:
430
0
    return SignExtend64<25>(readShuffle<e>(buf) << 2);
431
3
  case R_MICROMIPS_PC26_S1:
432
3
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
433
2
  default:
434
1
    return 0;
435
27
  }
436
27
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getImplicitAddend(unsigned char const*, unsigned int) const
Line
Count
Source
368
330
int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
369
330
  const endianness e = ELFT::TargetEndianness;
370
330
  switch (type) {
371
330
  case R_MIPS_32:
372
25
  case R_MIPS_GPREL32:
373
25
  case R_MIPS_TLS_DTPREL32:
374
25
  case R_MIPS_TLS_TPREL32:
375
25
    return SignExtend64<32>(read32<e>(buf));
376
64
  case R_MIPS_26:
377
64
    // FIXME (simon): If the relocation target symbol is not a PLT entry
378
64
    // we should use another expression for calculation:
379
64
    // ((A << 2) | (P & 0xf0000000)) >> 2
380
64
    return SignExtend64<28>(read32<e>(buf) << 2);
381
64
  case R_MIPS_GOT16:
382
64
  case R_MIPS_HI16:
383
64
  case R_MIPS_PCHI16:
384
64
    return SignExtend64<16>(read32<e>(buf)) << 16;
385
92
  case R_MIPS_GPREL16:
386
92
  case R_MIPS_LO16:
387
92
  case R_MIPS_PCLO16:
388
92
  case R_MIPS_TLS_DTPREL_HI16:
389
92
  case R_MIPS_TLS_DTPREL_LO16:
390
92
  case R_MIPS_TLS_TPREL_HI16:
391
92
  case R_MIPS_TLS_TPREL_LO16:
392
92
    return SignExtend64<16>(read32<e>(buf));
393
92
  case R_MICROMIPS_GOT16:
394
5
  case R_MICROMIPS_HI16:
395
5
    return SignExtend64<16>(readShuffle<e>(buf)) << 16;
396
7
  case R_MICROMIPS_GPREL16:
397
7
  case R_MICROMIPS_LO16:
398
7
  case R_MICROMIPS_TLS_DTPREL_HI16:
399
7
  case R_MICROMIPS_TLS_DTPREL_LO16:
400
7
  case R_MICROMIPS_TLS_TPREL_HI16:
401
7
  case R_MICROMIPS_TLS_TPREL_LO16:
402
7
    return SignExtend64<16>(readShuffle<e>(buf));
403
7
  case R_MICROMIPS_GPREL7_S2:
404
0
    return SignExtend64<9>(readShuffle<e>(buf) << 2);
405
7
  case R_MIPS_PC16:
406
2
    return SignExtend64<18>(read32<e>(buf) << 2);
407
7
  case R_MIPS_PC19_S2:
408
1
    return SignExtend64<21>(read32<e>(buf) << 2);
409
7
  case R_MIPS_PC21_S2:
410
1
    return SignExtend64<23>(read32<e>(buf) << 2);
411
7
  case R_MIPS_PC26_S2:
412
1
    return SignExtend64<28>(read32<e>(buf) << 2);
413
7
  case R_MIPS_PC32:
414
1
    return SignExtend64<32>(read32<e>(buf));
415
7
  case R_MICROMIPS_26_S1:
416
6
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
417
7
  case R_MICROMIPS_PC7_S1:
418
1
    return SignExtend64<8>(read16<e>(buf) << 1);
419
7
  case R_MICROMIPS_PC10_S1:
420
2
    return SignExtend64<11>(read16<e>(buf) << 1);
421
7
  case R_MICROMIPS_PC16_S1:
422
1
    return SignExtend64<17>(readShuffle<e>(buf) << 1);
423
7
  case R_MICROMIPS_PC18_S3:
424
0
    return SignExtend64<21>(readShuffle<e>(buf) << 3);
425
7
  case R_MICROMIPS_PC19_S2:
426
1
    return SignExtend64<21>(readShuffle<e>(buf) << 2);
427
7
  case R_MICROMIPS_PC21_S1:
428
1
    return SignExtend64<22>(readShuffle<e>(buf) << 1);
429
7
  case R_MICROMIPS_PC23_S2:
430
0
    return SignExtend64<25>(readShuffle<e>(buf) << 2);
431
7
  case R_MICROMIPS_PC26_S1:
432
3
    return SignExtend64<27>(readShuffle<e>(buf) << 1);
433
52
  default:
434
52
    return 0;
435
330
  }
436
330
}
437
438
static std::pair<uint32_t, uint64_t>
439
10.0k
calculateMipsRelChain(uint8_t *loc, RelType type, uint64_t val) {
440
10.0k
  // MIPS N64 ABI packs multiple relocations into the single relocation
441
10.0k
  // record. In general, all up to three relocations can have arbitrary
442
10.0k
  // types. In fact, Clang and GCC uses only a few combinations. For now,
443
10.0k
  // we support two of them. That is allow to pass at least all LLVM
444
10.0k
  // test suite cases.
445
10.0k
  // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16
446
10.0k
  // <any relocation> / R_MIPS_64 / R_MIPS_NONE
447
10.0k
  // The first relocation is a 'real' relocation which is calculated
448
10.0k
  // using the corresponding symbol's value. The second and the third
449
10.0k
  // relocations used to modify result of the first one: extend it to
450
10.0k
  // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
451
10.0k
  // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
452
10.0k
  RelType type2 = (type >> 8) & 0xff;
453
10.0k
  RelType type3 = (type >> 16) & 0xff;
454
10.0k
  if (type2 == R_MIPS_NONE && 
type3 == R_MIPS_NONE10.0k
)
455
10.0k
    return std::make_pair(type, val);
456
12
  if (type2 == R_MIPS_64 && 
type3 == R_MIPS_NONE1
)
457
1
    return std::make_pair(type2, val);
458
11
  if (type2 == R_MIPS_SUB && (type3 == R_MIPS_HI16 || 
type3 == R_MIPS_LO164
))
459
11
    return std::make_pair(type3, -val);
460
0
  error(getErrorLocation(loc) + "unsupported relocations combination " +
461
0
        Twine(type));
462
0
  return std::make_pair(type & 0xff, val);
463
0
}
464
465
52
static bool isBranchReloc(RelType type) {
466
52
  return type == R_MIPS_26 || 
type == R_MIPS_PC26_S250
||
467
52
         
type == R_MIPS_PC21_S250
||
type == R_MIPS_PC1650
;
468
52
}
469
470
10.4k
static bool isMicroBranchReloc(RelType type) {
471
10.4k
  return type == R_MICROMIPS_26_S1 || 
type == R_MICROMIPS_PC16_S110.4k
||
472
10.4k
         
type == R_MICROMIPS_PC10_S110.4k
||
type == R_MICROMIPS_PC7_S110.4k
;
473
10.4k
}
474
475
template <class ELFT>
476
10.4k
static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
477
10.4k
  // Here we need to detect jump/branch from regular MIPS code
478
10.4k
  // to a microMIPS target and vice versa. In that cases jump
479
10.4k
  // instructions need to be replaced by their "cross-mode"
480
10.4k
  // equivalents.
481
10.4k
  const endianness e = ELFT::TargetEndianness;
482
10.4k
  bool isMicroTgt = val & 0x1;
483
10.4k
  bool isCrossJump = (isMicroTgt && 
isBranchReloc(type)52
) ||
484
10.4k
                     
(10.4k
!isMicroTgt10.4k
&&
isMicroBranchReloc(type)10.4k
);
485
10.4k
  if (!isCrossJump)
486
10.4k
    return val;
487
7
488
7
  switch (type) {
489
7
  case R_MIPS_26: {
490
2
    uint32_t inst = read32<e>(loc) >> 26;
491
2
    if (inst == 0x3 || 
inst == 0x1d0
) { // JAL or JALX
492
2
      writeValue<e>(loc, 0x1d << 26, 32, 0);
493
2
      return val;
494
2
    }
495
0
    break;
496
0
  }
497
2
  case R_MICROMIPS_26_S1: {
498
2
    uint32_t inst = readShuffle<e>(loc) >> 26;
499
2
    if (inst == 0x3d || 
inst == 0x3c0
) { // JAL32 or JALX32
500
2
      val >>= 1;
501
2
      writeShuffleValue<e>(loc, 0x3c << 26, 32, 0);
502
2
      return val;
503
2
    }
504
0
    break;
505
0
  }
506
2
  case R_MIPS_PC26_S2:
507
2
  case R_MIPS_PC21_S2:
508
2
  case R_MIPS_PC16:
509
2
  case R_MICROMIPS_PC16_S1:
510
2
  case R_MICROMIPS_PC10_S1:
511
2
  case R_MICROMIPS_PC7_S1:
512
2
    // FIXME (simon): Support valid branch relocations.
513
2
    break;
514
2
  default:
515
0
    llvm_unreachable("unexpected jump/branch relocation");
516
2
  }
517
2
518
2
  error(getErrorLocation(loc) +
519
2
        "unsupported jump/branch instruction between ISA modes referenced by " +
520
2
        toString(type) + " relocation");
521
2
  return val;
522
2
}
Mips.cpp:unsigned long long fixupCrossModeJump<llvm::object::ELFType<(llvm::support::endianness)1, false> >(unsigned char*, unsigned int, unsigned long long)
Line
Count
Source
476
36
static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
477
36
  // Here we need to detect jump/branch from regular MIPS code
478
36
  // to a microMIPS target and vice versa. In that cases jump
479
36
  // instructions need to be replaced by their "cross-mode"
480
36
  // equivalents.
481
36
  const endianness e = ELFT::TargetEndianness;
482
36
  bool isMicroTgt = val & 0x1;
483
36
  bool isCrossJump = (isMicroTgt && 
isBranchReloc(type)19
) ||
484
36
                     (!isMicroTgt && 
isMicroBranchReloc(type)17
);
485
36
  if (!isCrossJump)
486
36
    return val;
487
0
488
0
  switch (type) {
489
0
  case R_MIPS_26: {
490
0
    uint32_t inst = read32<e>(loc) >> 26;
491
0
    if (inst == 0x3 || inst == 0x1d) { // JAL or JALX
492
0
      writeValue<e>(loc, 0x1d << 26, 32, 0);
493
0
      return val;
494
0
    }
495
0
    break;
496
0
  }
497
0
  case R_MICROMIPS_26_S1: {
498
0
    uint32_t inst = readShuffle<e>(loc) >> 26;
499
0
    if (inst == 0x3d || inst == 0x3c) { // JAL32 or JALX32
500
0
      val >>= 1;
501
0
      writeShuffleValue<e>(loc, 0x3c << 26, 32, 0);
502
0
      return val;
503
0
    }
504
0
    break;
505
0
  }
506
0
  case R_MIPS_PC26_S2:
507
0
  case R_MIPS_PC21_S2:
508
0
  case R_MIPS_PC16:
509
0
  case R_MICROMIPS_PC16_S1:
510
0
  case R_MICROMIPS_PC10_S1:
511
0
  case R_MICROMIPS_PC7_S1:
512
0
    // FIXME (simon): Support valid branch relocations.
513
0
    break;
514
0
  default:
515
0
    llvm_unreachable("unexpected jump/branch relocation");
516
0
  }
517
0
518
0
  error(getErrorLocation(loc) +
519
0
        "unsupported jump/branch instruction between ISA modes referenced by " +
520
0
        toString(type) + " relocation");
521
0
  return val;
522
0
}
Mips.cpp:unsigned long long fixupCrossModeJump<llvm::object::ELFType<(llvm::support::endianness)0, false> >(unsigned char*, unsigned int, unsigned long long)
Line
Count
Source
476
386
static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
477
386
  // Here we need to detect jump/branch from regular MIPS code
478
386
  // to a microMIPS target and vice versa. In that cases jump
479
386
  // instructions need to be replaced by their "cross-mode"
480
386
  // equivalents.
481
386
  const endianness e = ELFT::TargetEndianness;
482
386
  bool isMicroTgt = val & 0x1;
483
386
  bool isCrossJump = (isMicroTgt && 
isBranchReloc(type)31
) ||
484
386
                     
(383
!isMicroTgt383
&&
isMicroBranchReloc(type)355
);
485
386
  if (!isCrossJump)
486
379
    return val;
487
7
488
7
  switch (type) {
489
7
  case R_MIPS_26: {
490
2
    uint32_t inst = read32<e>(loc) >> 26;
491
2
    if (inst == 0x3 || 
inst == 0x1d0
) { // JAL or JALX
492
2
      writeValue<e>(loc, 0x1d << 26, 32, 0);
493
2
      return val;
494
2
    }
495
0
    break;
496
0
  }
497
2
  case R_MICROMIPS_26_S1: {
498
2
    uint32_t inst = readShuffle<e>(loc) >> 26;
499
2
    if (inst == 0x3d || 
inst == 0x3c0
) { // JAL32 or JALX32
500
2
      val >>= 1;
501
2
      writeShuffleValue<e>(loc, 0x3c << 26, 32, 0);
502
2
      return val;
503
2
    }
504
0
    break;
505
0
  }
506
2
  case R_MIPS_PC26_S2:
507
2
  case R_MIPS_PC21_S2:
508
2
  case R_MIPS_PC16:
509
2
  case R_MICROMIPS_PC16_S1:
510
2
  case R_MICROMIPS_PC10_S1:
511
2
  case R_MICROMIPS_PC7_S1:
512
2
    // FIXME (simon): Support valid branch relocations.
513
2
    break;
514
2
  default:
515
0
    llvm_unreachable("unexpected jump/branch relocation");
516
2
  }
517
2
518
2
  error(getErrorLocation(loc) +
519
2
        "unsupported jump/branch instruction between ISA modes referenced by " +
520
2
        toString(type) + " relocation");
521
2
  return val;
522
2
}
Unexecuted instantiation: Mips.cpp:unsigned long long fixupCrossModeJump<llvm::object::ELFType<(llvm::support::endianness)1, true> >(unsigned char*, unsigned int, unsigned long long)
Mips.cpp:unsigned long long fixupCrossModeJump<llvm::object::ELFType<(llvm::support::endianness)0, true> >(unsigned char*, unsigned int, unsigned long long)
Line
Count
Source
476
10.0k
static uint64_t fixupCrossModeJump(uint8_t *loc, RelType type, uint64_t val) {
477
10.0k
  // Here we need to detect jump/branch from regular MIPS code
478
10.0k
  // to a microMIPS target and vice versa. In that cases jump
479
10.0k
  // instructions need to be replaced by their "cross-mode"
480
10.0k
  // equivalents.
481
10.0k
  const endianness e = ELFT::TargetEndianness;
482
10.0k
  bool isMicroTgt = val & 0x1;
483
10.0k
  bool isCrossJump = (isMicroTgt && 
isBranchReloc(type)2
) ||
484
10.0k
                     (!isMicroTgt && 
isMicroBranchReloc(type)10.0k
);
485
10.0k
  if (!isCrossJump)
486
10.0k
    return val;
487
0
488
0
  switch (type) {
489
0
  case R_MIPS_26: {
490
0
    uint32_t inst = read32<e>(loc) >> 26;
491
0
    if (inst == 0x3 || inst == 0x1d) { // JAL or JALX
492
0
      writeValue<e>(loc, 0x1d << 26, 32, 0);
493
0
      return val;
494
0
    }
495
0
    break;
496
0
  }
497
0
  case R_MICROMIPS_26_S1: {
498
0
    uint32_t inst = readShuffle<e>(loc) >> 26;
499
0
    if (inst == 0x3d || inst == 0x3c) { // JAL32 or JALX32
500
0
      val >>= 1;
501
0
      writeShuffleValue<e>(loc, 0x3c << 26, 32, 0);
502
0
      return val;
503
0
    }
504
0
    break;
505
0
  }
506
0
  case R_MIPS_PC26_S2:
507
0
  case R_MIPS_PC21_S2:
508
0
  case R_MIPS_PC16:
509
0
  case R_MICROMIPS_PC16_S1:
510
0
  case R_MICROMIPS_PC10_S1:
511
0
  case R_MICROMIPS_PC7_S1:
512
0
    // FIXME (simon): Support valid branch relocations.
513
0
    break;
514
0
  default:
515
0
    llvm_unreachable("unexpected jump/branch relocation");
516
0
  }
517
0
518
0
  error(getErrorLocation(loc) +
519
0
        "unsupported jump/branch instruction between ISA modes referenced by " +
520
0
        toString(type) + " relocation");
521
0
  return val;
522
0
}
523
524
template <class ELFT>
525
10.4k
void MIPS<ELFT>::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
526
10.4k
  const endianness e = ELFT::TargetEndianness;
527
10.4k
528
10.4k
  if (ELFT::Is64Bits || 
config->mipsN32Abi422
)
529
10.0k
    std::tie(type, val) = calculateMipsRelChain(loc, type, val);
530
10.4k
531
10.4k
  // Detect cross-mode jump/branch and fix instruction.
532
10.4k
  val = fixupCrossModeJump<ELFT>(loc, type, val);
533
10.4k
534
10.4k
  // Thread pointer and DRP offsets from the start of TLS data area.
535
10.4k
  // https://www.linux-mips.org/wiki/NPTL
536
10.4k
  if (type == R_MIPS_TLS_DTPREL_HI16 || 
type == R_MIPS_TLS_DTPREL_LO1610.4k
||
537
10.4k
      
type == R_MIPS_TLS_DTPREL3210.4k
||
type == R_MIPS_TLS_DTPREL6410.4k
||
538
10.4k
      
type == R_MICROMIPS_TLS_DTPREL_HI1610.4k
||
539
10.4k
      
type == R_MICROMIPS_TLS_DTPREL_LO1610.4k
) {
540
6
    val -= 0x8000;
541
10.4k
  } else if (type == R_MIPS_TLS_TPREL_HI16 || 
type == R_MIPS_TLS_TPREL_LO1610.4k
||
542
10.4k
             
type == R_MIPS_TLS_TPREL3210.4k
||
type == R_MIPS_TLS_TPREL6410.4k
||
543
10.4k
             
type == R_MICROMIPS_TLS_TPREL_HI1610.4k
||
544
10.4k
             
type == R_MICROMIPS_TLS_TPREL_LO1610.4k
) {
545
6
    val -= 0x7000;
546
6
  }
547
10.4k
548
10.4k
  switch (type) {
549
10.4k
  case R_MIPS_32:
550
33
  case R_MIPS_GPREL32:
551
33
  case R_MIPS_TLS_DTPREL32:
552
33
  case R_MIPS_TLS_TPREL32:
553
33
    write32<e>(loc, val);
554
33
    break;
555
33
  case R_MIPS_64:
556
8
  case R_MIPS_TLS_DTPREL64:
557
8
  case R_MIPS_TLS_TPREL64:
558
8
    write64<e>(loc, val);
559
8
    break;
560
68
  case R_MIPS_26:
561
68
    writeValue<e>(loc, val, 26, 2);
562
68
    break;
563
46
  case R_MIPS_GOT16:
564
46
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
565
46
    // is updated addend (not a GOT index). In that case write high 16 bits
566
46
    // to store a correct addend value.
567
46
    if (config->relocatable) {
568
6
      writeValue<e>(loc, val + 0x8000, 16, 16);
569
40
    } else {
570
40
      checkInt(loc, val, 16, type);
571
40
      writeValue<e>(loc, val, 16, 0);
572
40
    }
573
46
    break;
574
8
  case R_MICROMIPS_GOT16:
575
4
    if (config->relocatable) {
576
0
      writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
577
4
    } else {
578
4
      checkInt(loc, val, 16, type);
579
4
      writeShuffleValue<e>(loc, val, 16, 0);
580
4
    }
581
4
    break;
582
10.0k
  case R_MIPS_CALL16:
583
10.0k
  case R_MIPS_GOT_DISP:
584
10.0k
  case R_MIPS_GOT_PAGE:
585
10.0k
  case R_MIPS_GPREL16:
586
10.0k
  case R_MIPS_TLS_GD:
587
10.0k
  case R_MIPS_TLS_GOTTPREL:
588
10.0k
  case R_MIPS_TLS_LDM:
589
10.0k
    checkInt(loc, val, 16, type);
590
10.0k
    LLVM_FALLTHROUGH;
591
10.1k
  case R_MIPS_CALL_LO16:
592
10.1k
  case R_MIPS_GOT_LO16:
593
10.1k
  case R_MIPS_GOT_OFST:
594
10.1k
  case R_MIPS_LO16:
595
10.1k
  case R_MIPS_PCLO16:
596
10.1k
  case R_MIPS_TLS_DTPREL_LO16:
597
10.1k
  case R_MIPS_TLS_TPREL_LO16:
598
10.1k
    writeValue<e>(loc, val, 16, 0);
599
10.1k
    break;
600
10.1k
  case R_MICROMIPS_GPREL16:
601
0
  case R_MICROMIPS_TLS_GD:
602
0
  case R_MICROMIPS_TLS_LDM:
603
0
    checkInt(loc, val, 16, type);
604
0
    writeShuffleValue<e>(loc, val, 16, 0);
605
0
    break;
606
13
  case R_MICROMIPS_CALL16:
607
13
  case R_MICROMIPS_CALL_LO16:
608
13
  case R_MICROMIPS_LO16:
609
13
  case R_MICROMIPS_TLS_DTPREL_LO16:
610
13
  case R_MICROMIPS_TLS_GOTTPREL:
611
13
  case R_MICROMIPS_TLS_TPREL_LO16:
612
13
    writeShuffleValue<e>(loc, val, 16, 0);
613
13
    break;
614
13
  case R_MICROMIPS_GPREL7_S2:
615
0
    checkInt(loc, val, 7, type);
616
0
    writeShuffleValue<e>(loc, val, 7, 2);
617
0
    break;
618
81
  case R_MIPS_CALL_HI16:
619
81
  case R_MIPS_GOT_HI16:
620
81
  case R_MIPS_HI16:
621
81
  case R_MIPS_PCHI16:
622
81
  case R_MIPS_TLS_DTPREL_HI16:
623
81
  case R_MIPS_TLS_TPREL_HI16:
624
81
    writeValue<e>(loc, val + 0x8000, 16, 16);
625
81
    break;
626
81
  case R_MICROMIPS_CALL_HI16:
627
8
  case R_MICROMIPS_GOT_HI16:
628
8
  case R_MICROMIPS_HI16:
629
8
  case R_MICROMIPS_TLS_DTPREL_HI16:
630
8
  case R_MICROMIPS_TLS_TPREL_HI16:
631
8
    writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
632
8
    break;
633
8
  case R_MIPS_HIGHER:
634
2
    writeValue<e>(loc, val + 0x80008000, 16, 32);
635
2
    break;
636
8
  case R_MIPS_HIGHEST:
637
2
    writeValue<e>(loc, val + 0x800080008000, 16, 48);
638
2
    break;
639
8
  case R_MIPS_JALR:
640
0
  case R_MICROMIPS_JALR:
641
0
    // Ignore this optimization relocation for now
642
0
    break;
643
2
  case R_MIPS_PC16:
644
2
    checkAlignment(loc, val, 4, type);
645
2
    checkInt(loc, val, 18, type);
646
2
    writeValue<e>(loc, val, 16, 2);
647
2
    break;
648
1
  case R_MIPS_PC19_S2:
649
1
    checkAlignment(loc, val, 4, type);
650
1
    checkInt(loc, val, 21, type);
651
1
    writeValue<e>(loc, val, 19, 2);
652
1
    break;
653
1
  case R_MIPS_PC21_S2:
654
1
    checkAlignment(loc, val, 4, type);
655
1
    checkInt(loc, val, 23, type);
656
1
    writeValue<e>(loc, val, 21, 2);
657
1
    break;
658
1
  case R_MIPS_PC26_S2:
659
1
    checkAlignment(loc, val, 4, type);
660
1
    checkInt(loc, val, 28, type);
661
1
    writeValue<e>(loc, val, 26, 2);
662
1
    break;
663
2
  case R_MIPS_PC32:
664
2
    writeValue<e>(loc, val, 32, 0);
665
2
    break;
666
19
  case R_MICROMIPS_26_S1:
667
19
  case R_MICROMIPS_PC26_S1:
668
19
    checkInt(loc, val, 27, type);
669
19
    writeShuffleValue<e>(loc, val, 26, 1);
670
19
    break;
671
19
  case R_MICROMIPS_PC7_S1:
672
2
    checkInt(loc, val, 8, type);
673
2
    writeMicroRelocation16<e>(loc, val, 7, 1);
674
2
    break;
675
19
  case R_MICROMIPS_PC10_S1:
676
3
    checkInt(loc, val, 11, type);
677
3
    writeMicroRelocation16<e>(loc, val, 10, 1);
678
3
    break;
679
19
  case R_MICROMIPS_PC16_S1:
680
2
    checkInt(loc, val, 17, type);
681
2
    writeShuffleValue<e>(loc, val, 16, 1);
682
2
    break;
683
19
  case R_MICROMIPS_PC18_S3:
684
0
    checkInt(loc, val, 21, type);
685
0
    writeShuffleValue<e>(loc, val, 18, 3);
686
0
    break;
687
19
  case R_MICROMIPS_PC19_S2:
688
6
    checkInt(loc, val, 21, type);
689
6
    writeShuffleValue<e>(loc, val, 19, 2);
690
6
    break;
691
19
  case R_MICROMIPS_PC21_S1:
692
2
    checkInt(loc, val, 22, type);
693
2
    writeShuffleValue<e>(loc, val, 21, 1);
694
2
    break;
695
19
  case R_MICROMIPS_PC23_S2:
696
8
    checkInt(loc, val, 25, type);
697
8
    writeShuffleValue<e>(loc, val, 23, 2);
698
8
    break;
699
19
  default:
700
0
    llvm_unreachable("unknown relocation");
701
10.4k
  }
702
10.4k
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::relocateOne(unsigned char*, unsigned int, unsigned long long) const
Line
Count
Source
525
36
void MIPS<ELFT>::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
526
36
  const endianness e = ELFT::TargetEndianness;
527
36
528
36
  if (ELFT::Is64Bits || config->mipsN32Abi)
529
0
    std::tie(type, val) = calculateMipsRelChain(loc, type, val);
530
36
531
36
  // Detect cross-mode jump/branch and fix instruction.
532
36
  val = fixupCrossModeJump<ELFT>(loc, type, val);
533
36
534
36
  // Thread pointer and DRP offsets from the start of TLS data area.
535
36
  // https://www.linux-mips.org/wiki/NPTL
536
36
  if (type == R_MIPS_TLS_DTPREL_HI16 || type == R_MIPS_TLS_DTPREL_LO16 ||
537
36
      type == R_MIPS_TLS_DTPREL32 || type == R_MIPS_TLS_DTPREL64 ||
538
36
      type == R_MICROMIPS_TLS_DTPREL_HI16 ||
539
36
      
type == R_MICROMIPS_TLS_DTPREL_LO1635
) {
540
0
    val -= 0x8000;
541
36
  } else if (type == R_MIPS_TLS_TPREL_HI16 || 
type == R_MIPS_TLS_TPREL_LO1635
||
542
36
             
type == R_MIPS_TLS_TPREL3235
||
type == R_MIPS_TLS_TPREL6435
||
543
36
             
type == R_MICROMIPS_TLS_TPREL_HI1635
||
544
36
             
type == R_MICROMIPS_TLS_TPREL_LO1635
) {
545
0
    val -= 0x7000;
546
0
  }
547
36
548
36
  switch (type) {
549
36
  case R_MIPS_32:
550
4
  case R_MIPS_GPREL32:
551
4
  case R_MIPS_TLS_DTPREL32:
552
4
  case R_MIPS_TLS_TPREL32:
553
4
    write32<e>(loc, val);
554
4
    break;
555
4
  case R_MIPS_64:
556
0
  case R_MIPS_TLS_DTPREL64:
557
0
  case R_MIPS_TLS_TPREL64:
558
0
    write64<e>(loc, val);
559
0
    break;
560
0
  case R_MIPS_26:
561
0
    writeValue<e>(loc, val, 26, 2);
562
0
    break;
563
6
  case R_MIPS_GOT16:
564
6
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
565
6
    // is updated addend (not a GOT index). In that case write high 16 bits
566
6
    // to store a correct addend value.
567
6
    if (config->relocatable) {
568
2
      writeValue<e>(loc, val + 0x8000, 16, 16);
569
4
    } else {
570
4
      checkInt(loc, val, 16, type);
571
4
      writeValue<e>(loc, val, 16, 0);
572
4
    }
573
6
    break;
574
1
  case R_MICROMIPS_GOT16:
575
1
    if (config->relocatable) {
576
0
      writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
577
1
    } else {
578
1
      checkInt(loc, val, 16, type);
579
1
      writeShuffleValue<e>(loc, val, 16, 0);
580
1
    }
581
1
    break;
582
0
  case R_MIPS_CALL16:
583
0
  case R_MIPS_GOT_DISP:
584
0
  case R_MIPS_GOT_PAGE:
585
0
  case R_MIPS_GPREL16:
586
0
  case R_MIPS_TLS_GD:
587
0
  case R_MIPS_TLS_GOTTPREL:
588
0
  case R_MIPS_TLS_LDM:
589
0
    checkInt(loc, val, 16, type);
590
0
    LLVM_FALLTHROUGH;
591
2
  case R_MIPS_CALL_LO16:
592
2
  case R_MIPS_GOT_LO16:
593
2
  case R_MIPS_GOT_OFST:
594
2
  case R_MIPS_LO16:
595
2
  case R_MIPS_PCLO16:
596
2
  case R_MIPS_TLS_DTPREL_LO16:
597
2
  case R_MIPS_TLS_TPREL_LO16:
598
2
    writeValue<e>(loc, val, 16, 0);
599
2
    break;
600
2
  case R_MICROMIPS_GPREL16:
601
0
  case R_MICROMIPS_TLS_GD:
602
0
  case R_MICROMIPS_TLS_LDM:
603
0
    checkInt(loc, val, 16, type);
604
0
    writeShuffleValue<e>(loc, val, 16, 0);
605
0
    break;
606
4
  case R_MICROMIPS_CALL16:
607
4
  case R_MICROMIPS_CALL_LO16:
608
4
  case R_MICROMIPS_LO16:
609
4
  case R_MICROMIPS_TLS_DTPREL_LO16:
610
4
  case R_MICROMIPS_TLS_GOTTPREL:
611
4
  case R_MICROMIPS_TLS_TPREL_LO16:
612
4
    writeShuffleValue<e>(loc, val, 16, 0);
613
4
    break;
614
4
  case R_MICROMIPS_GPREL7_S2:
615
0
    checkInt(loc, val, 7, type);
616
0
    writeShuffleValue<e>(loc, val, 7, 2);
617
0
    break;
618
4
  case R_MIPS_CALL_HI16:
619
0
  case R_MIPS_GOT_HI16:
620
0
  case R_MIPS_HI16:
621
0
  case R_MIPS_PCHI16:
622
0
  case R_MIPS_TLS_DTPREL_HI16:
623
0
  case R_MIPS_TLS_TPREL_HI16:
624
0
    writeValue<e>(loc, val + 0x8000, 16, 16);
625
0
    break;
626
3
  case R_MICROMIPS_CALL_HI16:
627
3
  case R_MICROMIPS_GOT_HI16:
628
3
  case R_MICROMIPS_HI16:
629
3
  case R_MICROMIPS_TLS_DTPREL_HI16:
630
3
  case R_MICROMIPS_TLS_TPREL_HI16:
631
3
    writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
632
3
    break;
633
3
  case R_MIPS_HIGHER:
634
0
    writeValue<e>(loc, val + 0x80008000, 16, 32);
635
0
    break;
636
3
  case R_MIPS_HIGHEST:
637
0
    writeValue<e>(loc, val + 0x800080008000, 16, 48);
638
0
    break;
639
3
  case R_MIPS_JALR:
640
0
  case R_MICROMIPS_JALR:
641
0
    // Ignore this optimization relocation for now
642
0
    break;
643
0
  case R_MIPS_PC16:
644
0
    checkAlignment(loc, val, 4, type);
645
0
    checkInt(loc, val, 18, type);
646
0
    writeValue<e>(loc, val, 16, 2);
647
0
    break;
648
0
  case R_MIPS_PC19_S2:
649
0
    checkAlignment(loc, val, 4, type);
650
0
    checkInt(loc, val, 21, type);
651
0
    writeValue<e>(loc, val, 19, 2);
652
0
    break;
653
0
  case R_MIPS_PC21_S2:
654
0
    checkAlignment(loc, val, 4, type);
655
0
    checkInt(loc, val, 23, type);
656
0
    writeValue<e>(loc, val, 21, 2);
657
0
    break;
658
0
  case R_MIPS_PC26_S2:
659
0
    checkAlignment(loc, val, 4, type);
660
0
    checkInt(loc, val, 28, type);
661
0
    writeValue<e>(loc, val, 26, 2);
662
0
    break;
663
0
  case R_MIPS_PC32:
664
0
    writeValue<e>(loc, val, 32, 0);
665
0
    break;
666
7
  case R_MICROMIPS_26_S1:
667
7
  case R_MICROMIPS_PC26_S1:
668
7
    checkInt(loc, val, 27, type);
669
7
    writeShuffleValue<e>(loc, val, 26, 1);
670
7
    break;
671
7
  case R_MICROMIPS_PC7_S1:
672
1
    checkInt(loc, val, 8, type);
673
1
    writeMicroRelocation16<e>(loc, val, 7, 1);
674
1
    break;
675
7
  case R_MICROMIPS_PC10_S1:
676
1
    checkInt(loc, val, 11, type);
677
1
    writeMicroRelocation16<e>(loc, val, 10, 1);
678
1
    break;
679
7
  case R_MICROMIPS_PC16_S1:
680
1
    checkInt(loc, val, 17, type);
681
1
    writeShuffleValue<e>(loc, val, 16, 1);
682
1
    break;
683
7
  case R_MICROMIPS_PC18_S3:
684
0
    checkInt(loc, val, 21, type);
685
0
    writeShuffleValue<e>(loc, val, 18, 3);
686
0
    break;
687
7
  case R_MICROMIPS_PC19_S2:
688
3
    checkInt(loc, val, 21, type);
689
3
    writeShuffleValue<e>(loc, val, 19, 2);
690
3
    break;
691
7
  case R_MICROMIPS_PC21_S1:
692
1
    checkInt(loc, val, 22, type);
693
1
    writeShuffleValue<e>(loc, val, 21, 1);
694
1
    break;
695
7
  case R_MICROMIPS_PC23_S2:
696
2
    checkInt(loc, val, 25, type);
697
2
    writeShuffleValue<e>(loc, val, 23, 2);
698
2
    break;
699
7
  default:
700
0
    llvm_unreachable("unknown relocation");
701
36
  }
702
36
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::relocateOne(unsigned char*, unsigned int, unsigned long long) const
Line
Count
Source
525
386
void MIPS<ELFT>::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
526
386
  const endianness e = ELFT::TargetEndianness;
527
386
528
386
  if (ELFT::Is64Bits || config->mipsN32Abi)
529
5
    std::tie(type, val) = calculateMipsRelChain(loc, type, val);
530
386
531
386
  // Detect cross-mode jump/branch and fix instruction.
532
386
  val = fixupCrossModeJump<ELFT>(loc, type, val);
533
386
534
386
  // Thread pointer and DRP offsets from the start of TLS data area.
535
386
  // https://www.linux-mips.org/wiki/NPTL
536
386
  if (type == R_MIPS_TLS_DTPREL_HI16 || 
type == R_MIPS_TLS_DTPREL_LO16382
||
537
386
      
type == R_MIPS_TLS_DTPREL32380
||
type == R_MIPS_TLS_DTPREL64379
||
538
386
      
type == R_MICROMIPS_TLS_DTPREL_HI16380
||
539
386
      
type == R_MICROMIPS_TLS_DTPREL_LO16379
) {
540
5
    val -= 0x8000;
541
381
  } else if (type == R_MIPS_TLS_TPREL_HI16 || 
type == R_MIPS_TLS_TPREL_LO16377
||
542
381
             
type == R_MIPS_TLS_TPREL32375
||
type == R_MIPS_TLS_TPREL64374
||
543
381
             
type == R_MICROMIPS_TLS_TPREL_HI16375
||
544
381
             
type == R_MICROMIPS_TLS_TPREL_LO16375
) {
545
5
    val -= 0x7000;
546
5
  }
547
386
548
386
  switch (type) {
549
386
  case R_MIPS_32:
550
26
  case R_MIPS_GPREL32:
551
26
  case R_MIPS_TLS_DTPREL32:
552
26
  case R_MIPS_TLS_TPREL32:
553
26
    write32<e>(loc, val);
554
26
    break;
555
26
  case R_MIPS_64:
556
0
  case R_MIPS_TLS_DTPREL64:
557
0
  case R_MIPS_TLS_TPREL64:
558
0
    write64<e>(loc, val);
559
0
    break;
560
66
  case R_MIPS_26:
561
66
    writeValue<e>(loc, val, 26, 2);
562
66
    break;
563
40
  case R_MIPS_GOT16:
564
40
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
565
40
    // is updated addend (not a GOT index). In that case write high 16 bits
566
40
    // to store a correct addend value.
567
40
    if (config->relocatable) {
568
4
      writeValue<e>(loc, val + 0x8000, 16, 16);
569
36
    } else {
570
36
      checkInt(loc, val, 16, type);
571
36
      writeValue<e>(loc, val, 16, 0);
572
36
    }
573
40
    break;
574
3
  case R_MICROMIPS_GOT16:
575
3
    if (config->relocatable) {
576
0
      writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
577
3
    } else {
578
3
      checkInt(loc, val, 16, type);
579
3
      writeShuffleValue<e>(loc, val, 16, 0);
580
3
    }
581
3
    break;
582
34
  case R_MIPS_CALL16:
583
34
  case R_MIPS_GOT_DISP:
584
34
  case R_MIPS_GOT_PAGE:
585
34
  case R_MIPS_GPREL16:
586
34
  case R_MIPS_TLS_GD:
587
34
  case R_MIPS_TLS_GOTTPREL:
588
34
  case R_MIPS_TLS_LDM:
589
34
    checkInt(loc, val, 16, type);
590
34
    LLVM_FALLTHROUGH;
591
130
  case R_MIPS_CALL_LO16:
592
130
  case R_MIPS_GOT_LO16:
593
130
  case R_MIPS_GOT_OFST:
594
130
  case R_MIPS_LO16:
595
130
  case R_MIPS_PCLO16:
596
130
  case R_MIPS_TLS_DTPREL_LO16:
597
130
  case R_MIPS_TLS_TPREL_LO16:
598
130
    writeValue<e>(loc, val, 16, 0);
599
130
    break;
600
130
  case R_MICROMIPS_GPREL16:
601
0
  case R_MICROMIPS_TLS_GD:
602
0
  case R_MICROMIPS_TLS_LDM:
603
0
    checkInt(loc, val, 16, type);
604
0
    writeShuffleValue<e>(loc, val, 16, 0);
605
0
    break;
606
9
  case R_MICROMIPS_CALL16:
607
9
  case R_MICROMIPS_CALL_LO16:
608
9
  case R_MICROMIPS_LO16:
609
9
  case R_MICROMIPS_TLS_DTPREL_LO16:
610
9
  case R_MICROMIPS_TLS_GOTTPREL:
611
9
  case R_MICROMIPS_TLS_TPREL_LO16:
612
9
    writeShuffleValue<e>(loc, val, 16, 0);
613
9
    break;
614
9
  case R_MICROMIPS_GPREL7_S2:
615
0
    checkInt(loc, val, 7, type);
616
0
    writeShuffleValue<e>(loc, val, 7, 2);
617
0
    break;
618
75
  case R_MIPS_CALL_HI16:
619
75
  case R_MIPS_GOT_HI16:
620
75
  case R_MIPS_HI16:
621
75
  case R_MIPS_PCHI16:
622
75
  case R_MIPS_TLS_DTPREL_HI16:
623
75
  case R_MIPS_TLS_TPREL_HI16:
624
75
    writeValue<e>(loc, val + 0x8000, 16, 16);
625
75
    break;
626
75
  case R_MICROMIPS_CALL_HI16:
627
5
  case R_MICROMIPS_GOT_HI16:
628
5
  case R_MICROMIPS_HI16:
629
5
  case R_MICROMIPS_TLS_DTPREL_HI16:
630
5
  case R_MICROMIPS_TLS_TPREL_HI16:
631
5
    writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
632
5
    break;
633
5
  case R_MIPS_HIGHER:
634
0
    writeValue<e>(loc, val + 0x80008000, 16, 32);
635
0
    break;
636
5
  case R_MIPS_HIGHEST:
637
0
    writeValue<e>(loc, val + 0x800080008000, 16, 48);
638
0
    break;
639
5
  case R_MIPS_JALR:
640
0
  case R_MICROMIPS_JALR:
641
0
    // Ignore this optimization relocation for now
642
0
    break;
643
2
  case R_MIPS_PC16:
644
2
    checkAlignment(loc, val, 4, type);
645
2
    checkInt(loc, val, 18, type);
646
2
    writeValue<e>(loc, val, 16, 2);
647
2
    break;
648
1
  case R_MIPS_PC19_S2:
649
1
    checkAlignment(loc, val, 4, type);
650
1
    checkInt(loc, val, 21, type);
651
1
    writeValue<e>(loc, val, 19, 2);
652
1
    break;
653
1
  case R_MIPS_PC21_S2:
654
1
    checkAlignment(loc, val, 4, type);
655
1
    checkInt(loc, val, 23, type);
656
1
    writeValue<e>(loc, val, 21, 2);
657
1
    break;
658
1
  case R_MIPS_PC26_S2:
659
1
    checkAlignment(loc, val, 4, type);
660
1
    checkInt(loc, val, 28, type);
661
1
    writeValue<e>(loc, val, 26, 2);
662
1
    break;
663
1
  case R_MIPS_PC32:
664
1
    writeValue<e>(loc, val, 32, 0);
665
1
    break;
666
12
  case R_MICROMIPS_26_S1:
667
12
  case R_MICROMIPS_PC26_S1:
668
12
    checkInt(loc, val, 27, type);
669
12
    writeShuffleValue<e>(loc, val, 26, 1);
670
12
    break;
671
12
  case R_MICROMIPS_PC7_S1:
672
1
    checkInt(loc, val, 8, type);
673
1
    writeMicroRelocation16<e>(loc, val, 7, 1);
674
1
    break;
675
12
  case R_MICROMIPS_PC10_S1:
676
2
    checkInt(loc, val, 11, type);
677
2
    writeMicroRelocation16<e>(loc, val, 10, 1);
678
2
    break;
679
12
  case R_MICROMIPS_PC16_S1:
680
1
    checkInt(loc, val, 17, type);
681
1
    writeShuffleValue<e>(loc, val, 16, 1);
682
1
    break;
683
12
  case R_MICROMIPS_PC18_S3:
684
0
    checkInt(loc, val, 21, type);
685
0
    writeShuffleValue<e>(loc, val, 18, 3);
686
0
    break;
687
12
  case R_MICROMIPS_PC19_S2:
688
3
    checkInt(loc, val, 21, type);
689
3
    writeShuffleValue<e>(loc, val, 19, 2);
690
3
    break;
691
12
  case R_MICROMIPS_PC21_S1:
692
1
    checkInt(loc, val, 22, type);
693
1
    writeShuffleValue<e>(loc, val, 21, 1);
694
1
    break;
695
12
  case R_MICROMIPS_PC23_S2:
696
6
    checkInt(loc, val, 25, type);
697
6
    writeShuffleValue<e>(loc, val, 23, 2);
698
6
    break;
699
12
  default:
700
0
    llvm_unreachable("unknown relocation");
701
386
  }
702
386
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::relocateOne(unsigned char*, unsigned int, unsigned long long) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::relocateOne(unsigned char*, unsigned int, unsigned long long) const
Line
Count
Source
525
10.0k
void MIPS<ELFT>::relocateOne(uint8_t *loc, RelType type, uint64_t val) const {
526
10.0k
  const endianness e = ELFT::TargetEndianness;
527
10.0k
528
10.0k
  if (ELFT::Is64Bits || 
config->mipsN32Abi0
)
529
10.0k
    std::tie(type, val) = calculateMipsRelChain(loc, type, val);
530
10.0k
531
10.0k
  // Detect cross-mode jump/branch and fix instruction.
532
10.0k
  val = fixupCrossModeJump<ELFT>(loc, type, val);
533
10.0k
534
10.0k
  // Thread pointer and DRP offsets from the start of TLS data area.
535
10.0k
  // https://www.linux-mips.org/wiki/NPTL
536
10.0k
  if (type == R_MIPS_TLS_DTPREL_HI16 || type == R_MIPS_TLS_DTPREL_LO16 ||
537
10.0k
      type == R_MIPS_TLS_DTPREL32 || type == R_MIPS_TLS_DTPREL64 ||
538
10.0k
      
type == R_MICROMIPS_TLS_DTPREL_HI1610.0k
||
539
10.0k
      
type == R_MICROMIPS_TLS_DTPREL_LO1610.0k
) {
540
1
    val -= 0x8000;
541
10.0k
  } else if (type == R_MIPS_TLS_TPREL_HI16 || type == R_MIPS_TLS_TPREL_LO16 ||
542
10.0k
             type == R_MIPS_TLS_TPREL32 || type == R_MIPS_TLS_TPREL64 ||
543
10.0k
             
type == R_MICROMIPS_TLS_TPREL_HI1610.0k
||
544
10.0k
             
type == R_MICROMIPS_TLS_TPREL_LO1610.0k
) {
545
1
    val -= 0x7000;
546
1
  }
547
10.0k
548
10.0k
  switch (type) {
549
10.0k
  case R_MIPS_32:
550
3
  case R_MIPS_GPREL32:
551
3
  case R_MIPS_TLS_DTPREL32:
552
3
  case R_MIPS_TLS_TPREL32:
553
3
    write32<e>(loc, val);
554
3
    break;
555
8
  case R_MIPS_64:
556
8
  case R_MIPS_TLS_DTPREL64:
557
8
  case R_MIPS_TLS_TPREL64:
558
8
    write64<e>(loc, val);
559
8
    break;
560
8
  case R_MIPS_26:
561
2
    writeValue<e>(loc, val, 26, 2);
562
2
    break;
563
8
  case R_MIPS_GOT16:
564
0
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
565
0
    // is updated addend (not a GOT index). In that case write high 16 bits
566
0
    // to store a correct addend value.
567
0
    if (config->relocatable) {
568
0
      writeValue<e>(loc, val + 0x8000, 16, 16);
569
0
    } else {
570
0
      checkInt(loc, val, 16, type);
571
0
      writeValue<e>(loc, val, 16, 0);
572
0
    }
573
0
    break;
574
8
  case R_MICROMIPS_GOT16:
575
0
    if (config->relocatable) {
576
0
      writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
577
0
    } else {
578
0
      checkInt(loc, val, 16, type);
579
0
      writeShuffleValue<e>(loc, val, 16, 0);
580
0
    }
581
0
    break;
582
10.0k
  case R_MIPS_CALL16:
583
10.0k
  case R_MIPS_GOT_DISP:
584
10.0k
  case R_MIPS_GOT_PAGE:
585
10.0k
  case R_MIPS_GPREL16:
586
10.0k
  case R_MIPS_TLS_GD:
587
10.0k
  case R_MIPS_TLS_GOTTPREL:
588
10.0k
  case R_MIPS_TLS_LDM:
589
10.0k
    checkInt(loc, val, 16, type);
590
10.0k
    LLVM_FALLTHROUGH;
591
10.0k
  case R_MIPS_CALL_LO16:
592
10.0k
  case R_MIPS_GOT_LO16:
593
10.0k
  case R_MIPS_GOT_OFST:
594
10.0k
  case R_MIPS_LO16:
595
10.0k
  case R_MIPS_PCLO16:
596
10.0k
  case R_MIPS_TLS_DTPREL_LO16:
597
10.0k
  case R_MIPS_TLS_TPREL_LO16:
598
10.0k
    writeValue<e>(loc, val, 16, 0);
599
10.0k
    break;
600
10.0k
  case R_MICROMIPS_GPREL16:
601
0
  case R_MICROMIPS_TLS_GD:
602
0
  case R_MICROMIPS_TLS_LDM:
603
0
    checkInt(loc, val, 16, type);
604
0
    writeShuffleValue<e>(loc, val, 16, 0);
605
0
    break;
606
0
  case R_MICROMIPS_CALL16:
607
0
  case R_MICROMIPS_CALL_LO16:
608
0
  case R_MICROMIPS_LO16:
609
0
  case R_MICROMIPS_TLS_DTPREL_LO16:
610
0
  case R_MICROMIPS_TLS_GOTTPREL:
611
0
  case R_MICROMIPS_TLS_TPREL_LO16:
612
0
    writeShuffleValue<e>(loc, val, 16, 0);
613
0
    break;
614
0
  case R_MICROMIPS_GPREL7_S2:
615
0
    checkInt(loc, val, 7, type);
616
0
    writeShuffleValue<e>(loc, val, 7, 2);
617
0
    break;
618
6
  case R_MIPS_CALL_HI16:
619
6
  case R_MIPS_GOT_HI16:
620
6
  case R_MIPS_HI16:
621
6
  case R_MIPS_PCHI16:
622
6
  case R_MIPS_TLS_DTPREL_HI16:
623
6
  case R_MIPS_TLS_TPREL_HI16:
624
6
    writeValue<e>(loc, val + 0x8000, 16, 16);
625
6
    break;
626
6
  case R_MICROMIPS_CALL_HI16:
627
0
  case R_MICROMIPS_GOT_HI16:
628
0
  case R_MICROMIPS_HI16:
629
0
  case R_MICROMIPS_TLS_DTPREL_HI16:
630
0
  case R_MICROMIPS_TLS_TPREL_HI16:
631
0
    writeShuffleValue<e>(loc, val + 0x8000, 16, 16);
632
0
    break;
633
2
  case R_MIPS_HIGHER:
634
2
    writeValue<e>(loc, val + 0x80008000, 16, 32);
635
2
    break;
636
2
  case R_MIPS_HIGHEST:
637
2
    writeValue<e>(loc, val + 0x800080008000, 16, 48);
638
2
    break;
639
0
  case R_MIPS_JALR:
640
0
  case R_MICROMIPS_JALR:
641
0
    // Ignore this optimization relocation for now
642
0
    break;
643
0
  case R_MIPS_PC16:
644
0
    checkAlignment(loc, val, 4, type);
645
0
    checkInt(loc, val, 18, type);
646
0
    writeValue<e>(loc, val, 16, 2);
647
0
    break;
648
0
  case R_MIPS_PC19_S2:
649
0
    checkAlignment(loc, val, 4, type);
650
0
    checkInt(loc, val, 21, type);
651
0
    writeValue<e>(loc, val, 19, 2);
652
0
    break;
653
0
  case R_MIPS_PC21_S2:
654
0
    checkAlignment(loc, val, 4, type);
655
0
    checkInt(loc, val, 23, type);
656
0
    writeValue<e>(loc, val, 21, 2);
657
0
    break;
658
0
  case R_MIPS_PC26_S2:
659
0
    checkAlignment(loc, val, 4, type);
660
0
    checkInt(loc, val, 28, type);
661
0
    writeValue<e>(loc, val, 26, 2);
662
0
    break;
663
1
  case R_MIPS_PC32:
664
1
    writeValue<e>(loc, val, 32, 0);
665
1
    break;
666
0
  case R_MICROMIPS_26_S1:
667
0
  case R_MICROMIPS_PC26_S1:
668
0
    checkInt(loc, val, 27, type);
669
0
    writeShuffleValue<e>(loc, val, 26, 1);
670
0
    break;
671
0
  case R_MICROMIPS_PC7_S1:
672
0
    checkInt(loc, val, 8, type);
673
0
    writeMicroRelocation16<e>(loc, val, 7, 1);
674
0
    break;
675
0
  case R_MICROMIPS_PC10_S1:
676
0
    checkInt(loc, val, 11, type);
677
0
    writeMicroRelocation16<e>(loc, val, 10, 1);
678
0
    break;
679
0
  case R_MICROMIPS_PC16_S1:
680
0
    checkInt(loc, val, 17, type);
681
0
    writeShuffleValue<e>(loc, val, 16, 1);
682
0
    break;
683
0
  case R_MICROMIPS_PC18_S3:
684
0
    checkInt(loc, val, 21, type);
685
0
    writeShuffleValue<e>(loc, val, 18, 3);
686
0
    break;
687
0
  case R_MICROMIPS_PC19_S2:
688
0
    checkInt(loc, val, 21, type);
689
0
    writeShuffleValue<e>(loc, val, 19, 2);
690
0
    break;
691
0
  case R_MICROMIPS_PC21_S1:
692
0
    checkInt(loc, val, 22, type);
693
0
    writeShuffleValue<e>(loc, val, 21, 1);
694
0
    break;
695
0
  case R_MICROMIPS_PC23_S2:
696
0
    checkInt(loc, val, 25, type);
697
0
    writeShuffleValue<e>(loc, val, 23, 2);
698
0
    break;
699
0
  default:
700
0
    llvm_unreachable("unknown relocation");
701
10.0k
  }
702
10.0k
}
703
704
34
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
705
34
  return type == R_MIPS_LO16 || 
type == R_MIPS_GOT_OFST18
||
706
34
         
type == R_MICROMIPS_LO1617
;
707
34
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::usesOnlyLowPageBits(unsigned int) const
Line
Count
Source
704
2
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
705
2
  return type == R_MIPS_LO16 || type == R_MIPS_GOT_OFST ||
706
2
         type == R_MICROMIPS_LO16;
707
2
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::usesOnlyLowPageBits(unsigned int) const
Line
Count
Source
704
26
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
705
26
  return type == R_MIPS_LO16 || 
type == R_MIPS_GOT_OFST10
||
706
26
         
type == R_MICROMIPS_LO1610
;
707
26
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::usesOnlyLowPageBits(unsigned int) const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::usesOnlyLowPageBits(unsigned int) const
Line
Count
Source
704
6
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
705
6
  return type == R_MIPS_LO16 || type == R_MIPS_GOT_OFST ||
706
6
         
type == R_MICROMIPS_LO165
;
707
6
}
708
709
// Return true if the symbol is a PIC function.
710
163
template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
711
163
  if (!sym->isFunc())
712
79
    return false;
713
84
714
84
  if (sym->stOther & STO_MIPS_PIC)
715
9
    return true;
716
75
717
75
  if (!sym->section)
718
0
    return false;
719
75
720
75
  ObjFile<ELFT> *file =
721
75
      cast<InputSectionBase>(sym->section)->template getFile<ELFT>();
722
75
  if (!file)
723
1
    return false;
724
74
725
74
  return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
726
74
}
bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)1, false> >(lld::elf::Defined const*)
Line
Count
Source
710
8
template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
711
8
  if (!sym->isFunc())
712
5
    return false;
713
3
714
3
  if (sym->stOther & STO_MIPS_PIC)
715
0
    return true;
716
3
717
3
  if (!sym->section)
718
0
    return false;
719
3
720
3
  ObjFile<ELFT> *file =
721
3
      cast<InputSectionBase>(sym->section)->template getFile<ELFT>();
722
3
  if (!file)
723
0
    return false;
724
3
725
3
  return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
726
3
}
bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::Defined const*)
Line
Count
Source
710
144
template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
711
144
  if (!sym->isFunc())
712
63
    return false;
713
81
714
81
  if (sym->stOther & STO_MIPS_PIC)
715
9
    return true;
716
72
717
72
  if (!sym->section)
718
0
    return false;
719
72
720
72
  ObjFile<ELFT> *file =
721
72
      cast<InputSectionBase>(sym->section)->template getFile<ELFT>();
722
72
  if (!file)
723
1
    return false;
724
71
725
71
  return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
726
71
}
Unexecuted instantiation: bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)1, true> >(lld::elf::Defined const*)
bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)0, true> >(lld::elf::Defined const*)
Line
Count
Source
710
11
template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
711
11
  if (!sym->isFunc())
712
11
    return false;
713
0
714
0
  if (sym->stOther & STO_MIPS_PIC)
715
0
    return true;
716
0
717
0
  if (!sym->section)
718
0
    return false;
719
0
720
0
  ObjFile<ELFT> *file =
721
0
      cast<InputSectionBase>(sym->section)->template getFile<ELFT>();
722
0
  if (!file)
723
0
    return false;
724
0
725
0
  return file->getObj().getHeader()->e_flags & EF_MIPS_PIC;
726
0
}
727
728
398
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
729
398
  static MIPS<ELFT> target;
730
398
  return &target;
731
398
}
lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)1, false> >()
Line
Count
Source
728
48
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
729
48
  static MIPS<ELFT> target;
730
48
  return &target;
731
48
}
lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)0, false> >()
Line
Count
Source
728
253
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
729
253
  static MIPS<ELFT> target;
730
253
  return &target;
731
253
}
lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)1, true> >()
Line
Count
Source
728
6
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
729
6
  static MIPS<ELFT> target;
730
6
  return &target;
731
6
}
lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)0, true> >()
Line
Count
Source
728
91
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
729
91
  static MIPS<ELFT> target;
730
91
  return &target;
731
91
}
732
733
template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
734
template TargetInfo *elf::getMipsTargetInfo<ELF32BE>();
735
template TargetInfo *elf::getMipsTargetInfo<ELF64LE>();
736
template TargetInfo *elf::getMipsTargetInfo<ELF64BE>();
737
738
template bool elf::isMipsPIC<ELF32LE>(const Defined *);
739
template bool elf::isMipsPIC<ELF32BE>(const Defined *);
740
template bool elf::isMipsPIC<ELF64LE>(const Defined *);
741
template bool elf::isMipsPIC<ELF64BE>(const Defined *);