@@ -41,6 +41,21 @@ namespace mold::elf {
41
41
42
42
using E = S390X;
43
43
44
+ static void write_low12 (u8 *loc, u64 val) {
45
+ *(ub16 *)loc &= 0xf000 ;
46
+ *(ub16 *)loc |= val & 0x0fff ;
47
+ }
48
+
49
+ static void write_mid20 (u8 *loc, u64 val) {
50
+ *(ub32 *)loc &= 0xf000'00ff ;
51
+ *(ub32 *)loc |= (bits (val, 11 , 0 ) << 16 ) | (bits (val, 19 , 12 ) << 8 );
52
+ }
53
+
54
+ static void write_low24 (u8 *loc, u64 val) {
55
+ *(ub32 *)loc &= 0xff00'0000 ;
56
+ *(ub32 *)loc |= val & 0x00ff'ffff ;
57
+ }
58
+
44
59
template <>
45
60
void write_plt_header (Context<E> &ctx, u8 *buf) {
46
61
static u8 insn[] = {
@@ -133,8 +148,7 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
133
148
*loc = S + A;
134
149
break ;
135
150
case R_390_12:
136
- *(ub16 *)loc &= 0xf000 ;
137
- *(ub16 *)loc |= (S + A) & 0x0fff ;
151
+ write_low12 (loc, S + A);
138
152
break ;
139
153
case R_390_16:
140
154
*(ub16 *)loc = S + A;
@@ -146,15 +160,26 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
146
160
case R_390_PLT64:
147
161
*(ub64 *)loc = S + A;
148
162
break ;
163
+ case R_390_PC12DBL:
164
+ case R_390_PLT12DBL:
165
+ write_low12 (loc, (S + A - P) >> 1 );
166
+ break ;
149
167
case R_390_PC16:
150
168
*(ub16 *)loc = S + A - P;
151
169
break ;
170
+ case R_390_PC32:
171
+ *(ub32 *)loc = S + A - P;
172
+ break ;
173
+ case R_390_PC64:
174
+ *(ub64 *)loc = S + A - P;
175
+ break ;
152
176
case R_390_PC16DBL:
153
177
case R_390_PLT16DBL:
154
178
*(ub16 *)loc = (S + A - P) >> 1 ;
155
179
break ;
156
- case R_390_PC32:
157
- *(ub32 *)loc = S + A - P;
180
+ case R_390_PC24DBL:
181
+ case R_390_PLT24DBL:
182
+ write_low24 (loc, (S + A - P) >> 1 );
158
183
break ;
159
184
case R_390_PC32DBL:
160
185
case R_390_PLT32DBL:
@@ -166,26 +191,36 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
166
191
*(ub32 *)loc = (S + A - P) >> 1 ;
167
192
}
168
193
break ;
169
- case R_390_PC64:
170
- *(ub64 *)loc = S + A - P;
171
- break ;
172
194
case R_390_GOT12:
173
- *(ub16 *)loc &= 0xf000 ;
174
- *(ub16 *) loc |= ( G + A) & 0x0fff ;
195
+ case R_390_GOTPLT12:
196
+ write_low12 ( loc, G + A);
175
197
break ;
176
198
case R_390_GOT16:
199
+ case R_390_GOTPLT16:
177
200
*(ub16 *)loc = G + A;
178
201
break ;
202
+ case R_390_GOT20:
203
+ case R_390_GOTPLT20:
204
+ write_mid20 (loc, G + A);
205
+ break ;
179
206
case R_390_GOT32:
207
+ case R_390_GOTPLT32:
180
208
*(ub32 *)loc = G + A;
181
209
break ;
182
210
case R_390_GOT64:
211
+ case R_390_GOTPLT64:
183
212
*(ub64 *)loc = G + A;
184
213
break ;
185
214
case R_390_GOTOFF16:
215
+ case R_390_PLTOFF16:
186
216
*(ub16 *)loc = S + A - GOT;
187
217
break ;
218
+ case R_390_GOTOFF32:
219
+ case R_390_PLTOFF32:
220
+ *(ub32 *)loc = S + A - GOT;
221
+ break ;
188
222
case R_390_GOTOFF64:
223
+ case R_390_PLTOFF64:
189
224
*(ub64 *)loc = S + A - GOT;
190
225
break ;
191
226
case R_390_GOTPC:
@@ -203,12 +238,9 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
203
238
case R_390_TLS_LE64:
204
239
*(ub64 *)loc = S + A - ctx.tp_addr ;
205
240
break ;
206
- case R_390_TLS_GOTIE20: {
207
- i64 val = sym.get_gottp_addr (ctx) + A - GOT;
208
- *(ub32 *)loc &= 0xf000'00ff ;
209
- *(ub32 *)loc |= (bits (val, 11 , 0 ) << 16 ) | (bits (val, 19 , 12 ) << 8 );
241
+ case R_390_TLS_GOTIE20:
242
+ write_mid20 (loc, sym.get_gottp_addr (ctx) + A - GOT);
210
243
break ;
211
- }
212
244
case R_390_TLS_IEENT:
213
245
*(ub32 *)loc = (sym.get_gottp_addr (ctx) + A - P) >> 1 ;
214
246
break ;
@@ -359,19 +391,31 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
359
391
break ;
360
392
case R_390_GOT12:
361
393
case R_390_GOT16:
394
+ case R_390_GOT20:
362
395
case R_390_GOT32:
363
396
case R_390_GOT64:
364
397
case R_390_GOTOFF16:
398
+ case R_390_GOTOFF32:
365
399
case R_390_GOTOFF64:
400
+ case R_390_GOTPLT12:
401
+ case R_390_GOTPLT16:
402
+ case R_390_GOTPLT20:
403
+ case R_390_GOTPLT32:
404
+ case R_390_GOTPLT64:
366
405
case R_390_GOTPC:
367
406
case R_390_GOTPCDBL:
368
407
case R_390_GOTENT:
369
408
sym.flags |= NEEDS_GOT;
370
409
break ;
410
+ case R_390_PLT12DBL:
371
411
case R_390_PLT16DBL:
412
+ case R_390_PLT24DBL:
372
413
case R_390_PLT32:
373
414
case R_390_PLT32DBL:
374
415
case R_390_PLT64:
416
+ case R_390_PLTOFF16:
417
+ case R_390_PLTOFF32:
418
+ case R_390_PLTOFF64:
375
419
if (sym.is_imported )
376
420
sym.flags |= NEEDS_PLT;
377
421
break ;
0 commit comments