6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
9
+ #include " OutputSections.h"
9
10
#include " Symbols.h"
10
11
#include " SyntheticSections.h"
11
12
#include " Target.h"
@@ -24,10 +25,17 @@ class SPARCV9 final : public TargetInfo {
24
25
SPARCV9 (Ctx &);
25
26
RelExpr getRelExpr (RelType type, const Symbol &s,
26
27
const uint8_t *loc) const override ;
28
+ RelType getDynRel (RelType type) const override ;
29
+ void writeGotHeader (uint8_t *buf) const override ;
27
30
void writePlt (uint8_t *buf, const Symbol &sym,
28
31
uint64_t pltEntryAddr) const override ;
29
32
void relocate (uint8_t *loc, const Relocation &rel,
30
33
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 ;
31
39
};
32
40
} // namespace
33
41
@@ -36,9 +44,16 @@ SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {
36
44
gotRel = R_SPARC_GLOB_DAT;
37
45
pltRel = R_SPARC_JMP_SLOT;
38
46
relativeRel = R_SPARC_RELATIVE;
47
+ iRelativeRel = R_SPARC_IRELATIVE;
39
48
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 ;
40
54
pltEntrySize = 32 ;
41
55
pltHeaderSize = 4 * pltEntrySize;
56
+ usesGotPlt = false ;
42
57
43
58
defaultCommonPageSize = 8192 ;
44
59
defaultMaxPageSize = 0x100000 ;
@@ -48,109 +63,222 @@ SPARCV9::SPARCV9(Ctx &ctx) : TargetInfo(ctx) {
48
63
RelExpr SPARCV9::getRelExpr (RelType type, const Symbol &s,
49
64
const uint8_t *loc) const {
50
65
switch (type) {
66
+ case R_SPARC_NONE:
67
+ return R_NONE;
68
+ case R_SPARC_8:
69
+ case R_SPARC_16:
51
70
case R_SPARC_32:
71
+ case R_SPARC_HI22:
72
+ case R_SPARC_13:
73
+ case R_SPARC_LO10:
52
74
case R_SPARC_UA32:
53
75
case R_SPARC_64:
54
- case R_SPARC_UA64:
55
- case R_SPARC_H44:
56
- case R_SPARC_M44:
57
- case R_SPARC_L44:
58
76
case R_SPARC_HH22:
59
77
case R_SPARC_HM10:
60
78
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:
63
86
return R_ABS;
64
- case R_SPARC_PC10 :
65
- case R_SPARC_PC22 :
87
+ case R_SPARC_DISP8 :
88
+ case R_SPARC_DISP16 :
66
89
case R_SPARC_DISP32:
67
90
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:
68
96
return R_PC;
69
97
case R_SPARC_GOT10:
70
- return R_GOT_OFF;
98
+ case R_SPARC_GOT13:
71
99
case R_SPARC_GOT22:
100
+ case R_SPARC_GOTDATA_OP_HIX22:
101
+ case R_SPARC_GOTDATA_OP_LOX10:
102
+ case R_SPARC_GOTDATA_OP:
72
103
return R_GOT_OFF;
73
104
case R_SPARC_WPLT30:
105
+ case R_SPARC_TLS_GD_CALL:
106
+ case R_SPARC_TLS_LDM_CALL:
74
107
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;
77
127
case R_SPARC_TLS_LE_HIX22:
78
128
case R_SPARC_TLS_LE_LOX10:
79
129
return R_TPREL;
130
+ case R_SPARC_GOTDATA_HIX22:
131
+ case R_SPARC_GOTDATA_LOX10:
132
+ return R_GOTREL;
80
133
default :
81
134
Err (ctx) << getErrorLoc (ctx, loc) << " unknown relocation (" << type.v
82
135
<< " ) against symbol " << &s;
83
136
return R_NONE;
84
137
}
85
138
}
86
139
140
+ RelType SPARCV9::getDynRel (RelType type) const {
141
+ if (type == symbolicRel)
142
+ return type;
143
+ return R_SPARC_NONE;
144
+ }
145
+
87
146
void SPARCV9::relocate (uint8_t *loc, const Relocation &rel,
88
147
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
+
89
155
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 ;
90
167
case R_SPARC_32:
91
168
case R_SPARC_UA32:
92
169
// V-word32
93
170
checkUInt (ctx, loc, val, 32 , rel);
94
171
write32be (loc, val);
95
172
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 ;
96
183
case R_SPARC_DISP32:
97
184
// V-disp32
98
- checkInt (ctx, loc, val, 32 , rel);
185
+ checkIntUInt (ctx, loc, val, 32 , rel);
99
186
write32be (loc, val);
100
187
break ;
101
188
case R_SPARC_WDISP30:
102
189
case R_SPARC_WPLT30:
190
+ case R_SPARC_TLS_GD_CALL:
191
+ case R_SPARC_TLS_LDM_CALL:
103
192
// V-disp30
104
- checkInt (ctx, loc, val, 32 , rel);
193
+ checkIntUInt (ctx, loc, val, 32 , rel);
105
194
write32be (loc, (read32be (loc) & ~0x3fffffff ) | ((val >> 2 ) & 0x3fffffff ));
106
195
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 ));
111
200
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);
116
204
write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 10 ) & 0x003fffff ));
117
205
break ;
118
- case R_SPARC_HI22 :
206
+ case R_SPARC_22 :
119
207
// 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 ));
122
210
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 ));
127
216
break ;
217
+ case R_SPARC_LO10:
128
218
case R_SPARC_GOT10:
129
219
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
131
224
write32be (loc, (read32be (loc) & ~0x000003ff ) | (val & 0x000003ff ));
132
225
break ;
133
- case R_SPARC_LO10 :
226
+ case R_SPARC_TLS_LDO_LOX10 :
134
227
// T-simm13
135
228
write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x000003ff ));
136
229
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 ;
137
244
case R_SPARC_64:
245
+ case R_SPARC_DISP64:
138
246
case R_SPARC_UA64:
139
247
// V-xword64
140
248
write64be (loc, val);
141
249
break ;
142
250
case R_SPARC_HH22:
143
251
// V-imm22
144
- checkUInt (ctx, loc, val >> 42 , 22 , rel);
145
252
write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 42 ) & 0x003fffff ));
146
253
break ;
147
254
case R_SPARC_HM10:
148
255
// 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 );
150
278
break ;
151
279
case R_SPARC_H44:
152
280
// V-imm22
153
- checkUInt (ctx, loc, val >> 22 , 22 , rel);
281
+ checkUInt (ctx, loc, val, 44 , rel);
154
282
write32be (loc, (read32be (loc) & ~0x003fffff ) | ((val >> 22 ) & 0x003fffff ));
155
283
break ;
156
284
case R_SPARC_M44:
@@ -159,21 +287,90 @@ void SPARCV9::relocate(uint8_t *loc, const Relocation &rel,
159
287
break ;
160
288
case R_SPARC_L44:
161
289
// T-imm13
162
- write32be (loc, (read32be (loc) & ~0x00001fff ) | (val & 0x00000fff ));
290
+ write32be (loc, (read32be (loc) & ~0x00000fff ) | (val & 0x00000fff ));
163
291
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.
165
301
// T-imm22
166
302
write32be (loc, (read32be (loc) & ~0x003fffff ) | ((~val >> 10 ) & 0x003fffff ));
167
303
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.
171
325
break ;
172
326
default :
173
327
llvm_unreachable (" unknown relocation" );
174
328
}
175
329
}
176
330
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
+
177
374
void SPARCV9::writePlt (uint8_t *buf, const Symbol & /* sym*/ ,
178
375
uint64_t pltEntryAddr) const {
179
376
const uint8_t pltData[] = {
0 commit comments