comparison lld/ELF/Arch/SPARCV9.cpp @ 150:1d019706d866

LLVM10
author anatofuz
date Thu, 13 Feb 2020 15:10:13 +0900
parents
children 0572611fdcc8
comparison
equal deleted inserted replaced
147:c2174574ed3a 150:1d019706d866
1 //===- SPARCV9.cpp --------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "InputFiles.h"
10 #include "Symbols.h"
11 #include "SyntheticSections.h"
12 #include "Target.h"
13 #include "lld/Common/ErrorHandler.h"
14 #include "llvm/Support/Endian.h"
15
16 using namespace llvm;
17 using namespace llvm::support::endian;
18 using namespace llvm::ELF;
19
20 namespace lld {
21 namespace elf {
22
23 namespace {
24 class SPARCV9 final : public TargetInfo {
25 public:
26 SPARCV9();
27 RelExpr getRelExpr(RelType type, const Symbol &s,
28 const uint8_t *loc) const override;
29 void writePlt(uint8_t *buf, const Symbol &sym,
30 uint64_t pltEntryAddr) const override;
31 void relocate(uint8_t *loc, const Relocation &rel,
32 uint64_t val) const override;
33 };
34 } // namespace
35
36 SPARCV9::SPARCV9() {
37 copyRel = R_SPARC_COPY;
38 gotRel = R_SPARC_GLOB_DAT;
39 noneRel = R_SPARC_NONE;
40 pltRel = R_SPARC_JMP_SLOT;
41 relativeRel = R_SPARC_RELATIVE;
42 symbolicRel = R_SPARC_64;
43 pltEntrySize = 32;
44 pltHeaderSize = 4 * pltEntrySize;
45
46 defaultCommonPageSize = 8192;
47 defaultMaxPageSize = 0x100000;
48 defaultImageBase = 0x100000;
49 }
50
51 RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s,
52 const uint8_t *loc) const {
53 switch (type) {
54 case R_SPARC_32:
55 case R_SPARC_UA32:
56 case R_SPARC_64:
57 case R_SPARC_UA64:
58 return R_ABS;
59 case R_SPARC_PC10:
60 case R_SPARC_PC22:
61 case R_SPARC_DISP32:
62 case R_SPARC_WDISP30:
63 return R_PC;
64 case R_SPARC_GOT10:
65 return R_GOT_OFF;
66 case R_SPARC_GOT22:
67 return R_GOT_OFF;
68 case R_SPARC_WPLT30:
69 return R_PLT_PC;
70 case R_SPARC_NONE:
71 return R_NONE;
72 default:
73 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) +
74 ") against symbol " + toString(s));
75 return R_NONE;
76 }
77 }
78
79 void SPARCV9::relocate(uint8_t *loc, const Relocation &rel,
80 uint64_t val) const {
81 switch (rel.type) {
82 case R_SPARC_32:
83 case R_SPARC_UA32:
84 // V-word32
85 checkUInt(loc, val, 32, rel);
86 write32be(loc, val);
87 break;
88 case R_SPARC_DISP32:
89 // V-disp32
90 checkInt(loc, val, 32, rel);
91 write32be(loc, val);
92 break;
93 case R_SPARC_WDISP30:
94 case R_SPARC_WPLT30:
95 // V-disp30
96 checkInt(loc, val, 32, rel);
97 write32be(loc, (read32be(loc) & ~0x3fffffff) | ((val >> 2) & 0x3fffffff));
98 break;
99 case R_SPARC_22:
100 // V-imm22
101 checkUInt(loc, val, 22, rel);
102 write32be(loc, (read32be(loc) & ~0x003fffff) | (val & 0x003fffff));
103 break;
104 case R_SPARC_GOT22:
105 case R_SPARC_PC22:
106 // T-imm22
107 write32be(loc, (read32be(loc) & ~0x003fffff) | ((val >> 10) & 0x003fffff));
108 break;
109 case R_SPARC_WDISP19:
110 // V-disp19
111 checkInt(loc, val, 21, rel);
112 write32be(loc, (read32be(loc) & ~0x0007ffff) | ((val >> 2) & 0x0007ffff));
113 break;
114 case R_SPARC_GOT10:
115 case R_SPARC_PC10:
116 // T-simm10
117 write32be(loc, (read32be(loc) & ~0x000003ff) | (val & 0x000003ff));
118 break;
119 case R_SPARC_64:
120 case R_SPARC_UA64:
121 // V-xword64
122 write64be(loc, val);
123 break;
124 default:
125 llvm_unreachable("unknown relocation");
126 }
127 }
128
129 void SPARCV9::writePlt(uint8_t *buf, const Symbol & /*sym*/,
130 uint64_t pltEntryAddr) const {
131 const uint8_t pltData[] = {
132 0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1
133 0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1
134 0x01, 0x00, 0x00, 0x00, // nop
135 0x01, 0x00, 0x00, 0x00, // nop
136 0x01, 0x00, 0x00, 0x00, // nop
137 0x01, 0x00, 0x00, 0x00, // nop
138 0x01, 0x00, 0x00, 0x00, // nop
139 0x01, 0x00, 0x00, 0x00 // nop
140 };
141 memcpy(buf, pltData, sizeof(pltData));
142
143 uint64_t off = pltEntryAddr - in.plt->getVA();
144 relocateNoSym(buf, R_SPARC_22, off);
145 relocateNoSym(buf + 4, R_SPARC_WDISP19, -(off + 4 - pltEntrySize));
146 }
147
148 TargetInfo *getSPARCV9TargetInfo() {
149 static SPARCV9 target;
150 return ⌖
151 }
152
153 } // namespace elf
154 } // namespace lld