[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