Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
Re: ld.so/sparc64: fix UA64 relocation mask selection and byte order
To:
Kirill A. Korinsky <kirill@korins.ky>
Cc:
tech@openbsd.org
Date:
Thu, 09 Jul 2026 14:05:59 +0200

Download raw body.

Thread
> Date: Thu, 09 Jul 2026 12:06:51 +0200
> From: Kirill A. Korinsky <kirill@korins.ky>
> 
> tech@,
> 
> tb@ continue to test my sparc64-by-llvm diff and he discovered a new issues.
> 
> After some search here and where I think I had spoted two separated issues
> in ld.so for sparc64.
> 
> The first one is missing comma. The relocation mask table is indexed by
> relocation number; the missing separator after the R_SPARC_6 entry shifts
> subsequent initializers, so R_SPARC_UA64 receives the R_SPARC_UA16 mask.
> Restore the table layout, otherwise only the low 16 bits of relocated 64 bit
> pointers survive.
> 
> Ok, the next one is byte order. The unaligned relocation path reconstructs
> the relocation target in SPARC byte order, but writes the adjusted value
> back least significant byte first; this reverses R_SPARC_UA64 results on a
> big endian target. Write the value back in target byte order, so relocated
> function pointers retain their canonical representation.
> 
> Ok?

Those fixes look correct; ok kettenis@

However, it worries me that you actually hit the RELOC_UNALIGNED()
cases.  To me that indicates that something isn't quite right in the
generated code.

> Index: libexec/ld.so/sparc64/rtld_machine.c
> ===================================================================
> RCS file: /home/cvs/src/libexec/ld.so/sparc64/rtld_machine.c,v
> diff -u -p -r1.72 rtld_machine.c
> --- libexec/ld.so/sparc64/rtld_machine.c	6 May 2026 08:07:05 -0000	1.72
> +++ libexec/ld.so/sparc64/rtld_machine.c	9 Jul 2026 09:55:55 -0000
> @@ -189,7 +189,7 @@ static const long reloc_target_bitmask[]
>  	_BM(22), _BM(10), _BM(22),	/* _PC_HH22, _PC_HM10, _PC_LM22 */
>  	_BM(16), _BM(19),		/* _WDISP16, _WDISP19 */
>  	-1,				/* GLOB_JMP */
> -	_BM(7), _BM(5), _BM(6)		/* _7, _5, _6 */
> +	_BM(7), _BM(5), _BM(6),		/* _7, _5, _6 */
>  	-1, -1,				/* DISP64, PLT64 */
>  	_BM(22), _BM(13),		/* HIX22, LOX10 */
>  	_BM(22), _BM(10), _BM(13),	/* H44, M44, L44 */
> @@ -328,7 +328,7 @@ resolve_failed:
>  
>  			/* Write it back out. */
>  			for (i=0; i<size; i++)
> -				ptr[i] = ((tmp >> (8*i)) & 0xff);
> +				ptr[i] = ((tmp >> (8*(size - i - 1))) & 0xff);
>  		} else if (RELOC_TARGET_SIZE(type) > 32) {
>  			*where &= ~mask;
>  			*where |= value;
> 
> 
> -- 
> wbr, Kirill
> 
>