bfd/
authorAlan Modra <amodra@gmail.com>
Tue, 25 Sep 2007 08:27:39 +0000 (08:27 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 25 Sep 2007 08:27:39 +0000 (08:27 +0000)
* 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.

bfd/ChangeLog
bfd/elf32-spu.c
ld/testsuite/ChangeLog
ld/testsuite/ld-spu/ovl.d
ld/testsuite/ld-spu/ovl2.d

index 7a7834314ad518e8aad69409ded5a38ec8452778..61ebc1874f4936bd8bb46769941119da78e03d6c 100644 (file)
@@ -1,5 +1,9 @@
 2007-09-25  Alan Modra  <amodra@bigpond.net.au>
 
+       * 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.
+
        * elf32-spu.c (struct spu_link_hash_table): Add "stubs".
        (spu_elf_link_hash_table_create): Init new field.
        (spu_elf_size_stubs): Store sorted stub syms in new htab field
index f6a5a60762d688d67ec17324ed97645f3c3af83c..3ca236793caa62fc12b1e1dc89ac8b7462732680 100644 (file)
@@ -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_entry *ent, struct bfd_link_info *info)
   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_entry *ent, struct bfd_link_info *info)
 
       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 cc46a65ff27f8c1d3293ec1523073f817a0dc5b3..519fe2430e6ac5b1f9fba1fba3120de4243a44a6 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-25  Alan Modra  <amodra@bigpond.net.au>
+
+       * ld-spu/ovl.d: Adjust for stub relocs.
+       * ld-spu/ovl2.d: Likewise.
+
 2007-09-20  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR 658
index 5f126fcc0c72feba9767efcd43193593d0ed828e..0f3deb20af4ff4d1218702c995c28472e0633e69 100644 (file)
@@ -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 52b362d9c2ad2dba40fe59ff7bcd0d3e3ed9d267..e4a47a62315144c9577cea83fe88c87e977af79d 100644 (file)
@@ -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: