powerpc64 unaligned relocs

Jakub Jelinek jakub@redhat.com
Tue Jun 17 12:48:00 GMT 2003


On Tue, Jun 17, 2003 at 10:08:49PM +0930, Alan Modra wrote:
> Another one prompted by Jakub.
> 
> 	* elf64-ppc.c (ppc64_elf_relocate_section): Optimize unaligned relocs.

Thanks, but wouldn't it be better to move this right before
              if (skip)
                memset (&outrel, 0, sizeof outrel);
              else if (h != NULL
                       && !SYMBOL_REFERENCES_LOCAL (info, h)
                       && !is_opd)
                outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
	      else {....}
and do it on r_type instead of ELF64_R_TYPE (outrel.r_info)?
Otherwise, there might be unaligned R_PPC64_RELATIVE relocs still.
cat > test.s <<EOF
.section .data
.balign 16
foo:
.byte 1
.8byte foo
.skip 7
EOF
gcc -shared -o test.so test.s -nostdlib

> --- bfd/elf64-ppc.c	17 Jun 2003 09:10:41 -0000	1.104
> +++ bfd/elf64-ppc.c	17 Jun 2003 12:28:13 -0000
> @@ -8272,6 +8272,26 @@ ppc64_elf_relocate_section (output_bfd, 
>  		    }
>  		}
>  
> +	      /* Optimize unaligned reloc use.  */
> +	      if ((ELF64_R_TYPE (outrel.r_info) == R_PPC64_ADDR64
> +		   && (outrel.r_offset & 7) != 0)
> +		  || (ELF64_R_TYPE (outrel.r_info) == R_PPC64_UADDR64
> +		      && (outrel.r_offset & 7) == 0))
> +		outrel.r_info ^= (ELF64_R_INFO (0, R_PPC64_ADDR64)
> +				  ^ ELF64_R_INFO (0, R_PPC64_UADDR64));
> +	      else if ((ELF64_R_TYPE (outrel.r_info) == R_PPC64_ADDR32
> +			&& (outrel.r_offset & 3) != 0)
> +		       || (ELF64_R_TYPE (outrel.r_info) == R_PPC64_UADDR32
> +			   && (outrel.r_offset & 3) == 0))
> +		outrel.r_info ^= (ELF64_R_INFO (0, R_PPC64_ADDR32)
> +				  ^ ELF64_R_INFO (0, R_PPC64_UADDR32));
> +	      else if ((ELF64_R_TYPE (outrel.r_info) == R_PPC64_ADDR16
> +			&& (outrel.r_offset & 1) != 0)
> +		       || (ELF64_R_TYPE (outrel.r_info) == R_PPC64_UADDR16
> +			   && (outrel.r_offset & 1) == 0))
> +		outrel.r_info ^= (ELF64_R_INFO (0, R_PPC64_ADDR16)
> +				  ^ ELF64_R_INFO (0, R_PPC64_UADDR16));
> +
>  	      sreloc = elf_section_data (input_section)->sreloc;
>  	      if (sreloc == NULL)
>  		abort ();

	Jakub



More information about the Binutils mailing list