@@ -390,7 +390,8 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
390390 }
391391 } else {
392392 u32 rs2 = bits (*(ub32 *)loc, 4 , 0 );
393- *(ub32 *)loc = 0x9001'c000 | rs2; // add %g7, %reg, %o0
393+ u32 rd = bits (*(ub32 *)loc, 29 , 25 );
394+ *(ub32 *)loc = 0x9001'c000 | (rd << 25 ) | rs2; // add %g7, %reg, %rd
394395 }
395396 break ;
396397 case R_SPARC_TLS_GD_CALL:
@@ -420,7 +421,8 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
420421 // do nothing
421422 } else {
422423 u32 rs2 = bits (*(ub32 *)loc, 4 , 0 );
423- *(ub32 *)loc = 0x9021'c000 | rs2; // sub %g7, %reg, %o0
424+ u32 rd = bits (*(ub32 *)loc, 29 , 25 );
425+ *(ub32 *)loc = 0x9021'c000 | (rd << 25 ) | rs2; // sub %g7, %reg, %rd
424426 }
425427 break ;
426428 case R_SPARC_TLS_LDM_CALL:
@@ -429,6 +431,13 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
429431 *(ub32 *)loc |= bits (addr + A - P, 31 , 2 );
430432 } else {
431433 *(ub32 *)loc = 0x0100'0000 ; // nop
434+
435+ // If the argument to __tls_get_addr is set in the delay slot of the call,
436+ // turn the delay slot instruction into a nop too.
437+ u32 ds_rd = bits (*(ub32 *)(loc + 4 ), 29 , 25 );
438+ if (ds_rd == 8 ) { // rd is %o0
439+ *(ub32 *)(loc + 4 ) = 0x0100'0000 ; // nop
440+ }
432441 }
433442 break ;
434443 case R_SPARC_TLS_LDO_HIX22:
0 commit comments