summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2006-03-02 08:50:04 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2006-03-02 08:50:04 +0000
commit4a3dc54359e79df0cb556cd5b4ab5c1bc91019b5 (patch)
treefe67901dab8531bb6298e2bd2717d1ea8cca508a
parent2c10a7e506c2bced576c630be7e32d04de15862d (diff)
downloadbinutils-4a3dc54359e79df0cb556cd5b4ab5c1bc91019b5.tar.gz
binutils-4a3dc54359e79df0cb556cd5b4ab5c1bc91019b5.tar.bz2
binutils-4a3dc54359e79df0cb556cd5b4ab5c1bc91019b5.zip
bfd/
* elf32-ppc.c (ppc_elf_plt_type): New enumeration. (ppc_elf_link_hash_table): Replace old_got and new_got with plt_type and can_use_new_plt. (ppc_elf_create_dynamic_sections): Add SEC_HAS_CONTENTS, SEC_LOAD and SEC_READONLY to the VxWorks .plt flags. (ppc_elf_check_relocs): Set can_use_new_plt instead of new_plt. Move from plt_type == PLT_UNSET to PLT_OLD instead of setting old_plt. (ppc_elf_select_plt_layout): Move from plt_type == PLT_UNSET to either plt_type == PLT_OLD or plt_type == PLT_NEW. Assert that this function should not be called for VxWorks targets. (ppc_elf_tls_setup): Use plt_type instead of old_got. (allocate_got): Likewise. Rearrange so that max_before_header is only used for PLT_OLD and PLT_NEW. (allocate_dynrelocs): Use plt_type instead of old_got and is_vxworks. (ppc_elf_size_dynamic_sections): Likewise. (ppc_elf_relax_section): Likewise. (ppc_elf_relocate_section): Likewise. (ppc_elf_finish_dynamic_symbol): Likewise. (ppc_elf_vxworks_link_hash_table_create): Initialize plt_type. ld/ * emulparams/elf32ppccommon.sh: New file, extracted from... * emulparams/elf32ppc.sh: ...here. * emulparams/elf32ppcvxworks.sh: Include elf32ppccommon.sh instead of elf32ppc.sh. (BSS_PLT): Remove override. * Makefile.am (eelf32lppc.c): Depend on elf32ppccommons.h. (eelf32lppcnto.c, eelf32lppcsim.c, eelf32ppcnto.c): Likewise. (eelf32ppc.c, eelf32ppc_fbsd.c, eelf32ppcsimm): Likewise. (eelf32ppclinux.c): Likewise. (eelf32ppcvxworks.c): Likewise. Add missing vxworks.sh dependency. * Makefile.in: Regenerate. ld/testsuite/ * ld-powerpc/vxworks1-lib.s, ld-powerpc/vxworks1-lib.dd, * ld-powerpc/vxworks1-lib.rd, ld-powerpc/vxworks1.s, * ld-powerpc/vxworks1.dd, ld-powerpc/vxworks1.rd, * ld-powerpc/vxworks1.ld, ld-powerpc/vxworks1.sd: New test. * ld-powerpc/powerpc.exp: Run it.
-rw-r--r--bfd/ChangeLog22
-rw-r--r--bfd/elf32-ppc.c120
-rw-r--r--ld/ChangeLog14
-rw-r--r--ld/Makefile.am32
-rw-r--r--ld/Makefile.in32
-rw-r--r--ld/emulparams/elf32ppc.sh52
-rw-r--r--ld/emulparams/elf32ppccommon.sh49
-rw-r--r--ld/emulparams/elf32ppcvxworks.sh3
-rw-r--r--ld/testsuite/ChangeLog8
-rw-r--r--ld/testsuite/ld-powerpc/powerpc.exp19
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1-lib.dd56
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1-lib.rd12
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1-lib.s35
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1-lib.sd12
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1.dd48
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1.ld27
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1.rd22
-rw-r--r--ld/testsuite/ld-powerpc/vxworks1.s14
18 files changed, 446 insertions, 131 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index b95b908f92f..105ef257f25 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,25 @@
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * elf32-ppc.c (ppc_elf_plt_type): New enumeration.
+ (ppc_elf_link_hash_table): Replace old_got and new_got with
+ plt_type and can_use_new_plt.
+ (ppc_elf_create_dynamic_sections): Add SEC_HAS_CONTENTS,
+ SEC_LOAD and SEC_READONLY to the VxWorks .plt flags.
+ (ppc_elf_check_relocs): Set can_use_new_plt instead of new_plt.
+ Move from plt_type == PLT_UNSET to PLT_OLD instead of setting old_plt.
+ (ppc_elf_select_plt_layout): Move from plt_type == PLT_UNSET to
+ either plt_type == PLT_OLD or plt_type == PLT_NEW. Assert that
+ this function should not be called for VxWorks targets.
+ (ppc_elf_tls_setup): Use plt_type instead of old_got.
+ (allocate_got): Likewise. Rearrange so that max_before_header
+ is only used for PLT_OLD and PLT_NEW.
+ (allocate_dynrelocs): Use plt_type instead of old_got and is_vxworks.
+ (ppc_elf_size_dynamic_sections): Likewise.
+ (ppc_elf_relax_section): Likewise.
+ (ppc_elf_relocate_section): Likewise.
+ (ppc_elf_finish_dynamic_symbol): Likewise.
+ (ppc_elf_vxworks_link_hash_table_create): Initialize plt_type.
+
2006-02-28 Richard Sandiford <richard@codesourcery.com>
* elf32-i386.c (elf_i386_link_hash_table): Add next_tls_desc_index.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index ec407fdb402..952075513b5 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -2313,6 +2313,13 @@ struct ppc_elf_link_hash_entry
#define ppc_elf_hash_entry(ent) ((struct ppc_elf_link_hash_entry *) (ent))
+enum ppc_elf_plt_type {
+ PLT_UNSET,
+ PLT_OLD,
+ PLT_NEW,
+ PLT_VXWORKS
+};
+
/* PPC ELF linker hash table. */
struct ppc_elf_link_hash_table
@@ -2349,9 +2356,11 @@ struct ppc_elf_link_hash_table
/* Non-zero if allocating the header left a gap. */
unsigned int got_gap;
- /* Whether to use new plt/got layout or not. */
- unsigned int new_plt:1;
- unsigned int old_plt:1;
+ /* The type of PLT we have chosen to use. */
+ enum ppc_elf_plt_type plt_type;
+
+ /* Whether we can use the new PLT layout. */
+ unsigned int can_use_new_plt:1;
/* Set if we should emit symbols for stubs. */
unsigned int emit_stub_syms:1;
@@ -2559,6 +2568,9 @@ ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
abort ();
flags = SEC_ALLOC | SEC_CODE | SEC_LINKER_CREATED;
+ if (htab->plt_type == PLT_VXWORKS)
+ /* The VxWorks PLT is a loaded section with contents. */
+ flags |= SEC_HAS_CONTENTS | SEC_LOAD | SEC_READONLY;
return bfd_set_section_flags (abfd, s, flags);
}
@@ -3245,7 +3257,7 @@ ppc_elf_check_relocs (bfd *abfd,
case R_PPC_REL16_LO:
case R_PPC_REL16_HI:
case R_PPC_REL16_HA:
- htab->new_plt = 1;
+ htab->can_use_new_plt = 1;
break;
/* These are just markers. */
@@ -3273,8 +3285,8 @@ ppc_elf_check_relocs (bfd *abfd,
/* This refers only to functions defined in the shared library. */
case R_PPC_LOCAL24PC:
- if (h && h == htab->elf.hgot)
- htab->old_plt = 1;
+ if (h && h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
+ htab->plt_type = PLT_OLD;
break;
/* This relocation describes the C++ object vtable hierarchy.
@@ -3315,7 +3327,7 @@ ppc_elf_check_relocs (bfd *abfd,
&& got2 != NULL
&& (sec->flags & SEC_CODE) != 0
&& (info->shared || info->pie)
- && !htab->old_plt)
+ && htab->plt_type == PLT_UNSET)
{
/* Old -fPIC gcc code has .long LCTOC1-LCFx just before
the start of a function, which assembles to a REL32
@@ -3328,7 +3340,7 @@ ppc_elf_check_relocs (bfd *abfd,
s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec,
r_symndx);
if (s == got2)
- htab->old_plt = 1;
+ htab->plt_type = PLT_OLD;
}
/* fall through */
@@ -3338,9 +3350,9 @@ ppc_elf_check_relocs (bfd *abfd,
case R_PPC_REL14_BRNTAKEN:
if (h == NULL)
break;
- if (h == htab->elf.hgot)
+ if (h == htab->elf.hgot && htab->plt_type == PLT_UNSET)
{
- htab->old_plt = 1;
+ htab->plt_type = PLT_OLD;
break;
}
/* fall through */
@@ -3600,22 +3612,16 @@ ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
flagword flags;
htab = ppc_elf_hash_table (info);
- if (force_old_plt || !htab->new_plt)
- htab->old_plt = 1;
+
+ if (htab->plt_type == PLT_UNSET)
+ htab->plt_type = (force_old_plt || !htab->can_use_new_plt
+ ? PLT_OLD : PLT_NEW);
htab->emit_stub_syms = emit_stub_syms;
- if (htab->is_vxworks)
- {
- /* The VxWorks PLT is a loaded section with contents. */
- flags = SEC_ALLOC | SEC_CODE | SEC_IN_MEMORY | SEC_LINKER_CREATED
- | SEC_HAS_CONTENTS | SEC_LOAD | SEC_READONLY;
+ BFD_ASSERT (htab->plt_type != PLT_VXWORKS);
- if (htab->plt != NULL
- && !bfd_set_section_flags (htab->elf.dynobj, htab->plt, flags))
- return -1;
- }
- else if (!htab->old_plt)
+ if (htab->plt_type == PLT_NEW)
{
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
@@ -3637,7 +3643,7 @@ ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
&& !bfd_set_section_alignment (htab->elf.dynobj, htab->glink, 0))
return -1;
}
- return !htab->old_plt;
+ return htab->plt_type == PLT_NEW;
}
/* Return the section that should be marked against GC for a given
@@ -3825,7 +3831,7 @@ ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
struct ppc_elf_link_hash_table *htab;
htab = ppc_elf_hash_table (info);
- if (!htab->old_plt
+ if (htab->plt_type == PLT_NEW
&& htab->plt != NULL
&& htab->plt->output_section != NULL)
{
@@ -4269,31 +4275,32 @@ static bfd_vma
allocate_got (struct ppc_elf_link_hash_table *htab, unsigned int need)
{
bfd_vma where;
- unsigned int max_before_header = 32768;
-
- if (htab->old_plt)
- max_before_header = 32764;
+ unsigned int max_before_header;
- if (htab->is_vxworks)
+ if (htab->plt_type == PLT_VXWORKS)
{
where = htab->got->size;
htab->got->size += need;
}
- else if (need <= htab->got_gap)
- {
- where = max_before_header - htab->got_gap;
- htab->got_gap -= need;
- }
else
{
- if (htab->got->size + need > max_before_header
- && htab->got->size <= max_before_header)
+ max_before_header = htab->plt_type == PLT_NEW ? 32768 : 32764;
+ if (need <= htab->got_gap)
{
- htab->got_gap = max_before_header - htab->got->size;
- htab->got->size = max_before_header + htab->got_header_size;
+ where = max_before_header - htab->got_gap;
+ htab->got_gap -= need;
+ }
+ else
+ {
+ if (htab->got->size + need > max_before_header
+ && htab->got->size <= max_before_header)
+ {
+ htab->got_gap = max_before_header - htab->got->size;
+ htab->got->size = max_before_header + htab->got_header_size;
+ }
+ where = htab->got->size;
+ htab->got->size += need;
}
- where = htab->got->size;
- htab->got->size += need;
}
return where;
}
@@ -4340,7 +4347,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
asection *s = htab->plt;
- if (!(htab->old_plt || htab->is_vxworks))
+ if (htab->plt_type == PLT_NEW)
{
if (!doneone)
{
@@ -4404,7 +4411,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
s->size += htab->plt_entry_size;
/* After the 8192nd entry, room for two entries
is allocated. */
- if (!htab->is_vxworks
+ if (htab->plt_type == PLT_OLD
&& (s->size - htab->plt_initial_entry_size)
/ htab->plt_entry_size
> PLT_NUM_SINGLE_ENTRIES)
@@ -4418,7 +4425,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
htab->relplt->size += sizeof (Elf32_External_Rela);
- if (htab->is_vxworks)
+ if (htab->plt_type == PLT_VXWORKS)
{
/* Allocate space for the unloaded relocations. */
if (!info->shared)
@@ -4659,9 +4666,9 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
}
}
- if (htab->old_plt)
+ if (htab->plt_type == PLT_OLD)
htab->got_header_size = 16;
- else
+ else if (htab->plt_type == PLT_NEW)
htab->got_header_size = 12;
/* Set up .got offsets for local syms, and space for local dynamic
@@ -4775,7 +4782,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
/* Allocate space for global sym dynamic relocs. */
elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
- if (htab->got != NULL && !htab->is_vxworks)
+ if (htab->got != NULL && htab->plt_type != PLT_VXWORKS)
{
unsigned int g_o_t = 32768;
@@ -4786,7 +4793,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
if (htab->got->size <= 32768)
{
g_o_t = htab->got->size;
- if (htab->old_plt)
+ if (htab->plt_type == PLT_OLD)
g_o_t += 4;
htab->got->size += htab->got_header_size;
}
@@ -5122,7 +5129,7 @@ ppc_elf_relax_section (bfd *abfd,
if (ent != NULL)
{
- if (!htab->old_plt)
+ if (htab->plt_type == PLT_NEW)
{
tsec = htab->glink;
toff = ent->glink_offset;
@@ -6337,7 +6344,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
{
struct plt_entry *ent = find_plt_ent (h, got2, addend);
- if (!htab->old_plt)
+ if (htab->plt_type == PLT_NEW)
relocation = (htab->glink->output_section->vma
+ htab->glink->output_offset
+ ent->glink_offset);
@@ -6427,7 +6434,7 @@ ppc_elf_relocate_section (bfd *output_bfd,
}
unresolved_reloc = FALSE;
- if (!htab->old_plt)
+ if (htab->plt_type == PLT_NEW)
relocation = (htab->glink->output_section->vma
+ htab->glink->output_offset
+ ent->glink_offset);
@@ -6747,20 +6754,20 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
bfd_byte *loc;
bfd_vma reloc_index;
- if (!(htab->old_plt || htab->is_vxworks))
+ if (htab->plt_type == PLT_NEW)
reloc_index = ent->plt.offset / 4;
else
{
reloc_index = ((ent->plt.offset - htab->plt_initial_entry_size)
/ htab->plt_slot_size);
if (reloc_index > PLT_NUM_SINGLE_ENTRIES
- && !htab->is_vxworks)
+ && htab->plt_type == PLT_OLD)
reloc_index -= (reloc_index - PLT_NUM_SINGLE_ENTRIES) / 2;
}
/* This symbol has an entry in the procedure linkage table.
Set it up. */
- if (htab->is_vxworks)
+ if (htab->plt_type == PLT_VXWORKS)
{
bfd_vma got_offset;
const bfd_vma *plt_entry;
@@ -6894,7 +6901,7 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset);
- if (htab->old_plt)
+ if (htab->plt_type == PLT_OLD)
{
/* We don't need to fill in the .plt. The ppc dynamic
linker will fill it in. */
@@ -6932,7 +6939,7 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
doneone = TRUE;
}
- if (!htab->old_plt)
+ if (htab->plt_type == PLT_NEW)
{
bfd_vma plt;
unsigned char *p;
@@ -7154,7 +7161,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
bfd_vma val;
p += htab->elf.hgot->root.u.def.value;
- if (htab->old_plt && !htab->is_vxworks)
+ if (htab->plt_type == PLT_OLD)
bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, p - 4);
val = 0;
@@ -7526,6 +7533,7 @@ ppc_elf_vxworks_link_hash_table_create (bfd *abfd)
struct ppc_elf_link_hash_table *htab
= (struct ppc_elf_link_hash_table *)ret;
htab->is_vxworks = 1;
+ htab->plt_type = PLT_VXWORKS;
htab->plt_entry_size = VXWORKS_PLT_ENTRY_SIZE;
htab->plt_slot_size = VXWORKS_PLT_ENTRY_SIZE;
htab->plt_initial_entry_size = VXWORKS_PLT_INITIAL_ENTRY_SIZE;
diff --git a/ld/ChangeLog b/ld/ChangeLog
index bbfa9e07d88..7568cd447d7 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,17 @@
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * emulparams/elf32ppccommon.sh: New file, extracted from...
+ * emulparams/elf32ppc.sh: ...here.
+ * emulparams/elf32ppcvxworks.sh: Include elf32ppccommon.sh
+ instead of elf32ppc.sh.
+ (BSS_PLT): Remove override.
+ * Makefile.am (eelf32lppc.c): Depend on elf32ppccommons.h.
+ (eelf32lppcnto.c, eelf32lppcsim.c, eelf32ppcnto.c): Likewise.
+ (eelf32ppc.c, eelf32ppc_fbsd.c, eelf32ppcsimm): Likewise.
+ (eelf32ppclinux.c): Likewise.
+ (eelf32ppcvxworks.c): Likewise. Add missing vxworks.sh dependency.
+ * Makefile.in: Regenerate.
+
2006-02-27 Carlos O'Donell <carlos@codesourcery.com>
* Makefile.am: Add html target.
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 5de4d468c57..9554ab77241 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -744,26 +744,30 @@ eelf32mipswindiss.c: $(srcdir)/emulparams/elf32mipswindiss.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32mipswindiss "$(tdir_elf32mipswindiss)"
eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \
+ $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)"
eelf32lppcnto.c: $(srcdir)/emulparams/elf32lppcnto.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppcnto "$(tdir_elf32lppcnto)"
eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \
$(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \
- $(srcdir)/emultempl/ppc32elf.em \
+ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppcsim "$(tdir_elf32lppcsim)"
eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcnto "$(tdir_elf32ppcnto)"
eelf32ppcwindiss.c: $(srcdir)/emulparams/elf32ppcwindiss.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcwindiss "$(tdir_elf32ppcwindiss)"
eelf32ppcvxworks.c: $(srcdir)/emulparams/elf32ppcvxworks.sh \
+ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emulparams/vxworks.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcvxworks "$(tdir_elf32ppcvxworks)"
eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
@@ -773,20 +777,24 @@ eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
eelf32openrisc.c: $(srcdir)/emulparams/elf32openrisc.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32openrisc "$(tdir_openrisc)"
-eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
+eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \
+ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)"
eelf32ppc_fbsd.c: $(srcdir)/emulparams/elf32ppc_fbsd.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppc_fbsd "$(tdir_elf32ppc_fbsd)"
eelf32ppcsim.c: $(srcdir)/emulparams/elf32ppcsim.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcsim "$(tdir_elf32ppcsim)"
eelf32ppclinux.c: $(srcdir)/emulparams/elf32ppclinux.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppclinux "$(tdir_elf32ppclinux)"
eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 37ae95d6a48..a1a6f031ace 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -1550,26 +1550,30 @@ eelf32mipswindiss.c: $(srcdir)/emulparams/elf32mipswindiss.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32mipswindiss "$(tdir_elf32mipswindiss)"
eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \
+ $(srcdir)/emulparams/elf32ppccommon.sh \
$(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)"
eelf32lppcnto.c: $(srcdir)/emulparams/elf32lppcnto.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppcnto "$(tdir_elf32lppcnto)"
eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \
$(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \
- $(srcdir)/emultempl/ppc32elf.em \
+ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppcsim "$(tdir_elf32lppcsim)"
eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcnto "$(tdir_elf32ppcnto)"
eelf32ppcwindiss.c: $(srcdir)/emulparams/elf32ppcwindiss.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcwindiss "$(tdir_elf32ppcwindiss)"
eelf32ppcvxworks.c: $(srcdir)/emulparams/elf32ppcvxworks.sh \
+ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emulparams/vxworks.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcvxworks "$(tdir_elf32ppcvxworks)"
eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
@@ -1579,20 +1583,24 @@ eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
eelf32openrisc.c: $(srcdir)/emulparams/elf32openrisc.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32openrisc "$(tdir_openrisc)"
-eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
+eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \
+ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)"
eelf32ppc_fbsd.c: $(srcdir)/emulparams/elf32ppc_fbsd.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppc_fbsd "$(tdir_elf32ppc_fbsd)"
eelf32ppcsim.c: $(srcdir)/emulparams/elf32ppcsim.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcsim "$(tdir_elf32ppcsim)"
eelf32ppclinux.c: $(srcdir)/emulparams/elf32ppclinux.sh \
- $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \
- $(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \
+ $(srcdir)/emultempl/ppc32elf.em $(srcdir)/emultempl/elf32.em \
+ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppclinux "$(tdir_elf32ppclinux)"
eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
diff --git a/ld/emulparams/elf32ppc.sh b/ld/emulparams/elf32ppc.sh
index ad6876dd4fb..587b8d3aca0 100644
--- a/ld/emulparams/elf32ppc.sh
+++ b/ld/emulparams/elf32ppc.sh
@@ -1,17 +1,7 @@
# If you change this file, please also look at files which source this one:
-# elf32lppc.sh elf32ppclinux.sh elf32ppcsim.sh elf32ppcvxworks.sh
+# elf32lppc.sh elf32ppclinux.sh elf32ppcsim.sh
-TEMPLATE_NAME=elf32
-EXTRA_EM_FILE=ppc32elf
-GENERATE_SHLIB_SCRIPT=yes
-GENERATE_PIE_SCRIPT=yes
-SCRIPT_NAME=elf
-OUTPUT_FORMAT="elf32-powerpc"
-TEXT_START_ADDR=0x01800000
-MAXPAGESIZE=0x10000
-COMMONPAGESIZE=0x1000
-ARCH=powerpc:common
-MACHINE=
+. ${srcdir}/emulparams/elf32ppccommon.sh
# Yes, we want duplicate .got and .plt sections. The linker chooses the
# appropriate one magically in ppc_after_open
DATA_GOT=
@@ -22,40 +12,4 @@ GOT=".got ${RELOCATING-0} : SPECIAL { *(.got) }"
PLT=".plt ${RELOCATING-0} : SPECIAL { *(.plt) }"
GOTPLT="${PLT}"
OTHER_TEXT_SECTIONS="*(.glink)"
-EXECUTABLE_SYMBOLS='PROVIDE (__stack = 0); PROVIDE (___stack = 0);'
-if test -z "${CREATE_SHLIB}"; then
- SDATA_START_SYMBOLS="PROVIDE (_SDA_BASE_ = 32768);"
- SDATA2_START_SYMBOLS="PROVIDE (_SDA2_BASE_ = 32768);"
- SBSS_START_SYMBOLS="PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);"
- SBSS_END_SYMBOLS="PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);"
-else
- unset SDATA_START_SYMBOLS
- unset SDATA2_START_SYMBOLS
- unset SBSS_START_SYMBOLS
- unset SBSS_END_SYMBOLS
-fi
-OTHER_END_SYMBOLS="__end = .;"
-OTHER_RELRO_SECTIONS="
- .fixup ${RELOCATING-0} : { *(.fixup) }
- .got1 ${RELOCATING-0} : { *(.got1) }
- .got2 ${RELOCATING-0} : { *(.got2) }
-"
-OTHER_GOT_RELOC_SECTIONS="
- .rela.got1 ${RELOCATING-0} : { *(.rela.got1) }
- .rela.got2 ${RELOCATING-0} : { *(.rela.got2) }
-"
-
-# Treat a host that matches the target with the possible exception of "64"
-# in the name as if it were native.
-if test `echo "$host" | sed -e s/64//` = `echo "$target" | sed -e s/64//`; then
- case " $EMULATION_LIBPATH " in
- *" ${EMULATION_NAME} "*)
- NATIVE=yes
- ;;
- esac
-fi
-
-# Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first.
-case "$EMULATION_NAME" in
- *64*) LIBPATH_SUFFIX=64 ;;
-esac
+EXTRA_EM_FILE=ppc32elf
diff --git a/ld/emulparams/elf32ppccommon.sh b/ld/emulparams/elf32ppccommon.sh
new file mode 100644
index 00000000000..b5fbc8d8e89
--- /dev/null
+++ b/ld/emulparams/elf32ppccommon.sh
@@ -0,0 +1,49 @@
+# The PLT-agnostic parts of a generic 32-bit ELF PowerPC target. Included by:
+# elf32ppc.sh elf32ppcvxworks.sh
+TEMPLATE_NAME=elf32
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_PIE_SCRIPT=yes
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-powerpc"
+TEXT_START_ADDR=0x01800000
+MAXPAGESIZE=0x10000
+COMMONPAGESIZE=0x1000
+ARCH=powerpc:common
+MACHINE=
+EXECUTABLE_SYMBOLS='PROVIDE (__stack = 0); PROVIDE (___stack = 0);'
+if test -z "${CREATE_SHLIB}"; then
+ SDATA_START_SYMBOLS="PROVIDE (_SDA_BASE_ = 32768);"
+ SDATA2_START_SYMBOLS="PROVIDE (_SDA2_BASE_ = 32768);"
+ SBSS_START_SYMBOLS="PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .);"
+ SBSS_END_SYMBOLS="PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .);"
+else
+ unset SDATA_START_SYMBOLS
+ unset SDATA2_START_SYMBOLS
+ unset SBSS_START_SYMBOLS
+ unset SBSS_END_SYMBOLS
+fi
+OTHER_END_SYMBOLS="__end = .;"
+OTHER_RELRO_SECTIONS="
+ .fixup ${RELOCATING-0} : { *(.fixup) }
+ .got1 ${RELOCATING-0} : { *(.got1) }
+ .got2 ${RELOCATING-0} : { *(.got2) }
+"
+OTHER_GOT_RELOC_SECTIONS="
+ .rela.got1 ${RELOCATING-0} : { *(.rela.got1) }
+ .rela.got2 ${RELOCATING-0} : { *(.rela.got2) }
+"
+
+# Treat a host that matches the target with the possible exception of "64"
+# in the name as if it were native.
+if test `echo "$host" | sed -e s/64//` = `echo "$target" | sed -e s/64//`; then
+ case " $EMULATION_LIBPATH " in
+ *" ${EMULATION_NAME} "*)
+ NATIVE=yes
+ ;;
+ esac
+fi
+
+# Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first.
+case "$EMULATION_NAME" in
+ *64*) LIBPATH_SUFFIX=64 ;;
+esac
diff --git a/ld/emulparams/elf32ppcvxworks.sh b/ld/emulparams/elf32ppcvxworks.sh
index b45a238b5c0..1bc3f3093c9 100644
--- a/ld/emulparams/elf32ppcvxworks.sh
+++ b/ld/emulparams/elf32ppcvxworks.sh
@@ -1,4 +1,3 @@
-. ${srcdir}/emulparams/elf32ppc.sh
+. ${srcdir}/emulparams/elf32ppccommon.sh
OUTPUT_FORMAT="elf32-powerpc-vxworks"
-unset BSS_PLT
. ${srcdir}/emulparams/vxworks.sh
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index c9f439581d9..5c2bcb63d39 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2006-03-02 Richard Sandiford <richard@codesourcery.com>
+
+ * ld-powerpc/vxworks1-lib.s, ld-powerpc/vxworks1-lib.dd,
+ * ld-powerpc/vxworks1-lib.rd, ld-powerpc/vxworks1.s,
+ * ld-powerpc/vxworks1.dd, ld-powerpc/vxworks1.rd,
+ * ld-powerpc/vxworks1.ld, ld-powerpc/vxworks1.sd: New test.
+ * ld-powerpc/powerpc.exp: Run it.
+
2006-02-28 Richard Sandiford <richard@codesourcery.com>
* ld-i386/vxworks1-lib.s, ld-i386/vxworks1-lib.dd,
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index e43a2953199..5cfb313e353 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -20,6 +20,25 @@ if { ![istarget "powerpc*-*-*"] } {
return
}
+if {[istarget "*-*-vxworks"]} {
+ set ppcvxtests {
+ {"VxWorks shared library test 1 (default script)" "-shared"
+ "-mregnames" {vxworks1-lib.s}
+ {{readelf --segments vxworks1-lib.sd}}
+ "libvxworks1.so"}
+ {"VxWorks shared library test 1" "-shared -Tvxworks1.ld"
+ "-mregnames" {vxworks1-lib.s}
+ {{readelf --relocs vxworks1-lib.rd} {objdump -dr vxworks1-lib.dd}}
+ "libvxworks1.so"}
+ {"VxWorks dynamic executable test 1" \
+ "tmpdir/libvxworks1.so -Tvxworks1.ld -q" "-mregnames" {vxworks1.s}
+ {{readelf --relocs vxworks1.rd} {objdump -dr vxworks1.dd}}
+ "vxworks1"}
+ }
+ run_ld_link_tests $ppcvxtests
+ return
+}
+
# powerpc ELF only at the moment.
if { [istarget "*-*-macos*"] || [istarget "*-*-netware*"]
diff --git a/ld/testsuite/ld-powerpc/vxworks1-lib.dd b/ld/testsuite/ld-powerpc/vxworks1-lib.dd
new file mode 100644
index 00000000000..1c1861eb0ac
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1-lib.dd
@@ -0,0 +1,56 @@
+
+.*: file format .*
+
+Disassembly of section \.plt:
+
+00080800 <_PROCEDURE_LINKAGE_TABLE_>:
+ 80800: 81 9e 00 08 lwz r12,8\(r30\)
+ 80804: 7d 89 03 a6 mtctr r12
+ 80808: 81 9e 00 04 lwz r12,4\(r30\)
+ 8080c: 4e 80 04 20 bctr
+ 80810: 60 00 00 00 nop
+ 80814: 60 00 00 00 nop
+ 80818: 60 00 00 00 nop
+ 8081c: 60 00 00 00 nop
+ 80820: 3d 9e 00 00 addis r12,r30,0
+ 80824: 81 8c 00 0c lwz r12,12\(r12\)
+ 80828: 7d 89 03 a6 mtctr r12
+ 8082c: 4e 80 04 20 bctr
+ 80830: 39 60 00 00 li r11,0
+ 80834: 4b ff ff cc b 80800 <_PROCEDURE_LINKAGE_TABLE_>
+ 80838: 60 00 00 00 nop
+ 8083c: 60 00 00 00 nop
+ 80840: 3d 9e 00 00 addis r12,r30,0
+ 80844: 81 8c 00 10 lwz r12,16\(r12\)
+ 80848: 7d 89 03 a6 mtctr r12
+ 8084c: 4e 80 04 20 bctr
+ 80850: 39 60 00 01 li r11,1
+ 80854: 4b ff ff ac b 80800 <_PROCEDURE_LINKAGE_TABLE_>
+ 80858: 60 00 00 00 nop
+ 8085c: 60 00 00 00 nop
+Disassembly of section \.text:
+
+00080c00 <foo>:
+ 80c00: 94 21 ff e8 stwu r1,-24\(r1\)
+ 80c04: 7c 08 02 a6 mflr r0
+ 80c08: 90 01 00 1c stw r0,28\(r1\)
+ 80c0c: 3f c0 00 00 lis r30,0
+ 80c10: 83 de 00 00 lwz r30,0\(r30\)
+ 80c14: 83 de 00 00 lwz r30,0\(r30\)
+ 80c18: 80 3e 00 14 lwz r1,20\(r30\)
+ 80c1c: 80 01 00 00 lwz r0,0\(r1\)
+ 80c20: 38 00 00 01 li r0,1
+ 80c24: 90 01 00 00 stw r0,0\(r1\)
+ 80c28: 48 00 00 1d bl 80c44 <slocal>
+ 80c2c: 4b ff fc 15 bl 80840 <_PROCEDURE_LINKAGE_TABLE_\+0x40>
+ 80c30: 4b ff fb f1 bl 80820 <_PROCEDURE_LINKAGE_TABLE_\+0x20>
+ 80c34: 80 01 00 1c lwz r0,28\(r1\)
+ 80c38: 7c 08 03 a6 mtlr r0
+ 80c3c: 38 21 00 18 addi r1,r1,24
+ 80c40: 4e 80 00 20 blr
+
+00080c44 <slocal>:
+ 80c44: 4e 80 00 20 blr
+
+00080c48 <sglobal>:
+ 80c48: 4e 80 00 20 blr
diff --git a/ld/testsuite/ld-powerpc/vxworks1-lib.rd b/ld/testsuite/ld-powerpc/vxworks1-lib.rd
new file mode 100644
index 00000000000..17087f1bf57
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1-lib.rd
@@ -0,0 +1,12 @@
+
+Relocation section '\.rela\.plt' at offset .* contains 2 entries:
+ Offset Info Type Sym\.Value Sym\. Name \+ Addend
+0008140c .*15 R_PPC_JMP_SLOT 00000000 sexternal \+ 0
+00081410 .*15 R_PPC_JMP_SLOT 00080c48 sglobal \+ 0
+
+Relocation section '\.rela\.dyn' at offset .* contains 4 entries:
+ Offset Info Type Sym\.Value Sym\. Name \+ Addend
+00080c0e .*06 R_PPC_ADDR16_HA 00000000 __GOTT_BASE__ \+ 0
+00080c12 .*04 R_PPC_ADDR16_LO 00000000 __GOTT_BASE__ \+ 0
+00080c16 .*03 R_PPC_ADDR16 00000000 __GOTT_INDEX__ \+ 0
+00081414 .*14 R_PPC_GLOB_DAT 00081800 x \+ 0
diff --git a/ld/testsuite/ld-powerpc/vxworks1-lib.s b/ld/testsuite/ld-powerpc/vxworks1-lib.s
new file mode 100644
index 00000000000..8e286c17e14
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1-lib.s
@@ -0,0 +1,35 @@
+ .text
+ .globl foo
+ .type foo, @function
+foo:
+ stwu r1,-24(r1)
+ mflr r0
+ stw r0,28(r1)
+ lis r30,__GOTT_BASE__@ha
+ lwz r30,__GOTT_BASE__@l(r30)
+ lwz r30,__GOTT_INDEX__(r30)
+ lwz r1,x@got(r30)
+ lwz r0,0(r1)
+ addi r0,r0,1
+ stw r0,0(r1)
+ bl slocal
+ bl sglobal@plt
+ bl sexternal@plt
+ lwz r0,28(r1)
+ mtlr r0
+ addi r1,r1,24
+ blr
+ .size foo, .-foo
+
+ .type slocal, @function
+slocal:
+ blr
+ .size slocal, .-slocal
+
+ .globl sglobal
+ .type sglobal, @function
+sglobal:
+ blr
+ .size sglobal, .-sglobal
+
+ .comm x,4,4
diff --git a/ld/testsuite/ld-powerpc/vxworks1-lib.sd b/ld/testsuite/ld-powerpc/vxworks1-lib.sd
new file mode 100644
index 00000000000..1d2ed5c82ce
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1-lib.sd
@@ -0,0 +1,12 @@
+#...
+Program Headers:
+ Type .* Flg Align
+ LOAD .* R E 0x10000
+ LOAD .* RW 0x10000
+ DYNAMIC .* RW 0x4
+
+ Section to Segment mapping:
+ Segment Sections\.\.\.
+ 00 .* \.plt .*
+ 01 .* \.got .*
+ 02 .* \.dynamic $
diff --git a/ld/testsuite/ld-powerpc/vxworks1.dd b/ld/testsuite/ld-powerpc/vxworks1.dd
new file mode 100644
index 00000000000..e4c7b06dec8
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1.dd
@@ -0,0 +1,48 @@
+
+.*: file format .*
+
+Disassembly of section \.plt:
+
+00080800 <_PROCEDURE_LINKAGE_TABLE_>:
+ 80800: 3d 80 00 08 lis r12,8
+ 80802: R_PPC_ADDR16_HA _GLOBAL_OFFSET_TABLE_
+ 80804: 39 8c 14 00 addi r12,r12,5120
+ 80806: R_PPC_ADDR16_LO _GLOBAL_OFFSET_TABLE_
+ 80808: 80 0c 00 08 lwz r0,8\(r12\)
+ 8080c: 7c 09 03 a6 mtctr r0
+ 80810: 81 8c 00 04 lwz r12,4\(r12\)
+ 80814: 4e 80 04 20 bctr
+ 80818: 60 00 00 00 nop
+ 8081c: 60 00 00 00 nop
+ 80820: 3d 80 00 08 lis r12,8
+ 80822: R_PPC_ADDR16_HA _GLOBAL_OFFSET_TABLE_\+0xc
+ 80824: 81 8c 14 0c lwz r12,5132\(r12\)
+ 80826: R_PPC_ADDR16_LO _GLOBAL_OFFSET_TABLE_\+0xc
+ 80828: 7d 89 03 a6 mtctr r12
+ 8082c: 4e 80 04 20 bctr
+ 80830: 39 60 00 00 li r11,0
+ 80834: 4b ff ff cc b 80800 <_PROCEDURE_LINKAGE_TABLE_>
+ 80838: 60 00 00 00 nop
+ 8083c: 60 00 00 00 nop
+ 80840: 3d 80 00 08 lis r12,8
+ 80842: R_PPC_ADDR16_HA _GLOBAL_OFFSET_TABLE_\+0x10
+ 80844: 81 8c 14 10 lwz r12,5136\(r12\)
+ 80846: R_PPC_ADDR16_LO _GLOBAL_OFFSET_TABLE_\+0x10
+ 80848: 7d 89 03 a6 mtctr r12
+ 8084c: 4e 80 04 20 bctr
+ 80850: 39 60 00 01 li r11,1
+ 80854: 4b ff ff ac b 80800 <_PROCEDURE_LINKAGE_TABLE_>
+ 80858: 60 00 00 00 nop
+ 8085c: 60 00 00 00 nop
+Disassembly of section \.text:
+
+00080c00 <_start>:
+ 80c00: 4b ff fc 41 bl 80840 <_PROCEDURE_LINKAGE_TABLE_\+0x40>
+ 80c00: R_PPC_PLTREL24 \.plt\+0x40
+ 80c04: 48 00 00 09 bl 80c0c <sexternal>
+ 80c04: R_PPC_PLTREL24 sexternal
+ 80c08: 4b ff fc 19 bl 80820 <_PROCEDURE_LINKAGE_TABLE_\+0x20>
+ 80c08: R_PPC_PLTREL24 \.plt\+0x20
+
+00080c0c <sexternal>:
+ 80c0c: 4e 80 00 20 blr
diff --git a/ld/testsuite/ld-powerpc/vxworks1.ld b/ld/testsuite/ld-powerpc/vxworks1.ld
new file mode 100644
index 00000000000..540e0ebe5b9
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1.ld
@@ -0,0 +1,27 @@
+SECTIONS
+{
+ . = 0x80000;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+
+ . = ALIGN (0x400);
+ .rela.dyn : { *(.rela.dyn) }
+ .rela.plt : { *(.rela.plt) }
+
+ . = ALIGN (0x400);
+ .plt : { *(.plt) }
+
+ . = ALIGN (0x400);
+ .text : { *(.text) }
+
+ . = ALIGN (0x1000);
+ .dynamic : { *(.dynamic) }
+
+ . = ALIGN (0x400);
+ .got : { *(.got.plt) *(.got) }
+
+ . = ALIGN (0x400);
+ .bss : { *(.bss) }
+}
diff --git a/ld/testsuite/ld-powerpc/vxworks1.rd b/ld/testsuite/ld-powerpc/vxworks1.rd
new file mode 100644
index 00000000000..fd14cfe0423
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1.rd
@@ -0,0 +1,22 @@
+
+Relocation section '\.rela\.plt' at offset .* contains 2 entries:
+ Offset Info Type Sym\.Value Sym\. Name \+ Addend
+0008140c .*15 R_PPC_JMP_SLOT 00080820 sglobal \+ 0
+00081410 .*15 R_PPC_JMP_SLOT 00080840 foo \+ 0
+
+Relocation section '\.rela\.text' at offset .* contains 3 entries:
+ Offset Info Type Sym\.Value Sym\. Name \+ Addend
+00080c00 .*12 R_PPC_PLTREL24 00080800 \.plt \+ 40
+00080c04 .*12 R_PPC_PLTREL24 00080c0c sexternal \+ 0
+00080c08 .*12 R_PPC_PLTREL24 00080800 \.plt \+ 20
+
+Relocation section '\.rela\.plt\.unloaded' at offset .* contains 8 entries:
+ Offset Info Type Sym\.Value Sym\. Name \+ Addend
+00080802 .*06 R_PPC_ADDR16_HA 00081400 _GLOBAL_OFFSET_TABLE_ \+ 0
+00080806 .*04 R_PPC_ADDR16_LO 00081400 _GLOBAL_OFFSET_TABLE_ \+ 0
+00080822 .*06 R_PPC_ADDR16_HA 00081400 _GLOBAL_OFFSET_TABLE_ \+ c
+00080826 .*04 R_PPC_ADDR16_LO 00081400 _GLOBAL_OFFSET_TABLE_ \+ c
+0008140c .*01 R_PPC_ADDR32 00080800 _PROCEDURE_LINKAGE_TAB.* \+ 30
+00080842 .*06 R_PPC_ADDR16_HA 00081400 _GLOBAL_OFFSET_TABLE_ \+ 10
+00080846 .*04 R_PPC_ADDR16_LO 00081400 _GLOBAL_OFFSET_TABLE_ \+ 10
+00081410 .*01 R_PPC_ADDR32 00080800 _PROCEDURE_LINKAGE_TAB.* \+ 50
diff --git a/ld/testsuite/ld-powerpc/vxworks1.s b/ld/testsuite/ld-powerpc/vxworks1.s
new file mode 100644
index 00000000000..cd54d5795c1
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/vxworks1.s
@@ -0,0 +1,14 @@
+ .text
+ .globl _start
+ .type _start,@function
+_start:
+ bl foo@plt
+ bl sexternal@plt
+ bl sglobal@plt
+ .size _start, .-_start
+
+ .globl sexternal
+ .type sexternal,@function
+sexternal:
+ blr
+ .size sexternal, .-sexternal