This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: MIPS PLT entry
- From: "Fu, Chao-Ying" <fu at mips dot com>
- To: "Maciej W. Rozycki" <macro at linux-mips dot org>, "Richard Sandiford" <rdsandiford at googlemail dot com>
- Cc: <binutils at sourceware dot org>
- Date: Wed, 15 Jul 2009 16:01:07 -0700
- Subject: RE: MIPS PLT entry
> >
> > ... it's trivial to implement it flexibly, so that both MIPS
> > I support is
> > retained and newer platforms benefit from a faster sequence,
> > and I plan to
> > do so unless Chao-Ying beats me, ;) so I see no point in doing it
> > otherwise.
>
Hi Maciej,
I didn't see your patch, so I made a patch. Do you think
this patch does what you plan to do? Thanks a lot!
Regards,
Chao-ying
2009-07-15 Chao-ying Fu <fu@mips.com>
* elfxx-mips.c (mips_exec_fast_plt_entry): New table.
(_bfd_mips_elf_size_dynamic_sections): For MIPS1, the last PLT
entry needs a nop in the branch delay slot.
(_bfd_mips_elf_finish_dynamic_symbol): For non-MIPS1 CPUs,
we can use the fast PLT entry that don't need the 5th instruction.
Index: src/bfd/elfxx-mips.c
===================================================================
--- src.orig/bfd/elfxx-mips.c 2009-05-21 11:59:36.000000000 -0700
+++ src/bfd/elfxx-mips.c 2009-07-15 15:55:52.366101000 -0700
@@ -923,6 +923,14 @@ static const bfd_vma mips_exec_plt_entry
0x03200008 /* jr $25 */
};
+/* This plt entry is for non-MIPS1 CPUs that have load interlocking. */
+static const bfd_vma mips_exec_fast_plt_entry[] = {
+ 0x3c0f0000, /* lui $15, %hi(.got.plt entry) */
+ 0x01f90000, /* l[wd] $25, %lo(.got.plt entry)($15) */
+ 0x03200008, /* jr $25 */
+ 0x25f80000 /* addiu $24, $15, %lo(.got.plt entry) */
+};
+
/* The format of the first PLT entry in a VxWorks executable. */
static const bfd_vma mips_vxworks_exec_plt0_entry[] = {
0x3c190000, /* lui t9, %hi(_GLOBAL_OFFSET_TABLE_) */
@@ -8630,10 +8638,12 @@ _bfd_mips_elf_size_dynamic_sections (bfd
s->size += mips_elf_hash_table (info)->compact_rel_size;
else if (s == htab->splt)
{
- /* If the last PLT entry has a branch delay slot, allocate
+ /* For MIPS1, if the last PLT entry has a branch delay slot, allocate
room for an extra nop to fill the delay slot. */
- if (!htab->is_vxworks && s->size > 0)
- s->size += 4;
+ if (((elf_elfheader (output_bfd)->e_flags & EF_MIPS_ARCH)
+ == E_MIPS_ARCH_1)
+ && !htab->is_vxworks && s->size > 0)
+ s->size += 4;
}
else if (! CONST_STRNEQ (name, ".init")
&& s != htab->sgot
@@ -9352,11 +9362,26 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd
load = MIPS_ELF_LOAD_WORD (output_bfd);
/* Fill in the PLT entry itself. */
- plt_entry = mips_exec_plt_entry;
+ if ((elf_elfheader (output_bfd)->e_flags & EF_MIPS_ARCH)
+ == E_MIPS_ARCH_1)
+ plt_entry = mips_exec_plt_entry;
+ else
+ /* We can use the fast PLT entry for non-MIPS1 CPUs. */
+ plt_entry = mips_exec_fast_plt_entry;
bfd_put_32 (output_bfd, plt_entry[0] | got_address_high, loc);
bfd_put_32 (output_bfd, plt_entry[1] | got_address_low | load, loc + 4);
- bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 8);
- bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+
+ if ((elf_elfheader (output_bfd)->e_flags & EF_MIPS_ARCH)
+ == E_MIPS_ARCH_1)
+ {
+ bfd_put_32 (output_bfd, plt_entry[2] | got_address_low, loc + 8);
+ bfd_put_32 (output_bfd, plt_entry[3], loc + 12);
+ }
+ else
+ {
+ bfd_put_32 (output_bfd, plt_entry[2], loc + 8);
+ bfd_put_32 (output_bfd, plt_entry[3] | got_address_low, loc + 12);
+ }
/* Emit an R_MIPS_JUMP_SLOT relocation against the .got.plt entry. */
mips_elf_output_dynamic_relocation (output_bfd, htab->srelplt,