* 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.
This commit is contained in:
Alan Modra
2007-09-25 08:27:39 +00:00
parent 98e89a7d84
commit 2cb5950ea3
5 changed files with 93 additions and 0 deletions

View File

@ -1,5 +1,9 @@
2007-09-25 Alan Modra <amodra@bigpond.net.au> 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". * elf32-spu.c (struct spu_link_hash_table): Add "stubs".
(spu_elf_link_hash_table_create): Init new field. (spu_elf_link_hash_table_create): Init new field.
(spu_elf_size_stubs): Store sorted stub syms in new htab field (spu_elf_size_stubs): Store sorted stub syms in new htab field

View File

@ -272,6 +272,7 @@ struct spu_link_hash_table
asection *ovtab; asection *ovtab;
struct elf_link_hash_entry *ovly_load; 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 /* 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 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->stubs.sh[i]->off = htab->stub->size;
htab->stub->size += SIZEOF_STUB1; htab->stub->size += SIZEOF_STUB1;
if (info->emitrelocations)
htab->stub->reloc_count += 1;
} }
else else
htab->stubs.sh[i]->off = htab->stubs.sh[i - 1]->off; htab->stubs.sh[i]->off = htab->stubs.sh[i - 1]->off;
} }
if (group != i) if (group != i)
htab->stub->size += SIZEOF_STUB2; htab->stub->size += SIZEOF_STUB2;
if (info->emitrelocations)
htab->stub->flags |= SEC_RELOC;
for (; group != i; group++) for (; group != i; group++)
htab->stubs.sh[group]->delta htab->stubs.sh[group]->delta
= htab->stubs.sh[i - 1]->off - htab->stubs.sh[group]->off; = 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), bfd_put_32 (sec->owner, BR + ((val << 5) & 0x007fff80),
sec->contents + ent->off + 4); 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 this is the last stub of this group, write stub2. */
if (ent->delta == 0) 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), bfd_put_32 (sec->owner, BR + ((val << 5) & 0x007fff80),
sec->contents + ent->off + 12); 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) if (htab->emit_stub_syms)

View 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> 2007-09-20 H.J. Lu <hongjiu.lu@intel.com>
PR 658 PR 658

View File

@ -26,28 +26,40 @@ Disassembly of section \.text:
0000012c <f0>: 0000012c <f0>:
12c: 35 00 00 00 bi \$0 12c: 35 00 00 00 bi \$0
00000130 <00000000\.ovl_call\.f1_a1>: 00000130 <00000000\.ovl_call\.f1_a1>:
130: 42 02 00 4f ila \$79,1024 # 400 130: 42 02 00 4f ila \$79,1024 # 400
134: 32 00 02 80 br 148 .* 134: 32 00 02 80 br 148 .*
134: SPU_REL16 \*ABS\*\+0x148
00000138 <00000000\.ovl_call\.f2_a1>: 00000138 <00000000\.ovl_call\.f2_a1>:
138: 42 02 02 4f ila \$79,1028 # 404 138: 42 02 02 4f ila \$79,1028 # 404
13c: 32 00 01 80 br 148 .* 13c: 32 00 01 80 br 148 .*
13c: SPU_REL16 \*ABS\*\+0x148
00000140 <00000000\.ovl_call\.f4_a1>: 00000140 <00000000\.ovl_call\.f4_a1>:
140: 42 02 08 4f ila \$79,1040 # 410 140: 42 02 08 4f ila \$79,1040 # 410
144: 40 20 00 00 nop \$0 144: 40 20 00 00 nop \$0
148: 42 00 00 ce ila \$78,1 148: 42 00 00 ce ila \$78,1
14c: 32 00 0a 80 br 1a0 <__ovly_load> # 1a0 14c: 32 00 0a 80 br 1a0 <__ovly_load> # 1a0
14c: SPU_REL16 __ovly_load
00000150 <00000000\.ovl_call\.f1_a2>: 00000150 <00000000\.ovl_call\.f1_a2>:
150: 42 02 00 4f ila \$79,1024 # 400 150: 42 02 00 4f ila \$79,1024 # 400
154: 32 00 02 80 br 168 .* 154: 32 00 02 80 br 168 .*
154: SPU_REL16 \*ABS\*\+0x168
00000158 <00000000\.ovl_call\.f2_a2>: 00000158 <00000000\.ovl_call\.f2_a2>:
158: 42 02 12 4f ila \$79,1060 # 424 158: 42 02 12 4f ila \$79,1060 # 424
15c: 32 00 01 80 br 168 .* 15c: 32 00 01 80 br 168 .*
15c: SPU_REL16 \*ABS\*\+0x168
00000160 <00000000\.ovl_call\.14:8>: 00000160 <00000000\.ovl_call\.14:8>:
160: 42 02 1a 4f ila \$79,1076 # 434 160: 42 02 1a 4f ila \$79,1076 # 434
164: 40 20 00 00 nop \$0 164: 40 20 00 00 nop \$0
168: 42 00 01 4e ila \$78,2 168: 42 00 01 4e ila \$78,2
16c: 32 00 06 80 br 1a0 <__ovly_load> # 1a0 16c: 32 00 06 80 br 1a0 <__ovly_load> # 1a0
16c: SPU_REL16 __ovly_load
#... #...
[0-9a-f]+ <__ovly_return>: [0-9a-f]+ <__ovly_return>:
[0-9a-f ]+: 3f e1 00 4e shlqbyi \$78,\$0,4 [0-9a-f ]+: 3f e1 00 4e shlqbyi \$78,\$0,4

View File

@ -26,18 +26,21 @@ Disassembly of section \.text:
124: 40 20 00 00 nop \$0 124: 40 20 00 00 nop \$0
128: 42 00 00 4e ila \$78,0 128: 42 00 00 4e ila \$78,0
12c: 32 00 0a 80 br 180 <__ovly_load> # 180 12c: 32 00 0a 80 br 180 <__ovly_load> # 180
12c: SPU_REL16 __ovly_load
00000130 <00000000\.ovl_call.f1_a1>: 00000130 <00000000\.ovl_call.f1_a1>:
130: 42 02 00 4f ila \$79,1024 # 400 130: 42 02 00 4f ila \$79,1024 # 400
134: 40 20 00 00 nop \$0 134: 40 20 00 00 nop \$0
138: 42 00 00 ce ila \$78,1 138: 42 00 00 ce ila \$78,1
13c: 32 00 08 80 br 180 <__ovly_load> # 180 13c: 32 00 08 80 br 180 <__ovly_load> # 180
13c: SPU_REL16 __ovly_load
00000140 <_SPUEAR_f1_a2>: 00000140 <_SPUEAR_f1_a2>:
140: 42 02 00 4f ila \$79,1024 # 400 140: 42 02 00 4f ila \$79,1024 # 400
144: 40 20 00 00 nop \$0 144: 40 20 00 00 nop \$0
148: 42 00 01 4e ila \$78,2 148: 42 00 01 4e ila \$78,2
14c: 32 00 06 80 br 180 <__ovly_load> # 180 14c: 32 00 06 80 br 180 <__ovly_load> # 180
14c: SPU_REL16 __ovly_load
#... #...
Disassembly of section \.ov_a1: Disassembly of section \.ov_a1: