66//
77// ===----------------------------------------------------------------------===//
88
9+ #include " OutputSections.h"
910#include " Symbols.h"
1011#include " SyntheticSections.h"
1112#include " Target.h"
@@ -24,10 +25,17 @@ class SPARCV9 final : public TargetInfo {
2425 SPARCV9 (Ctx &);
2526 RelExpr getRelExpr (RelType type, const Symbol &s,
2627 const uint8_t *loc) const override ;
28+ RelType getDynRel (RelType type) const override ;
29+ void writeGotHeader (uint8_t *buf) const override ;
2730 void writePlt (uint8_t *buf, const Symbol &sym,
2831 uint64_t pltEntryAddr) const override ;
2932 void relocate (uint8_t *loc, const Relocation &rel,
3033 uint64_t val) const override ;
34+ RelExpr adjustGotOffExpr (RelType type, const Symbol &sym, int64_t addend,
35+ const uint8_t *loc) const override ;
36+
37+ private:
38+ void relaxGot (uint8_t *loc, const Relocation &rel, uint64_t val) const ;
3139};
3240} // namespace
3341
@@ -36,9 +44,16 @@ SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {
3644 gotRel = R_SPARC_GLOB_DAT;
3745 pltRel = R_SPARC_JMP_SLOT;
3846 relativeRel = R_SPARC_RELATIVE;
47+ iRelativeRel = R_SPARC_IRELATIVE;
3948 symbolicRel = R_SPARC_64;
49+ tlsGotRel = R_SPARC_TLS_TPOFF64;
50+ tlsModuleIndexRel = R_SPARC_TLS_DTPMOD64;
51+ tlsOffsetRel = R_SPARC_TLS_DTPOFF64;
52+
53+ gotHeaderEntriesNum = 1 ;
4054 pltEntrySize = 32 ;
4155 pltHeaderSize = 4 * pltEntrySize;
56+ usesGotPlt = false ;
4257
4358 defaultCommonPageSize = 8192 ;
4459 defaultMaxPageSize = 0x100000 ;
@@ -48,109 +63,222 @@ SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {
4863RelExpr SPARCV9::getRelExpr (RelType type, const Symbol &s,
4964 const uint8_t *loc) const {
5065 switch (type) {
66+ case R_SPARC_NONE:
67+ return R_NONE;
68+ case R_SPARC_8:
69+ case R_SPARC_16:
5170 case R_SPARC_32:
71+ case R_SPARC_HI22:
72+ case R_SPARC_13:
73+ case R_SPARC_LO10:
5274 case R_SPARC_UA32:
5375 case R_SPARC_64:
54- case R_SPARC_UA64:
55- case R_SPARC_H44:
56- case R_SPARC_M44:
57- case R_SPARC_L44:
5876 case R_SPARC_HH22:
5977 case R_SPARC_HM10:
6078 case R_SPARC_LM22:
61- case R_SPARC_HI22:
62- case R_SPARC_LO10:
79+ case R_SPARC_HIX22:
80+ case R_SPARC_LOX10:
81+ case R_SPARC_H44:
82+ case R_SPARC_M44:
83+ case R_SPARC_L44:
84+ case R_SPARC_UA64:
85+ case R_SPARC_UA16:
6386 return R_ABS;
64- case R_SPARC_PC10 :
65- case R_SPARC_PC22 :
87+ case R_SPARC_DISP8 :
88+ case R_SPARC_DISP16 :
6689 case R_SPARC_DISP32:
6790 case R_SPARC_WDISP30:
91+ case R_SPARC_WDISP22:
92+ case R_SPARC_PC10:
93+ case R_SPARC_PC22:
94+ case R_SPARC_WDISP16:
95+ case R_SPARC_DISP64:
6896 return R_PC;
6997 case R_SPARC_GOT10:
70- return R_GOT_OFF;
98+ case R_SPARC_GOT13:
7199 case R_SPARC_GOT22:
100+ case R_SPARC_GOTDATA_OP_HIX22:
101+ case R_SPARC_GOTDATA_OP_LOX10:
102+ case R_SPARC_GOTDATA_OP:
72103 return R_GOT_OFF;
73104 case R_SPARC_WPLT30:
105+ case R_SPARC_TLS_GD_CALL:
106+ case R_SPARC_TLS_LDM_CALL:
74107 return R_PLT_PC;
75- case R_SPARC_NONE:
76- return R_NONE;
108+ case R_SPARC_TLS_GD_HI22:
109+ case R_SPARC_TLS_GD_LO10:
110+ return R_TLSGD_GOT;
111+ case R_SPARC_TLS_GD_ADD:
112+ case R_SPARC_TLS_LDM_ADD:
113+ case R_SPARC_TLS_LDO_ADD:
114+ case R_SPARC_TLS_IE_LD:
115+ case R_SPARC_TLS_IE_LDX:
116+ case R_SPARC_TLS_IE_ADD:
117+ return R_NONE; // TODO: Relax TLS relocations.
118+ case R_SPARC_TLS_LDM_HI22:
119+ case R_SPARC_TLS_LDM_LO10:
120+ return R_TLSLD_GOT;
121+ case R_SPARC_TLS_LDO_HIX22:
122+ case R_SPARC_TLS_LDO_LOX10:
123+ return R_DTPREL;
124+ case R_SPARC_TLS_IE_HI22:
125+ case R_SPARC_TLS_IE_LO10:
126+ return R_GOT;
77127 case R_SPARC_TLS_LE_HIX22:
78128 case R_SPARC_TLS_LE_LOX10:
79129 return R_TPREL;
130+ case R_SPARC_GOTDATA_HIX22:
131+ case R_SPARC_GOTDATA_LOX10:
132+ return R_GOTREL;
80133 default :
81134 Err (ctx) << getErrorLoc (ctx, loc) << " unknown relocation (" << type.v
82135 << " ) against symbol " << &s;
83136 return R_NONE;
84137 }
85138}
86139
140+ RelType SPARCV9::getDynRel (RelType type) const {
141+ if (type == symbolicRel)
142+ return type;
143+ return R_SPARC_NONE;
144+ }
145+
87146void SPARCV9::relocate (uint8_t *loc, const Relocation &rel,
88147 uint64_t val) const {
148+ switch (rel.expr ) {
149+ case R_RELAX_GOT_OFF:
150+ return relaxGot (loc, rel, val);
151+ default :
152+ break ;
153+ }
154+
89155 switch (rel.type ) {
156+ case R_SPARC_8:
157+ // V-byte8
158+ checkUInt (ctx, loc, val, 8 , rel);
159+ *loc = val;
160+ break ;
161+ case R_SPARC_16:
162+ case R_SPARC_UA16:
163+ // V-half16
164+ checkUInt (ctx, loc, val, 16 , rel);
165+ write16be (loc, val);
166+ break ;
90167 case R_SPARC_32:
91168 case R_SPARC_UA32:
92169 // V-word32
93170 checkUInt (ctx, loc, val, 32 , rel);
94171 write32be (loc, val);
95172 break ;
173+ case R_SPARC_DISP8:
174+ // V-byte8
175+ checkIntUInt (ctx, loc, val, 8 , rel);
176+ *loc = val;
177+ break ;
178+ case R_SPARC_DISP16:
179+ // V-half16
180+ checkIntUInt (ctx, loc, val, 16 , rel);
181+ write16be (loc, val);
182+ break ;
96183 case R_SPARC_DISP32:
97184 // V-disp32
98- checkInt (ctx, loc, val, 32 , rel);
185+ checkIntUInt (ctx, loc, val, 32 , rel);
99186 write32be (loc, val);
100187 break ;
101188 case R_SPARC_WDISP30:
102189 case R_SPARC_WPLT30:
190+ case R_SPARC_TLS_GD_CALL:
191+ case R_SPARC_TLS_LDM_CALL:
103192 // V-disp30
104- checkInt (ctx, loc, val, 32 , rel);
193+ checkIntUInt (ctx, loc, val, 32 , rel);
105194 write32be (loc, (read32be (loc) & ~0x3fffffff ) | ((val >> 2 ) & 0x3fffffff ));
106195 break ;
107- case R_SPARC_22 :
108- // V-imm22
109- checkUInt (ctx, loc, val, 22 , rel);
110- write32be (loc, (read32be (loc) & ~0x003fffff ) | (val & 0x003fffff ));
196+ case R_SPARC_WDISP22 :
197+ // V-disp22
198+ checkIntUInt (ctx, loc, val, 24 , rel);
199+ write32be (loc, (read32be (loc) & ~0x003fffff ) | (( val >> 2 ) & 0x003fffff ));
111200 break ;
112- case R_SPARC_GOT22:
113- case R_SPARC_PC22:
114- case R_SPARC_LM22:
115- // T-imm22
201+ case R_SPARC_HI22: // Only T-imm22 on 32-bit, despite binutils behavior.
202+ // V-imm22
203+ checkUInt (ctx, loc, val, 32 , rel);
116204 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 10 ) & 0x003fffff ));
117205 break ;
118- case R_SPARC_HI22 :
206+ case R_SPARC_22 :
119207 // V-imm22
120- checkUInt (ctx, loc, val >> 10 , 22 , rel);
121- write32be (loc, (read32be (loc) & ~0x003fffff ) | (( val >> 10 ) & 0x003fffff ));
208+ checkUInt (ctx, loc, val, 22 , rel);
209+ write32be (loc, (read32be (loc) & ~0x003fffff ) | (val & 0x003fffff ));
122210 break ;
123- case R_SPARC_WDISP19:
124- // V-disp19
125- checkInt (ctx, loc, val, 21 , rel);
126- write32be (loc, (read32be (loc) & ~0x0007ffff ) | ((val >> 2 ) & 0x0007ffff ));
211+ case R_SPARC_13:
212+ case R_SPARC_GOT13:
213+ // V-simm13
214+ checkIntUInt (ctx, loc, val, 13 , rel);
215+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x00001fff ));
127216 break ;
217+ case R_SPARC_LO10:
128218 case R_SPARC_GOT10:
129219 case R_SPARC_PC10:
130- // T-simm10
220+ case R_SPARC_TLS_GD_LO10:
221+ case R_SPARC_TLS_LDM_LO10:
222+ case R_SPARC_TLS_IE_LO10:
223+ // T-simm13
131224 write32be (loc, (read32be (loc) & ~0x000003ff ) | (val & 0x000003ff ));
132225 break ;
133- case R_SPARC_LO10 :
226+ case R_SPARC_TLS_LDO_LOX10 :
134227 // T-simm13
135228 write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ));
136229 break ;
230+ case R_SPARC_GOT22:
231+ case R_SPARC_LM22:
232+ case R_SPARC_TLS_GD_HI22:
233+ case R_SPARC_TLS_LDM_HI22:
234+ case R_SPARC_TLS_LDO_HIX22: // Not V-simm22, despite binutils behavior.
235+ case R_SPARC_TLS_IE_HI22:
236+ // T-(s)imm22
237+ write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 10 ) & 0x003fffff ));
238+ break ;
239+ case R_SPARC_PC22:
240+ // V-disp22
241+ checkIntUInt (ctx, loc, val, 32 , rel);
242+ write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 10 ) & 0x003fffff ));
243+ break ;
137244 case R_SPARC_64:
245+ case R_SPARC_DISP64:
138246 case R_SPARC_UA64:
139247 // V-xword64
140248 write64be (loc, val);
141249 break ;
142250 case R_SPARC_HH22:
143251 // V-imm22
144- checkUInt (ctx, loc, val >> 42 , 22 , rel);
145252 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 42 ) & 0x003fffff ));
146253 break ;
147254 case R_SPARC_HM10:
148255 // T-simm13
149- write32be (loc, (read32be (loc) & ~0x00001fff ) | ((val >> 32 ) & 0x000003ff ));
256+ write32be (loc, (read32be (loc) & ~0x000003ff ) | ((val >> 32 ) & 0x000003ff ));
257+ break ;
258+ case R_SPARC_WDISP16:
259+ // V-d2/disp14
260+ checkIntUInt (ctx, loc, val, 18 , rel);
261+ write32be (loc, (read32be (loc) & ~0x0303fff ) | (((val >> 2 ) & 0xc000 ) << 6 ) |
262+ ((val >> 2 ) & 0x00003fff ));
263+ break ;
264+ case R_SPARC_WDISP19:
265+ // V-disp19
266+ checkIntUInt (ctx, loc, val, 21 , rel);
267+ write32be (loc, (read32be (loc) & ~0x0007ffff ) | ((val >> 2 ) & 0x0007ffff ));
268+ break ;
269+ case R_SPARC_HIX22:
270+ // V-imm22
271+ checkUInt (ctx, loc, ~val, 32 , rel);
272+ write32be (loc, (read32be (loc) & ~0x003fffff ) | ((~val >> 10 ) & 0x003fffff ));
273+ break ;
274+ case R_SPARC_LOX10:
275+ case R_SPARC_TLS_LE_LOX10:
276+ // T-simm13
277+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) | 0x1c00 );
150278 break ;
151279 case R_SPARC_H44:
152280 // V-imm22
153- checkUInt (ctx, loc, val >> 22 , 22 , rel);
281+ checkUInt (ctx, loc, val, 44 , rel);
154282 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 22 ) & 0x003fffff ));
155283 break ;
156284 case R_SPARC_M44:
@@ -159,21 +287,90 @@ void SPARCV9::relocate(uint8_t *loc, const Relocation &rel,
159287 break ;
160288 case R_SPARC_L44:
161289 // T-imm13
162- write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x00000fff ));
290+ write32be (loc, (read32be (loc) & ~0x00000fff ) | (val & 0x00000fff ));
163291 break ;
164- case R_SPARC_TLS_LE_HIX22:
292+ case R_SPARC_TLS_GD_ADD:
293+ case R_SPARC_TLS_LDM_ADD:
294+ case R_SPARC_TLS_LDO_ADD:
295+ case R_SPARC_TLS_IE_LD:
296+ case R_SPARC_TLS_IE_LDX:
297+ case R_SPARC_TLS_IE_ADD:
298+ // None
299+ break ;
300+ case R_SPARC_TLS_LE_HIX22: // Not V-imm2, despite binutils behavior.
165301 // T-imm22
166302 write32be (loc, (read32be (loc) & ~0x003fffff ) | ((~val >> 10 ) & 0x003fffff ));
167303 break ;
168- case R_SPARC_TLS_LE_LOX10:
169- // T-simm13
170- write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) | 0x1C00 );
304+ case R_SPARC_GOTDATA_HIX22:
305+ // V-imm22
306+ checkUInt (ctx, loc, ((int64_t )val < 0 ? ~val : val), 32 , rel);
307+ write32be (loc, (read32be (loc) & ~0x003fffff ) |
308+ ((((int64_t )val < 0 ? ~val : val) >> 10 ) & 0x003fffff ));
309+ break ;
310+ case R_SPARC_GOTDATA_OP_HIX22: // Not V-imm22, despite binutils behavior.
311+ // Non-relaxed case.
312+ // T-imm22
313+ write32be (loc, (read32be (loc) & ~0x003fffff ) |
314+ ((((int64_t )val < 0 ? ~val : val) >> 10 ) & 0x003fffff ));
315+ break ;
316+ case R_SPARC_GOTDATA_LOX10:
317+ case R_SPARC_GOTDATA_OP_LOX10: // Non-relaxed case.
318+ // T-imm13
319+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) |
320+ ((int64_t )val < 0 ? 0x1c00 : 0 ));
321+ break ;
322+ case R_SPARC_GOTDATA_OP: // Non-relaxed case.
323+ // word32
324+ // Nothing needs to be done in the non-relaxed case.
171325 break ;
172326 default :
173327 llvm_unreachable (" unknown relocation" );
174328 }
175329}
176330
331+ RelExpr SPARCV9::adjustGotOffExpr (RelType type, const Symbol &sym,
332+ int64_t addend, const uint8_t *loc) const {
333+ switch (type) {
334+ case R_SPARC_GOTDATA_OP_HIX22:
335+ case R_SPARC_GOTDATA_OP_LOX10:
336+ case R_SPARC_GOTDATA_OP:
337+ if (sym.isLocal ())
338+ return R_RELAX_GOT_OFF;
339+
340+ [[fallthrough]];
341+ default :
342+ return R_GOT_OFF;
343+ }
344+ }
345+
346+ void SPARCV9::relaxGot (uint8_t *loc, const Relocation &rel,
347+ uint64_t val) const {
348+ switch (rel.type ) {
349+ case R_SPARC_GOTDATA_OP_HIX22: // Not V-imm22, despite binutils behavior.
350+ // T-imm22
351+ write32be (loc, (read32be (loc) & ~0x003fffff ) |
352+ ((((int64_t )val < 0 ? ~val : val) >> 10 ) & 0x003fffff ));
353+ break ;
354+ case R_SPARC_GOTDATA_OP_LOX10:
355+ // T-imm13
356+ write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ) |
357+ ((int64_t )val < 0 ? 0x1c00 : 0 ));
358+ break ;
359+ case R_SPARC_GOTDATA_OP:
360+ // word32
361+ // ldx [%rs1 + %rs2], %rd -> add %rs1, %rs2, %rd
362+ write32be (loc, (read32be (loc) & 0x3e07c01f ) | 0x80000000 );
363+ break ;
364+ default :
365+ llvm_unreachable (" unknown relocation" );
366+ }
367+ }
368+
369+ void SPARCV9::writeGotHeader (uint8_t *buf) const {
370+ // _GLOBAL_OFFSET_TABLE_[0] = _DYNAMIC
371+ write32 (ctx, buf, ctx.mainPart ->dynamic ->getVA ());
372+ }
373+
177374void SPARCV9::writePlt (uint8_t *buf, const Symbol & /* sym*/ ,
178375 uint64_t pltEntryAddr) const {
179376 const uint8_t pltData[] = {
0 commit comments