2005-05-07 Paul Brook <paul@codesourcery.com>

bfd/
	* config.bfd: Add separate case for ppc-vxworks.
	* configure: Regenerate.
	* configure.in: Include elf-vxworks.lo on ppc targets.
	* elf-vxworks.c (elf_vxworks_final_write_processing): Handle
	.rela.plt.unloaded.
	* elf32-ppc.c: Add VxWorks target vec.	Include elf-vxworks.h.
	(PLT_ENTRY_SIZE, PLT_INITIAL_ENTRY_SIZE, PLT_SLOT_SIZE): Remove.
	(VXWORKS_PLT_ENTRY_SIZE, ppc_elf_vxworks_plt_entry,
	ppc_elf_vxworks_pic_plt_entry, VXWORKS_PLT_INITIAL_ENTRY_SIZE,
	ppc_elf_vxworks_plt0_entry, ppc_elf_vxworks_pic_plt0_entry,
	VXWORKS_PLT_NON_JMP_SLOT_RELOCS, VXWORKS_PLTRESOLVE_RELOCS,
	VXWORKS_PLTRESOLVE_RELOCS_SHLIB): New.
	(ppc_elf_link_hash_table): Add srelplt2, sgotplt, hgot, hplt,
	is_vxworks, plt_entry_size, plt_slot_size, plt_initial_entry_size.
	(ppc_elf_link_hash_table_create): Initialize hadtab plt fields.
	(ppc_elf_create_got): Create .got.plt for VxWorks.
	(ppc_elf_create_dynamic_sections): Create unloaded plt relocation
	section for VxWorks.
	(ppc_elf_select_plt_layout): Handle VxWorks plt format.
	(allocate_got): VxWorks does not need a got header.
	(allocate_dynrelocs): Handle VxWorks plt format.
	(ppc_elf_size_dynamic_sections): Save _G_O_T_ and _P_L_T_ symbols for
	VxWorks.  Handle VxWorks plt/got.
	(ppc_elf_finish_dynamic_sections): Fill in VxWorks plt.
	(ppc_elf_vxworks_special_sections): New.
	(ppc_elf_vxworks_link_hash_table_create,
	ppc_elf_vxworks_add_symbol_hook,
	elf_i386_vxworks_link_output_symbol_hook,
	ppc_elf_vxworks_final_write_processing): New functions.
	* targets.c (bfd_elf32_powerpc_vxworks_vec): Declare.
	(_bfd_target_vector): Use it.
gas/
	* config/tc-ppc.c (ppc_target_format): Add VxWorks.
gas/testsuite/
	* gas/ppc/altivec.d: Match all powerpc target vecs.
	* gas/ppc/booke.d: Ditto.
	* gas/ppc/e500.d: Ditto.
ld/
	* Makefile.am (ALL_EMULATIONS): Add eelf32ppcvxworks.o.
	(eelf32ppcvxworks.o): Add dependencies.
	* Makefile.in: Regenerate.
	* configure.tgt: Add entry for powerpc-vxworks.
	* emulparams/elf32-ppc.c: Mention elf32ppcvxworks.sh in comment.
	* emulparams/elf32ppcvxworks.sh: New file.
	* emultempl/ppc32elf.em (bfd_elf32_powerpc_vxworks_vec): Declare.
	(is_ppc_elf32_vec): New function.
	(ppc_after_open, ppc_before_allocation,
	gld${EMULATION_NAME}_after_allocation): Use it.
This commit is contained in:
Paul Brook 2005-07-05 13:25:56 +00:00
parent a0defb2e23
commit 9d8504b17f
20 changed files with 856 additions and 306 deletions

View File

@ -1,3 +1,37 @@
2005-05-07 Paul Brook <paul@codesourcery.com>
* config.bfd: Add separate case for ppc-vxworks.
* configure: Regenerate.
* configure.in: Include elf-vxworks.lo on ppc targets.
* elf-vxworks.c (elf_vxworks_final_write_processing): Handle
.rela.plt.unloaded.
* elf32-ppc.c: Add VxWorks target vec. Include elf-vxworks.h.
(PLT_ENTRY_SIZE, PLT_INITIAL_ENTRY_SIZE, PLT_SLOT_SIZE): Remove.
(VXWORKS_PLT_ENTRY_SIZE, ppc_elf_vxworks_plt_entry,
ppc_elf_vxworks_pic_plt_entry, VXWORKS_PLT_INITIAL_ENTRY_SIZE,
ppc_elf_vxworks_plt0_entry, ppc_elf_vxworks_pic_plt0_entry,
VXWORKS_PLT_NON_JMP_SLOT_RELOCS, VXWORKS_PLTRESOLVE_RELOCS,
VXWORKS_PLTRESOLVE_RELOCS_SHLIB): New.
(ppc_elf_link_hash_table): Add srelplt2, sgotplt, hgot, hplt,
is_vxworks, plt_entry_size, plt_slot_size, plt_initial_entry_size.
(ppc_elf_link_hash_table_create): Initialize hadtab plt fields.
(ppc_elf_create_got): Create .got.plt for VxWorks.
(ppc_elf_create_dynamic_sections): Create unloaded plt relocation
section for VxWorks.
(ppc_elf_select_plt_layout): Handle VxWorks plt format.
(allocate_got): VxWorks does not need a got header.
(allocate_dynrelocs): Handle VxWorks plt format.
(ppc_elf_size_dynamic_sections): Save _G_O_T_ and _P_L_T_ symbols for
VxWorks. Handle VxWorks plt/got.
(ppc_elf_finish_dynamic_sections): Fill in VxWorks plt.
(ppc_elf_vxworks_special_sections): New.
(ppc_elf_vxworks_link_hash_table_create,
ppc_elf_vxworks_add_symbol_hook,
elf_i386_vxworks_link_output_symbol_hook,
ppc_elf_vxworks_final_write_processing): New functions.
* targets.c (bfd_elf32_powerpc_vxworks_vec): Declare.
(_bfd_target_vector): Use it.
2005-07-05 Jakub Jelinek <jakub@redhat.com>
* libbfd-in.h (struct artdata): Add extended_names_size field.

