Coverage Report

Created: 2018-01-17 21:32

/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
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "InputFiles.h"
11
#include "OutputSections.h"
12
#include "Symbols.h"
13
#include "SyntheticSections.h"
14
#include "Target.h"
15
#include "Thunks.h"
16
#include "lld/Common/ErrorHandler.h"
17
#include "llvm/Object/ELF.h"
18
#include "llvm/Support/Endian.h"
19
20
using namespace llvm;
21
using namespace llvm::object;
22
using namespace llvm::support::endian;
23
using namespace llvm::ELF;
24
using namespace lld;
25
using namespace lld::elf;
26
27
namespace {
28
template <class ELFT> class MIPS final : public TargetInfo {
29
public:
30
  MIPS();
31
  uint32_t calcEFlags() const override;
32
  RelExpr getRelExpr(RelType Type, const Symbol &S,
33
                     const uint8_t *Loc) const override;
34
  int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
35
  bool isPicRel(RelType Type) const override;
36
  RelType getDynRel(RelType Type) const override;
37
  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
38
  void writePltHeader(uint8_t *Buf) const override;
39
  void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
40
                int32_t Index, unsigned RelOff) const override;
41
  bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
42
                  uint64_t BranchAddr, const Symbol &S) const override;
43
  void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
44
  bool usesOnlyLowPageBits(RelType Type) const override;
45
};
46
} // namespace
47
48
76
template <class ELFT> MIPS<ELFT>::MIPS() {
49
76
  GotPltHeaderEntriesNum = 2;
50
76
  DefaultMaxPageSize = 65536;
51
76
  GotEntrySize = sizeof(typename ELFT::uint);
52
76
  GotPltEntrySize = sizeof(typename ELFT::uint);
53
76
  PltEntrySize = 16;
54
76
  PltHeaderSize = 32;
55
76
  CopyRel = R_MIPS_COPY;
56
76
  PltRel = R_MIPS_JUMP_SLOT;
57
76
  NeedsThunks = true;
58
76
  TrapInstr = 0xefefefef;
59
76
60
76
  if (ELFT::Is64Bits) {
61
19
    RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
19
    TlsGotRel = R_MIPS_TLS_TPREL64;
63
19
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
64
19
    TlsOffsetRel = R_MIPS_TLS_DTPREL64;
65
57
  } else {
66
57
    RelativeRel = R_MIPS_REL32;
67
57
    TlsGotRel = R_MIPS_TLS_TPREL32;
68
57
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
69
57
    TlsOffsetRel = R_MIPS_TLS_DTPREL32;
70
57
  }
71
76
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::MIPS()
Line
Count
Source
48
4
template <class ELFT> MIPS<ELFT>::MIPS() {
49
4
  GotPltHeaderEntriesNum = 2;
50
4
  DefaultMaxPageSize = 65536;
51
4
  GotEntrySize = sizeof(typename ELFT::uint);
52
4
  GotPltEntrySize = sizeof(typename ELFT::uint);
53
4
  PltEntrySize = 16;
54
4
  PltHeaderSize = 32;
55
4
  CopyRel = R_MIPS_COPY;
56
4
  PltRel = R_MIPS_JUMP_SLOT;
57
4
  NeedsThunks = true;
58
4
  TrapInstr = 0xefefefef;
59
4
60
4
  if (ELFT::Is64Bits) {
61
0
    RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
0
    TlsGotRel = R_MIPS_TLS_TPREL64;
63
0
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
64
0
    TlsOffsetRel = R_MIPS_TLS_DTPREL64;
65
4
  } else {
66
4
    RelativeRel = R_MIPS_REL32;
67
4
    TlsGotRel = R_MIPS_TLS_TPREL32;
68
4
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
69
4
    TlsOffsetRel = R_MIPS_TLS_DTPREL32;
70
4
  }
71
4
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::MIPS()
Line
Count
Source
48
53
template <class ELFT> MIPS<ELFT>::MIPS() {
49
53
  GotPltHeaderEntriesNum = 2;
50
53
  DefaultMaxPageSize = 65536;
51
53
  GotEntrySize = sizeof(typename ELFT::uint);
52
53
  GotPltEntrySize = sizeof(typename ELFT::uint);
53
53
  PltEntrySize = 16;
54
53
  PltHeaderSize = 32;
55
53
  CopyRel = R_MIPS_COPY;
56
53
  PltRel = R_MIPS_JUMP_SLOT;
57
53
  NeedsThunks = true;
58
53
  TrapInstr = 0xefefefef;
59
53
60
53
  if (ELFT::Is64Bits) {
61
0
    RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
0
    TlsGotRel = R_MIPS_TLS_TPREL64;
63
0
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
64
0
    TlsOffsetRel = R_MIPS_TLS_DTPREL64;
65
53
  } else {
66
53
    RelativeRel = R_MIPS_REL32;
67
53
    TlsGotRel = R_MIPS_TLS_TPREL32;
68
53
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
69
53
    TlsOffsetRel = R_MIPS_TLS_DTPREL32;
70
53
  }
71
53
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::MIPS()
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::MIPS()
Line
Count
Source
48
19
template <class ELFT> MIPS<ELFT>::MIPS() {
49
19
  GotPltHeaderEntriesNum = 2;
50
19
  DefaultMaxPageSize = 65536;
51
19
  GotEntrySize = sizeof(typename ELFT::uint);
52
19
  GotPltEntrySize = sizeof(typename ELFT::uint);
53
19
  PltEntrySize = 16;
54
19
  PltHeaderSize = 32;
55
19
  CopyRel = R_MIPS_COPY;
56
19
  PltRel = R_MIPS_JUMP_SLOT;
57
19
  NeedsThunks = true;
58
19
  TrapInstr = 0xefefefef;
59
19
60
19
  if (ELFT::Is64Bits) {
61
19
    RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
62
19
    TlsGotRel = R_MIPS_TLS_TPREL64;
63
19
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
64
19
    TlsOffsetRel = R_MIPS_TLS_DTPREL64;
65
19
  } else {
66
0
    RelativeRel = R_MIPS_REL32;
67
0
    TlsGotRel = R_MIPS_TLS_TPREL32;
68
0
    TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
69
0
    TlsOffsetRel = R_MIPS_TLS_DTPREL32;
70
0
  }
71
19
}
72
73
74
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
74
74
  return calcMipsEFlags<ELFT>();
75
74
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::calcEFlags() const
Line
Count
Source
73
4
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
74
4
  return calcMipsEFlags<ELFT>();
75
4
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::calcEFlags() const
Line
Count
Source
73
51
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
74
51
  return calcMipsEFlags<ELFT>();
75
51
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::calcEFlags() const
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::calcEFlags() const
Line
Count
Source
73
19
template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
74
19
  return calcMipsEFlags<ELFT>();
75
19
}
76
77
template <class ELFT>
78
RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const Symbol &S,
79
10.1k
                               const uint8_t *Loc) const {
80
10.1k
  // See comment in the calculateMipsRelChain.
81
10.1k
  if (ELFT::Is64Bits || 
Config->MipsN32Abi127
)
82
10.0k
    Type &= 0xff;
83
10.1k
84
10.1k
  switch (Type) {
85
10.1k
  case R_MIPS_JALR:
86
0
  case R_MICROMIPS_JALR:
87
0
    return R_HINT;
88
12
  case R_MIPS_GPREL16:
89
12
  case R_MIPS_GPREL32:
90
12
  case R_MICROMIPS_GPREL16:
91
12
  case R_MICROMIPS_GPREL7_S2:
92
12
    return R_MIPS_GOTREL;
93
33
  case R_MIPS_26:
94
33
  case R_MICROMIPS_26_S1:
95
33
    return R_PLT;
96
33
  case R_MICROMIPS_PC26_S1:
97
0
    return R_PLT_PC;
98
33
  case R_MIPS_HI16:
99
25
  case R_MIPS_LO16:
100
25
  case R_MIPS_HIGHER:
101
25
  case R_MIPS_HIGHEST:
102
25
  case R_MICROMIPS_HI16:
103
25
  case R_MICROMIPS_LO16:
104
25
  case R_MICROMIPS_HIGHER:
105
25
  case R_MICROMIPS_HIGHEST:
106
25
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
107
25
    // offset between start of function and 'gp' value which by default
108
25
    // equal to the start of .got section. In that case we consider these
109
25
    // relocations as relative.
110
25
    if (&S == ElfSym::MipsGpDisp)
111
6
      return R_MIPS_GOT_GP_PC;
112
19
    if (&S == ElfSym::MipsLocalGp)
113
0
      return R_MIPS_GOT_GP;
114
19
    LLVM_FALLTHROUGH;
115
37
  case R_MIPS_32:
116
37
  case R_MIPS_64:
117
37
  case R_MIPS_GOT_OFST:
118
37
  case R_MIPS_SUB:
119
37
  case R_MIPS_TLS_DTPREL_HI16:
120
37
  case R_MIPS_TLS_DTPREL_LO16:
121
37
  case R_MIPS_TLS_DTPREL32:
122
37
  case R_MIPS_TLS_DTPREL64:
123
37
  case R_MIPS_TLS_TPREL_HI16:
124
37
  case R_MIPS_TLS_TPREL_LO16:
125
37
  case R_MIPS_TLS_TPREL32:
126
37
  case R_MIPS_TLS_TPREL64:
127
37
  case R_MICROMIPS_GOT_OFST:
128
37
  case R_MICROMIPS_SUB:
129
37
  case R_MICROMIPS_TLS_DTPREL_HI16:
130
37
  case R_MICROMIPS_TLS_DTPREL_LO16:
131
37
  case R_MICROMIPS_TLS_TPREL_HI16:
132
37
  case R_MICROMIPS_TLS_TPREL_LO16:
133
37
    return R_ABS;
134
37
  case R_MIPS_PC32:
135
11
  case R_MIPS_PC16:
136
11
  case R_MIPS_PC19_S2:
137
11
  case R_MIPS_PC21_S2:
138
11
  case R_MIPS_PC26_S2:
139
11
  case R_MIPS_PCHI16:
140
11
  case R_MIPS_PCLO16:
141
11
  case R_MICROMIPS_PC7_S1:
142
11
  case R_MICROMIPS_PC10_S1:
143
11
  case R_MICROMIPS_PC16_S1:
144
11
  case R_MICROMIPS_PC18_S3:
145
11
  case R_MICROMIPS_PC19_S2:
146
11
  case R_MICROMIPS_PC23_S2:
147
11
  case R_MICROMIPS_PC21_S1:
148
11
    return R_PC;
149
21
  case R_MIPS_GOT16:
150
21
  case R_MICROMIPS_GOT16:
151
21
    if (S.isLocal())
152
11
      return R_MIPS_GOT_LOCAL_PAGE;
153
10
    LLVM_FALLTHROUGH;
154
10.0k
  case R_MIPS_CALL16:
155
10.0k
  case R_MIPS_GOT_DISP:
156
10.0k
  case R_MIPS_TLS_GOTTPREL:
157
10.0k
  case R_MICROMIPS_CALL16:
158
10.0k
  case R_MICROMIPS_GOT_DISP:
159
10.0k
  case R_MICROMIPS_TLS_GOTTPREL:
160
10.0k
    return R_MIPS_GOT_OFF;
161
10.0k
  case R_MIPS_CALL_HI16:
162
16
  case R_MIPS_CALL_LO16:
163
16
  case R_MIPS_GOT_HI16:
164
16
  case R_MIPS_GOT_LO16:
165
16
  case R_MICROMIPS_CALL_HI16:
166
16
  case R_MICROMIPS_CALL_LO16:
167
16
  case R_MICROMIPS_GOT_HI16:
168
16
  case R_MICROMIPS_GOT_LO16:
169
16
    return R_MIPS_GOT_OFF32;
170
16
  case R_MIPS_GOT_PAGE:
171
6
  case R_MICROMIPS_GOT_PAGE:
172
6
    return R_MIPS_GOT_LOCAL_PAGE;
173
6
  case R_MIPS_TLS_GD:
174
1
  case R_MICROMIPS_TLS_GD:
175
1
    return R_MIPS_TLSGD;
176
1
  case R_MIPS_TLS_LDM:
177
1
  case R_MICROMIPS_TLS_LDM:
178
1
    return R_MIPS_TLSLD;
179
1
  case R_MIPS_NONE:
180
0
    return R_NONE;
181
1
  default:
182
0
    return R_INVALID;
183
0
  }
184
0
}
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
79
4
                               const uint8_t *Loc) const {
80
4
  // See comment in the calculateMipsRelChain.
81
4
  if (ELFT::Is64Bits || Config->MipsN32Abi)
82
0
    Type &= 0xff;
83
4
84
4
  switch (Type) {
85
4
  case R_MIPS_JALR:
86
0
  case R_MICROMIPS_JALR:
87
0
    return R_HINT;
88
0
  case R_MIPS_GPREL16:
89
0
  case R_MIPS_GPREL32:
90
0
  case R_MICROMIPS_GPREL16:
91
0
  case R_MICROMIPS_GPREL7_S2:
92
0
    return R_MIPS_GOTREL;
93
2
  case R_MIPS_26:
94
2
  case R_MICROMIPS_26_S1:
95
2
    return R_PLT;
96
2
  case R_MICROMIPS_PC26_S1:
97
0
    return R_PLT_PC;
98
2
  case R_MIPS_HI16:
99
0
  case R_MIPS_LO16:
100
0
  case R_MIPS_HIGHER:
101
0
  case R_MIPS_HIGHEST:
102
0
  case R_MICROMIPS_HI16:
103
0
  case R_MICROMIPS_LO16:
104
0
  case R_MICROMIPS_HIGHER:
105
0
  case R_MICROMIPS_HIGHEST:
106
0
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
107
0
    // offset between start of function and 'gp' value which by default
108
0
    // equal to the start of .got section. In that case we consider these
109
0
    // relocations as relative.
110
0
    if (&S == ElfSym::MipsGpDisp)
111
0
      return R_MIPS_GOT_GP_PC;
112
0
    if (&S == ElfSym::MipsLocalGp)
113
0
      return R_MIPS_GOT_GP;
114
0
    LLVM_FALLTHROUGH;
115
2
  case R_MIPS_32:
116
2
  case R_MIPS_64:
117
2
  case R_MIPS_GOT_OFST:
118
2
  case R_MIPS_SUB:
119
2
  case R_MIPS_TLS_DTPREL_HI16:
120
2
  case R_MIPS_TLS_DTPREL_LO16:
121
2
  case R_MIPS_TLS_DTPREL32:
122
2
  case R_MIPS_TLS_DTPREL64:
123
2
  case R_MIPS_TLS_TPREL_HI16:
124
2
  case R_MIPS_TLS_TPREL_LO16:
125
2
  case R_MIPS_TLS_TPREL32:
126
2
  case R_MIPS_TLS_TPREL64:
127
2
  case R_MICROMIPS_GOT_OFST:
128
2
  case R_MICROMIPS_SUB:
129
2
  case R_MICROMIPS_TLS_DTPREL_HI16:
130
2
  case R_MICROMIPS_TLS_DTPREL_LO16:
131
2
  case R_MICROMIPS_TLS_TPREL_HI16:
132
2
  case R_MICROMIPS_TLS_TPREL_LO16:
133
2
    return R_ABS;
134
2
  case R_MIPS_PC32:
135
0
  case R_MIPS_PC16:
136
0
  case R_MIPS_PC19_S2:
137
0
  case R_MIPS_PC21_S2:
138
0
  case R_MIPS_PC26_S2:
139
0
  case R_MIPS_PCHI16:
140
0
  case R_MIPS_PCLO16:
141
0
  case R_MICROMIPS_PC7_S1:
142
0
  case R_MICROMIPS_PC10_S1:
143
0
  case R_MICROMIPS_PC16_S1:
144
0
  case R_MICROMIPS_PC18_S3:
145
0
  case R_MICROMIPS_PC19_S2:
146
0
  case R_MICROMIPS_PC23_S2:
147
0
  case R_MICROMIPS_PC21_S1:
148
0
    return R_PC;
149
0
  case R_MIPS_GOT16:
150
0
  case R_MICROMIPS_GOT16:
151
0
    if (S.isLocal())
152
0
      return R_MIPS_GOT_LOCAL_PAGE;
153
0
    LLVM_FALLTHROUGH;
154
0
  case R_MIPS_CALL16:
155
0
  case R_MIPS_GOT_DISP:
156
0
  case R_MIPS_TLS_GOTTPREL:
157
0
  case R_MICROMIPS_CALL16:
158
0
  case R_MICROMIPS_GOT_DISP:
159
0
  case R_MICROMIPS_TLS_GOTTPREL:
160
0
    return R_MIPS_GOT_OFF;
161
0
  case R_MIPS_CALL_HI16:
162
0
  case R_MIPS_CALL_LO16:
163
0
  case R_MIPS_GOT_HI16:
164
0
  case R_MIPS_GOT_LO16:
165
0
  case R_MICROMIPS_CALL_HI16:
166
0
  case R_MICROMIPS_CALL_LO16:
167
0
  case R_MICROMIPS_GOT_HI16:
168
0
  case R_MICROMIPS_GOT_LO16:
169
0
    return R_MIPS_GOT_OFF32;
170
0
  case R_MIPS_GOT_PAGE:
171
0
  case R_MICROMIPS_GOT_PAGE:
172
0
    return R_MIPS_GOT_LOCAL_PAGE;
173
0
  case R_MIPS_TLS_GD:
174
0
  case R_MICROMIPS_TLS_GD:
175
0
    return R_MIPS_TLSGD;
176
0
  case R_MIPS_TLS_LDM:
177
0
  case R_MICROMIPS_TLS_LDM:
178
0
    return R_MIPS_TLSLD;
179
0
  case R_MIPS_NONE:
180
0
    return R_NONE;
181
0
  default:
182
0
    return R_INVALID;
183
0
  }
184
0
}
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
79
123
                               const uint8_t *Loc) const {
80
123
  // See comment in the calculateMipsRelChain.
81
123
  if (ELFT::Is64Bits || Config->MipsN32Abi)
82
0
    Type &= 0xff;
83
123
84
123
  switch (Type) {
85
123
  case R_MIPS_JALR:
86
0
  case R_MICROMIPS_JALR:
87
0
    return R_HINT;
88
4
  case R_MIPS_GPREL16:
89
4
  case R_MIPS_GPREL32:
90
4
  case R_MICROMIPS_GPREL16:
91
4
  case R_MICROMIPS_GPREL7_S2:
92
4
    return R_MIPS_GOTREL;
93
30
  case R_MIPS_26:
94
30
  case R_MICROMIPS_26_S1:
95
30
    return R_PLT;
96
30
  case R_MICROMIPS_PC26_S1:
97
0
    return R_PLT_PC;
98
30
  case R_MIPS_HI16:
99
21
  case R_MIPS_LO16:
100
21
  case R_MIPS_HIGHER:
101
21
  case R_MIPS_HIGHEST:
102
21
  case R_MICROMIPS_HI16:
103
21
  case R_MICROMIPS_LO16:
104
21
  case R_MICROMIPS_HIGHER:
105
21
  case R_MICROMIPS_HIGHEST:
106
21
    // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
107
21
    // offset between start of function and 'gp' value which by default
108
21
    // equal to the start of .got section. In that case we consider these
109
21
    // relocations as relative.
110
21
    if (&S == ElfSym::MipsGpDisp)
111
6
      return R_MIPS_GOT_GP_PC;
112
15
    if (&S == ElfSym::MipsLocalGp)
113
0
      return R_MIPS_GOT_GP;
114
15
    LLVM_FALLTHROUGH;
115
27
  case R_MIPS_32:
116
27
  case R_MIPS_64:
117
27
  case R_MIPS_GOT_OFST:
118
27
  case R_MIPS_SUB:
119
27
  case R_MIPS_TLS_DTPREL_HI16:
120
27
  case R_MIPS_TLS_DTPREL_LO16:
121
27
  case R_MIPS_TLS_DTPREL32:
122
27
  case R_MIPS_TLS_DTPREL64:
123
27
  case R_MIPS_TLS_TPREL_HI16:
124
27
  case R_MIPS_TLS_TPREL_LO16:
125
27
  case R_MIPS_TLS_TPREL32:
126
27
  case R_MIPS_TLS_TPREL64:
127
27
  case R_MICROMIPS_GOT_OFST:
128
27
  case R_MICROMIPS_SUB:
129
27
  case R_MICROMIPS_TLS_DTPREL_HI16:
130
27
  case R_MICROMIPS_TLS_DTPREL_LO16:
131
27
  case R_MICROMIPS_TLS_TPREL_HI16:
132
27
  case R_MICROMIPS_TLS_TPREL_LO16:
133
27
    return R_ABS;
134
27
  case R_MIPS_PC32:
135
10
  case R_MIPS_PC16:
136
10
  case R_MIPS_PC19_S2:
137
10
  case R_MIPS_PC21_S2:
138
10
  case R_MIPS_PC26_S2:
139
10
  case R_MIPS_PCHI16:
140
10
  case R_MIPS_PCLO16:
141
10
  case R_MICROMIPS_PC7_S1:
142
10
  case R_MICROMIPS_PC10_S1:
143
10
  case R_MICROMIPS_PC16_S1:
144
10
  case R_MICROMIPS_PC18_S3:
145
10
  case R_MICROMIPS_PC19_S2:
146
10
  case R_MICROMIPS_PC23_S2:
147
10
  case R_MICROMIPS_PC21_S1:
148
10
    return R_PC;
149
21
  case R_MIPS_GOT16:
150
21
  case R_MICROMIPS_GOT16:
151
21
    if (S.isLocal())
152
11
      return R_MIPS_GOT_LOCAL_PAGE;
153
10
    LLVM_FALLTHROUGH;
154
17
  case R_MIPS_CALL16:
155
17
  case R_MIPS_GOT_DISP:
156
17
  case R_MIPS_TLS_GOTTPREL:
157
17
  case R_MICROMIPS_CALL16:
158
17
  case R_MICROMIPS_GOT_DISP:
159
17
  case R_MICROMIPS_TLS_GOTTPREL:
160
17
    return R_MIPS_GOT_OFF;
161
17
  case R_MIPS_CALL_HI16:
162
16
  case R_MIPS_CALL_LO16:
163
16
  case R_MIPS_GOT_HI16:
164
16
  case R_MIPS_GOT_LO16:
165
16
  case R_MICROMIPS_CALL_HI16:
166
16
  case R_MICROMIPS_CALL_LO16:
167
16
  case R_MICROMIPS_GOT_HI16:
168
16
  case R_MICROMIPS_GOT_LO16:
169
16
    return R_MIPS_GOT_OFF32;
170
16
  case R_MIPS_GOT_PAGE:
171
0
  case R_MICROMIPS_GOT_PAGE:
172
0
    return R_MIPS_GOT_LOCAL_PAGE;
173
1
  case R_MIPS_TLS_GD:
174
1
  case R_MICROMIPS_TLS_GD:
175
1
    return R_MIPS_TLSGD;
176
1
  case R_MIPS_TLS_LDM:
177
1
  case R_MICROMIPS_TLS_LDM:
178
1
    return R_MIPS_TLSLD;
179
1
  case R_MIPS_NONE:
180
0
    return R_NONE;
181
1
  default:
182
0
    return R_INVALID;
183
0
  }
184
0
}
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
79
10.0k
                               const uint8_t *Loc) const {
80
10.0k
  // See comment in the calculateMipsRelChain.
81
10.0k
  if (ELFT::Is64Bits || 
Config->MipsN32Abi0
)
82
10.0k
    Type &= 0xff;
83
10.0k
84
10.0k
  switch (Type) {
85
10.0k
  case R_MIPS_JALR:
86
0
  case R_MICROMIPS_JALR:
87
0
    return R_HINT;
88
8
  case R_MIPS_GPREL16:
89
8
  case R_MIPS_GPREL32:
90
8
  case R_MICROMIPS_GPREL16:
91
8
  case R_MICROMIPS_GPREL7_S2:
92
8
    return R_MIPS_GOTREL;
93
8
  case R_MIPS_26:
94
1
  case R_MICROMIPS_26_S1:
95
1
    return R_PLT;
96
1
  case R_MICROMIPS_PC26_S1:
97
0
    return R_PLT_PC;
98
4
  case R_MIPS_HI16:
99
4
  case R_MIPS_LO16:
100
4
  case R_MIPS_HIGHER:
101
4
  case R_MIPS_HIGHEST:
102
4
  case R_MICROMIPS_HI16:
103
4
  case R_MICROMIPS_LO16:
104
4
  case R_MICROMIPS_HIGHER:
105
4
  case R_MICROMIPS_HIGHEST:
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
8
  case R_MIPS_32:
116
8
  case R_MIPS_64:
117
8
  case R_MIPS_GOT_OFST:
118
8
  case R_MIPS_SUB:
119
8
  case R_MIPS_TLS_DTPREL_HI16:
120
8
  case R_MIPS_TLS_DTPREL_LO16:
121
8
  case R_MIPS_TLS_DTPREL32:
122
8
  case R_MIPS_TLS_DTPREL64:
123
8
  case R_MIPS_TLS_TPREL_HI16:
124
8
  case R_MIPS_TLS_TPREL_LO16:
125
8
  case R_MIPS_TLS_TPREL32:
126
8
  case R_MIPS_TLS_TPREL64:
127
8
  case R_MICROMIPS_GOT_OFST:
128
8
  case R_MICROMIPS_SUB:
129
8
  case R_MICROMIPS_TLS_DTPREL_HI16:
130
8
  case R_MICROMIPS_TLS_DTPREL_LO16:
131
8
  case R_MICROMIPS_TLS_TPREL_HI16:
132
8
  case R_MICROMIPS_TLS_TPREL_LO16:
133
8
    return R_ABS;
134
8
  case R_MIPS_PC32:
135
1
  case R_MIPS_PC16:
136
1
  case R_MIPS_PC19_S2:
137
1
  case R_MIPS_PC21_S2:
138
1
  case R_MIPS_PC26_S2:
139
1
  case R_MIPS_PCHI16:
140
1
  case R_MIPS_PCLO16:
141
1
  case R_MICROMIPS_PC7_S1:
142
1
  case R_MICROMIPS_PC10_S1:
143
1
  case R_MICROMIPS_PC16_S1:
144
1
  case R_MICROMIPS_PC18_S3:
145
1
  case R_MICROMIPS_PC19_S2:
146
1
  case R_MICROMIPS_PC23_S2:
147
1
  case R_MICROMIPS_PC21_S1:
148
1
    return R_PC;
149
1
  case R_MIPS_GOT16:
150
0
  case R_MICROMIPS_GOT16:
151
0
    if (S.isLocal())
152
0
      return R_MIPS_GOT_LOCAL_PAGE;
153
0
    LLVM_FALLTHROUGH;
154
10.0k
  case R_MIPS_CALL16:
155
10.0k
  case R_MIPS_GOT_DISP:
156
10.0k
  case R_MIPS_TLS_GOTTPREL:
157
10.0k
  case R_MICROMIPS_CALL16:
158
10.0k
  case R_MICROMIPS_GOT_DISP:
159
10.0k
  case R_MICROMIPS_TLS_GOTTPREL:
160
10.0k
    return R_MIPS_GOT_OFF;
161
10.0k
  case R_MIPS_CALL_HI16:
162
0
  case R_MIPS_CALL_LO16:
163
0
  case R_MIPS_GOT_HI16:
164
0
  case R_MIPS_GOT_LO16:
165
0
  case R_MICROMIPS_CALL_HI16:
166
0
  case R_MICROMIPS_CALL_LO16:
167
0
  case R_MICROMIPS_GOT_HI16:
168
0
  case R_MICROMIPS_GOT_LO16:
169
0
    return R_MIPS_GOT_OFF32;
170
6
  case R_MIPS_GOT_PAGE:
171
6
  case R_MICROMIPS_GOT_PAGE:
172
6
    return R_MIPS_GOT_LOCAL_PAGE;
173
6
  case R_MIPS_TLS_GD:
174
0
  case R_MICROMIPS_TLS_GD:
175
0
    return R_MIPS_TLSGD;
176
0
  case R_MIPS_TLS_LDM:
177
0
  case R_MICROMIPS_TLS_LDM:
178
0
    return R_MIPS_TLSLD;
179
0
  case R_MIPS_NONE:
180
0
    return R_NONE;
181
0
  default:
182
0
    return R_INVALID;
183
0
  }
184
0
}
185
186
1
template <class ELFT> bool MIPS<ELFT>::isPicRel(RelType Type) const {
187
1
  return Type == R_MIPS_32 || 
Type == R_MIPS_640
;
188
1
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::isPicRel(unsigned int) const
Line
Count
Source
186
1
template <class ELFT> bool MIPS<ELFT>::isPicRel(RelType Type) const {
187
1
  return Type == R_MIPS_32 || 
Type == R_MIPS_640
;
188
1
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::isPicRel(unsigned int) const
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::isPicRel(unsigned int) const
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::isPicRel(unsigned int) const
189
190
1
template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
191
1
  return RelativeRel;
192
1
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getDynRel(unsigned int) const
Line
Count
Source
190
1
template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType Type) const {
191
1
  return RelativeRel;
192
1
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getDynRel(unsigned int) const
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getDynRel(unsigned int) const
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getDynRel(unsigned int) const
193
194
template <class ELFT>
195
5
void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
196
5
  uint64_t VA = InX::Plt->getVA();
197
5
  if (isMicroMips())
198
3
    VA |= 1;
199
5
  write32<ELFT::TargetEndianness>(Buf, VA);
200
5
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writeGotPlt(unsigned char*, lld::elf::Symbol const&) const
Line
Count
Source
195
1
void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
196
1
  uint64_t VA = InX::Plt->getVA();
197
1
  if (isMicroMips())
198
1
    VA |= 1;
199
1
  write32<ELFT::TargetEndianness>(Buf, VA);
200
1
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::writeGotPlt(unsigned char*, lld::elf::Symbol const&) const
Line
Count
Source
195
3
void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
196
3
  uint64_t VA = InX::Plt->getVA();
197
3
  if (isMicroMips())
198
2
    VA |= 1;
199
3
  write32<ELFT::TargetEndianness>(Buf, VA);
200
3
}
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
195
1
void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const Symbol &) const {
196
1
  uint64_t VA = InX::Plt->getVA();
197
1
  if (isMicroMips())
198
0
    VA |= 1;
199
1
  write32<ELFT::TargetEndianness>(Buf, VA);
200
1
}
201
202
13
template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) {
203
13
  // The major opcode of a microMIPS instruction needs to appear
204
13
  // in the first 16-bit word (lowest address) for efficient hardware
205
13
  // decode so that it knows if the instruction is 16-bit or 32-bit
206
13
  // as early as possible. To do so, little-endian binaries keep 16-bit
207
13
  // words in a big-endian order. That is why we have to swap these
208
13
  // words to get a correct value.
209
13
  uint32_t V = read32<E>(Loc);
210
13
  if (E == support::little)
211
2
    return (V << 16) | (V >> 16);
212
11
  return V;
213
11
}
Mips.cpp:unsigned int readShuffle<(llvm::support::endianness)1>(unsigned char const*)
Line
Count
Source
202
2
template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) {
203
2
  // The major opcode of a microMIPS instruction needs to appear
204
2
  // in the first 16-bit word (lowest address) for efficient hardware
205
2
  // decode so that it knows if the instruction is 16-bit or 32-bit
206
2
  // as early as possible. To do so, little-endian binaries keep 16-bit
207
2
  // words in a big-endian order. That is why we have to swap these
208
2
  // words to get a correct value.
209
2
  uint32_t V = read32<E>(Loc);
210
2
  if (E == support::little)
211
2
    return (V << 16) | (V >> 16);
212
0
  return V;
213
0
}
Mips.cpp:unsigned int readShuffle<(llvm::support::endianness)0>(unsigned char const*)
Line
Count
Source
202
11
template <endianness E> static uint32_t readShuffle(const uint8_t *Loc) {
203
11
  // The major opcode of a microMIPS instruction needs to appear
204
11
  // in the first 16-bit word (lowest address) for efficient hardware
205
11
  // decode so that it knows if the instruction is 16-bit or 32-bit
206
11
  // as early as possible. To do so, little-endian binaries keep 16-bit
207
11
  // words in a big-endian order. That is why we have to swap these
208
11
  // words to get a correct value.
209
11
  uint32_t V = read32<E>(Loc);
210
11
  if (E == support::little)
211
0
    return (V << 16) | (V >> 16);
212
11
  return V;
213
11
}
214
215
template <endianness E>
216
static void writeRelocation(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
217
10.1k
                            uint8_t Shift) {
218
10.1k
  uint32_t Instr = read32<E>(Loc);
219
10.1k
  uint32_t Mask = 0xffffffff >> (32 - BitsSize);
220
10.1k
  uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
221
10.1k
  write32<E>(Loc, Data);
222
10.1k
}
Mips.cpp:void writeRelocation<(llvm::support::endianness)1>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
217
7
                            uint8_t Shift) {
218
7
  uint32_t Instr = read32<E>(Loc);
219
7
  uint32_t Mask = 0xffffffff >> (32 - BitsSize);
220
7
  uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
221
7
  write32<E>(Loc, Data);
222
7
}
Mips.cpp:void writeRelocation<(llvm::support::endianness)0>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
217
10.1k
                            uint8_t Shift) {
218
10.1k
  uint32_t Instr = read32<E>(Loc);
219
10.1k
  uint32_t Mask = 0xffffffff >> (32 - BitsSize);
220
10.1k
  uint32_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
221
10.1k
  write32<E>(Loc, Data);
222
10.1k
}
223
224
template <endianness E>
225
static void writeMicroRelocation32(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
226
25
                                   uint8_t Shift) {
227
25
  // See comments in readShuffle for purpose of this code.
228
25
  uint16_t *Words = (uint16_t *)Loc;
229
25
  if (E == support::little)
230
7
    std::swap(Words[0], Words[1]);
231
25
232
25
  writeRelocation<E>(Loc, V, BitsSize, Shift);
233
25
234
25
  if (E == support::little)
235
7
    std::swap(Words[0], Words[1]);
236
25
}
Mips.cpp:void writeMicroRelocation32<(llvm::support::endianness)1>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
226
7
                                   uint8_t Shift) {
227
7
  // See comments in readShuffle for purpose of this code.
228
7
  uint16_t *Words = (uint16_t *)Loc;
229
7
  if (E == support::little)
230
7
    std::swap(Words[0], Words[1]);
231
7
232
7
  writeRelocation<E>(Loc, V, BitsSize, Shift);
233
7
234
7
  if (E == support::little)
235
7
    std::swap(Words[0], Words[1]);
236
7
}
Mips.cpp:void writeMicroRelocation32<(llvm::support::endianness)0>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
226
18
                                   uint8_t Shift) {
227
18
  // See comments in readShuffle for purpose of this code.
228
18
  uint16_t *Words = (uint16_t *)Loc;
229
18
  if (E == support::little)
230
0
    std::swap(Words[0], Words[1]);
231
18
232
18
  writeRelocation<E>(Loc, V, BitsSize, Shift);
233
18
234
18
  if (E == support::little)
235
0
    std::swap(Words[0], Words[1]);
236
18
}
237
238
template <endianness E>
239
static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
240
2
                                   uint8_t Shift) {
241
2
  uint16_t Instr = read16<E>(Loc);
242
2
  uint16_t Mask = 0xffff >> (16 - BitsSize);
243
2
  uint16_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
244
2
  write16<E>(Loc, Data);
245
2
}
Unexecuted instantiation: Mips.cpp:void writeMicroRelocation16<(llvm::support::endianness)1>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Mips.cpp:void writeMicroRelocation16<(llvm::support::endianness)0>(unsigned char*, unsigned long long, unsigned char, unsigned char)
Line
Count
Source
240
2
                                   uint8_t Shift) {
241
2
  uint16_t Instr = read16<E>(Loc);
242
2
  uint16_t Mask = 0xffff >> (16 - BitsSize);
243
2
  uint16_t Data = (Instr & ~Mask) | ((V >> Shift) & Mask);
244
2
  write16<E>(Loc, Data);
245
2
}
246
247
5
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
248
5
  const endianness E = ELFT::TargetEndianness;
249
5
  if (isMicroMips()) {
250
3
    uint64_t GotPlt = InX::GotPlt->getVA();
251
3
    uint64_t Plt = InX::Plt->getVA();
252
3
    // Overwrite trap instructions written by Writer::writeTrapInstr.
253
3
    memset(Buf, 0, PltHeaderSize);
254
3
255
3
    write16<E>(Buf, isMipsR6() ? 
0x78601
:
0x79802
); // addiupc v1, (GOTPLT) - .
256
3
    write16<E>(Buf + 4, 0xff23);    // lw      $25, 0($3)
257
3
    write16<E>(Buf + 8, 0x0535);    // subu16  $2,  $2, $3
258
3
    write16<E>(Buf + 10, 0x2525);   // srl16   $2,  $2, 2
259
3
    write16<E>(Buf + 12, 0x3302);   // addiu   $24, $2, -2
260
3
    write16<E>(Buf + 14, 0xfffe);
261
3
    write16<E>(Buf + 16, 0x0dff);   // move    $15, $31
262
3
    if (isMipsR6()) {
263
1
      write16<E>(Buf + 18, 0x0f83); // move    $28, $3
264
1
      write16<E>(Buf + 20, 0x472b); // jalrc   $25
265
1
      write16<E>(Buf + 22, 0x0c00); // nop
266
1
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPlt - Plt);
267
2
    } else {
268
2
      write16<E>(Buf + 18, 0x45f9); // jalrc   $25
269
2
      write16<E>(Buf + 20, 0x0f83); // move    $28, $3
270
2
      write16<E>(Buf + 22, 0x0c00); // nop
271
2
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPlt - Plt);
272
2
    }
273
3
    return;
274
3
  }
