[Cbe-oss-dev] [PATCH] libspe2: Extended __ea support

Alan Modra amodra at bigpond.net.au
Sat Apr 12 17:47:07 EST 2008


On Fri, Apr 11, 2008 at 11:47:03PM +0900, Kazunori Asayama wrote:
> Alan Modra wrote:
> >+		if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU32)) {
> >+			Elf32_Word *loc = reloc_base + r->r_offset;
> >+			Elf32_Word v = (Elf32_Word)(long)start + r->r_addend;
> >+			/* Don't dirty pages unnecessarily.  */
> >+			if (*loc != v)
> >+				*loc = v;
> 
> IIRC, ELF images are embedded in the .rodata section.
> Is this write operation possible when the SPU ELF image is embedded in
> the PPU program?

The write won't be needed when embedded since the embedding process
will emit ppc or ppc64 relocs to relocate these fields.  However, I
had intended to change embedspu to put images into .data when an ._ea
section is detected.  The SPU needs to be able to write into ._ea.

> >+			DEBUG_PRINTF("PPU32(%p) = %#x\n", loc, v);
> >+		} else if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU32)) {
> 
> I guess that this line should be:
> 
> +		} else if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU64)) {
> 
> Right?

Oops, yes, indeed.  Corrected patch follows.

Signed-off-by: Alan Modra <amodra at bigpond.net.au>

-- 
Alan Modra
Australia Development Lab, IBM

diff -urp libspe2-2.2.80.orig/spebase/elf_loader.c libspe2-2.2.80/spebase/elf_loader.c
--- libspe2-2.2.80.orig/spebase/elf_loader.c	2008-03-25 22:30:47.000000000 +1030
+++ libspe2-2.2.80/spebase/elf_loader.c	2008-04-12 17:03:43.000000000 +0930
@@ -197,6 +197,44 @@ copy_to_ld_buffer(spe_program_handle_t *
 	DEBUG_PRINTF("done ...\n");
 }
 
+/* Apply certain R_SPU_PPU* relocs in RH to SH.  We only handle relocs
+   without a symbol, which are to locations within ._ea.  */
+
+static void
+apply_relocations(spe_program_handle_t *handle, Elf32_Shdr *rh, Elf32_Shdr *sh)
+{
+#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;
+
+	r = start + rh->sh_offset;
+	r_end = (void *)r + rh->sh_size;
+	DEBUG_PRINTF("apply_relocations: %p, %#x\n", r, rh->sh_size);
+	for (; r < r_end; ++r)
+	{
+		if (r->r_info == ELF32_R_INFO(0,R_SPU_PPU32)) {
+			Elf32_Word *loc = reloc_base + r->r_offset;
+			Elf32_Word v = (Elf32_Word)(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)) {
+			Elf64_Xword *loc = reloc_base + r->r_offset;
+			Elf64_Xword v = (Elf64_Xword)(long)start + r->r_addend;
+			if (*loc != v)
+				*loc = v;
+			DEBUG_PRINTF("PPU64(%p) = %#llx\n", loc, v);
+		}
+	}
+}
+
 int
 _base_spe_load_spe_elf (spe_program_handle_t *handle, void *ld_buffer, struct spe_ld_info *ld_info)
 {
@@ -237,6 +275,8 @@ _base_spe_load_spe_elf (spe_program_hand
 	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;



More information about the cbe-oss-dev mailing list