View File

@ -1022,7 +1022,7 @@ case "${targ}" in
#endif
powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \
powerpc-*-solaris2* | powerpc-*-linux-* | powerpc-*-rtems* | \
powerpc-*-chorus* | powerpc-*-vxworks* | powerpc-*-windiss*)
powerpc-*-chorus*)
targ_defvec=bfd_elf32_powerpc_vec
targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_vec ppcboot_vec"
targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec"
@ -1053,6 +1053,11 @@ case "${targ}" in
targ_defvec=bfd_elf32_powerpc_vec
targ_selvecs="rs6000coff_vec bfd_elf32_powerpcle_vec ppcboot_vec"
;;
powerpc-*-vxworks* | powerpc-*-windiss*)
targ_defvec=bfd_elf32_powerpc_vxworks_vec
targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec bfd_elf32_powerpcle_vec ppcboot_vec"
targ64_selvecs="bfd_elf64_powerpc_vec bfd_elf64_powerpcle_vec"
;;
powerpcle-*-nto*)
targ_defvec=bfd_elf32_powerpcle_vec
targ_selvecs="rs6000coff_vec bfd_elf32_powerpc_vec ppcboot_vec"

347
bfd/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -646,8 +646,9 @@ do
bfd_elf32_or32_big_vec) tb="$tb elf32-or32.lo elf32.lo $elf" ;;
bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";;
bfd_elf32_pjl_vec) tb="$tb elf32-pj.lo elf32.lo $elf";;
bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.lo elf32.lo $elf" ;;
bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.lo elf32.lo $elf" ;;
bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
bfd_elf32_powerpc_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
bfd_elf32_s390_vec) tb="$tb elf32-s390.lo elf32.lo $elf" ;;
# FIXME: We include cofflink.lo not because it's needed for
# bfd_elf32_sh64[l]_vec, but because we include bfd_elf32_sh[l]_vec

View File

@ -141,6 +141,8 @@ elf_vxworks_final_write_processing (bfd *abfd,
struct bfd_elf_section_data *d;
sec = bfd_get_section_by_name (abfd, ".rel.plt.unloaded");
if (!sec)
sec = bfd_get_section_by_name (abfd, ".rela.plt.unloaded");
if (!sec)
return;
d = elf_section_data (sec);

View File

@ -32,6 +32,7 @@
#include "elf-bfd.h"
#include "elf/ppc.h"
#include "elf32-ppc.h"
#include "elf-vxworks.h"
/* RELA relocations are used here. */
@ -52,12 +53,6 @@ static bfd_reloc_status_type ppc_elf_unhandled_reloc
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
/* For old-style PLT. */
/* The size in bytes of an entry in the procedure linkage table. */
#define PLT_ENTRY_SIZE 12
/* The initial size of the plt reserved for the dynamic linker. */
#define PLT_INITIAL_ENTRY_SIZE 72
/* The size of the gap between entries in the PLT. */
#define PLT_SLOT_SIZE 8
/* The number of single-slot PLT entries (the rest use two slots). */
#define PLT_NUM_SINGLE_ENTRIES 8192
@ -65,6 +60,73 @@ static bfd_reloc_status_type ppc_elf_unhandled_reloc
#define GLINK_PLTRESOLVE 16*4
#define GLINK_ENTRY_SIZE 4*4
/* VxWorks uses its own plt layout, filled in by the static linker. */
/* The standard VxWorks PLT entry. */
#define VXWORKS_PLT_ENTRY_SIZE 32
static const bfd_vma ppc_elf_vxworks_plt_entry
[VXWORKS_PLT_ENTRY_SIZE / 4] =
{
0x3d800000, /* lis r12,0 */
0x818c0000, /* lwz r12,0(r12) */
0x7d8903a6, /* mtctr r12 */
0x4e800420, /* bctr */
0x39600000, /* li r11,0 */
0x48000000, /* b 14 <.PLT0resolve+0x4> */
0x60000000, /* nop */
0x60000000, /* nop */
};
static const bfd_vma ppc_elf_vxworks_pic_plt_entry
[VXWORKS_PLT_ENTRY_SIZE / 4] =
{
0x3d9e0000, /* addis r12,r30,0 */
0x818c0000, /* lwz r12,0(r12) */
0x7d8903a6, /* mtctr r12 */
0x4e800420, /* bctr */
0x39600000, /* li r11,0 */
0x48000000, /* b 14 <.PLT0resolve+0x4> 14: R_PPC_REL24 .PLTresolve */
0x60000000, /* nop */
0x60000000, /* nop */
};
/* The initial VxWorks PLT entry. */
#define VXWORKS_PLT_INITIAL_ENTRY_SIZE 32
static const bfd_vma ppc_elf_vxworks_plt0_entry
[VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
{
0x3d800000, /* lis r12,0 */
0x398c0000, /* addi r12,r12,0 */
0x800c0008, /* lwz r0,8(r12) */
0x7c0903a6, /* mtctr r0 */
0x818c0004, /* lwz r12,4(r12) */
0x4e800420, /* bctr */
0x60000000, /* nop */
0x60000000, /* nop */
};
static const bfd_vma ppc_elf_vxworks_pic_plt0_entry
[VXWORKS_PLT_INITIAL_ENTRY_SIZE / 4] =
{
0x819e0008, /* lwz r12,8(r30) */
0x7d8903a6, /* mtctr r12 */
0x819e0004, /* lwz r12,4(r30) */
0x4e800420, /* bctr */
0x60000000, /* nop */
0x60000000, /* nop */
0x60000000, /* nop */
0x60000000, /* nop */
};
/* For executables, we have some additional relocations in
.rela.plt.unloaded, for the kernel loader. */
/* The number of non-JMP_SLOT relocations per PLT0 slot. */
#define VXWORKS_PLT_NON_JMP_SLOT_RELOCS 3
/* The number of relocations in the PLTResolve slot. */
#define VXWORKS_PLTRESOLVE_RELOCS 2
/* The number of relocations in the PLTResolve slot when when creating
a shared library. */
#define VXWORKS_PLTRESOLVE_RELOCS_SHLIB 0
/* Some instructions. */
#define ADDIS_11_11 0x3d6b0000
#define ADDIS_11_30 0x3d7e0000
@ -2293,6 +2355,25 @@ struct ppc_elf_link_hash_table
/* Small local sym to section mapping cache. */
struct sym_sec_cache sym_sec;
/* The (unloaded but important) .rela.plt.unloaded on VxWorks. */
asection *srelplt2;
/* The .got.plt section (VxWorks only)*/
asection *sgotplt;
/* Short-cuts to frequently used symbols on VxWorks targets. */
struct elf_link_hash_entry *hgot, *hplt;
/* True if the target system is VxWorks. */
int is_vxworks;
/* The size of PLT entries. */
int plt_entry_size;
/* The distance between adjacent PLT slots. */
int plt_slot_size;
/* The size of the first PLT entry. */
int plt_initial_entry_size;
};
/* Get the PPC ELF linker hash table from a link_info structure. */
@ -2360,10 +2441,16 @@ ppc_elf_link_hash_table_create (bfd *abfd)
ret->sdata[1].sym_name = "_SDA2_BASE_";
ret->sdata[1].bss_name = ".sbss2";
ret->plt_entry_size = 12;
ret->plt_slot_size = 8;
ret->plt_initial_entry_size = 72;
ret->is_vxworks = 0;
return &ret->elf.root;
}
/* The powerpc .got has a blrl instruction in it. Mark it executable. */
/* Create .got and the related sections. */
static bfd_boolean
ppc_elf_create_got (bfd *abfd, struct bfd_link_info *info)
@ -2380,10 +2467,21 @@ ppc_elf_create_got (bfd *abfd, struct bfd_link_info *info)
if (s == NULL)
abort ();
flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED);
if (htab->is_vxworks)
{
htab->sgotplt = bfd_get_section_by_name (abfd, ".got.plt");
if (!htab->sgotplt)
abort ();
}
else
{
/* The powerpc .got has a blrl instruction in it. Mark it
executable. */
flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
if (!bfd_set_section_flags (abfd, s, flags))
return FALSE;
}
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
| SEC_LINKER_CREATED | SEC_READONLY);
@ -2441,6 +2539,20 @@ ppc_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
return FALSE;
}
/* Create the section for VxWorks static plt relocations. */
if (htab->is_vxworks && !info->shared)
{
s = bfd_make_section (abfd, ".rela.plt.unloaded");
flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY
| SEC_LINKER_CREATED);
if (s == NULL
|| ! bfd_set_section_flags (abfd, s, flags)
|| ! bfd_set_section_alignment (abfd, s,
get_elf_backend_data (abfd)->s->log_file_align))
return FALSE;
htab->srelplt2 = s;
}
htab->relplt = bfd_get_section_by_name (abfd, ".rela.plt");
htab->plt = s = bfd_get_section_by_name (abfd, ".plt");
if (s == NULL)
@ -3423,14 +3535,25 @@ ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED,
int force_old_plt)
{
struct ppc_elf_link_hash_table *htab;
flagword flags;
htab = ppc_elf_hash_table (info);
if (force_old_plt || !htab->new_plt)
htab->old_plt = 1;
if (!htab->old_plt)
if (htab->is_vxworks)
{
flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
/* 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;
if (htab->plt != NULL
&& !bfd_set_section_flags (htab->elf.dynobj, htab->plt, flags))
return -1;
}
else if (!htab->old_plt)
{
flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
| SEC_IN_MEMORY | SEC_LINKER_CREATED);
/* The new PLT is a loaded section. */
@ -4042,7 +4165,12 @@ allocate_got (struct ppc_elf_link_hash_table *htab, unsigned int need)
if (htab->old_plt)
max_before_header = 32764;
if (need <= htab->got_gap)
if (htab->is_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;
@ -4103,7 +4231,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
asection *s = htab->plt;
if (!htab->old_plt)
if (!(htab->old_plt || htab->is_vxworks))
{
if (!doneone)
{
@ -4134,16 +4262,17 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
/* If this is the first .plt entry, make room
for the special first entry. */
if (s->size == 0)
s->size += PLT_INITIAL_ENTRY_SIZE;
s->size += htab->plt_initial_entry_size;
/* The PowerPC PLT is actually composed of two
parts, the first part is 2 words (for a load
and a jump), and then there is a remaining
word available at the end. */
plt_offset = (PLT_INITIAL_ENTRY_SIZE
+ (PLT_SLOT_SIZE
* ((s->size - PLT_INITIAL_ENTRY_SIZE)
/ PLT_ENTRY_SIZE)));
plt_offset = (htab->plt_initial_entry_size
+ (htab->plt_slot_size
* ((s->size
- htab->plt_initial_entry_size)
/ htab->plt_entry_size)));
/* If this symbol is not defined in a regular
file, and we are not generating a shared
@ -4158,12 +4287,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
h->root.u.def.value = plt_offset;
}
/* Make room for this entry. After the 8192nd
entry, room for two entries is allocated. */
s->size += PLT_ENTRY_SIZE;
if ((s->size - PLT_INITIAL_ENTRY_SIZE) / PLT_ENTRY_SIZE
/* Make room for this entry. */
s->size += htab->plt_entry_size;
/* After the 8192nd entry, room for two entries
is allocated. */
if (!htab->is_vxworks
&& (s->size - htab->plt_initial_entry_size)
/ htab->plt_entry_size
> PLT_NUM_SINGLE_ENTRIES)
s->size += PLT_ENTRY_SIZE;
s->size += htab->plt_entry_size;
}
ent->plt.offset = plt_offset;
}
@ -4172,6 +4304,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (!doneone)
{
htab->relplt->size += sizeof (Elf32_External_Rela);
if (htab->is_vxworks)
{
/* Allocate space for the unloaded relocations. */
if (!info->shared)
{
if (ent->plt.offset
== (bfd_vma) htab->plt_initial_entry_size)
{
htab->srelplt2->size
+= sizeof (Elf32_External_Rela)
* VXWORKS_PLTRESOLVE_RELOCS;
}
htab->srelplt2->size
+= sizeof (Elf32_External_Rela)
* VXWORKS_PLT_NON_JMP_SLOT_RELOCS;
}
/* Every PLT entry has an associated GOT entry in
.got.plt. */
htab->sgotplt->size += 4;
}
doneone = TRUE;
}
}
@ -4489,10 +4644,31 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
else
htab->tlsld_got.offset = (bfd_vma) -1;
if (htab->is_vxworks)
{
/* Save the GOT and PLT symbols in the hash table for easy access.
Mark them as having relocations; they might not, but we won't
know for sure until we build the GOT in finish_dynamic_symbol. */
htab->hgot = elf_link_hash_lookup (elf_hash_table (info),
"_GLOBAL_OFFSET_TABLE_",
FALSE, FALSE, FALSE);
if (htab->hgot)
htab->hgot->indx = -2;
htab->hplt = elf_link_hash_lookup (elf_hash_table (info),
"_PROCEDURE_LINKAGE_TABLE_",
FALSE, FALSE, FALSE);
if (htab->hplt)
htab->hplt->indx = -2;
/* If the PLT is executable then give the symbol function type. */
if (htab->hplt && htab->plt->flags & SEC_CODE)
htab->hplt->type = STT_FUNC;
}
/* Allocate space for global sym dynamic relocs. */
elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
if (htab->got != NULL)
if (htab->got != NULL && !htab->is_vxworks)
{
unsigned int g_o_t = 32768;
@ -4502,7 +4678,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
g_o_t = htab->got->size;
htab->got->size += htab->got_header_size;
}
if (htab->old_plt)
if (htab->old_plt && !htab->is_vxworks)
g_o_t += 4;
htab->elf.hgot->root.u.def.value = g_o_t;
@ -4523,14 +4699,22 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
relocs = FALSE;
for (s = htab->elf.dynobj->sections; s != NULL; s = s->next)
{
bfd_boolean strip_section = TRUE;
if ((s->flags & SEC_LINKER_CREATED) == 0)
continue;
if (s == htab->plt
|| s == htab->glink
|| s == htab->got
|| s == htab->sgotplt
|| s == htab->sbss)
{
/* We'd like to strip these sections if they aren't needed, but if
we've exported dynamic symbols from them we must leave them.
It's too late to tell BFD to get rid of the symbols. */
if ((s == htab->plt || s == htab->got) && htab->hplt != NULL)
strip_section = FALSE;
/* Strip this section if we don't need it; see the
comment below. */
}
@ -4569,7 +4753,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
continue;
}
if (s->size == 0)
if (s->size == 0 && strip_section)
{
s->flags |= SEC_EXCLUDE;
continue;
@ -6453,8 +6637,152 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
bfd_byte *loc;
bfd_vma reloc_index;
if (!(htab->old_plt || htab->is_vxworks))
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)
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)
{
bfd_vma got_offset;
const bfd_vma *plt_entry;
/* The first three entries in .got.plt are reserved. */
got_offset = (reloc_index + 3) * 4;
/* Use the right PLT. */
plt_entry = info->shared ? ppc_elf_vxworks_pic_plt_entry
: ppc_elf_vxworks_plt_entry;
/* Fill in the .plt on VxWorks. */
if (info->shared)
{
bfd_vma got_offset_hi = (got_offset >> 16)
+ ((got_offset & 0x8000) >> 15);
bfd_put_32 (output_bfd,
plt_entry[0] | (got_offset_hi & 0xffff),
htab->plt->contents + ent->plt.offset + 0);
bfd_put_32 (output_bfd,
plt_entry[1] | (got_offset & 0xffff),
htab->plt->contents + ent->plt.offset + 4);
}
else
{
bfd_vma got_loc = (got_offset
+ htab->hgot->root.u.def.value
+ htab->hgot->root.u.def.section->output_offset
+ htab->hgot->root.u.def.section->output_section->vma);
bfd_vma got_loc_hi = (got_loc >> 16)
+ ((got_loc & 0x8000) >> 15);
bfd_put_32 (output_bfd,
plt_entry[0] | (got_loc_hi & 0xffff),
htab->plt->contents + ent->plt.offset + 0);
bfd_put_32 (output_bfd,
plt_entry[1] | (got_loc & 0xffff),
htab->plt->contents + ent->plt.offset + 4);
}
bfd_put_32 (output_bfd, plt_entry[2],
htab->plt->contents + ent->plt.offset + 8);
bfd_put_32 (output_bfd, plt_entry[3],
htab->plt->contents + ent->plt.offset + 12);
/* This instruction is an immediate load. The value loaded is
the byte offset of the R_PPC_JMP_SLOT relocation from the
start of the .rela.plt section. The value is stored in the
low-order 16 bits of the load instruction. */
/* NOTE: It appears that this is now an index rather than a
prescaled offset. */
bfd_put_32 (output_bfd,
plt_entry[4] | reloc_index,
htab->plt->contents + ent->plt.offset + 16);
/* This instruction is a PC-relative branch whose target is
the start of the PLT section. The address of this branch
instruction is 20 bytes beyond the start of this PLT entry.
The address is encoded in bits 6-29, inclusive. The value
stored is right-shifted by two bits, permitting a 26-bit
offset. */
bfd_put_32 (output_bfd,
(plt_entry[5]
| (-(ent->plt.offset + 20) & 0x03fffffc)),
htab->plt->contents + ent->plt.offset + 20);
bfd_put_32 (output_bfd, plt_entry[6],
htab->plt->contents + ent->plt.offset + 24);
bfd_put_32 (output_bfd, plt_entry[7],
htab->plt->contents + ent->plt.offset + 28);
/* Fill in the GOT entry corresponding to this PLT slot with
the address immediately after the the "bctr" instruction
in this PLT entry. */
bfd_put_32 (output_bfd, (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset + 16),
htab->sgotplt->contents + got_offset);
if (!info->shared)
{
/* Fill in a couple of entries in .rela.plt.unloaded. */
loc = htab->srelplt2->contents
+ ((VXWORKS_PLTRESOLVE_RELOCS + reloc_index
* VXWORKS_PLT_NON_JMP_SLOT_RELOCS)
* sizeof (Elf32_External_Rela));
/* Provide the @ha relocation for the first instruction. */
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset + 2);
rela.r_info = ELF32_R_INFO (htab->hgot->indx,
R_PPC_ADDR16_HA);
rela.r_addend = got_offset;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
loc += sizeof (Elf32_External_Rela);
/* Provide the @l relocation for the second instruction. */
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset + 6);
rela.r_info = ELF32_R_INFO (htab->hgot->indx,
R_PPC_ADDR16_LO);
rela.r_addend = got_offset;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
loc += sizeof (Elf32_External_Rela);
/* Provide a relocation for the GOT entry corresponding to this
PLT slot. Point it at the middle of the .plt entry. */
rela.r_offset = (htab->sgotplt->output_section->vma
+ htab->sgotplt->output_offset
+ got_offset);
rela.r_info = ELF32_R_INFO (htab->hplt->indx,
R_PPC_ADDR32);
rela.r_addend = ent->plt.offset + 16;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
}
/* VxWorks uses non-standard semantics for R_PPC_JMP_SLOT.
In particular, the offset for the relocation is not the
address of the PLT entry for this function, as specified
by the ABI. Instead, the offset is set to the address of
the GOT slot for this function. See EABI 4.4.4.1. */
rela.r_offset = (htab->sgotplt->output_section->vma
+ htab->sgotplt->output_offset
+ got_offset);
}
else
{
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset);
if (htab->old_plt)
{
/* We don't need to fill in the .plt. The ppc dynamic
@ -6468,23 +6796,12 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
bfd_put_32 (output_bfd, val,
htab->plt->contents + ent->plt.offset);
}
}
/* Fill in the entry in the .rela.plt section. */
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ ent->plt.offset);
rela.r_info = ELF32_R_INFO (h->dynindx, R_PPC_JMP_SLOT);
rela.r_addend = 0;
if (!htab->old_plt)
reloc_index = ent->plt.offset / 4;
else
{
reloc_index = ((ent->plt.offset - PLT_INITIAL_ENTRY_SIZE)
/ PLT_SLOT_SIZE);
if (reloc_index > PLT_NUM_SINGLE_ENTRIES)
reloc_index -= (reloc_index - PLT_NUM_SINGLE_ENTRIES) / 2;
}
loc = (htab->relplt->contents
+ reloc_index * sizeof (Elf32_External_Rela));
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
@ -6605,9 +6922,11 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd,
#endif
/* Mark some specially defined symbols as absolute. */
if (h == htab->elf.hgot
|| strcmp (h->root.root.string, "_DYNAMIC") == 0
|| strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
if (strcmp (h->root.root.string, "_DYNAMIC") == 0
|| (!htab->is_vxworks
&& (h == htab->elf.hgot
|| strcmp (h->root.root.string,
"_PROCEDURE_LINKAGE_TABLE_") == 0)))
sym->st_shndx = SHN_ABS;
return TRUE;
@ -6638,15 +6957,22 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
{
asection *sdyn;
asection *splt;
struct ppc_elf_link_hash_table *htab;
bfd_vma got;
bfd * dynobj;
#ifdef DEBUG
fprintf (stderr, "ppc_elf_finish_dynamic_sections called\n");
#endif
htab = ppc_elf_hash_table (info);
sdyn = bfd_get_section_by_name (htab->elf.dynobj, ".dynamic");
dynobj = elf_hash_table (info)->dynobj;
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
if (htab->is_vxworks)
splt = bfd_get_section_by_name (dynobj, ".plt");
else
splt = NULL;
got = 0;
if (htab->elf.hgot != NULL)
@ -6667,11 +6993,14 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
Elf_Internal_Dyn dyn;
asection *s;
bfd_elf32_swap_dyn_in (htab->elf.dynobj, dyncon, &dyn);
bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
switch (dyn.d_tag)
{
case DT_PLTGOT:
if (htab->is_vxworks)
s = htab->sgotplt;
else
s = htab->plt;
dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
break;
@ -6689,6 +7018,15 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
dyn.d_un.d_ptr = got;
break;
case DT_RELASZ:
if (htab->is_vxworks)
{
if (htab->relplt)
dyn.d_un.d_ptr -= htab->relplt->size;
break;
}
continue;
default:
continue;
}
@ -6705,7 +7043,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
bfd_vma val;
p += elf_hash_table (info)->hgot->root.u.def.value;
if (htab->old_plt)
if (htab->old_plt && !htab->is_vxworks)
bfd_put_32 (output_bfd, 0x4e800021 /* blrl */, p - 4);
val = 0;
@ -6716,6 +7054,89 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
elf_section_data (htab->got->output_section)->this_hdr.sh_entsize = 4;
}
/* Fill in the first entry in the VxWorks procedure linkage table. */
if (splt && splt->size > 0)
{
/* Use the right PLT. */
static const bfd_vma *plt_entry = NULL;
plt_entry = info->shared ?
ppc_elf_vxworks_pic_plt0_entry : ppc_elf_vxworks_plt0_entry;
if (!info->shared)
{
bfd_vma got_value =
(htab->hgot->root.u.def.section->output_section->vma
+ htab->hgot->root.u.def.section->output_offset
+ htab->hgot->root.u.def.value);
bfd_vma got_hi = (got_value >> 16) + ((got_value & 0x8000) >> 15);
bfd_put_32 (output_bfd, plt_entry[0] | (got_hi & 0xffff),
splt->contents + 0);
bfd_put_32 (output_bfd, plt_entry[1] | (got_value & 0xffff),
splt->contents + 4);
}
else
{
bfd_put_32 (output_bfd, plt_entry[0], splt->contents + 0);
bfd_put_32 (output_bfd, plt_entry[1], splt->contents + 4);
}
bfd_put_32 (output_bfd, plt_entry[2], splt->contents + 8);
bfd_put_32 (output_bfd, plt_entry[3], splt->contents + 12);
bfd_put_32 (output_bfd, plt_entry[4], splt->contents + 16);
bfd_put_32 (output_bfd, plt_entry[5], splt->contents + 20);
bfd_put_32 (output_bfd, plt_entry[6], splt->contents + 24);
bfd_put_32 (output_bfd, plt_entry[7], splt->contents + 28);
if (! info->shared)
{
Elf_Internal_Rela rela;
bfd_byte *loc;
loc = htab->srelplt2->contents;
/* Output the @ha relocation for the first instruction. */
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ 2);
rela.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_HA);
rela.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
loc += sizeof (Elf32_External_Rela);
/* Output the @l relocation for the second instruction. */
rela.r_offset = (htab->plt->output_section->vma
+ htab->plt->output_offset
+ 6);
rela.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_LO);
rela.r_addend = 0;
bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
loc += sizeof (Elf32_External_Rela);
/* Fix up the remaining relocations. They may have the wrong
symbol index for _G_O_T_ or _P_L_T_ depending on the order
in which symbols were output. */
while (loc < htab->srelplt2->contents + htab->srelplt2->size)
{
Elf_Internal_Rela rel;
bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_HA);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
loc += sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
rel.r_info = ELF32_R_INFO (htab->hgot->indx, R_PPC_ADDR16_LO);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
loc += sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloc_in (output_bfd, loc, &rel);
rel.r_info = ELF32_R_INFO (htab->hplt->indx, R_PPC_ADDR32);
bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
loc += sizeof (Elf32_External_Rela);
}
}
}
if (htab->glink != NULL && htab->glink->contents != NULL)
{
unsigned char *p;
@ -6956,3 +7377,147 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
#define elf_backend_plt_sym_val ppc_elf_plt_sym_val
#include "elf32-target.h"
/* VxWorks Target */
#undef TARGET_LITTLE_SYM
#undef TARGET_LITTLE_NAME
#undef TARGET_BIG_SYM
#define TARGET_BIG_SYM bfd_elf32_powerpc_vxworks_vec
#undef TARGET_BIG_NAME
#define TARGET_BIG_NAME "elf32-powerpc-vxworks"
/* This is the same as ppc_elf_special_sections except it does not include
the entry for .plt. */
static struct bfd_elf_special_section const *
ppc_elf_vxworks_special_sections[27]=
{
NULL, /* 'a' */
NULL, /* 'b' */
NULL, /* 'c' */
NULL, /* 'd' */
NULL, /* 'e' */
NULL, /* 'f' */
NULL, /* 'g' */
NULL, /* 'h' */
NULL, /* 'i' */
NULL, /* 'j' */
NULL, /* 'k' */
NULL, /* 'l' */
NULL, /* 'm' */
NULL, /* 'n' */
NULL, /* 'o' */
NULL, /* 'p' */
NULL, /* 'q' */
NULL, /* 'r' */
ppc_special_sections_s, /* 's' */
ppc_special_sections_t, /* 's' */
NULL, /* 'u' */
NULL, /* 'v' */
NULL, /* 'w' */
NULL, /* 'x' */
NULL, /* 'y' */
NULL, /* 'z' */
ppc_special_sections_other, /* other */
};
/* Like ppc_elf_link_hash_table_create, but overrides
appropriately for VxWorks. */
static struct bfd_link_hash_table *
ppc_elf_vxworks_link_hash_table_create (bfd *abfd)
{
struct bfd_link_hash_table *ret;
ret = ppc_elf_link_hash_table_create (abfd);
if (ret)
{
struct ppc_elf_link_hash_table *htab
= (struct ppc_elf_link_hash_table *)ret;
htab->is_vxworks = 1;
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;
}
return ret;
}
/* Tweak magic VxWorks symbols as they are loaded. */
static bfd_boolean
ppc_elf_vxworks_add_symbol_hook (bfd *abfd,
struct bfd_link_info *info,
Elf_Internal_Sym *sym,
const char **namep ATTRIBUTE_UNUSED,
flagword *flagsp ATTRIBUTE_UNUSED,
asection **secp,
bfd_vma *valp)
{
if (!elf_vxworks_add_symbol_hook(abfd, info, sym,namep, flagsp, secp,
valp))
return FALSE;
return ppc_elf_add_symbol_hook(abfd, info, sym,namep, flagsp, secp, valp);
}
/* Tweak magic VxWorks symbols as they are written to the output file. */
static bfd_boolean
elf_i386_vxworks_link_output_symbol_hook (struct bfd_link_info *info
ATTRIBUTE_UNUSED,
const char *name,
Elf_Internal_Sym *sym,
asection *input_sec ATTRIBUTE_UNUSED,
struct elf_link_hash_entry *h
ATTRIBUTE_UNUSED)
{
/* Ignore the first dummy symbol. */
if (!name)
return TRUE;
return elf_vxworks_link_output_symbol_hook (name, sym);
}
static void
ppc_elf_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker)
{
ppc_elf_final_write_processing(abfd, linker);
elf_vxworks_final_write_processing(abfd, linker);
}
/* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
define it. */
#undef elf_backend_want_plt_sym
#define elf_backend_want_plt_sym 1
#undef elf_backend_want_got_plt
#define elf_backend_want_got_plt 1
#undef elf_backend_got_symbol_offset
#define elf_backend_got_symbol_offset 0
#undef elf_backend_plt_not_loaded
#define elf_backend_plt_not_loaded 0
#undef elf_backend_plt_readonly
#define elf_backend_plt_readonly 1
#undef elf_backend_got_header_size
#define elf_backend_got_header_size 12
#undef bfd_elf32_bfd_link_hash_table_create
#define bfd_elf32_bfd_link_hash_table_create \
ppc_elf_vxworks_link_hash_table_create
#undef elf_backend_special_sections
#define elf_backend_special_sections \
ppc_elf_vxworks_special_sections
#undef elf_backend_add_symbol_hook
#define elf_backend_add_symbol_hook \
ppc_elf_vxworks_add_symbol_hook
#undef elf_backend_link_output_symbol_hook
#define elf_backend_link_output_symbol_hook \
elf_i386_vxworks_link_output_symbol_hook
#undef elf_backend_final_write_processing
#define elf_backend_final_write_processing \
ppc_elf_vxworks_final_write_processing
#undef elf_backend_emit_relocs
#define elf_backend_emit_relocs \
elf_vxworks_emit_relocs
#undef elf32_bed
#define elf32_bed ppc_elf_vxworks_bed
#include "elf32-target.h"

View File

@ -606,6 +606,7 @@ extern const bfd_target bfd_elf32_pj_vec;
extern const bfd_target bfd_elf32_pjl_vec;
extern const bfd_target bfd_elf32_powerpc_vec;
extern const bfd_target bfd_elf32_powerpcle_vec;
extern const bfd_target bfd_elf32_powerpc_vxworks_vec;
extern const bfd_target bfd_elf32_s390_vec;
extern const bfd_target bfd_elf32_sh64_vec;
extern const bfd_target bfd_elf32_sh64l_vec;
@ -912,6 +913,7 @@ static const bfd_target * const _bfd_target_vector[] = {
&bfd_elf32_pj_vec,
&bfd_elf32_pjl_vec,
&bfd_elf32_powerpc_vec,
&bfd_elf32_powerpc_vxworks_vec,
&bfd_elf32_powerpcle_vec,
&bfd_elf32_s390_vec,
&bfd_elf32_sh_vec,

View File

@ -1,3 +1,7 @@
2005-07-05 Paul Brook <paul@codesourcery.com>
* config/tc-ppc.c (ppc_target_format): Add VxWorks.
2005-07-05 Aldy Hernandez <aldyh@redhat.com>
* config/tc-ms1.c: New.

View File

@ -1216,9 +1216,13 @@ ppc_target_format ()
#endif
#endif
#ifdef OBJ_ELF
# ifdef TE_VXWORKS
return "elf32-powerpc-vxworks";
# else
return (target_big_endian
? (ppc_obj64 ? "elf64-powerpc" : "elf32-powerpc")
: (ppc_obj64 ? "elf64-powerpcle" : "elf32-powerpcle"));
# endif
#endif
}

View File

@ -1,3 +1,9 @@
2005-05-07 Paul Brook <paul@codesourcery.com>
* gas/ppc/altivec.d: Match all powerpc target vecs.
* gas/ppc/booke.d: Ditto.
* gas/ppc/e500.d: Ditto.
2005-07-05 Aldy Hernandez <aldyh@redhat.com>
* gas/ms1: New directory.

View File

@ -2,7 +2,7 @@
#objdump: -dr
#name: AltiVec tests
.*: +file format elf32-powerpc
.*: +file format elf32-powerpc.*
Disassembly of section \.text:

View File

@ -2,7 +2,7 @@
#objdump: -dr -Mbooke
#name: BookE tests
.*: +file format elf(32)?(64)?-powerpc
.*: +file format elf(32)?(64)?-powerpc.*
Disassembly of section \.text:

View File

@ -2,7 +2,7 @@
#objdump: -dr -Me500
#name: e500 tests
.*: +file format elf(32)?(64)?-powerpc
.*: +file format elf(32)?(64)?-powerpc.*
Disassembly of section \.text:

View File

@ -1,3 +1,16 @@
2005-05-07 Paul Brook <paul@codesourcery.com>
* Makefile.am (ALL_EMULATIONS): Add eelf32ppcvxworks.o.
(eelf32ppcvxworks.o): Add dependencies.
* Makefile.in: Regenerate.
* configure.tgt: Add entry for powerpc-vxworks.
* emulparams/elf32-ppc.c: Mention elf32ppcvxworks.sh in comment.
* emulparams/elf32ppcvxworks.sh: New file.
* emultempl/ppc32elf.em (bfd_elf32_powerpc_vxworks_vec): Declare.
(is_ppc_elf32_vec): New function.
(ppc_after_open, ppc_before_allocation,
gld${EMULATION_NAME}_after_allocation): Use it.
2005-07-05 Peter S. Mazinger" <ps.m@gmx.net>
* emulparams/elf32bmip.sh (GENERATE_PIE_SCRIPT): Define as "yes".

View File

@ -181,6 +181,7 @@ ALL_EMULATIONS = \
eelf32ppcnto.o \
eelf32ppcsim.o \
eelf32ppcwindiss.o \
eelf32ppcvxworks.o \
eelf32vax.o \
eelf32xstormy16.o \
eelf32xtensa.o \
@ -745,6 +746,9 @@ eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \
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)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcvxworks "$(tdir_elf32ppcvxworks)"
eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
$(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}

View File

@ -404,6 +404,7 @@ ALL_EMULATIONS = \
eelf32ppcnto.o \
eelf32ppcsim.o \
eelf32ppcwindiss.o \
eelf32ppcvxworks.o \
eelf32vax.o \
eelf32xstormy16.o \
eelf32xtensa.o \
@ -1549,6 +1550,9 @@ eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \
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)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32ppcvxworks "$(tdir_elf32ppcvxworks)"
eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
$(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
$(srcdir)/emultempl/elf32.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}

View File

@ -524,7 +524,7 @@ powerpc*le-*-elf* | powerpc*le-*-eabi* | powerpc*le-*-solaris* \
targ_extra_emuls="elf32ppcsim" ;;
esac ;;
powerpc*-*-elf* | powerpc*-*-eabi* | powerpc*-*-sysv* \
| powerpc*-*-netbsd* | powerpc-*-openbsd* | powerpc*-*-vxworks* | powerpc*-*-kaos*)
| powerpc*-*-netbsd* | powerpc-*-openbsd* | powerpc*-*-kaos*)
case "${targ}" in
*64*) targ_emul=elf64ppc
targ_extra_emuls="elf32ppc elf32ppclinux elf32ppcsim"
@ -534,6 +534,10 @@ powerpc*-*-elf* | powerpc*-*-eabi* | powerpc*-*-sysv* \
*) targ_emul=elf32ppc
targ_extra_emuls="elf32ppclinux elf32ppcsim" ;;
esac ;;
powerpc-*-vxworks*)
targ_emul=elf32ppcvxworks
targ_extra_emuls="elf32ppc elf32ppclinux elf32ppcsim"
;;
powerpc-*-nto*) targ_emul=elf32ppcnto ;;
powerpcle-*-nto*) targ_emul=elf32lppcnto ;;
powerpcle-*-rtems*) targ_emul=elf32leppc ;;

