aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf32-ppc.c47
-rw-r--r--ld/testsuite/ChangeLog7
-rw-r--r--ld/testsuite/ld-powerpc/powerpc.exp5
-rw-r--r--ld/testsuite/ld-powerpc/vxworks-relax.rd9
-rw-r--r--ld/testsuite/ld-powerpc/vxworks-relax.s13
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1.ld2
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1.rd4
8 files changed, 83 insertions, 11 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 705b5b69..5873b1b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2009-01-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_relax_section): Add space for relocs
+ describing the trampolines.
+ (ppc_elf_relocate_section): Update relocs to describe the
+ trampolines.
+
2009-01-25 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* elf-hppa.h (elf_hppa_final_link_relocate): Add check to ensure that
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 432605b..b04bea4 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -5576,7 +5576,7 @@ ppc_elf_relax_section (bfd *abfd,
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;
@@ -5823,6 +5823,7 @@ ppc_elf_relax_section (bfd *abfd,
fixups = f;
trampoff += size;
+ changes++;
}
else
{
@@ -5873,7 +5874,6 @@ ppc_elf_relax_section (bfd *abfd,
}
/* Write out the trampolines. */
- changed = fixups != NULL;
if (fixups != NULL)
{
const int *stub;
@@ -5939,7 +5939,7 @@ ppc_elf_relax_section (bfd *abfd,
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
{
@@ -5948,15 +5948,35 @@ ppc_elf_relax_section (bfd *abfd,
}
}
- 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:
@@ -6950,6 +6970,17 @@ ppc_elf_relocate_section (bfd *output_bfd,
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;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index b708780..78b39cd 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+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.
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index af812a0..1630cd7 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -49,6 +49,11 @@ if {[istarget "*-*-vxworks"]} {
"-mregnames" {vxworks2.s}
{{readelf --segments vxworks2-static.sd}}
"vxworks2"}
+ {"VxWorks relax test"
+ "-Tvxworks1.ld --relax -q"
+ "-mregnames" {vxworks-relax.s}
+ {{readelf --relocs vxworks-relax.rd}}
+ "vxworks-relax"}
}
run_ld_link_tests $ppcvxtests
run_dump_test "vxworks1-static"
diff --git a/ld/testsuite/ld-powerpc/vxworks-relax.rd b/ld/testsuite/ld-powerpc/vxworks-relax.rd
new file mode 100644
index 0000000..e28094c
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks-relax.rd
@@ -0,0 +1,9 @@
+
+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
diff --git a/ld/testsuite/ld-powerpc/vxworks-relax.s b/ld/testsuite/ld-powerpc/vxworks-relax.s
new file mode 100644
index 0000000..b4ebb9a
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks-relax.s
@@ -0,0 +1,13 @@
+ .globl _start
+_start:
+ bl elsewhere
+ lis 9,elsewhere@ha
+ la 0,elsewhere@l(9)
+
+
+ .section .far,"ax",@progbits
+elsewhere:
+ bl _start
+
+ .section .pad
+ .space 0x4000000
diff --git a/ld/testsuite/ld-powerpc/vxworks1.ld b/ld/testsuite/ld-powerpc/vxworks1.ld
index ce750b0..3106d55 100644
--- a/ld/testsuite/ld-powerpc/vxworks1.ld
+++ b/ld/testsuite/ld-powerpc/vxworks1.ld
@@ -14,7 +14,7 @@ SECTIONS
.plt : { *(.plt) }
. = ALIGN (0x400);
- .text : { *(.text) }
+ .text : { *(.text) *(.pad) *(.far) }
. = ALIGN (0x10000);
.dynamic : { *(.dynamic) }
diff --git a/ld/testsuite/ld-powerpc/vxworks1.rd b/ld/testsuite/ld-powerpc/vxworks1.rd
index 27d2404..b8591a8 100644
--- a/ld/testsuite/ld-powerpc/vxworks1.rd
+++ b/ld/testsuite/ld-powerpc/vxworks1.rd
@@ -1,8 +1,8 @@
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