diff options
author | Alan Modra <amodra@gmail.com> | 2007-09-25 08:27:39 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2007-09-25 08:27:39 +0000 |
commit | 2cb5950ea381372122f39de325d985e0c828ece2 (patch) | |
tree | efedc3c8cf7179fe80ae7bc559f76bf2cd4a2da1 | |
parent | 98e89a7d8460331aaf46665d74bbc6491cfac14d (diff) | |
download | gdb-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/ChangeLog | 4 | ||||
-rw-r--r-- | bfd/elf32-spu.c | 69 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-spu/ovl.d | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-spu/ovl2.d | 3 |
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: |