SPU overlay stub relocs

Alan Modra amodra@bigpond.net.au
Tue Sep 25 15:20:00 GMT 2007


Emits relocations on linker generated overlay call stubs, to help
post-link optimisation tools.

bfd/
	* elf32-spu.c (struct spu_link_hash_table): Add ovly_load_r_symndx.
	(spu_elf_size_stubs): Count stub relocs.
	(write_one_stub): Emit relocs on overlay call stubs.
ld/testsuite/
	* ld-spu/ovl.d: Adjust for stub relocs.
	* ld-spu/ovl2.d: Likewise.

Index: bfd/elf32-spu.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-spu.c,v
retrieving revision 1.23
diff -u -p -r1.23 elf32-spu.c
--- bfd/elf32-spu.c	25 Sep 2007 07:58:21 -0000	1.23
+++ bfd/elf32-spu.c	25 Sep 2007 08:01:22 -0000
@@ -272,6 +272,7 @@ struct spu_link_hash_table
   asection *ovtab;
 
   struct elf_link_hash_entry *ovly_load;
+  unsigned long ovly_load_r_symndx;
 
   /* An array of two output sections per overlay region, chosen such that
      the first section vma is the overlay buffer vma (ie. the section has
@@ -1148,12 +1149,16 @@ spu_elf_size_stubs (bfd *output_bfd,
 	{
 	  htab->stubs.sh[i]->off = htab->stub->size;
 	  htab->stub->size += SIZEOF_STUB1;
+	  if (info->emitrelocations)
+	    htab->stub->reloc_count += 1;
 	}
       else
 	htab->stubs.sh[i]->off = htab->stubs.sh[i - 1]->off;
     }
   if (group != i)
     htab->stub->size += SIZEOF_STUB2;
+  if (info->emitrelocations)
+    htab->stub->flags |= SEC_RELOC;
   for (; group != i; group++)
     htab->stubs.sh[group]->delta
       = htab->stubs.sh[i - 1]->off - htab->stubs.sh[group]->off;
@@ -1241,6 +1246,56 @@ write_one_stub (struct spu_stub_hash_ent
   bfd_put_32 (sec->owner, BR + ((val << 5) & 0x007fff80),
 	      sec->contents + ent->off + 4);
 
+  if (info->emitrelocations)
+    {
+      Elf_Internal_Rela *relocs, *r;
+      struct bfd_elf_section_data *elfsec_data;
+
+      elfsec_data = elf_section_data (sec);
+      relocs = elfsec_data->relocs;
+      if (relocs == NULL)
+	{
+	  bfd_size_type relsize;
+	  Elf_Internal_Shdr *symtab_hdr;
+	  struct elf_link_hash_entry **sym_hash;
+	  unsigned long symcount;
+	  bfd_vma amt;
+
+	  relsize = sec->reloc_count * sizeof (*relocs);
+	  relocs = bfd_alloc (sec->owner, relsize);
+	  if (relocs == NULL)
+	    return FALSE;
+	  elfsec_data->relocs = relocs;
+	  elfsec_data->rel_hdr.sh_size
+	    = sec->reloc_count * sizeof (Elf32_External_Rela);
+	  elfsec_data->rel_hdr.sh_entsize = sizeof (Elf32_External_Rela);
+	  sec->reloc_count = 0;
+
+	  /* Increase the size of symbol hash array on the bfd to
+	     which we attached our .stub section.  This hack allows
+	     us to create relocs against global symbols.  */
+	  symtab_hdr = &elf_tdata (sec->owner)->symtab_hdr;
+	  symcount = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
+	  symcount -= symtab_hdr->sh_info;
+	  amt = symcount * sizeof (*sym_hash);
+	  sym_hash = bfd_alloc (sec->owner, amt + sizeof (*sym_hash));
+	  if (sym_hash == NULL)
+	    return FALSE;
+	  memcpy (sym_hash, elf_sym_hashes (sec->owner), amt);
+	  sym_hash[symcount] = htab->ovly_load;
+	  htab->ovly_load_r_symndx = symcount + symtab_hdr->sh_info;
+	  elf_sym_hashes (sec->owner) = sym_hash;
+	}
+      r = relocs + sec->reloc_count;
+      sec->reloc_count += 1;
+      r->r_offset = ent->off + 4;
+      r->r_info = ELF32_R_INFO (0, R_SPU_REL16);
+      r->r_addend = (sec->output_section->vma
+		     + sec->output_offset
+		     + ent->off + 4
+		     + val);
+    }
+
   /* If this is the last stub of this group, write stub2.  */
   if (ent->delta == 0)
     {
@@ -1263,6 +1318,20 @@ write_one_stub (struct spu_stub_hash_ent
 
       bfd_put_32 (sec->owner, BR + ((val << 5) & 0x007fff80),
 		  sec->contents + ent->off + 12);
+
+      if (info->emitrelocations)
+	{
+	  Elf_Internal_Rela *relocs, *r;
+	  struct bfd_elf_section_data *elfsec_data;
+
+	  elfsec_data = elf_section_data (sec);
+	  relocs = elfsec_data->relocs;
+	  /* The last branch is overwritten, so overwrite its reloc too.  */
+	  r = relocs + sec->reloc_count - 1;
+	  r->r_offset = ent->off + 12;
+	  r->r_info = ELF32_R_INFO (htab->ovly_load_r_symndx, R_SPU_REL16);
+	  r->r_addend = 0;
+	}
     }
 
   if (htab->emit_stub_syms)
Index: ld/testsuite/ld-spu/ovl.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-spu/ovl.d,v
retrieving revision 1.3
diff -u -p -r1.3 ovl.d
--- ld/testsuite/ld-spu/ovl.d	14 Jun 2007 08:53:09 -0000	1.3
+++ ld/testsuite/ld-spu/ovl.d	25 Sep 2007 08:01:51 -0000
@@ -26,28 +26,40 @@ Disassembly of section \.text:
 
 0000012c <f0>:
  12c:	35 00 00 00 	bi	\$0
+
 00000130 <00000000\.ovl_call\.f1_a1>:
  130:	42 02 00 4f 	ila	\$79,1024	# 400
  134:	32 00 02 80 	br	148 .*
+			134: SPU_REL16	\*ABS\*\+0x148
+
 00000138 <00000000\.ovl_call\.f2_a1>:
  138:	42 02 02 4f 	ila	\$79,1028	# 404
  13c:	32 00 01 80 	br	148 .*
+			13c: SPU_REL16	\*ABS\*\+0x148
+
 00000140 <00000000\.ovl_call\.f4_a1>:
  140:	42 02 08 4f 	ila	\$79,1040	# 410
  144:	40 20 00 00 	nop	\$0
  148:	42 00 00 ce 	ila	\$78,1
  14c:	32 00 0a 80 	br	1a0 <__ovly_load>	# 1a0
+			14c: SPU_REL16	__ovly_load
+
 00000150 <00000000\.ovl_call\.f1_a2>:
  150:	42 02 00 4f 	ila	\$79,1024	# 400
  154:	32 00 02 80 	br	168 .*
+			154: SPU_REL16	\*ABS\*\+0x168
+
 00000158 <00000000\.ovl_call\.f2_a2>:
  158:	42 02 12 4f 	ila	\$79,1060	# 424
  15c:	32 00 01 80 	br	168 .*
+			15c: SPU_REL16	\*ABS\*\+0x168
+
 00000160 <00000000\.ovl_call\.14:8>:
  160:	42 02 1a 4f 	ila	\$79,1076	# 434
  164:	40 20 00 00 	nop	\$0
  168:	42 00 01 4e 	ila	\$78,2
  16c:	32 00 06 80 	br	1a0 <__ovly_load>	# 1a0
+			16c: SPU_REL16	__ovly_load
 #...
 [0-9a-f]+ <__ovly_return>:
 [0-9a-f ]+:	3f e1 00 4e 	shlqbyi	\$78,\$0,4
Index: ld/testsuite/ld-spu/ovl2.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-spu/ovl2.d,v
retrieving revision 1.3
diff -u -p -r1.3 ovl2.d
--- ld/testsuite/ld-spu/ovl2.d	14 Jun 2007 08:53:09 -0000	1.3
+++ ld/testsuite/ld-spu/ovl2.d	25 Sep 2007 08:01:51 -0000
@@ -26,18 +26,21 @@ Disassembly of section \.text:
  124:	40 20 00 00 	nop	\$0
  128:	42 00 00 4e 	ila	\$78,0
  12c:	32 00 0a 80 	br	180 <__ovly_load>	# 180
+			12c: SPU_REL16	__ovly_load
 
 00000130 <00000000\.ovl_call.f1_a1>:
  130:	42 02 00 4f 	ila	\$79,1024	# 400
  134:	40 20 00 00 	nop	\$0
  138:	42 00 00 ce 	ila	\$78,1
  13c:	32 00 08 80 	br	180 <__ovly_load>	# 180
+			13c: SPU_REL16	__ovly_load
 
 00000140 <_SPUEAR_f1_a2>:
  140:	42 02 00 4f 	ila	\$79,1024	# 400
  144:	40 20 00 00 	nop	\$0
  148:	42 00 01 4e 	ila	\$78,2
  14c:	32 00 06 80 	br	180 <__ovly_load>	# 180
+			14c: SPU_REL16	__ovly_load
 #...
 Disassembly of section \.ov_a1:
 

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list