@@ -41,6 +41,21 @@ namespace mold::elf {
4141
4242using E = S390X;
4343
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+
4459template <>
4560void write_plt_header (Context<E> &ctx, u8 *buf) {
4661 static u8 insn[] = {
@@ -133,28 +148,41 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
133148 *loc = S + A;
134149 break ;
135150 case R_390_12:
136- *(ub16 *)loc &= 0xf000 ;
137- *(ub16 *)loc |= (S + A) & 0x0fff ;
151+ write_low12 (loc, S + A);
138152 break ;
139153 case R_390_16:
140154 *(ub16 *)loc = S + A;
141155 break ;
156+ case R_390_20:
157+ write_mid20 (loc, S + A);
158+ break ;
142159 case R_390_32:
143160 case R_390_PLT32:
144161 *(ub32 *)loc = S + A;
145162 break ;
146163 case R_390_PLT64:
147164 *(ub64 *)loc = S + A;
148165 break ;
166+ case R_390_PC12DBL:
167+ case R_390_PLT12DBL:
168+ write_low12 (loc, (S + A - P) >> 1 );
169+ break ;
149170 case R_390_PC16:
150171 *(ub16 *)loc = S + A - P;
151172 break ;
173+ case R_390_PC32:
174+ *(ub32 *)loc = S + A - P;
175+ break ;
176+ case R_390_PC64:
177+ *(ub64 *)loc = S + A - P;
178+ break ;
152179 case R_390_PC16DBL:
153180 case R_390_PLT16DBL:
154181 *(ub16 *)loc = (S + A - P) >> 1 ;
155182 break ;
156- case R_390_PC32:
157- *(ub32 *)loc = S + A - P;
183+ case R_390_PC24DBL:
184+ case R_390_PLT24DBL:
185+ write_low24 (loc, (S + A - P) >> 1 );
158186 break ;
159187 case R_390_PC32DBL:
160188 case R_390_PLT32DBL:
@@ -166,26 +194,36 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
166194 *(ub32 *)loc = (S + A - P) >> 1 ;
167195 }
168196 break ;
169- case R_390_PC64:
170- *(ub64 *)loc = S + A - P;
171- break ;
172197 case R_390_GOT12:
173- *(ub16 *)loc &= 0xf000 ;
174- *(ub16 *) loc |= ( G + A) & 0x0fff ;
198+ case R_390_GOTPLT12:
199+ write_low12 ( loc, G + A);
175200 break ;
176201 case R_390_GOT16:
202+ case R_390_GOTPLT16:
177203 *(ub16 *)loc = G + A;
178204 break ;
205+ case R_390_GOT20:
206+ case R_390_GOTPLT20:
207+ write_mid20 (loc, G + A);
208+ break ;
179209 case R_390_GOT32:
210+ case R_390_GOTPLT32:
180211 *(ub32 *)loc = G + A;
181212 break ;
182213 case R_390_GOT64:
214+ case R_390_GOTPLT64:
183215 *(ub64 *)loc = G + A;
184216 break ;
185217 case R_390_GOTOFF16:
218+ case R_390_PLTOFF16:
186219 *(ub16 *)loc = S + A - GOT;
187220 break ;
221+ case R_390_GOTOFF32:
222+ case R_390_PLTOFF32:
223+ *(ub32 *)loc = S + A - GOT;
224+ break ;
188225 case R_390_GOTOFF64:
226+ case R_390_PLTOFF64:
189227 *(ub64 *)loc = S + A - GOT;
190228 break ;
191229 case R_390_GOTPC:
@@ -203,12 +241,9 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
203241 case R_390_TLS_LE64:
204242 *(ub64 *)loc = S + A - ctx.tp_addr ;
205243 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 );
244+ case R_390_TLS_GOTIE20:
245+ write_mid20 (loc, sym.get_gottp_addr (ctx) + A - GOT);
210246 break ;
211- }
212247 case R_390_TLS_IEENT:
213248 *(ub32 *)loc = (sym.get_gottp_addr (ctx) + A - P) >> 1 ;
214249 break ;
@@ -347,6 +382,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
347382 case R_390_8:
348383 case R_390_12:
349384 case R_390_16:
385+ case R_390_20:
350386 case R_390_32:
351387 scan_rel (ctx, sym, rel, absrel_table);
352388 break ;
@@ -359,19 +395,31 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
359395 break ;
360396 case R_390_GOT12:
361397 case R_390_GOT16:
398+ case R_390_GOT20:
362399 case R_390_GOT32:
363400 case R_390_GOT64:
364401 case R_390_GOTOFF16:
402+ case R_390_GOTOFF32:
365403 case R_390_GOTOFF64:
404+ case R_390_GOTPLT12:
405+ case R_390_GOTPLT16:
406+ case R_390_GOTPLT20:
407+ case R_390_GOTPLT32:
408+ case R_390_GOTPLT64:
366409 case R_390_GOTPC:
367410 case R_390_GOTPCDBL:
368411 case R_390_GOTENT:
369412 sym.flags |= NEEDS_GOT;
370413 break ;
414+ case R_390_PLT12DBL:
371415 case R_390_PLT16DBL:
416+ case R_390_PLT24DBL:
372417 case R_390_PLT32:
373418 case R_390_PLT32DBL:
374419 case R_390_PLT64:
420+ case R_390_PLTOFF16:
421+ case R_390_PLTOFF32:
422+ case R_390_PLTOFF64:
375423 if (sym.is_imported )
376424 sym.flags |= NEEDS_PLT;
377425 break ;
0 commit comments