aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2007-09-25 08:27:39 +0000
committerAlan Modra <amodra@gmail.com>2007-09-25 08:27:39 +0000
commit2cb5950ea381372122f39de325d985e0c828ece2 (patch)
treeefedc3c8cf7179fe80ae7bc559f76bf2cd4a2da1
parent98e89a7d8460331aaf46665d74bbc6491cfac14d (diff)
downloadgdb-2cb5950ea381372122f39de325d985e0c828ece2.zip
gdb-2cb5950ea381372122f39de325d985e0c828ece2.tar.gz
gdb-2cb5950ea381372122f39de325d985e0c828ece2.tar.bz2
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.
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/elf32-spu.c69
-rw-r--r--ld/testsuite/ChangeLog5
-rw-r--r--ld/testsuite/ld-spu/ovl.d12
-rw-r--r--ld/testsuite/ld-spu/ovl2.d3
5 files changed, 93 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7a78343..61ebc18 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index f6a5a60..3ca2367 100644
--- a/bfd/elf32-spu.c
+++ b/bfd/elf32-spu.c
@@ -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)
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index cc46a65..519fe24 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -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
diff --git a/ld/testsuite/ld-spu/ovl.d b/ld/testsuite/ld-spu/ovl.d
index 5f126fc..0f3deb2 100644
--- a/ld/testsuite/ld-spu/ovl.d
+++ b/ld/testsuite/ld-spu/ovl.d
@@ -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
diff --git a/ld/testsuite/ld-spu/ovl2.d b/ld/testsuite/ld-spu/ovl2.d
index 52b362d..e4a47a6 100644
--- a/ld/testsuite/ld-spu/ovl2.d
+++ b/ld/testsuite/ld-spu/ovl2.d
@@ -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: