66//
77// ===----------------------------------------------------------------------===//
88
9+ #include " OutputSections.h"
910#include " Symbols.h"
1011#include " SyntheticSections.h"
1112#include " Target.h"
@@ -23,10 +24,17 @@ class SPARCV9 final : public TargetInfo {
2324 SPARCV9 (Ctx &);
2425 RelExpr getRelExpr (RelType type, const Symbol &s,
2526 const uint8_t *loc) const override ;
27+ RelType getDynRel (RelType type) const override ;
28+ void writeGotHeader (uint8_t *buf) const override ;
2629 void writePlt (uint8_t *buf, const Symbol &sym,
2730 uint64_t pltEntryAddr) const override ;
2831 void relocate (uint8_t *loc, const Relocation &rel,
2932 uint64_t val) const override ;
33+ RelExpr adjustGotOffExpr (RelType type, const Symbol &sym, int64_t addend,
34+ const uint8_t *loc) const override ;
35+
36+ private:
37+ void relaxGot (uint8_t *loc, const Relocation &rel, uint64_t val) const ;
3038};
3139} // namespace
3240
@@ -35,9 +43,16 @@ SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {
3543 gotRel = R_SPARC_GLOB_DAT;
3644 pltRel = R_SPARC_JMP_SLOT;
3745 relativeRel = R_SPARC_RELATIVE;
46+ iRelativeRel = R_SPARC_IRELATIVE;
3847 symbolicRel = R_SPARC_64;
48+ tlsGotRel = R_SPARC_TLS_TPOFF64;
49+ tlsModuleIndexRel = R_SPARC_TLS_DTPMOD64;
50+ tlsOffsetRel = R_SPARC_TLS_DTPOFF64;
51+
52+ gotHeaderEntriesNum = 1 ;
3953 pltEntrySize = 32 ;
4054 pltHeaderSize = 4 * pltEntrySize;
55+ usesGotPlt = false ;
4156
4257 defaultCommonPageSize = 8192 ;
4358 defaultMaxPageSize = 0x100000 ;
@@ -47,109 +62,222 @@ SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {
4762RelExpr SPARCV9::getRelExpr (RelType type, const Symbol &s,
4863 const uint8_t *loc) const {
4964 switch (type) {
65+ case R_SPARC_NONE:
66+ return R_NONE;
67+ case R_SPARC_8:
68+ case R_SPARC_16:
5069 case R_SPARC_32:
70+ case R_SPARC_HI22:
71+ case R_SPARC_13:
72+ case R_SPARC_LO10:
5173 case R_SPARC_UA32:
5274 case R_SPARC_64:
53- case R_SPARC_UA64:
54- case R_SPARC_H44:
55- case R_SPARC_M44:
56- case R_SPARC_L44:
5775 case R_SPARC_HH22:
5876 case R_SPARC_HM10:
5977 case R_SPARC_LM22:
60- case R_SPARC_HI22:
61- case R_SPARC_LO10:
78+ case R_SPARC_HIX22:
79+ case R_SPARC_LOX10:
80+ case R_SPARC_H44:
81+ case R_SPARC_M44:
82+ case R_SPARC_L44:
83+ case R_SPARC_UA64:
84+ case R_SPARC_UA16:
6285 return R_ABS;
63- case R_SPARC_PC10 :
64- case R_SPARC_PC22 :
86+ case R_SPARC_DISP8 :
87+ case R_SPARC_DISP16 :
6588 case R_SPARC_DISP32:
6689 case R_SPARC_WDISP30:
90+ case R_SPARC_WDISP22:
91+ case R_SPARC_PC10:
92+ case R_SPARC_PC22:
93+ case R_SPARC_WDISP16:
94+ case R_SPARC_DISP64:
6795 return R_PC;
6896 case R_SPARC_GOT10:
69- return R_GOT_OFF;
97+ case R_SPARC_GOT13:
7098 case R_SPARC_GOT22:
99+ case R_SPARC_GOTDATA_OP_HIX22:
100+ case R_SPARC_GOTDATA_OP_LOX10:
101+ case R_SPARC_GOTDATA_OP:
71102 return R_GOT_OFF;
72103 case R_SPARC_WPLT30:
104+ case R_SPARC_TLS_GD_CALL:
105+ case R_SPARC_TLS_LDM_CALL:
73106 return R_PLT_PC;
74- case R_SPARC_NONE:
75- return R_NONE;
107+ case R_SPARC_TLS_GD_HI22:
108+ case R_SPARC_TLS_GD_LO10:
109+ return R_TLSGD_GOT;
110+ case R_SPARC_TLS_GD_ADD:
111+ case R_SPARC_TLS_LDM_ADD:
112+ case R_SPARC_TLS_LDO_ADD:
113+ case R_SPARC_TLS_IE_LD:
114+ case R_SPARC_TLS_IE_LDX:
115+ case R_SPARC_TLS_IE_ADD:
116+ return R_NONE; // TODO: Relax TLS relocations.
117+ case R_SPARC_TLS_LDM_HI22:
118+ case R_SPARC_TLS_LDM_LO10:
119+ return R_TLSLD_GOT;
120+ case R_SPARC_TLS_LDO_HIX22:
121+ case R_SPARC_TLS_LDO_LOX10:
122+ return R_DTPREL;
123+ case R_SPARC_TLS_IE_HI22:
124+ case R_SPARC_TLS_IE_LO10:
125+ return R_GOT;
76126 case R_SPARC_TLS_LE_HIX22:
77127 case R_SPARC_TLS_LE_LOX10:
78128 return R_TPREL;
129+ case R_SPARC_GOTDATA_HIX22:
130+ case R_SPARC_GOTDATA_LOX10:
131+ return R_GOTREL;
79132 default :
80133 Err (ctx) << getErrorLoc (ctx, loc) << " unknown relocation (" << type.v
81134 << " ) against symbol " << &s;
82135 return R_NONE;
83136 }
84137}
85138
139+ RelType SPARCV9::getDynRel (RelType type) const {
140+ if (type == symbolicRel)
141+ return type;
142+ return R_SPARC_NONE;
143+ }
144+
86145void SPARCV9::relocate (uint8_t *loc, const Relocation &rel,
87146 uint64_t val) const {
147+ switch (rel.expr ) {
148+ case R_RELAX_GOT_OFF:
149+ return relaxGot (loc, rel, val);
150+ default :
151+ break ;
152+ }
153+
88154 switch (rel.type ) {
155+ case R_SPARC_8:
156+ // V-byte8
157+ checkUInt (ctx, loc, val, 8 , rel);
158+ *loc = val;
159+ break ;
160+ case R_SPARC_16:
161+ case R_SPARC_UA16:
162+ // V-half16
163+ checkUInt (ctx, loc, val, 16 , rel);
164+ write16be (loc, val);
165+ break ;
89166 case R_SPARC_32:
90167 case R_SPARC_UA32:
91168 // V-word32
92169 checkUInt (ctx, loc, val, 32 , rel);
93170 write32be (loc, val);
94171 break ;
172+ case R_SPARC_DISP8:
173+ // V-byte8
174+ checkIntUInt (ctx, loc, val, 8 , rel);
175+ *loc = val;
176+ break ;
177+ case R_SPARC_DISP16:
178+ // V-half16
179+ checkIntUInt (ctx, loc, val, 16 , rel);
180+ write16be (loc, val);
181+ break ;
95182 case R_SPARC_DISP32:
96183 // V-disp32
97- checkInt (ctx, loc, val, 32 , rel);
184+ checkIntUInt (ctx, loc, val, 32 , rel);
98185 write32be (loc, val);
99186 break ;
100187 case R_SPARC_WDISP30:
101188 case R_SPARC_WPLT30:
189+ case R_SPARC_TLS_GD_CALL:
190+ case R_SPARC_TLS_LDM_CALL:
102191 // V-disp30
103- checkInt (ctx, loc, val, 32 , rel);
192+ checkIntUInt (ctx, loc, val, 32 , rel);
104193 write32be (loc, (read32be (loc) & ~0x3fffffff ) | ((val >> 2 ) & 0x3fffffff ));
105194 break ;
106- case R_SPARC_22 :
107- // V-imm22
108- checkUInt (ctx, loc, val, 22 , rel);
109- write32be (loc, (read32be (loc) & ~0x003fffff ) | (val & 0x003fffff ));
195+ case R_SPARC_WDISP22 :
196+ // V-disp22
197+ checkIntUInt (ctx, loc, val, 24 , rel);
198+ write32be (loc, (read32be (loc) & ~0x003fffff ) | (( val >> 2 ) & 0x003fffff ));
110199 break ;
111- case R_SPARC_GOT22:
112- case R_SPARC_PC22:
113- case R_SPARC_LM22:
114- // T-imm22
200+ case R_SPARC_HI22: // Only T-imm22 on 32-bit, despite binutils behavior.
201+ // V-imm22
202+ checkUInt (ctx, loc, val, 32 , rel);
115203 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 10 ) & 0x003fffff ));
116204 break ;
117- case R_SPARC_HI22 :
205+ case R_SPARC_22 :
118206 // V-imm22
119- checkUInt (ctx, loc, val >> 10 , 22 , rel);
120- write32be (loc, (read32be (loc) & ~0x003fffff ) | (( val >> 10 ) & 0x003fffff ));
207+ checkUInt (ctx, loc, val, 22 , rel);
208+ write32be (loc, (read32be (loc) & ~0x003fffff ) | (val & 0x003fffff ));
121209 break ;
122- case R_SPARC_WDISP19:
123- // V-disp19
124- checkInt (ctx, loc, val, 21 , rel);
125- write32be (loc, (read32be (loc) & ~0x0007ffff ) | ((val >> 2 ) & 0x0007ffff ));
210+ case R_SPARC_13:
211+ case R_SPARC_GOT13:
212+ // V-simm13
213+ checkIntUInt (ctx, loc, val, 13 , rel);
214+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x00001fff ));
126215 break ;
216+ case R_SPARC_LO10:
127217 case R_SPARC_GOT10:
128218 case R_SPARC_PC10:
129- // T-simm10
219+ case R_SPARC_TLS_GD_LO10:
220+ case R_SPARC_TLS_LDM_LO10:
221+ case R_SPARC_TLS_IE_LO10:
222+ // T-simm13
130223 write32be (loc, (read32be (loc) & ~0x000003ff ) | (val & 0x000003ff ));
131224 break ;
132- case R_SPARC_LO10 :
225+ case R_SPARC_TLS_LDO_LOX10 :
133226 // T-simm13
134227 write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ));
135228 break ;
229+ case R_SPARC_GOT22:
230+ case R_SPARC_LM22:
231+ case R_SPARC_TLS_GD_HI22:
232+ case R_SPARC_TLS_LDM_HI22:
233+ case R_SPARC_TLS_LDO_HIX22: // Not V-simm22, despite binutils behavior.
234+ case R_SPARC_TLS_IE_HI22:
235+ // T-(s)imm22
236+ write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 10 ) & 0x003fffff ));
237+ break ;
238+ case R_SPARC_PC22:
239+ // V-disp22
240+ checkIntUInt (ctx, loc, val, 32 , rel);
241+ write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 10 ) & 0x003fffff ));
242+ break ;
136243 case R_SPARC_64:
244+ case R_SPARC_DISP64:
137245 case R_SPARC_UA64:
138246 // V-xword64
139247 write64be (loc, val);
140248 break ;
141249 case R_SPARC_HH22:
142250 // V-imm22
143- checkUInt (ctx, loc, val >> 42 , 22 , rel);
144251 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 42 ) & 0x003fffff ));
145252 break ;
146253 case R_SPARC_HM10:
147254 // T-simm13
148- write32be (loc, (read32be (loc) & ~0x00001fff ) | ((val >> 32 ) & 0x000003ff ));
255+ write32be (loc, (read32be (loc) & ~0x000003ff ) | ((val >> 32 ) & 0x000003ff ));
256+ break ;
257+ case R_SPARC_WDISP16:
258+ // V-d2/disp14
259+ checkIntUInt (ctx, loc, val, 18 , rel);
260+ write32be (loc, (read32be (loc) & ~0x0303fff ) | (((val >> 2 ) & 0xc000 ) << 6 ) |
261+ ((val >> 2 ) & 0x00003fff ));
262+ break ;
263+ case R_SPARC_WDISP19:
264+ // V-disp19
265+ checkIntUInt (ctx, loc, val, 21 , rel);
266+ write32be (loc, (read32be (loc) & ~0x0007ffff ) | ((val >> 2 ) & 0x0007ffff ));
267+ break ;
268+ case R_SPARC_HIX22:
269+ // V-imm22
270+ checkUInt (ctx, loc, ~val, 32 , rel);
271+ write32be (loc, (read32be (loc) & ~0x003fffff ) | ((~val >> 10 ) & 0x003fffff ));
272+ break ;
273+ case R_SPARC_LOX10:
274+ case R_SPARC_TLS_LE_LOX10:
275+ // T-simm13
276+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) | 0x1c00 );
149277 break ;
150278 case R_SPARC_H44:
151279 // V-imm22
152- checkUInt (ctx, loc, val >> 22 , 22 , rel);
280+ checkUInt (ctx, loc, val, 44 , rel);
153281 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 22 ) & 0x003fffff ));
154282 break ;
155283 case R_SPARC_M44:
@@ -158,21 +286,90 @@ void SPARCV9::relocate(uint8_t *loc, const Relocation &rel,
158286 break ;
159287 case R_SPARC_L44:
160288 // T-imm13
161- write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x00000fff ));
289+ write32be (loc, (read32be (loc) & ~0x00000fff ) | (val & 0x00000fff ));
162290 break ;
163- case R_SPARC_TLS_LE_HIX22:
291+ case R_SPARC_TLS_GD_ADD:
292+ case R_SPARC_TLS_LDM_ADD:
293+ case R_SPARC_TLS_LDO_ADD:
294+ case R_SPARC_TLS_IE_LD:
295+ case R_SPARC_TLS_IE_LDX:
296+ case R_SPARC_TLS_IE_ADD:
297+ // None
298+ break ;
299+ case R_SPARC_TLS_LE_HIX22: // Not V-imm2, despite binutils behavior.
164300 // T-imm22
165301 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((~val >> 10 ) & 0x003fffff ));
166302 break ;
167- case R_SPARC_TLS_LE_LOX10:
168- // T-simm13
169- write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) | 0x1C00 );
303+ case R_SPARC_GOTDATA_HIX22:
304+ // V-imm22
305+ checkUInt (ctx, loc, ((int64_t )val < 0 ? ~val : val), 32 , rel);
306+ write32be (loc, (read32be (loc) & ~0x003fffff ) |
307+ ((((int64_t )val < 0 ? ~val : val) >> 10 ) & 0x003fffff ));
308+ break ;
309+ case R_SPARC_GOTDATA_OP_HIX22: // Not V-imm22, despite binutils behavior.
310+ // Non-relaxed case.
311+ // T-imm22
312+ write32be (loc, (read32be (loc) & ~0x003fffff ) |
313+ ((((int64_t )val < 0 ? ~val : val) >> 10 ) & 0x003fffff ));
314+ break ;
315+ case R_SPARC_GOTDATA_LOX10:
316+ case R_SPARC_GOTDATA_OP_LOX10: // Non-relaxed case.
317+ // T-imm13
318+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) |
319+ ((int64_t )val < 0 ? 0x1c00 : 0 ));
320+ break ;
321+ case R_SPARC_GOTDATA_OP: // Non-relaxed case.
322+ // word32
323+ // Nothing needs to be done in the non-relaxed case.
170324 break ;
171325 default :
172326 llvm_unreachable (" unknown relocation" );
173327 }
174328}
175329
330+ RelExpr SPARCV9::adjustGotOffExpr (RelType type, const Symbol &sym,
331+ int64_t addend, const uint8_t *loc) const {
332+ switch (type) {
333+ case R_SPARC_GOTDATA_OP_HIX22:
334+ case R_SPARC_GOTDATA_OP_LOX10:
335+ case R_SPARC_GOTDATA_OP:
336+ if (sym.isLocal ())
337+ return R_RELAX_GOT_OFF;
338+
339+ [[fallthrough]];
340+ default :
341+ return R_GOT_OFF;
342+ }
343+ }
344+
345+ void SPARCV9::relaxGot (uint8_t *loc, const Relocation &rel,
346+ uint64_t val) const {
347+ switch (rel.type ) {
348+ case R_SPARC_GOTDATA_OP_HIX22: // Not V-imm22, despite binutils behavior.
349+ // T-imm22
350+ write32be (loc, (read32be (loc) & ~0x003fffff ) |
351+ ((((int64_t )val < 0 ? ~val : val) >> 10 ) & 0x003fffff ));
352+ break ;
353+ case R_SPARC_GOTDATA_OP_LOX10:
354+ // T-imm13
355+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) |
356+ ((int64_t )val < 0 ? 0x1c00 : 0 ));
357+ break ;
358+ case R_SPARC_GOTDATA_OP:
359+ // word32
360+ // ldx [%rs1 + %rs2], %rd -> add %rs1, %rs2, %rd
361+ write32be (loc, (read32be (loc) & 0x3e07c01f ) | 0x80000000 );
362+ break ;
363+ default :
364+ llvm_unreachable (" unknown relocation" );
365+ }
366+ }
367+
368+ void SPARCV9::writeGotHeader (uint8_t *buf) const {
369+ // _GLOBAL_OFFSET_TABLE_[0] = _DYNAMIC
370+ write32 (ctx, buf, ctx.mainPart ->dynamic ->getVA ());
371+ }
372+
176373void SPARCV9::writePlt (uint8_t *buf, const Symbol & /* sym*/ ,
177374 uint64_t pltEntryAddr) const {
178375 const uint8_t pltData[] = {
0 commit comments