@@ -662,6 +662,12 @@ static struct mips_got_info *mips_elf_got_for_ibfd
/* This will be used when we sort the dynamic relocation records. */
static bfd * reldyn_sorting_bfd ;
/* True if ABFD is for CPUs with load interlocking that include
non-MIPS1 CPUs and R3900. */
# define LOAD_INTERLOCKS_P(abfd) \
( ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) != E_MIPS_ARCH_1) \
|| ((elf_elfheader (abfd)->e_flags & EF_MIPS_MACH) == E_MIPS_MACH_3900))
/* True if ABFD is a PIC object. */
# define PIC_OBJECT_P(abfd) \
((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) != 0)
@@ -878,7 +884,8 @@ static bfd *reldyn_sorting_bfd;
# define CALL_FP_STUB_P(name) CONST_STRNEQ (name, CALL_FP_STUB)
/* The format of the first PLT entry in an O32 executable. */
static const bfd_vma mips_o32_exec_plt0_entry [ ] = {
static const bfd_vma mips_o32_exec_plt0_entry [ ] =
{
0x3c1c0000 , /* lui $28, %hi(&GOTPLT[0]) */
0x8f990000 , /* lw $25, %lo(&GOTPLT[0])($28) */
0x279c0000 , /* addiu $28, $28, %lo(&GOTPLT[0]) */
@@ -891,7 +898,8 @@ static const bfd_vma mips_o32_exec_plt0_entry[] = {
/* The format of the first PLT entry in an N32 executable. Different
because gp ($28) is not available; we use t2 ($14) instead. */
static const bfd_vma mips_n32_exec_plt0_entry [ ] = {
static const bfd_vma mips_n32_exec_plt0_entry [ ] =
{
0x3c0e0000 , /* lui $14, %hi(&GOTPLT[0]) */
0x8dd90000 , /* lw $25, %lo(&GOTPLT[0])($14) */
0x25ce0000 , /* addiu $14, $14, %lo(&GOTPLT[0]) */
@@ -904,7 +912,8 @@ static const bfd_vma mips_n32_exec_plt0_entry[] = {
/* The format of the first PLT entry in an N64 executable. Different
from N32 because of the increased size of GOT entries. */
static const bfd_vma mips_n64_exec_plt0_entry [ ] = {
static const bfd_vma mips_n64_exec_plt0_entry [ ] =
{
0x3c0e0000 , /* lui $14, %hi(&GOTPLT[0]) */
0xddd90000 , /* ld $25, %lo(&GOTPLT[0])($14) */
0x25ce0000 , /* addiu $14, $14, %lo(&GOTPLT[0]) */
@@ -916,7 +925,8 @@ static const bfd_vma mips_n64_exec_plt0_entry[] = {
} ;
/* The format of subsequent PLT entries. */
static const bfd_vma mips_exec_plt_entry [ ] = {
static const bfd_vma mips_exec_plt_entry [ ] =
{
0x3c0f0000 , /* lui $15, %hi(.got.plt entry) */
0x01f90000 , /* l[wd] $25, %lo(.got.plt entry)($15) */
0x25f80000 , /* addiu $24, $15, %lo(.got.plt entry) */
@@ -924,7 +934,8 @@ static const bfd_vma mips_exec_plt_entry[] = {
} ;
/* The format of the first PLT entry in a VxWorks executable. */
static const bfd_vma mips_vxworks_exec_plt0_entry [ ] = {
static const bfd_vma mips_vxworks_exec_plt0_entry [ ] =
{
0x3c190000 , /* lui t9, %hi(_GLOBAL_OFFSET_TABLE_) */
0x27390000 , /* addiu t9, t9, %lo(_GLOBAL_OFFSET_TABLE_) */
0x8f390008 , /* lw t9, 8(t9) */
@@ -934,7 +945,8 @@ static const bfd_vma mips_vxworks_exec_plt0_entry[] = {
} ;
/* The format of subsequent PLT entries. */
static const bfd_vma mips_vxworks_exec_plt_entry [ ] = {
static const bfd_vma mips_vxworks_exec_plt_entry [ ] =
{
0x10000000 , /* b .PLT_resolver */
0x24180000 , /* li t8, <pltindex> */
0x3c190000 , /* lui t9, %hi(<.got.plt slot>) */
@@ -946,7 +958,8 @@ static const bfd_vma mips_vxworks_exec_plt_entry[] = {
} ;
/* The format of the first PLT entry in a VxWorks shared object. */
static const bfd_vma mips_vxworks_shared_plt0_entry [ ] = {
static const bfd_vma mips_vxworks_shared_plt0_entry [ ] =
{
0x8f990008 , /* lw t9, 8(gp) */
0x00000000 , /* nop */
0x03200008 , /* jr t9 */
@@ -956,7 +969,8 @@ static const bfd_vma mips_vxworks_shared_plt0_entry[] = {
} ;
/* The format of subsequent PLT entries. */
static const bfd_vma mips_vxworks_shared_plt_entry [ ] = {
static const bfd_vma mips_vxworks_shared_plt_entry [ ] =
{
0x10000000 , /* b .PLT_resolver */
0x24180000 /* li t8, <pltindex> */
} ;
@@ -8631,8 +8645,10 @@ _bfd_mips_elf_size_dynamic_sections (bfd *output_bfd,
else if ( s = = htab - > splt )
{
/* 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 )
room for an extra nop to fill the delay slot. This is
for CPUs without load interlocking. */
if ( ! LOAD_INTERLOCKS_P ( output_bfd )
& & ! htab - > is_vxworks & & s - > size > 0 )
s - > size + = 4 ;
}
else if ( ! CONST_STRNEQ ( name , " .init " )
@@ -9355,8 +9371,17 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
plt_entry = mips_exec_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 ( ! LOAD_INTERLOCKS_P ( output_bfd ) )
{
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 [ 3 ] , loc + 8 ) ;
bfd_put_32 ( output_bfd , plt_entry [ 2 ] | 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 ,