Mercurial > hg > CbC > CbC_llvm
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 |