View File

@ -1,5 +1,5 @@
# If you change this file, please also look at files which source this one:
# elf32lppc.sh elf32ppclinux.sh elf32ppcsim.sh
# elf32lppc.sh elf32ppclinux.sh elf32ppcsim.sh elf32ppcvxworks.sh
TEMPLATE_NAME=elf32
EXTRA_EM_FILE=ppc32elf

View File

@ -0,0 +1,4 @@
. ${srcdir}/emulparams/elf32ppc.sh
OUTPUT_FORMAT="elf32-powerpc-vxworks"
unset BSS_PLT
. ${srcdir}/emulparams/vxworks.sh

View File

@ -28,6 +28,15 @@ cat >>e${EMULATION_NAME}.c <<EOF
extern const bfd_target bfd_elf32_powerpc_vec;
extern const bfd_target bfd_elf32_powerpcle_vec;
extern const bfd_target bfd_elf32_powerpc_vxworks_vec;
static inline int
is_ppc_elf32_vec(const bfd_target * vec)
{
return (vec == &bfd_elf32_powerpc_vec
|| vec == &bfd_elf32_powerpc_vxworks_vec
|| vec == &bfd_elf32_powerpcle_vec);
}
/* Whether to run tls optimization. */
static int notlsopt = 0;
@ -39,8 +48,7 @@ static int old_got = 0;
static void
ppc_after_open (void)
{
if (link_info.hash->creator == &bfd_elf32_powerpc_vec
|| link_info.hash->creator == &bfd_elf32_powerpcle_vec)
if (is_ppc_elf32_vec (link_info.hash->creator))
{
int new_plt;
int keep_new;
@ -95,8 +103,7 @@ ppc_after_open (void)
static void
ppc_before_allocation (void)
{
if (link_info.hash->creator == &bfd_elf32_powerpc_vec
|| link_info.hash->creator == &bfd_elf32_powerpcle_vec)
if (is_ppc_elf32_vec (link_info.hash->creator))
{
if (ppc_elf_tls_setup (output_bfd, &link_info) && !notlsopt)
{
@ -113,9 +120,7 @@ ppc_before_allocation (void)
static void
gld${EMULATION_NAME}_after_allocation (void)
{
if ((link_info.hash->creator == &bfd_elf32_powerpc_vec
|| link_info.hash->creator == &bfd_elf32_powerpcle_vec)
&& !link_info.relocatable)
if (is_ppc_elf32_vec (link_info.hash->creator))
{
if (!ppc_elf_set_sdata_syms (output_bfd, &link_info))
einfo ("%X%P: cannot set sdata syms %E\n");