Elf_Internal_Rela *internal_relocs = NULL;
Elf_Internal_Rela *irel, *irelend;
struct one_fixup *fixups = NULL;
- bfd_boolean changed;
+ unsigned changes = 0;
struct ppc_elf_link_hash_table *htab;
bfd_size_type trampoff;
asection *got2;
fixups = f;
trampoff += size;
+ changes++;
}
else
{
}
/* Write out the trampolines. */
- changed = fixups != NULL;
if (fixups != NULL)
{
const int *stub;
if (contents != NULL
&& elf_section_data (isec)->this_hdr.contents != contents)
{
- if (!changed && !link_info->keep_memory)
+ if (!changes && !link_info->keep_memory)
free (contents);
else
{
}
}
- if (elf_section_data (isec)->relocs != internal_relocs)
+ if (changes != 0)
{
- if (!changed)
+ /* Append sufficient NOP relocs so we can write out relocation
+ information for the trampolines. */
+ Elf_Internal_Rela *new_relocs = bfd_malloc ((changes + isec->reloc_count)
+ * sizeof (*new_relocs));
+ unsigned ix;
+
+ if (!new_relocs)
+ goto error_return;
+ memcpy (new_relocs, internal_relocs,
+ isec->reloc_count * sizeof (*new_relocs));
+ for (ix = changes; ix--;)
+ {
+ irel = new_relocs + ix + isec->reloc_count;
+
+ irel->r_info = ELF32_R_INFO (0, R_PPC_NONE);
+ }
+ if (internal_relocs != elf_section_data (isec)->relocs)
free (internal_relocs);
- else
- elf_section_data (isec)->relocs = internal_relocs;
+ elf_section_data (isec)->relocs = new_relocs;
+ isec->reloc_count += changes;
+ elf_section_data (isec)->rel_hdr.sh_size
+ += changes * elf_section_data (isec)->rel_hdr.sh_entsize;
}
+ else if (elf_section_data (isec)->relocs != internal_relocs)
+ free (internal_relocs);
- *again = changed;
+ *again = changes != 0;
return TRUE;
error_return:
bfd_put_32 (output_bfd, t0, contents + rel->r_offset);
bfd_put_32 (output_bfd, t1, contents + rel->r_offset + 4);
+
+ /* Rewrite the reloc and convert one of the trailing nop
+ relocs to describe this relocation. */
+ BFD_ASSERT (ELF32_R_TYPE (relend[-1].r_info) == R_PPC_NONE);
+ /* The relocs are at the bottom 2 bytes */
+ rel[0].r_offset += 2;
+ memmove (rel + 1, rel, (relend - rel - 1) * sizeof (*rel));
+ rel[0].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_HA);
+ rel[1].r_offset += 4;
+ rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_ADDR16_LO);
+ rel++;
}
continue;
+2009-01-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * ld-powerpc/powerpc.exp: Add vxworks relax testcase.
+ * ld-powerpc/vxworks-relax.s, ld-powerpc/vxworks-relax.rd: New.
+ * ld-powerpc/vxworks1.ld: Add .pad and .far input sections.
+ * ld-powerpc/vxworks1.rd: Correct regexp for undefined symbols.
+
2009-01-26 Andrew Stubbs <ams@codesourcery.com>
* ld-arm/attr-merge-3.attr: Update following gas change.
--- /dev/null
+
+Relocation section '.rela.text' at offset 0x4010150 contains 6 entries:
+ Offset Info Type Sym.Value Sym. Name \+ Addend
+00080012 00000106 R_PPC_ADDR16_HA 00080000 .text \+ 4000020
+00080016 00000104 R_PPC_ADDR16_LO 00080000 .text \+ 4000020
+00080006 00000106 R_PPC_ADDR16_HA 00080000 .text \+ 4000020
+0008000a 00000104 R_PPC_ADDR16_LO 00080000 .text \+ 4000020
+0408002a 00000306 R_PPC_ADDR16_HA 00080000 _start \+ 0
+0408002e 00000304 R_PPC_ADDR16_LO 00080000 _start \+ 0
Relocation section '\.rela\.plt' at offset .* contains 2 entries:
Offset Info Type Sym\.Value Sym\. Name \+ Addend
-0009040c .*15 R_PPC_JMP_SLOT 00080820 sglobal \+ 0
-00090410 .*15 R_PPC_JMP_SLOT 00080840 foo \+ 0
+0009040c .*15 R_PPC_JMP_SLOT 00000000 sglobal \+ 0
+00090410 .*15 R_PPC_JMP_SLOT 00000000 foo \+ 0
Relocation section '\.rela\.text' at offset .* contains 3 entries:
Offset Info Type Sym\.Value Sym\. Name \+ Addend