275
2
276
2
  if (Config->MipsN32Abi) {
277
0
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
278
0
    write32<E>(Buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
279
0
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
280
0
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
281
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
282
0
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
283
2
  } else if (ELFT::Is64Bits) {
284
1
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
285
1
    write32<E>(Buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
286
1
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
287
1
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
288
1
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
289
1
    write32<E>(Buf + 20, 0x0018c0c2); // srl   $24, $24, 3
290
1
  } else {
291
1
    write32<E>(Buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
292
1
    write32<E>(Buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
293
1
    write32<E>(Buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
294
1
    write32<E>(Buf + 12, 0x031cc023); // subu  $24, $24, $28
295
1
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
296
1
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
297
1
  }
298
2
299
2
  write32<E>(Buf + 24, 0x0320f809); // jalr  $25
300
2
  write32<E>(Buf + 28, 0x2718fffe); // subu  $24, $24, 2
301
2
302
2
  uint64_t GotPlt = InX::GotPlt->getVA();
303
2
  writeRelocation<E>(Buf, GotPlt + 0x8000, 16, 16);
304
2
  writeRelocation<E>(Buf + 4, GotPlt, 16, 0);
305
2
  writeRelocation<E>(Buf + 8, GotPlt, 16, 0);
306
2
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::writePltHeader(unsigned char*) const
Line
Count
Source
247
1
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
248
1
  const endianness E = ELFT::TargetEndianness;
249
1
  if (isMicroMips()) {
250
1
    uint64_t GotPlt = InX::GotPlt->getVA();
251
1
    uint64_t Plt = InX::Plt->getVA();
252
1
    // Overwrite trap instructions written by Writer::writeTrapInstr.
253
1
    memset(Buf, 0, PltHeaderSize);
254
1
255
1
    write16<E>(Buf, isMipsR6() ? 
0x78600
: 0x7980); // addiupc v1, (GOTPLT) - .
256
1
    write16<E>(Buf + 4, 0xff23);    // lw      $25, 0($3)
257
1
    write16<E>(Buf + 8, 0x0535);    // subu16  $2,  $2, $3
258
1
    write16<E>(Buf + 10, 0x2525);   // srl16   $2,  $2, 2
259
1
    write16<E>(Buf + 12, 0x3302);   // addiu   $24, $2, -2
260
1
    write16<E>(Buf + 14, 0xfffe);
261
1
    write16<E>(Buf + 16, 0x0dff);   // move    $15, $31
262
1
    if (isMipsR6()) {
263
0
      write16<E>(Buf + 18, 0x0f83); // move    $28, $3
264
0
      write16<E>(Buf + 20, 0x472b); // jalrc   $25
265
0
      write16<E>(Buf + 22, 0x0c00); // nop
266
0
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPlt - Plt);
267
1
    } else {
268
1
      write16<E>(Buf + 18, 0x45f9); // jalrc   $25
269
1
      write16<E>(Buf + 20, 0x0f83); // move    $28, $3
270
1
      write16<E>(Buf + 22, 0x0c00); // nop
271
1
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPlt - Plt);
272
1
    }
273
1
    return;
274
1
  }
275
0
276
0
  if (Config->MipsN32Abi) {
277
0
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
278
0
    write32<E>(Buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
279
0
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
280
0
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
281
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
282
0
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
283
0
  } else if (ELFT::Is64Bits) {
284
0
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
285
0
    write32<E>(Buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
286
0
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
287
0
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
288
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
289
0
    write32<E>(Buf + 20, 0x0018c0c2); // srl   $24, $24, 3
290
0
  } else {
291
0
    write32<E>(Buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
292
0
    write32<E>(Buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
293
0
    write32<E>(Buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
294
0
    write32<E>(Buf + 12, 0x031cc023); // subu  $24, $24, $28
295
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
296
0
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
297
0
  }
298
0
299
0
  write32<E>(Buf + 24, 0x0320f809); // jalr  $25
300
0
  write32<E>(Buf + 28, 0x2718fffe); // subu  $24, $24, 2
301
0
302
0
  uint64_t GotPlt = InX::GotPlt->getVA();
303
0
  writeRelocation<E>(Buf, GotPlt + 0x8000, 16, 16);
304
0
  writeRelocation<E>(Buf + 4, GotPlt, 16, 0);
305
0
  writeRelocation<E>(Buf + 8, GotPlt, 16, 0);
306
0
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::writePltHeader(unsigned char*) const
Line
Count
Source
247
3
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
248
3
  const endianness E = ELFT::TargetEndianness;
249
3
  if (isMicroMips()) {
250
2
    uint64_t GotPlt = InX::GotPlt->getVA();
251
2
    uint64_t Plt = InX::Plt->getVA();
252
2
    // Overwrite trap instructions written by Writer::writeTrapInstr.
253
2
    memset(Buf, 0, PltHeaderSize);
254
2
255
2
    write16<E>(Buf, isMipsR6() ? 
0x78601
:
0x79801
); // addiupc v1, (GOTPLT) - .
256
2
    write16<E>(Buf + 4, 0xff23);    // lw      $25, 0($3)
257
2
    write16<E>(Buf + 8, 0x0535);    // subu16  $2,  $2, $3
258
2
    write16<E>(Buf + 10, 0x2525);   // srl16   $2,  $2, 2
259
2
    write16<E>(Buf + 12, 0x3302);   // addiu   $24, $2, -2
260
2
    write16<E>(Buf + 14, 0xfffe);
261
2
    write16<E>(Buf + 16, 0x0dff);   // move    $15, $31
262
2
    if (isMipsR6()) {
263
1
      write16<E>(Buf + 18, 0x0f83); // move    $28, $3
264
1
      write16<E>(Buf + 20, 0x472b); // jalrc   $25
265
1
      write16<E>(Buf + 22, 0x0c00); // nop
266
1
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPlt - Plt);
267
1
    } else {
268
1
      write16<E>(Buf + 18, 0x45f9); // jalrc   $25
269
1
      write16<E>(Buf + 20, 0x0f83); // move    $28, $3
270
1
      write16<E>(Buf + 22, 0x0c00); // nop
271
1
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPlt - Plt);
272
1
    }
273
2
    return;
274
2
  }
275
1
276
1
  if (Config->MipsN32Abi) {
277
0
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
278
0
    write32<E>(Buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
279
0
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
280
0
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
281
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
282
0
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
283
1
  } else if (ELFT::Is64Bits) {
284
0
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
285
0
    write32<E>(Buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
286
0
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
287
0
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
288
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
289
0
    write32<E>(Buf + 20, 0x0018c0c2); // srl   $24, $24, 3
290
1
  } else {
291
1
    write32<E>(Buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
292
1
    write32<E>(Buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
293
1
    write32<E>(Buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
294
1
    write32<E>(Buf + 12, 0x031cc023); // subu  $24, $24, $28
295
1
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
296
1
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
297
1
  }
298
1
299
1
  write32<E>(Buf + 24, 0x0320f809); // jalr  $25
300
1
  write32<E>(Buf + 28, 0x2718fffe); // subu  $24, $24, 2
301
1
302
1
  uint64_t GotPlt = InX::GotPlt->getVA();
303
1
  writeRelocation<E>(Buf, GotPlt + 0x8000, 16, 16);
304
1
  writeRelocation<E>(Buf + 4, GotPlt, 16, 0);
305
1
  writeRelocation<E>(Buf + 8, GotPlt, 16, 0);
306
1
}
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
247
1
template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
248
1
  const endianness E = ELFT::TargetEndianness;
249
1
  if (isMicroMips()) {
250
0
    uint64_t GotPlt = InX::GotPlt->getVA();
251
0
    uint64_t Plt = InX::Plt->getVA();
252
0
    // Overwrite trap instructions written by Writer::writeTrapInstr.
253
0
    memset(Buf, 0, PltHeaderSize);
254
0
255
0
    write16<E>(Buf, isMipsR6() ? 0x7860 : 0x7980);  // addiupc v1, (GOTPLT) - .
256
0
    write16<E>(Buf + 4, 0xff23);    // lw      $25, 0($3)
257
0
    write16<E>(Buf + 8, 0x0535);    // subu16  $2,  $2, $3
258
0
    write16<E>(Buf + 10, 0x2525);   // srl16   $2,  $2, 2
259
0
    write16<E>(Buf + 12, 0x3302);   // addiu   $24, $2, -2
260
0
    write16<E>(Buf + 14, 0xfffe);
261
0
    write16<E>(Buf + 16, 0x0dff);   // move    $15, $31
262
0
    if (isMipsR6()) {
263
0
      write16<E>(Buf + 18, 0x0f83); // move    $28, $3
264
0
      write16<E>(Buf + 20, 0x472b); // jalrc   $25
265
0
      write16<E>(Buf + 22, 0x0c00); // nop
266
0
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPlt - Plt);
267
0
    } else {
268
0
      write16<E>(Buf + 18, 0x45f9); // jalrc   $25
269
0
      write16<E>(Buf + 20, 0x0f83); // move    $28, $3
270
0
      write16<E>(Buf + 22, 0x0c00); // nop
271
0
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPlt - Plt);
272
0
    }
273
0
    return;
274
0
  }
275
1
276
1
  if (Config->MipsN32Abi) {
277
0
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
278
0
    write32<E>(Buf + 4, 0x8dd90000);  // lw    $25, %lo(&GOTPLT[0])($14)
279
0
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
280
0
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
281
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
282
0
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
283
1
  } else if (ELFT::Is64Bits) {
284
1
    write32<E>(Buf, 0x3c0e0000);      // lui   $14, %hi(&GOTPLT[0])
285
1
    write32<E>(Buf + 4, 0xddd90000);  // ld    $25, %lo(&GOTPLT[0])($14)
286
1
    write32<E>(Buf + 8, 0x25ce0000);  // addiu $14, $14, %lo(&GOTPLT[0])
287
1
    write32<E>(Buf + 12, 0x030ec023); // subu  $24, $24, $14
288
1
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
289
1
    write32<E>(Buf + 20, 0x0018c0c2); // srl   $24, $24, 3
290
1
  } else {
291
0
    write32<E>(Buf, 0x3c1c0000);      // lui   $28, %hi(&GOTPLT[0])
292
0
    write32<E>(Buf + 4, 0x8f990000);  // lw    $25, %lo(&GOTPLT[0])($28)
293
0
    write32<E>(Buf + 8, 0x279c0000);  // addiu $28, $28, %lo(&GOTPLT[0])
294
0
    write32<E>(Buf + 12, 0x031cc023); // subu  $24, $24, $28
295
0
    write32<E>(Buf + 16, 0x03e07825); // move  $15, $31
296
0
    write32<E>(Buf + 20, 0x0018c082); // srl   $24, $24, 2
297
0
  }
298
1
299
1
  write32<E>(Buf + 24, 0x0320f809); // jalr  $25
300
1
  write32<E>(Buf + 28, 0x2718fffe); // subu  $24, $24, 2
301
1
302
1
  uint64_t GotPlt = InX::GotPlt->getVA();
303
1
  writeRelocation<E>(Buf, GotPlt + 0x8000, 16, 16);
304
1
  writeRelocation<E>(Buf + 4, GotPlt, 16, 0);
305
1
  writeRelocation<E>(Buf + 8, GotPlt, 16, 0);
306
1
}
307
308
template <class ELFT>
309
void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
310
                          uint64_t PltEntryAddr, int32_t Index,
311
5
                          unsigned RelOff) const {
312
5
  const endianness E = ELFT::TargetEndianness;
313
5
  if (isMicroMips()) {
314
3
    // Overwrite trap instructions written by Writer::writeTrapInstr.
315
3
    memset(Buf, 0, PltEntrySize);
316
3
317
3
    if (isMipsR6()) {
318
1
      write16<E>(Buf, 0x7840);      // addiupc $2, (GOTPLT) - .
319
1
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
320
1
      write16<E>(Buf + 8, 0x0f02);  // move $24, $2
321
1
      write16<E>(Buf + 10, 0x4723); // jrc $25 / jr16 $25
322
1
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPltEntryAddr - PltEntryAddr);
323
2
    } else {
324
2
      write16<E>(Buf, 0x7900);      // addiupc $2, (GOTPLT) - .
325
2
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
326
2
      write16<E>(Buf + 8, 0x4599);  // jrc $25 / jr16 $25
327
2
      write16<E>(Buf + 10, 0x0f02); // move $24, $2
328
2
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPltEntryAddr - PltEntryAddr);
329
2
    }
330
3
    return;
331
3
  }
332
2
333
2
  write32<E>(Buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
334
2
  write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15)
335
2
  write32<E>(Buf + 8, isMipsR6() ? 
0x032000090
: 0x03200008); // jr $25
336
2
  write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry)
337
2
  writeRelocation<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16);
338
2
  writeRelocation<E>(Buf + 4, GotPltEntryAddr, 16, 0);
339
2
  writeRelocation<E>(Buf + 12, GotPltEntryAddr, 16, 0);
340
2
}
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
311
1
                          unsigned RelOff) const {
312
1
  const endianness E = ELFT::TargetEndianness;
313
1
  if (isMicroMips()) {
314
1
    // Overwrite trap instructions written by Writer::writeTrapInstr.
315
1
    memset(Buf, 0, PltEntrySize);
316
1
317
1
    if (isMipsR6()) {
318
0
      write16<E>(Buf, 0x7840);      // addiupc $2, (GOTPLT) - .
319
0
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
320
0
      write16<E>(Buf + 8, 0x0f02);  // move $24, $2
321
0
      write16<E>(Buf + 10, 0x4723); // jrc $25 / jr16 $25
322
0
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPltEntryAddr - PltEntryAddr);
323
1
    } else {
324
1
      write16<E>(Buf, 0x7900);      // addiupc $2, (GOTPLT) - .
325
1
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
326
1
      write16<E>(Buf + 8, 0x4599);  // jrc $25 / jr16 $25
327
1
      write16<E>(Buf + 10, 0x0f02); // move $24, $2
328
1
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPltEntryAddr - PltEntryAddr);
329
1
    }
330
1
    return;
331
1
  }
332
0
333
0
  write32<E>(Buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
334
0
  write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15)
335
0
  write32<E>(Buf + 8, isMipsR6() ? 0x03200009 : 0x03200008);  // jr  $25
336
0
  write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry)
337
0
  writeRelocation<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16);
338
0
  writeRelocation<E>(Buf + 4, GotPltEntryAddr, 16, 0);
339
0
  writeRelocation<E>(Buf + 12, GotPltEntryAddr, 16, 0);
340
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
311
3
                          unsigned RelOff) const {
312
3
  const endianness E = ELFT::TargetEndianness;
313
3
  if (isMicroMips()) {
314
2
    // Overwrite trap instructions written by Writer::writeTrapInstr.
315
2
    memset(Buf, 0, PltEntrySize);
316
2
317
2
    if (isMipsR6()) {
318
1
      write16<E>(Buf, 0x7840);      // addiupc $2, (GOTPLT) - .
319
1
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
320
1
      write16<E>(Buf + 8, 0x0f02);  // move $24, $2
321
1
      write16<E>(Buf + 10, 0x4723); // jrc $25 / jr16 $25
322
1
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPltEntryAddr - PltEntryAddr);
323
1
    } else {
324
1
      write16<E>(Buf, 0x7900);      // addiupc $2, (GOTPLT) - .
325
1
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
326
1
      write16<E>(Buf + 8, 0x4599);  // jrc $25 / jr16 $25
327
1
      write16<E>(Buf + 10, 0x0f02); // move $24, $2
328
1
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPltEntryAddr - PltEntryAddr);
329
1
    }
330
2
    return;
331
2
  }
332
1
333
1
  write32<E>(Buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
334
1
  write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15)
335
1
  write32<E>(Buf + 8, isMipsR6() ? 
0x032000090
: 0x03200008); // jr $25
336
1
  write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry)
337
1
  writeRelocation<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16);
338
1
  writeRelocation<E>(Buf + 4, GotPltEntryAddr, 16, 0);
339
1
  writeRelocation<E>(Buf + 12, GotPltEntryAddr, 16, 0);
340
1
}
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
311
1
                          unsigned RelOff) const {
312
1
  const endianness E = ELFT::TargetEndianness;
313
1
  if (isMicroMips()) {
314
0
    // Overwrite trap instructions written by Writer::writeTrapInstr.
315
0
    memset(Buf, 0, PltEntrySize);
316
0
317
0
    if (isMipsR6()) {
318
0
      write16<E>(Buf, 0x7840);      // addiupc $2, (GOTPLT) - .
319
0
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
320
0
      write16<E>(Buf + 8, 0x0f02);  // move $24, $2
321
0
      write16<E>(Buf + 10, 0x4723); // jrc $25 / jr16 $25
322
0
      relocateOne(Buf, R_MICROMIPS_PC19_S2, GotPltEntryAddr - PltEntryAddr);
323
0
    } else {
324
0
      write16<E>(Buf, 0x7900);      // addiupc $2, (GOTPLT) - .
325
0
      write16<E>(Buf + 4, 0xff22);  // lw $25, 0($2)
326
0
      write16<E>(Buf + 8, 0x4599);  // jrc $25 / jr16 $25
327
0
      write16<E>(Buf + 10, 0x0f02); // move $24, $2
328
0
      relocateOne(Buf, R_MICROMIPS_PC23_S2, GotPltEntryAddr - PltEntryAddr);
329
0
    }
330
0
    return;
331
0
  }
332
1
333
1
  write32<E>(Buf, 0x3c0f0000);     // lui   $15, %hi(.got.plt entry)
334
1
  write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15)
335
1
  write32<E>(Buf + 8, isMipsR6() ? 
0x032000090
: 0x03200008); // jr $25
336
1
  write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry)
337
1
  writeRelocation<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16);
338
1
  writeRelocation<E>(Buf + 4, GotPltEntryAddr, 16, 0);
339
1
  writeRelocation<E>(Buf + 12, GotPltEntryAddr, 16, 0);
340
1
}
341
342
template <class ELFT>
343
bool MIPS<ELFT>::needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
344
10.1k
                            uint64_t BranchAddr, const Symbol &S) const {
345
10.1k
  // Any MIPS PIC code function is invoked with its address in register $t9.
346
10.1k
  // So if we have a branch instruction from non-PIC code to the PIC one
347
10.1k
  // we cannot make the jump directly and need to create a small stubs
348
10.1k
  // to save the target function address.
349
10.1k
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
350
10.1k
  if (Type != R_MIPS_26 && 
Type != R_MICROMIPS_26_S110.1k
&&
351
10.1k
      
Type != R_MICROMIPS_PC26_S110.1k
)
352
10.1k
    return false;
353
37
  auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
354
37
  if (!F)
355
0
    return false;
356
37
  // If current file has PIC code, LA25 stub is not required.
357
37
  if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
358
0
    return false;
359
37
  auto *D = dyn_cast<Defined>(&S);
360
37
  // LA25 is required if target file has PIC code
361
37
  // or target symbol is a PIC symbol.
362
37
  return D && 
isMipsPIC<ELFT>(D)32
;
363
37
}
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
344
2
                            uint64_t BranchAddr, const Symbol &S) const {
345
2
  // Any MIPS PIC code function is invoked with its address in register $t9.
346
2
  // So if we have a branch instruction from non-PIC code to the PIC one
347
2
  // we cannot make the jump directly and need to create a small stubs
348
2
  // to save the target function address.
349
2
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
350
2
  if (Type != R_MIPS_26 && Type != R_MICROMIPS_26_S1 &&
351
2
      
Type != R_MICROMIPS_PC26_S10
)
352
0
    return false;
353
2
  auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
354
2
  if (!F)
355
0
    return false;
356
2
  // If current file has PIC code, LA25 stub is not required.
357
2
  if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
358
0
    return false;
359
2
  auto *D = dyn_cast<Defined>(&S);
360
2
  // LA25 is required if target file has PIC code
361
2
  // or target symbol is a PIC symbol.
362
2
  return D && 
isMipsPIC<ELFT>(D)1
;
363
2
}
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
344
114
                            uint64_t BranchAddr, const Symbol &S) const {
345
114
  // Any MIPS PIC code function is invoked with its address in register $t9.
346
114
  // So if we have a branch instruction from non-PIC code to the PIC one
347
114
  // we cannot make the jump directly and need to create a small stubs
348
114
  // to save the target function address.
349
114
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
350
114
  if (Type != R_MIPS_26 && 
Type != R_MICROMIPS_26_S183
&&
351
114
      
Type != R_MICROMIPS_PC26_S180
)
352
80
    return false;
353
34
  auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
354
34
  if (!F)
355
0
    return false;
356
34
  // If current file has PIC code, LA25 stub is not required.
357
34
  if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
358
0
    return false;
359
34
  auto *D = dyn_cast<Defined>(&S);
360
34
  // LA25 is required if target file has PIC code
361
34
  // or target symbol is a PIC symbol.
362
34
  return D && 
isMipsPIC<ELFT>(D)31
;
363
34
}
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
344
10.0k
                            uint64_t BranchAddr, const Symbol &S) const {
345
10.0k
  // Any MIPS PIC code function is invoked with its address in register $t9.
346
10.0k
  // So if we have a branch instruction from non-PIC code to the PIC one
347
10.0k
  // we cannot make the jump directly and need to create a small stubs
348
10.0k
  // to save the target function address.
349
10.0k
  // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
350
10.0k
  if (Type != R_MIPS_26 && 
Type != R_MICROMIPS_26_S110.0k
&&
351
10.0k
      
Type != R_MICROMIPS_PC26_S110.0k
)
352
10.0k
    return false;
353
1
  auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
354
1
  if (!F)
355
0
    return false;
356
1
  // If current file has PIC code, LA25 stub is not required.
357
1
  if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
358
0
    return false;
359
1
  auto *D = dyn_cast<Defined>(&S);
360
1
  // LA25 is required if target file has PIC code
361
1
  // or target symbol is a PIC symbol.
362
1
  return D && 
isMipsPIC<ELFT>(D)0
;
363
1
}
364
365
template <class ELFT>
366
145
int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
367
145
  const endianness E = ELFT::TargetEndianness;
368
145
  switch (Type) {
369
145
  case R_MIPS_32:
370
15
  case R_MIPS_GPREL32:
371
15
  case R_MIPS_TLS_DTPREL32:
372
15
  case R_MIPS_TLS_TPREL32:
373
15
    return SignExtend64<32>(read32<E>(Buf));
374
27
  case R_MIPS_26:
375
27
    // FIXME (simon): If the relocation target symbol is not a PLT entry
376
27
    // we should use another expression for calculation:
377
27
    // ((A << 2) | (P & 0xf0000000)) >> 2
378
27
    return SignExtend64<28>(read32<E>(Buf) << 2);
379
24
  case R_MIPS_GOT16:
380
24
  case R_MIPS_HI16:
381
24
  case R_MIPS_PCHI16:
382
24
    return SignExtend64<16>(read32<E>(Buf)) << 16;
383
34
  case R_MIPS_GPREL16:
384
34
  case R_MIPS_LO16:
385
34
  case R_MIPS_PCLO16:
386
34
  case R_MIPS_TLS_DTPREL_HI16:
387
34
  case R_MIPS_TLS_DTPREL_LO16:
388
34
  case R_MIPS_TLS_TPREL_HI16:
389
34
  case R_MIPS_TLS_TPREL_LO16:
390
34
    return SignExtend64<16>(read32<E>(Buf));
391
34
  case R_MICROMIPS_GOT16:
392
3
  case R_MICROMIPS_HI16:
393
3
    return SignExtend64<16>(readShuffle<E>(Buf)) << 16;
394
4
  case R_MICROMIPS_GPREL16:
395
4
  case R_MICROMIPS_LO16:
396
4
  case R_MICROMIPS_TLS_DTPREL_HI16:
397
4
  case R_MICROMIPS_TLS_DTPREL_LO16:
398
4
  case R_MICROMIPS_TLS_TPREL_HI16:
399
4
  case R_MICROMIPS_TLS_TPREL_LO16:
400
4
    return SignExtend64<16>(readShuffle<E>(Buf));
401
4
  case R_MICROMIPS_GPREL7_S2:
402
0
    return SignExtend64<9>(readShuffle<E>(Buf) << 2);
403
4
  case R_MIPS_PC16:
404
1
    return SignExtend64<18>(read32<E>(Buf) << 2);
405
4
  case R_MIPS_PC19_S2:
406
1
    return SignExtend64<21>(read32<E>(Buf) << 2);
407
4
  case R_MIPS_PC21_S2:
408
1
    return SignExtend64<23>(read32<E>(Buf) << 2);
409
4
  case R_MIPS_PC26_S2:
410
1
    return SignExtend64<28>(read32<E>(Buf) << 2);
411
4
  case R_MIPS_PC32:
412
1
    return SignExtend64<32>(read32<E>(Buf));
413
5
  case R_MICROMIPS_26_S1:
414
5
    return SignExtend64<27>(readShuffle<E>(Buf) << 1);
415
4
  case R_MICROMIPS_PC7_S1:
416
1
    return SignExtend64<8>(read16<E>(Buf) << 1);
417
4
  case R_MICROMIPS_PC10_S1:
418
1
    return SignExtend64<11>(read16<E>(Buf) << 1);
419
4
  case R_MICROMIPS_PC16_S1:
420
1
    return SignExtend64<17>(readShuffle<E>(Buf) << 1);
421
4
  case R_MICROMIPS_PC18_S3:
422
0
    return SignExtend64<21>(readShuffle<E>(Buf) << 3);
423
4
  case R_MICROMIPS_PC19_S2:
424
0
    return SignExtend64<21>(readShuffle<E>(Buf) << 2);
425
4
  case R_MICROMIPS_PC21_S1:
426
0
    return SignExtend64<22>(readShuffle<E>(Buf) << 1);
427
4
  case R_MICROMIPS_PC23_S2:
428
0
    return SignExtend64<25>(readShuffle<E>(Buf) << 2);
429
4
  case R_MICROMIPS_PC26_S1:
430
0
    return SignExtend64<27>(readShuffle<E>(Buf) << 1);
431
25
  default:
432
25
    return 0;
433
0
  }
434
0
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::getImplicitAddend(unsigned char const*, unsigned int) const
Line
Count
Source
366
4
int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
367
4
  const endianness E = ELFT::TargetEndianness;
368
4
  switch (Type) {
369
4
  case R_MIPS_32:
370
2
  case R_MIPS_GPREL32:
371
2
  case R_MIPS_TLS_DTPREL32:
372
2
  case R_MIPS_TLS_TPREL32:
373
2
    return SignExtend64<32>(read32<E>(Buf));
374
2
  case R_MIPS_26:
375
0
    // FIXME (simon): If the relocation target symbol is not a PLT entry
376
0
    // we should use another expression for calculation:
377
0
    // ((A << 2) | (P & 0xf0000000)) >> 2
378
0
    return SignExtend64<28>(read32<E>(Buf) << 2);
379
2
  case R_MIPS_GOT16:
380
0
  case R_MIPS_HI16:
381
0
  case R_MIPS_PCHI16:
382
0
    return SignExtend64<16>(read32<E>(Buf)) << 16;
383
0
  case R_MIPS_GPREL16:
384
0
  case R_MIPS_LO16:
385
0
  case R_MIPS_PCLO16:
386
0
  case R_MIPS_TLS_DTPREL_HI16:
387
0
  case R_MIPS_TLS_DTPREL_LO16:
388
0
  case R_MIPS_TLS_TPREL_HI16:
389
0
  case R_MIPS_TLS_TPREL_LO16:
390
0
    return SignExtend64<16>(read32<E>(Buf));
391
0
  case R_MICROMIPS_GOT16:
392
0
  case R_MICROMIPS_HI16:
393
0
    return SignExtend64<16>(readShuffle<E>(Buf)) << 16;
394
0
  case R_MICROMIPS_GPREL16:
395
0
  case R_MICROMIPS_LO16:
396
0
  case R_MICROMIPS_TLS_DTPREL_HI16:
397
0
  case R_MICROMIPS_TLS_DTPREL_LO16:
398
0
  case R_MICROMIPS_TLS_TPREL_HI16:
399
0
  case R_MICROMIPS_TLS_TPREL_LO16:
400
0
    return SignExtend64<16>(readShuffle<E>(Buf));
401
0
  case R_MICROMIPS_GPREL7_S2:
402
0
    return SignExtend64<9>(readShuffle<E>(Buf) << 2);
403
0
  case R_MIPS_PC16:
404
0
    return SignExtend64<18>(read32<E>(Buf) << 2);
405
0
  case R_MIPS_PC19_S2:
406
0
    return SignExtend64<21>(read32<E>(Buf) << 2);
407
0
  case R_MIPS_PC21_S2:
408
0
    return SignExtend64<23>(read32<E>(Buf) << 2);
409
0
  case R_MIPS_PC26_S2:
410
0
    return SignExtend64<28>(read32<E>(Buf) << 2);
411
0
  case R_MIPS_PC32:
412
0
    return SignExtend64<32>(read32<E>(Buf));
413
2
  case R_MICROMIPS_26_S1:
414
2
    return SignExtend64<27>(readShuffle<E>(Buf) << 1);
415
0
  case R_MICROMIPS_PC7_S1:
416
0
    return SignExtend64<8>(read16<E>(Buf) << 1);
417
0
  case R_MICROMIPS_PC10_S1:
418
0
    return SignExtend64<11>(read16<E>(Buf) << 1);
419
0
  case R_MICROMIPS_PC16_S1:
420
0
    return SignExtend64<17>(readShuffle<E>(Buf) << 1);
421
0
  case R_MICROMIPS_PC18_S3:
422
0
    return SignExtend64<21>(readShuffle<E>(Buf) << 3);
423
0
  case R_MICROMIPS_PC19_S2:
424
0
    return SignExtend64<21>(readShuffle<E>(Buf) << 2);
425
0
  case R_MICROMIPS_PC21_S1:
426
0
    return SignExtend64<22>(readShuffle<E>(Buf) << 1);
427
0
  case R_MICROMIPS_PC23_S2:
428
0
    return SignExtend64<25>(readShuffle<E>(Buf) << 2);
429
0
  case R_MICROMIPS_PC26_S1:
430
0
    return SignExtend64<27>(readShuffle<E>(Buf) << 1);
431
0
  default:
432
0
    return 0;
433
0
  }
434
0
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::getImplicitAddend(unsigned char const*, unsigned int) const
Line
Count
Source
366
141
int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, RelType Type) const {
367
141
  const endianness E = ELFT::TargetEndianness;
368
141
  switch (Type) {
369
141
  case R_MIPS_32:
370
13
  case R_MIPS_GPREL32:
371
13
  case R_MIPS_TLS_DTPREL32:
372
13
  case R_MIPS_TLS_TPREL32:
373
13
    return SignExtend64<32>(read32<E>(Buf));
374
27
  case R_MIPS_26:
375
27
    // FIXME (simon): If the relocation target symbol is not a PLT entry
376
27
    // we should use another expression for calculation:
377
27
    // ((A << 2) | (P & 0xf0000000)) >> 2
378
27
    return SignExtend64<28>(read32<E>(Buf) << 2);
379
24
  case R_MIPS_GOT16:
380
24
  case R_MIPS_HI16:
381
24
  case R_MIPS_PCHI16:
382
24
    return SignExtend64<16>(read32<E>(Buf)) << 16;
383
34
  case R_MIPS_GPREL16:
384
34
  case R_MIPS_LO16:
385
34
  case R_MIPS_PCLO16:
386
34
  case R_MIPS_TLS_DTPREL_HI16:
387
34
  case R_MIPS_TLS_DTPREL_LO16:
388
34
  case R_MIPS_TLS_TPREL_HI16:
389
34
  case R_MIPS_TLS_TPREL_LO16:
390
34
    return SignExtend64<16>(read32<E>(Buf));
391
34
  case R_MICROMIPS_GOT16:
392
3
  case R_MICROMIPS_HI16:
393
3
    return SignExtend64<16>(readShuffle<E>(Buf)) << 16;
394
4
  case R_MICROMIPS_GPREL16:
395
4
  case R_MICROMIPS_LO16:
396
4
  case R_MICROMIPS_TLS_DTPREL_HI16:
397
4
  case R_MICROMIPS_TLS_DTPREL_LO16:
398
4
  case R_MICROMIPS_TLS_TPREL_HI16:
399
4
  case R_MICROMIPS_TLS_TPREL_LO16:
400
4
    return SignExtend64<16>(readShuffle<E>(Buf));
401
4
  case R_MICROMIPS_GPREL7_S2:
402
0
    return SignExtend64<9>(readShuffle<E>(Buf) << 2);
403
4
  case R_MIPS_PC16:
404
1
    return SignExtend64<18>(read32<E>(Buf) << 2);
405
4
  case R_MIPS_PC19_S2:
406
1
    return SignExtend64<21>(read32<E>(Buf) << 2);
407
4
  case R_MIPS_PC21_S2:
408
1
    return SignExtend64<23>(read32<E>(Buf) << 2);
409
4
  case R_MIPS_PC26_S2:
410
1
    return SignExtend64<28>(read32<E>(Buf) << 2);
411
4
  case R_MIPS_PC32:
412
1
    return SignExtend64<32>(read32<E>(Buf));
413
4
  case R_MICROMIPS_26_S1:
414
3
    return SignExtend64<27>(readShuffle<E>(Buf) << 1);
415
4
  case R_MICROMIPS_PC7_S1:
416
1
    return SignExtend64<8>(read16<E>(Buf) << 1);
417
4
  case R_MICROMIPS_PC10_S1:
418
1
    return SignExtend64<11>(read16<E>(Buf) << 1);
419
4
  case R_MICROMIPS_PC16_S1:
420
1
    return SignExtend64<17>(readShuffle<E>(Buf) << 1);
421
4
  case R_MICROMIPS_PC18_S3:
422
0
    return SignExtend64<21>(readShuffle<E>(Buf) << 3);
423
4
  case R_MICROMIPS_PC19_S2:
424
0
    return SignExtend64<21>(readShuffle<E>(Buf) << 2);
425
4
  case R_MICROMIPS_PC21_S1:
426
0
    return SignExtend64<22>(readShuffle<E>(Buf) << 1);
427
4
  case R_MICROMIPS_PC23_S2:
428
0
    return SignExtend64<25>(readShuffle<E>(Buf) << 2);
429
4
  case R_MICROMIPS_PC26_S1:
430
0
    return SignExtend64<27>(readShuffle<E>(Buf) << 1);
431
25
  default:
432
25
    return 0;
433
0
  }
434
0
}
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, true> >::getImplicitAddend(unsigned char const*, unsigned int) const
Unexecuted instantiation: Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, true> >::getImplicitAddend(unsigned char const*, unsigned int) const
435
436
static std::pair<uint32_t, uint64_t>
437
10.0k
calculateMipsRelChain(uint8_t *Loc, RelType Type, uint64_t Val) {
438
10.0k
  // MIPS N64 ABI packs multiple relocations into the single relocation
439
10.0k
  // record. In general, all up to three relocations can have arbitrary
440
10.0k
  // types. In fact, Clang and GCC uses only a few combinations. For now,
441
10.0k
  // we support two of them. That is allow to pass at least all LLVM
442
10.0k
  // test suite cases.
443
10.0k
  // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16
444
10.0k
  // <any relocation> / R_MIPS_64 / R_MIPS_NONE
445
10.0k
  // The first relocation is a 'real' relocation which is calculated
446
10.0k
  // using the corresponding symbol's value. The second and the third
447
10.0k
  // relocations used to modify result of the first one: extend it to
448
10.0k
  // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
449
10.0k
  // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
450
10.0k
  RelType Type2 = (Type >> 8) & 0xff;
451
10.0k
  RelType Type3 = (Type >> 16) & 0xff;
452
10.0k
  if (Type2 == R_MIPS_NONE && 
Type3 == R_MIPS_NONE10.0k
)
453
10.0k
    return std::make_pair(Type, Val);
454
8
  if (Type2 == R_MIPS_64 && 
Type3 == R_MIPS_NONE1
)
455
1
    return std::make_pair(Type2, Val);
456
7
  if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || 
Type3 == R_MIPS_LO162
))
457
7
    return std::make_pair(Type3, -Val);
458
0
  if (Type2 == R_MICROMIPS_SUB &&
459
0
      (Type3 == R_MICROMIPS_HI16 || Type3 == R_MICROMIPS_LO16))
460
0
    return std::make_pair(Type3, -Val);
461
0
  error(getErrorLocation(Loc) + "unsupported relocations combination " +
462
0
        Twine(Type));
463
0
  return std::make_pair(Type & 0xff, Val);
464
0
}
465
466
template <class ELFT>
467
10.1k
void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
468
10.1k
  const endianness E = ELFT::TargetEndianness;
469
10.1k
470
10.1k
  // Thread pointer and DRP offsets from the start of TLS data area.
471
10.1k
  // https://www.linux-mips.org/wiki/NPTL
472
10.1k
  if (Type == R_MIPS_TLS_DTPREL_HI16 || 
Type == R_MIPS_TLS_DTPREL_LO1610.1k
||
473
10.1k
      
Type == R_MIPS_TLS_DTPREL3210.1k
||
Type == R_MIPS_TLS_DTPREL6410.1k
||
474
10.1k
      
Type == R_MICROMIPS_TLS_DTPREL_HI1610.1k
||
475
10.1k
      
Type == R_MICROMIPS_TLS_DTPREL_LO1610.1k
) {
476
3
    Val -= 0x8000;
477
10.1k
  } else if (Type == R_MIPS_TLS_TPREL_HI16 || 
Type == R_MIPS_TLS_TPREL_LO1610.1k
||
478
10.1k
             
Type == R_MIPS_TLS_TPREL3210.1k
||
Type == R_MIPS_TLS_TPREL6410.1k
||
479
10.1k
             
Type == R_MICROMIPS_TLS_TPREL_HI1610.1k
||
480
10.1k
             
Type == R_MICROMIPS_TLS_TPREL_LO1610.1k
) {
481
3
    Val -= 0x7000;
482
3
  }
483
10.1k
484
10.1k
  if (ELFT::Is64Bits || 
Config->MipsN32Abi171
)
485
10.0k
    std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val);
486
10.1k
487
10.1k
  switch (Type) {
488
10.1k
  case R_MIPS_32:
489
14
  case R_MIPS_GPREL32:
490
14
  case R_MIPS_TLS_DTPREL32:
491
14
  case R_MIPS_TLS_TPREL32:
492
14
    write32<E>(Loc, Val);
493
14
    break;
494
14
  case R_MIPS_64:
495
1
  case R_MIPS_TLS_DTPREL64:
496
1
  case R_MIPS_TLS_TPREL64:
497
1
    write64<E>(Loc, Val);
498
1
    break;
499
28
  case R_MIPS_26:
500
28
    writeRelocation<E>(Loc, Val, 26, 2);
501
28
    break;
502
19
  case R_MIPS_GOT16:
503
19
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
504
19
    // is updated addend (not a GOT index). In that case write high 16 bits
505
19
    // to store a correct addend value.
506
19
    if (Config->Relocatable) {
507
0
      writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
508
19
    } else {
509
19
      checkInt<16>(Loc, Val, Type);
510
19
      writeRelocation<E>(Loc, Val, 16, 0);
511
19
    }
512
19
    break;
513
2
  case R_MICROMIPS_GOT16:
514
2
    if (Config->Relocatable) {
515
0
      writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
516
2
    } else {
517
2
      checkInt<16>(Loc, Val, Type);
518
2
      writeMicroRelocation32<E>(Loc, Val, 16, 0);
519
2
    }
520
2
    break;
521
10.0k
  case R_MIPS_CALL16:
522
10.0k
  case R_MIPS_GOT_DISP:
523
10.0k
  case R_MIPS_GOT_PAGE:
524
10.0k
  case R_MIPS_GPREL16:
525
10.0k
  case R_MIPS_TLS_GD:
526
10.0k
  case R_MIPS_TLS_GOTTPREL:
527
10.0k
  case R_MIPS_TLS_LDM:
528
10.0k
    checkInt<16>(Loc, Val, Type);
529
10.0k
    LLVM_FALLTHROUGH;
530
10.0k
  case R_MIPS_CALL_LO16:
531
10.0k
  case R_MIPS_GOT_LO16:
532
10.0k
  case R_MIPS_GOT_OFST:
533
10.0k
  case R_MIPS_LO16:
534
10.0k
  case R_MIPS_PCLO16:
535
10.0k
  case R_MIPS_TLS_DTPREL_LO16:
536
10.0k
  case R_MIPS_TLS_TPREL_LO16:
537
10.0k
    writeRelocation<E>(Loc, Val, 16, 0);
538
10.0k
    break;
539
10.0k
  case R_MICROMIPS_GOT_DISP:
540
0
  case R_MICROMIPS_GOT_PAGE:
541
0
  case R_MICROMIPS_GPREL16:
542
0
  case R_MICROMIPS_TLS_GD:
543
0
  case R_MICROMIPS_TLS_LDM:
544
0
    checkInt<16>(Loc, Val, Type);
545
0
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
546
0
    break;
547
6
  case R_MICROMIPS_CALL16:
548
6
  case R_MICROMIPS_CALL_LO16:
549
6
  case R_MICROMIPS_GOT_OFST:
550
6
  case R_MICROMIPS_LO16:
551
6
  case R_MICROMIPS_TLS_DTPREL_LO16:
552
6
  case R_MICROMIPS_TLS_GOTTPREL:
553
6
  case R_MICROMIPS_TLS_TPREL_LO16:
554
6
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
555
6
    break;
556
6
  case R_MICROMIPS_GPREL7_S2:
557
0
    checkInt<7>(Loc, Val, Type);
558
0
    writeMicroRelocation32<E>(Loc, Val, 7, 2);
559
0
    break;
560
36
  case R_MIPS_CALL_HI16:
561
36
  case R_MIPS_GOT_HI16:
562
36
  case R_MIPS_HI16:
563
36
  case R_MIPS_PCHI16:
564
36
  case R_MIPS_TLS_DTPREL_HI16:
565
36
  case R_MIPS_TLS_TPREL_HI16:
566
36
    writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
567
36
    break;
568
36
  case R_MICROMIPS_CALL_HI16:
569
3
  case R_MICROMIPS_GOT_HI16:
570
3
  case R_MICROMIPS_HI16:
571
3
  case R_MICROMIPS_TLS_DTPREL_HI16:
572
3
  case R_MICROMIPS_TLS_TPREL_HI16:
573
3
    writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
574
3
    break;
575
3
  case R_MIPS_HIGHER:
576
2
    writeRelocation<E>(Loc, Val + 0x80008000, 16, 32);
577
2
    break;
578
3
  case R_MIPS_HIGHEST:
579
2
    writeRelocation<E>(Loc, Val + 0x800080008000, 16, 48);
580
2
    break;
581
3
  case R_MICROMIPS_HIGHER:
582
0
    writeMicroRelocation32<E>(Loc, Val + 0x80008000, 16, 32);
583
0
    break;
584
3
  case R_MICROMIPS_HIGHEST:
585
0
    writeMicroRelocation32<E>(Loc, Val + 0x800080008000, 16, 48);
586
0
    break;
587
3
  case R_MIPS_JALR:
588
0
  case R_MICROMIPS_JALR:
589
0
    // Ignore this optimization relocation for now
590
0
    break;
591
1
  case R_MIPS_PC16:
592
1
    checkAlignment<4>(Loc, Val, Type);
593
1
    checkInt<18>(Loc, Val, Type);
594
1
    writeRelocation<E>(Loc, Val, 16, 2);
595
1
    break;
596
1
  case R_MIPS_PC19_S2:
597
1
    checkAlignment<4>(Loc, Val, Type);
598
1
    checkInt<21>(Loc, Val, Type);
599
1
    writeRelocation<E>(Loc, Val, 19, 2);
600
1
    break;
601
1
  case R_MIPS_PC21_S2:
602
1
    checkAlignment<4>(Loc, Val, Type);
603
1
    checkInt<23>(Loc, Val, Type);
604
1
    writeRelocation<E>(Loc, Val, 21, 2);
605
1
    break;
606
1
  case R_MIPS_PC26_S2:
607
1
    checkAlignment<4>(Loc, Val, Type);
608
1
    checkInt<28>(Loc, Val, Type);
609
1
    writeRelocation<E>(Loc, Val, 26, 2);
610
1
    break;
611
2
  case R_MIPS_PC32:
612
2
    writeRelocation<E>(Loc, Val, 32, 0);
613
2
    break;
614
7
  case R_MICROMIPS_26_S1:
615
7
  case R_MICROMIPS_PC26_S1:
616
7
    checkInt<27>(Loc, Val, Type);
617
7
    writeMicroRelocation32<E>(Loc, Val, 26, 1);
618
7
    break;
619
7
  case R_MICROMIPS_PC7_S1:
620
1
    checkInt<8>(Loc, Val, Type);
621
1
    writeMicroRelocation16<E>(Loc, Val, 7, 1);
622
1
    break;
623
7
  case R_MICROMIPS_PC10_S1:
624
1
    checkInt<11>(Loc, Val, Type);
625
1
    writeMicroRelocation16<E>(Loc, Val, 10, 1);
626
1
    break;
627
7
  case R_MICROMIPS_PC16_S1:
628
1
    checkInt<17>(Loc, Val, Type);
629
1
    writeMicroRelocation32<E>(Loc, Val, 16, 1);
630
1
    break;
631
7
  case R_MICROMIPS_PC18_S3:
632
0
    checkInt<21>(Loc, Val, Type);
633
0
    writeMicroRelocation32<E>(Loc, Val, 18, 3);
634
0
    break;
635
7
  case R_MICROMIPS_PC19_S2:
636
2
    checkInt<21>(Loc, Val, Type);
637
2
    writeMicroRelocation32<E>(Loc, Val, 19, 2);
638
2
    break;
639
7
  case R_MICROMIPS_PC21_S1:
640
0
    checkInt<22>(Loc, Val, Type);
641
0
    writeMicroRelocation32<E>(Loc, Val, 21, 1);
642
0
    break;
643
7
  case R_MICROMIPS_PC23_S2:
644
4
    checkInt<25>(Loc, Val, Type);
645
4
    writeMicroRelocation32<E>(Loc, Val, 23, 2);
646
4
    break;
647
7
  default:
648
0
    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
649
10.1k
  }
650
10.1k
}
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
467
8
void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
468
8
  const endianness E = ELFT::TargetEndianness;
469
8
470
8
  // Thread pointer and DRP offsets from the start of TLS data area.
471
8
  // https://www.linux-mips.org/wiki/NPTL
472
8
  if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 ||
473
8
      Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64 ||
474
8
      Type == R_MICROMIPS_TLS_DTPREL_HI16 ||
475
8
      Type == R_MICROMIPS_TLS_DTPREL_LO16) {
476
0
    Val -= 0x8000;
477
8
  } else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 ||
478
8
             Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64 ||
479
8
             Type == R_MICROMIPS_TLS_TPREL_HI16 ||
480
8
             Type == R_MICROMIPS_TLS_TPREL_LO16) {
481
0
    Val -= 0x7000;
482
0
  }
483
8
484
8
  if (ELFT::Is64Bits || Config->MipsN32Abi)
485
0
    std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val);
486
8
487
8
  switch (Type) {
488
8
  case R_MIPS_32:
489
1
  case R_MIPS_GPREL32:
490
1
  case R_MIPS_TLS_DTPREL32:
491
1
  case R_MIPS_TLS_TPREL32:
492
1
    write32<E>(Loc, Val);
493
1
    break;
494
1
  case R_MIPS_64:
495
0
  case R_MIPS_TLS_DTPREL64:
496
0
  case R_MIPS_TLS_TPREL64:
497
0
    write64<E>(Loc, Val);
498
0
    break;
499
0
  case R_MIPS_26:
500
0
    writeRelocation<E>(Loc, Val, 26, 2);
501
0
    break;
502
0
  case R_MIPS_GOT16:
503
0
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
504
0
    // is updated addend (not a GOT index). In that case write high 16 bits
505
0
    // to store a correct addend value.
506
0
    if (Config->Relocatable) {
507
0
      writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
508
0
    } else {
509
0
      checkInt<16>(Loc, Val, Type);
510
0
      writeRelocation<E>(Loc, Val, 16, 0);
511
0
    }
512
0
    break;
513
0
  case R_MICROMIPS_GOT16:
514
0
    if (Config->Relocatable) {
515
0
      writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
516
0
    } else {
517
0
      checkInt<16>(Loc, Val, Type);
518
0
      writeMicroRelocation32<E>(Loc, Val, 16, 0);
519
0
    }
520
0
    break;
521
0
  case R_MIPS_CALL16:
522
0
  case R_MIPS_GOT_DISP:
523
0
  case R_MIPS_GOT_PAGE:
524
0
  case R_MIPS_GPREL16:
525
0
  case R_MIPS_TLS_GD:
526
0
  case R_MIPS_TLS_GOTTPREL:
527
0
  case R_MIPS_TLS_LDM:
528
0
    checkInt<16>(Loc, Val, Type);
529
0
    LLVM_FALLTHROUGH;
530
0
  case R_MIPS_CALL_LO16:
531
0
  case R_MIPS_GOT_LO16:
532
0
  case R_MIPS_GOT_OFST:
533
0
  case R_MIPS_LO16:
534
0
  case R_MIPS_PCLO16:
535
0
  case R_MIPS_TLS_DTPREL_LO16:
536
0
  case R_MIPS_TLS_TPREL_LO16:
537
0
    writeRelocation<E>(Loc, Val, 16, 0);
538
0
    break;
539
0
  case R_MICROMIPS_GOT_DISP:
540
0
  case R_MICROMIPS_GOT_PAGE:
541
0
  case R_MICROMIPS_GPREL16:
542
0
  case R_MICROMIPS_TLS_GD:
543
0
  case R_MICROMIPS_TLS_LDM:
544
0
    checkInt<16>(Loc, Val, Type);
545
0
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
546
0
    break;
547
1
  case R_MICROMIPS_CALL16:
548
1
  case R_MICROMIPS_CALL_LO16:
549
1
  case R_MICROMIPS_GOT_OFST:
550
1
  case R_MICROMIPS_LO16:
551
1
  case R_MICROMIPS_TLS_DTPREL_LO16:
552
1
  case R_MICROMIPS_TLS_GOTTPREL:
553
1
  case R_MICROMIPS_TLS_TPREL_LO16:
554
1
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
555
1
    break;
556
1
  case R_MICROMIPS_GPREL7_S2:
557
0
    checkInt<7>(Loc, Val, Type);
558
0
    writeMicroRelocation32<E>(Loc, Val, 7, 2);
559
0
    break;
560
1
  case R_MIPS_CALL_HI16:
561
0
  case R_MIPS_GOT_HI16:
562
0
  case R_MIPS_HI16:
563
0
  case R_MIPS_PCHI16:
564
0
  case R_MIPS_TLS_DTPREL_HI16:
565
0
  case R_MIPS_TLS_TPREL_HI16:
566
0
    writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
567
0
    break;
568
1
  case R_MICROMIPS_CALL_HI16:
569
1
  case R_MICROMIPS_GOT_HI16:
570
1
  case R_MICROMIPS_HI16:
571
1
  case R_MICROMIPS_TLS_DTPREL_HI16:
572
1
  case R_MICROMIPS_TLS_TPREL_HI16:
573
1
    writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
574
1
    break;
575
1
  case R_MIPS_HIGHER:
576
0
    writeRelocation<E>(Loc, Val + 0x80008000, 16, 32);
577
0
    break;
578
1
  case R_MIPS_HIGHEST:
579
0
    writeRelocation<E>(Loc, Val + 0x800080008000, 16, 48);
580
0
    break;
581
1
  case R_MICROMIPS_HIGHER:
582
0
    writeMicroRelocation32<E>(Loc, Val + 0x80008000, 16, 32);
583
0
    break;
584
1
  case R_MICROMIPS_HIGHEST:
585
0
    writeMicroRelocation32<E>(Loc, Val + 0x800080008000, 16, 48);
586
0
    break;
587
1
  case R_MIPS_JALR:
588
0
  case R_MICROMIPS_JALR:
589
0
    // Ignore this optimization relocation for now
590
0
    break;
591
0
  case R_MIPS_PC16:
592
0
    checkAlignment<4>(Loc, Val, Type);
593
0
    checkInt<18>(Loc, Val, Type);
594
0
    writeRelocation<E>(Loc, Val, 16, 2);
595
0
    break;
596
0
  case R_MIPS_PC19_S2:
597
0
    checkAlignment<4>(Loc, Val, Type);
598
0
    checkInt<21>(Loc, Val, Type);
599
0
    writeRelocation<E>(Loc, Val, 19, 2);
600
0
    break;
601
0
  case R_MIPS_PC21_S2:
602
0
    checkAlignment<4>(Loc, Val, Type);
603
0
    checkInt<23>(Loc, Val, Type);
604
0
    writeRelocation<E>(Loc, Val, 21, 2);
605
0
    break;
606
0
  case R_MIPS_PC26_S2:
607
0
    checkAlignment<4>(Loc, Val, Type);
608
0
    checkInt<28>(Loc, Val, Type);
609
0
    writeRelocation<E>(Loc, Val, 26, 2);
610
0
    break;
611
0
  case R_MIPS_PC32:
612
0
    writeRelocation<E>(Loc, Val, 32, 0);
613
0
    break;
614
3
  case R_MICROMIPS_26_S1:
615
3
  case R_MICROMIPS_PC26_S1:
616
3
    checkInt<27>(Loc, Val, Type);
617
3
    writeMicroRelocation32<E>(Loc, Val, 26, 1);
618
3
    break;
619
3
  case R_MICROMIPS_PC7_S1:
620
0
    checkInt<8>(Loc, Val, Type);
621
0
    writeMicroRelocation16<E>(Loc, Val, 7, 1);
622
0
    break;
623
3
  case R_MICROMIPS_PC10_S1:
624
0
    checkInt<11>(Loc, Val, Type);
625
0
    writeMicroRelocation16<E>(Loc, Val, 10, 1);
626
0
    break;
627
3
  case R_MICROMIPS_PC16_S1:
628
0
    checkInt<17>(Loc, Val, Type);
629
0
    writeMicroRelocation32<E>(Loc, Val, 16, 1);
630
0
    break;
631
3
  case R_MICROMIPS_PC18_S3:
632
0
    checkInt<21>(Loc, Val, Type);
633
0
    writeMicroRelocation32<E>(Loc, Val, 18, 3);
634
0
    break;
635
3
  case R_MICROMIPS_PC19_S2:
636
0
    checkInt<21>(Loc, Val, Type);
637
0
    writeMicroRelocation32<E>(Loc, Val, 19, 2);
638
0
    break;
639
3
  case R_MICROMIPS_PC21_S1:
640
0
    checkInt<22>(Loc, Val, Type);
641
0
    writeMicroRelocation32<E>(Loc, Val, 21, 1);
642
0
    break;
643
3
  case R_MICROMIPS_PC23_S2:
644
2
    checkInt<25>(Loc, Val, Type);
645
2
    writeMicroRelocation32<E>(Loc, Val, 23, 2);
646
2
    break;
647
3
  default:
648
0
    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
649
8
  }
650
8
}
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
467
163
void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
468
163
  const endianness E = ELFT::TargetEndianness;
469
163
470
163
  // Thread pointer and DRP offsets from the start of TLS data area.
471
163
  // https://www.linux-mips.org/wiki/NPTL
472
163
  if (Type == R_MIPS_TLS_DTPREL_HI16 || 
Type == R_MIPS_TLS_DTPREL_LO16162
||
473
163
      
Type == R_MIPS_TLS_DTPREL32161
||
Type == R_MIPS_TLS_DTPREL64160
||
474
163
      
Type == R_MICROMIPS_TLS_DTPREL_HI16160
||
475
163
      
Type == R_MICROMIPS_TLS_DTPREL_LO16160
) {
476
3
    Val -= 0x8000;
477
160
  } else if (Type == R_MIPS_TLS_TPREL_HI16 || 
Type == R_MIPS_TLS_TPREL_LO16159
||
478
160
             
Type == R_MIPS_TLS_TPREL32158
||
Type == R_MIPS_TLS_TPREL64157
||
479
160
             
Type == R_MICROMIPS_TLS_TPREL_HI16157
||
480
160
             
Type == R_MICROMIPS_TLS_TPREL_LO16157
) {
481
3
    Val -= 0x7000;
482
3
  }
483
163
484
163
  if (ELFT::Is64Bits || Config->MipsN32Abi)
485
0
    std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val);
486
163
487
163
  switch (Type) {
488
163
  case R_MIPS_32:
489
13
  case R_MIPS_GPREL32:
490
13
  case R_MIPS_TLS_DTPREL32:
491
13
  case R_MIPS_TLS_TPREL32:
492
13
    write32<E>(Loc, Val);
493
13
    break;
494
13
  case R_MIPS_64:
495
0
  case R_MIPS_TLS_DTPREL64:
496
0
  case R_MIPS_TLS_TPREL64:
497
0
    write64<E>(Loc, Val);
498
0
    break;
499
27
  case R_MIPS_26:
500
27
    writeRelocation<E>(Loc, Val, 26, 2);
501
27
    break;
502
19
  case R_MIPS_GOT16:
503
19
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
504
19
    // is updated addend (not a GOT index). In that case write high 16 bits
505
19
    // to store a correct addend value.
506
19
    if (Config->Relocatable) {
507
0
      writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
508
19
    } else {
509
19
      checkInt<16>(Loc, Val, Type);
510
19
      writeRelocation<E>(Loc, Val, 16, 0);
511
19
    }
512
19
    break;
513
2
  case R_MICROMIPS_GOT16:
514
2
    if (Config->Relocatable) {
515
0
      writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
516
2
    } else {
517
2
      checkInt<16>(Loc, Val, Type);
518
2
      writeMicroRelocation32<E>(Loc, Val, 16, 0);
519
2
    }
520
2
    break;
521
7
  case R_MIPS_CALL16:
522
7
  case R_MIPS_GOT_DISP:
523
7
  case R_MIPS_GOT_PAGE:
524
7
  case R_MIPS_GPREL16:
525
7
  case R_MIPS_TLS_GD:
526
7
  case R_MIPS_TLS_GOTTPREL:
527
7
  case R_MIPS_TLS_LDM:
528
7
    checkInt<16>(Loc, Val, Type);
529
7
    LLVM_FALLTHROUGH;
530
48
  case R_MIPS_CALL_LO16:
531
48
  case R_MIPS_GOT_LO16:
532
48
  case R_MIPS_GOT_OFST:
533
48
  case R_MIPS_LO16:
534
48
  case R_MIPS_PCLO16:
535
48
  case R_MIPS_TLS_DTPREL_LO16:
536
48
  case R_MIPS_TLS_TPREL_LO16:
537
48
    writeRelocation<E>(Loc, Val, 16, 0);
538
48
    break;
539
48
  case R_MICROMIPS_GOT_DISP:
540
0
  case R_MICROMIPS_GOT_PAGE:
541
0
  case R_MICROMIPS_GPREL16:
542
0
  case R_MICROMIPS_TLS_GD:
543
0
  case R_MICROMIPS_TLS_LDM:
544
0
    checkInt<16>(Loc, Val, Type);
545
0
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
546
0
    break;
547
5
  case R_MICROMIPS_CALL16:
548
5
  case R_MICROMIPS_CALL_LO16:
549
5
  case R_MICROMIPS_GOT_OFST:
550
5
  case R_MICROMIPS_LO16:
551
5
  case R_MICROMIPS_TLS_DTPREL_LO16:
552
5
  case R_MICROMIPS_TLS_GOTTPREL:
553
5
  case R_MICROMIPS_TLS_TPREL_LO16:
554
5
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
555
5
    break;
556
5
  case R_MICROMIPS_GPREL7_S2:
557
0
    checkInt<7>(Loc, Val, Type);
558
0
    writeMicroRelocation32<E>(Loc, Val, 7, 2);
559
0
    break;
560
31
  case R_MIPS_CALL_HI16:
561
31
  case R_MIPS_GOT_HI16:
562
31
  case R_MIPS_HI16:
563
31
  case R_MIPS_PCHI16:
564
31
  case R_MIPS_TLS_DTPREL_HI16:
565
31
  case R_MIPS_TLS_TPREL_HI16:
566
31
    writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
567
31
    break;
568
31
  case R_MICROMIPS_CALL_HI16:
569
2
  case R_MICROMIPS_GOT_HI16:
570
2
  case R_MICROMIPS_HI16:
571
2
  case R_MICROMIPS_TLS_DTPREL_HI16:
572
2
  case R_MICROMIPS_TLS_TPREL_HI16:
573
2
    writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
574
2
    break;
575
2
  case R_MIPS_HIGHER:
576
0
    writeRelocation<E>(Loc, Val + 0x80008000, 16, 32);
577
0
    break;
578
2
  case R_MIPS_HIGHEST:
579
0
    writeRelocation<E>(Loc, Val + 0x800080008000, 16, 48);
580
0
    break;
581
2
  case R_MICROMIPS_HIGHER:
582
0
    writeMicroRelocation32<E>(Loc, Val + 0x80008000, 16, 32);
583
0
    break;
584
2
  case R_MICROMIPS_HIGHEST:
585
0
    writeMicroRelocation32<E>(Loc, Val + 0x800080008000, 16, 48);
586
0
    break;
587
2
  case R_MIPS_JALR:
588
0
  case R_MICROMIPS_JALR:
589
0
    // Ignore this optimization relocation for now
590
0
    break;
591
1
  case R_MIPS_PC16:
592
1
    checkAlignment<4>(Loc, Val, Type);
593
1
    checkInt<18>(Loc, Val, Type);
594
1
    writeRelocation<E>(Loc, Val, 16, 2);
595
1
    break;
596
1
  case R_MIPS_PC19_S2:
597
1
    checkAlignment<4>(Loc, Val, Type);
598
1
    checkInt<21>(Loc, Val, Type);
599
1
    writeRelocation<E>(Loc, Val, 19, 2);
600
1
    break;
601
1
  case R_MIPS_PC21_S2:
602
1
    checkAlignment<4>(Loc, Val, Type);
603
1
    checkInt<23>(Loc, Val, Type);
604
1
    writeRelocation<E>(Loc, Val, 21, 2);
605
1
    break;
606
1
  case R_MIPS_PC26_S2:
607
1
    checkAlignment<4>(Loc, Val, Type);
608
1
    checkInt<28>(Loc, Val, Type);
609
1
    writeRelocation<E>(Loc, Val, 26, 2);
610
1
    break;
611
1
  case R_MIPS_PC32:
612
1
    writeRelocation<E>(Loc, Val, 32, 0);
613
1
    break;
614
4
  case R_MICROMIPS_26_S1:
615
4
  case R_MICROMIPS_PC26_S1:
616
4
    checkInt<27>(Loc, Val, Type);
617
4
    writeMicroRelocation32<E>(Loc, Val, 26, 1);
618
4
    break;
619
4
  case R_MICROMIPS_PC7_S1:
620
1
    checkInt<8>(Loc, Val, Type);
621
1
    writeMicroRelocation16<E>(Loc, Val, 7, 1);
622
1
    break;
623
4
  case R_MICROMIPS_PC10_S1:
624
1
    checkInt<11>(Loc, Val, Type);
625
1
    writeMicroRelocation16<E>(Loc, Val, 10, 1);
626
1
    break;
627
4
  case R_MICROMIPS_PC16_S1:
628
1
    checkInt<17>(Loc, Val, Type);
629
1
    writeMicroRelocation32<E>(Loc, Val, 16, 1);
630
1
    break;
631
4
  case R_MICROMIPS_PC18_S3:
632
0
    checkInt<21>(Loc, Val, Type);
633
0
    writeMicroRelocation32<E>(Loc, Val, 18, 3);
634
0
    break;
635
4
  case R_MICROMIPS_PC19_S2:
636
2
    checkInt<21>(Loc, Val, Type);
637
2
    writeMicroRelocation32<E>(Loc, Val, 19, 2);
638
2
    break;
639
4
  case R_MICROMIPS_PC21_S1:
640
0
    checkInt<22>(Loc, Val, Type);
641
0
    writeMicroRelocation32<E>(Loc, Val, 21, 1);
642
0
    break;
643
4
  case R_MICROMIPS_PC23_S2:
644
2
    checkInt<25>(Loc, Val, Type);
645
2
    writeMicroRelocation32<E>(Loc, Val, 23, 2);
646
2
    break;
647
4
  default:
648
0
    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
649
163
  }
650
163
}
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
467
10.0k
void MIPS<ELFT>::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
468
10.0k
  const endianness E = ELFT::TargetEndianness;
469
10.0k
470
10.0k
  // Thread pointer and DRP offsets from the start of TLS data area.
471
10.0k
  // https://www.linux-mips.org/wiki/NPTL
472
10.0k
  if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 ||
473
10.0k
      Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64 ||
474
10.0k
      Type == R_MICROMIPS_TLS_DTPREL_HI16 ||
475
10.0k
      Type == R_MICROMIPS_TLS_DTPREL_LO16) {
476
0
    Val -= 0x8000;
477
10.0k
  } else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 ||
478
10.0k
             Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64 ||
479
10.0k
             Type == R_MICROMIPS_TLS_TPREL_HI16 ||
480
10.0k
             Type == R_MICROMIPS_TLS_TPREL_LO16) {
481
0
    Val -= 0x7000;
482
0
  }
483
10.0k
484
10.0k
  if (ELFT::Is64Bits || 
Config->MipsN32Abi0
)
485
10.0k
    std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val);
486
10.0k
487
10.0k
  switch (Type) {
488
10.0k
  case R_MIPS_32:
489
0
  case R_MIPS_GPREL32:
490
0
  case R_MIPS_TLS_DTPREL32:
491
0
  case R_MIPS_TLS_TPREL32:
492
0
    write32<E>(Loc, Val);
493
0
    break;
494
1
  case R_MIPS_64:
495
1
  case R_MIPS_TLS_DTPREL64:
496
1
  case R_MIPS_TLS_TPREL64:
497
1
    write64<E>(Loc, Val);
498
1
    break;
499
1
  case R_MIPS_26:
500
1
    writeRelocation<E>(Loc, Val, 26, 2);
501
1
    break;
502
1
  case R_MIPS_GOT16:
503
0
    // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
504
0
    // is updated addend (not a GOT index). In that case write high 16 bits
505
0
    // to store a correct addend value.
506
0
    if (Config->Relocatable) {
507
0
      writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
508
0
    } else {
509
0
      checkInt<16>(Loc, Val, Type);
510
0
      writeRelocation<E>(Loc, Val, 16, 0);
511
0
    }
512
0
    break;
513
1
  case R_MICROMIPS_GOT16:
514
0
    if (Config->Relocatable) {
515
0
      writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
516
0
    } else {
517
0
      checkInt<16>(Loc, Val, Type);
518
0
      writeMicroRelocation32<E>(Loc, Val, 16, 0);
519
0
    }
520
0
    break;
521
10.0k
  case R_MIPS_CALL16:
522
10.0k
  case R_MIPS_GOT_DISP:
523
10.0k
  case R_MIPS_GOT_PAGE:
524
10.0k
  case R_MIPS_GPREL16:
525
10.0k
  case R_MIPS_TLS_GD:
526
10.0k
  case R_MIPS_TLS_GOTTPREL:
527
10.0k
  case R_MIPS_TLS_LDM:
528
10.0k
    checkInt<16>(Loc, Val, Type);
529
10.0k
    LLVM_FALLTHROUGH;
530
10.0k
  case R_MIPS_CALL_LO16:
531
10.0k
  case R_MIPS_GOT_LO16:
532
10.0k
  case R_MIPS_GOT_OFST:
533
10.0k
  case R_MIPS_LO16:
534
10.0k
  case R_MIPS_PCLO16:
535
10.0k
  case R_MIPS_TLS_DTPREL_LO16:
536
10.0k
  case R_MIPS_TLS_TPREL_LO16:
537
10.0k
    writeRelocation<E>(Loc, Val, 16, 0);
538
10.0k
    break;
539
10.0k
  case R_MICROMIPS_GOT_DISP:
540
0
  case R_MICROMIPS_GOT_PAGE:
541
0
  case R_MICROMIPS_GPREL16:
542
0
  case R_MICROMIPS_TLS_GD:
543
0
  case R_MICROMIPS_TLS_LDM:
544
0
    checkInt<16>(Loc, Val, Type);
545
0
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
546
0
    break;
547
0
  case R_MICROMIPS_CALL16:
548
0
  case R_MICROMIPS_CALL_LO16:
549
0
  case R_MICROMIPS_GOT_OFST:
550
0
  case R_MICROMIPS_LO16:
551
0
  case R_MICROMIPS_TLS_DTPREL_LO16:
552
0
  case R_MICROMIPS_TLS_GOTTPREL:
553
0
  case R_MICROMIPS_TLS_TPREL_LO16:
554
0
    writeMicroRelocation32<E>(Loc, Val, 16, 0);
555
0
    break;
556
0
  case R_MICROMIPS_GPREL7_S2:
557
0
    checkInt<7>(Loc, Val, Type);
558
0
    writeMicroRelocation32<E>(Loc, Val, 7, 2);
559
0
    break;
560
5
  case R_MIPS_CALL_HI16:
561
5
  case R_MIPS_GOT_HI16:
562
5
  case R_MIPS_HI16:
563
5
  case R_MIPS_PCHI16:
564
5
  case R_MIPS_TLS_DTPREL_HI16:
565
5
  case R_MIPS_TLS_TPREL_HI16:
566
5
    writeRelocation<E>(Loc, Val + 0x8000, 16, 16);
567
5
    break;
568
5
  case R_MICROMIPS_CALL_HI16:
569
0
  case R_MICROMIPS_GOT_HI16:
570
0
  case R_MICROMIPS_HI16:
571
0
  case R_MICROMIPS_TLS_DTPREL_HI16:
572
0
  case R_MICROMIPS_TLS_TPREL_HI16:
573
0
    writeMicroRelocation32<E>(Loc, Val + 0x8000, 16, 16);
574
0
    break;
575
2
  case R_MIPS_HIGHER:
576
2
    writeRelocation<E>(Loc, Val + 0x80008000, 16, 32);
577
2
    break;
578
2
  case R_MIPS_HIGHEST:
579
2
    writeRelocation<E>(Loc, Val + 0x800080008000, 16, 48);
580
2
    break;
581
0
  case R_MICROMIPS_HIGHER:
582
0
    writeMicroRelocation32<E>(Loc, Val + 0x80008000, 16, 32);
583
0
    break;
584
0
  case R_MICROMIPS_HIGHEST:
585
0
    writeMicroRelocation32<E>(Loc, Val + 0x800080008000, 16, 48);
586
0
    break;
587
0
  case R_MIPS_JALR:
588
0
  case R_MICROMIPS_JALR:
589
0
    // Ignore this optimization relocation for now
590
0
    break;
591
0
  case R_MIPS_PC16:
592
0
    checkAlignment<4>(Loc, Val, Type);
593
0
    checkInt<18>(Loc, Val, Type);
594
0
    writeRelocation<E>(Loc, Val, 16, 2);
595
0
    break;
596
0
  case R_MIPS_PC19_S2:
597
0
    checkAlignment<4>(Loc, Val, Type);
598
0
    checkInt<21>(Loc, Val, Type);
599
0
    writeRelocation<E>(Loc, Val, 19, 2);
600
0
    break;
601
0
  case R_MIPS_PC21_S2:
602
0
    checkAlignment<4>(Loc, Val, Type);
603
0
    checkInt<23>(Loc, Val, Type);
604
0
    writeRelocation<E>(Loc, Val, 21, 2);
605
0
    break;
606
0
  case R_MIPS_PC26_S2:
607
0
    checkAlignment<4>(Loc, Val, Type);
608
0
    checkInt<28>(Loc, Val, Type);
609
0
    writeRelocation<E>(Loc, Val, 26, 2);
610
0
    break;
611
1
  case R_MIPS_PC32:
612
1
    writeRelocation<E>(Loc, Val, 32, 0);
613
1
    break;
614
0
  case R_MICROMIPS_26_S1:
615
0
  case R_MICROMIPS_PC26_S1:
616
0
    checkInt<27>(Loc, Val, Type);
617
0
    writeMicroRelocation32<E>(Loc, Val, 26, 1);
618
0
    break;
619
0
  case R_MICROMIPS_PC7_S1:
620
0
    checkInt<8>(Loc, Val, Type);
621
0
    writeMicroRelocation16<E>(Loc, Val, 7, 1);
622
0
    break;
623
0
  case R_MICROMIPS_PC10_S1:
624
0
    checkInt<11>(Loc, Val, Type);
625
0
    writeMicroRelocation16<E>(Loc, Val, 10, 1);
626
0
    break;
627
0
  case R_MICROMIPS_PC16_S1:
628
0
    checkInt<17>(Loc, Val, Type);
629
0
    writeMicroRelocation32<E>(Loc, Val, 16, 1);
630
0
    break;
631
0
  case R_MICROMIPS_PC18_S3:
632
0
    checkInt<21>(Loc, Val, Type);
633
0
    writeMicroRelocation32<E>(Loc, Val, 18, 3);
634
0
    break;
635
0
  case R_MICROMIPS_PC19_S2:
636
0
    checkInt<21>(Loc, Val, Type);
637
0
    writeMicroRelocation32<E>(Loc, Val, 19, 2);
638
0
    break;
639
0
  case R_MICROMIPS_PC21_S1:
640
0
    checkInt<22>(Loc, Val, Type);
641
0
    writeMicroRelocation32<E>(Loc, Val, 21, 1);
642
0
    break;
643
0
  case R_MICROMIPS_PC23_S2:
644
0
    checkInt<25>(Loc, Val, Type);
645
0
    writeMicroRelocation32<E>(Loc, Val, 23, 2);
646
0
    break;
647
0
  default:
648
0
    error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
649
10.0k
  }
650
10.0k
}
651
652
18
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const {
653
18
  return Type == R_MIPS_LO16 || 
Type == R_MIPS_GOT_OFST9
||
654
18
         
Type == R_MICROMIPS_LO168
||
Type == R_MICROMIPS_GOT_OFST8
;
655
18
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)1, false> >::usesOnlyLowPageBits(unsigned int) const
Line
Count
Source
652
2
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const {
653
2
  return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST ||
654
2
         Type == R_MICROMIPS_LO16 || Type == R_MICROMIPS_GOT_OFST;
655
2
}
Mips.cpp:(anonymous namespace)::MIPS<llvm::object::ELFType<(llvm::support::endianness)0, false> >::usesOnlyLowPageBits(unsigned int) const
Line
Count
Source
652
12
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const {
653
12
  return Type == R_MIPS_LO16 || 
Type == R_MIPS_GOT_OFST3
||
654
12
         
Type == R_MICROMIPS_LO163
||
Type == R_MICROMIPS_GOT_OFST3
;
655
12
}
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
652
4
template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType Type) const {
653
4
  return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST ||
654
4
         
Type == R_MICROMIPS_LO163
||
Type == R_MICROMIPS_GOT_OFST3
;
655
4
}
656
657
// Return true if the symbol is a PIC function.
658
58
template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) {
659
58
  typedef typename ELFT::Ehdr Elf_Ehdr;
660
58
  if (!Sym->Section || !Sym->isFunc())
661
21
    return false;
662
37
663
37
  auto *Sec = cast<InputSectionBase>(Sym->Section);
664
37
  const Elf_Ehdr *Hdr = Sec->template getFile<ELFT>()->getObj().getHeader();
665
37
  return (Sym->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
666
37
         
(Hdr->e_flags & EF_MIPS_PIC)33
;
667
37
}
bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)1, false> >(lld::elf::Defined const*)
Line
Count
Source
658
1
template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) {
659
1
  typedef typename ELFT::Ehdr Elf_Ehdr;
660
1
  if (!Sym->Section || !Sym->isFunc())
661
0
    return false;
662
1
663
1
  auto *Sec = cast<InputSectionBase>(Sym->Section);
664
1
  const Elf_Ehdr *Hdr = Sec->template getFile<ELFT>()->getObj().getHeader();
665
1
  return (Sym->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
666
1
         (Hdr->e_flags & EF_MIPS_PIC);
667
1
}
bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)0, false> >(lld::elf::Defined const*)
Line
Count
Source
658
57
template <class ELFT> bool elf::isMipsPIC(const Defined *Sym) {
659
57
  typedef typename ELFT::Ehdr Elf_Ehdr;
660
57
  if (!Sym->Section || !Sym->isFunc())
661
21
    return false;
662
36
663
36
  auto *Sec = cast<InputSectionBase>(Sym->Section);
664
36
  const Elf_Ehdr *Hdr = Sec->template getFile<ELFT>()->getObj().getHeader();
665
36
  return (Sym->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
666
36
         
(Hdr->e_flags & EF_MIPS_PIC)32
;
667
36
}
Unexecuted instantiation: bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)1, true> >(lld::elf::Defined const*)
Unexecuted instantiation: bool lld::elf::isMipsPIC<llvm::object::ELFType<(llvm::support::endianness)0, true> >(lld::elf::Defined const*)
668
669
76
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
670
76
  static MIPS<ELFT> Target;
671
76
  return &Target;
672
76
}
lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)1, false> >()
Line
Count
Source
669
4
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
670
4
  static MIPS<ELFT> Target;
671
4
  return &Target;
672
4
}
lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)0, false> >()
Line
Count
Source
669
53
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
670
53
  static MIPS<ELFT> Target;
671
53
  return &Target;
672
53
}
Unexecuted instantiation: lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)1, true> >()
lld::elf::TargetInfo* lld::elf::getMipsTargetInfo<llvm::object::ELFType<(llvm::support::endianness)0, true> >()
Line
Count
Source
669
19
template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
670
19
  static MIPS<ELFT> Target;
671
19
  return &Target;
672
19
}
673
674
template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
675
template TargetInfo *elf::getMipsTargetInfo<ELF32BE>();
676
template TargetInfo *elf::getMipsTargetInfo<ELF64LE>();
677
template TargetInfo *elf::getMipsTargetInfo<ELF64BE>();
678
679
template bool elf::isMipsPIC<ELF32LE>(const Defined *);
680
template bool elf::isMipsPIC<ELF32BE>(const Defined *);
681
template bool elf::isMipsPIC<ELF64LE>(const Defined *);
682
template bool elf::isMipsPIC<ELF64BE>(const Defined *);