[Cbe-oss-dev] [PATCH] libspe2: Tweak extended __ea support

D. Herrendoerfer d.herrendoerfer at herrendoerfer.name
Fri May 16 00:19:22 EST 2008


Added to subversion,

thank you very much.

D.Herrendoerfer

On Mon, 2008-05-12 at 14:17 +0930, Alan Modra wrote:
> This patch delays libspe relocation processing until after the image
> has been copied to ld_buffer.  The benefit in doing so is that only
> relocations applied to the ._ea section need to be applied directly to
> the image.  Others that apply to loaded spu segments can be applied
> to ld_buffer, which potentially saves memory since their ppu image
> pages are not dirtied.
> 
> I've also fixed a bug in casting that could affect a 32-bit libspe
> handling an -mea64 spu object.  (Elf64_Xword)(long)start might result
> in the high 32 bits being set to 1's due to sign extension.  I don't
> know whether this is a problem in practice, but it seems better to be
> safe by keeping the high 32 bits zero in this case.
> 
> Signed-off-by: Alan Modra <amodra at bigpond.net.au>
> 
> -- 
> Alan Modra
> Australia Development Lab, IBM
> 
> diff -urp libspe2-2.2.80.old/spebase/elf_loader.c libspe2-2.2.80/spebase/elf_loader.c
> --- libspe2-2.2.80.old/spebase/elf_loader.c	2008-04-12 17:03:43.000000000 +0930
> +++ libspe2-2.2.80/spebase/elf_loader.c	2008-05-12 07:53:27.000000000 +0930
> @@ -201,17 +201,26 @@ copy_to_ld_buffer(spe_program_handle_t *
>     without a symbol, which are to locations within ._ea.  */
>  
>  static void
> -apply_relocations(spe_program_handle_t *handle, Elf32_Shdr *rh, Elf32_Shdr *sh)
> +apply_relocations (spe_program_handle_t *handle,
> +		   void *buf,
> +		   Elf32_Shdr *rh,
> +		   Elf32_Shdr *sh,
> +		   Elf32_Shdr *eah)
>  {
>  #define R_SPU_PPU32 15
>  #define R_SPU_PPU64 16
>  	void *start = handle->elf_image;
>  	Elf32_Rela *r, *r_end;
> -	/* Relocations in an executable specify r_offset as a virtual
> -	   address, but we are applying the reloc in the image before
> -	   the section has been copied to its destination sh_addr.
> -	   Adjust so as to poke relative to the image base.  */
> -	void *reloc_base = start + sh->sh_offset - sh->sh_addr;
> +	void *reloc_base = buf;
> +
> +	if (sh == eah)
> +	{
> +		/* Relocations in an executable specify r_offset as a
> +		   virtual address, but if we are applying relocs for
> +		   ._ea then the location we want is in the image.
> +		   Adjust so as to poke relative to the image base.  */
> +		reloc_base = start + sh->sh_offset - sh->sh_addr;
> +	}
>  
>  	r = start + rh->sh_offset;
>  	r_end = (void *)r + rh->sh_size;
> @@ -219,15 +228,17 @@ apply_relocations(spe_program_handle_t *
>  	for (; r < r_end; ++r)
>  	{
>  		if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU32)) {
> +			/* v is in ._ea */
>  			Elf32_Word *loc = reloc_base + r->r_offset;
> -			Elf32_Word v = (Elf32_Word)(long)start + r->r_addend;
> +			Elf32_Word v = (unsigned long)start + r->r_addend;
>  			/* Don't dirty pages unnecessarily.  */
>  			if (*loc != v)
>  				*loc = v;
>  			DEBUG_PRINTF("PPU32(%p) = %#x\n", loc, v);
>  		} else if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU64)) {
> +			/* v is in ._ea */
>  			Elf64_Xword *loc = reloc_base + r->r_offset;
> -			Elf64_Xword v = (Elf64_Xword)(long)start + r->r_addend;
> +			Elf64_Xword v = (unsigned long)start + r->r_addend;
>  			if (*loc != v)
>  				*loc = v;
>  			DEBUG_PRINTF("PPU64(%p) = %#llx\n", loc, v);
> @@ -244,6 +255,7 @@ _base_spe_load_spe_elf (spe_program_hand
>  
>  	Elf32_Shdr *shdr;
>  	Elf32_Shdr *sh;
> +	Elf32_Shdr *eah;
>  
>  	Elf32_Off  toe_addr = 0;
>  	long	toe_size = 0;
> @@ -272,17 +284,18 @@ _base_spe_load_spe_elf (spe_program_hand
>  
>  	/* traverse the sections to locate the toe segment */
>  	/* by specification, the toe sections are grouped together in a segment */
> +	eah = 0;
>  	for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh)
>  	{
>  		DEBUG_PRINTF("section name: %s ( start: 0x%04x, size: 0x%04x)\n", str_table+sh->sh_name, sh->sh_offset, sh->sh_size );
> -		if (sh->sh_type == SHT_RELA)
> -			apply_relocations(handle, sh, &shdr[sh->sh_info]);
>  		if (strcmp(".toe", str_table+sh->sh_name) == 0) {
>  			DEBUG_PRINTF("section offset: %d\n", sh->sh_offset);
>  			toe_size += sh->sh_size;
>  			if ((toe_addr == 0) || (toe_addr > sh->sh_addr))
>  				toe_addr = sh->sh_addr;
>  		}
> +		else if (strcmp("._ea", str_table+sh->sh_name) == 0)
> +			eah = sh;
>  		/* Disabled : Actually not needed, only good for testing
>  		if (strcmp(".bss", str_table+sh->sh_name) == 0) {
>  			DEBUG_PRINTF("zeroing .bss section:\n");
> @@ -328,6 +341,12 @@ _base_spe_load_spe_elf (spe_program_hand
>  		  return -errno;
>  	  }
>  
> +	if (eah)
> +		for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh)
> +			if (sh->sh_type == SHT_RELA)
> +				apply_relocations (handle, ld_buffer,
> +						   sh, &shdr[sh->sh_info], eah);
> +
>  	/* Remember where the code wants to be started */
>  	ld_info->entry = ehdr->e_entry;
>  	DEBUG_PRINTF ("entry = 0x%x\n", ehdr->e_entry);
> _______________________________________________
> cbe-oss-dev mailing list
> cbe-oss-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/cbe-oss-dev




More information about the cbe-oss-dev mailing list