2011-12-19 Chung-Lin Tang <cltang@codesourcery.com>

Catherine Moore  <clm@codesourcery.com>
	    Sandra Loosemore  <sandra@codesourcery.com>
	    Richard Sandiford  <rdsandiford@googlemail.com>

	* elfxx-mips.c (mips_elf_local_pic_function_p): Return true when
	H is a MIPS16 function with a kept 32-bit stub. Update comments.
	(mips_elf_get_la25_target): New function.
	(mips_elf_add_la25_intro): Change to use mips_elf_get_la25_target().
	(mips_elf_add_la25_stub): Move compute of use_trampoline_p down,
	change to use mips_elf_get_la25_target().
	(mips_elf_relocation_needs_la25_stub): Add target_is_16_bit_code_p
	parameter, add switch case for R_MIPS16_26.
	(mips_elf_calculate_relocation): Redirect relocation to point to the
	LA25 stub if it exists, instead of the MIPS16 stub. Update arguments
	of call to mips_elf_relocation_needs_la25_stub(), don't use la25 stub
	for mips16->mips16 calls.
	(_bfd_mips_elf_check_relocs): Update arguments of call to
	mips_elf_relocation_needs_la25_stub().
	(mips_elf_create_la25_stub): Change to use mips_elf_get_la25_target().
This commit is contained in:
Chung-Lin Tang 2011-12-19 07:31:07 +00:00
parent 828cfa8d0b
commit 8f0c309a21
2 changed files with 83 additions and 21 deletions

View File

@ -1,3 +1,24 @@
2011-12-19 Chung-Lin Tang <cltang@codesourcery.com>
Catherine Moore <clm@codesourcery.com>
Sandra Loosemore <sandra@codesourcery.com>
Richard Sandiford <rdsandiford@googlemail.com>
* elfxx-mips.c (mips_elf_local_pic_function_p): Return true when
H is a MIPS16 function with a kept 32-bit stub. Update comments.
(mips_elf_get_la25_target): New function.
(mips_elf_add_la25_intro): Change to use mips_elf_get_la25_target().
(mips_elf_add_la25_stub): Move compute of use_trampoline_p down,
change to use mips_elf_get_la25_target().
(mips_elf_relocation_needs_la25_stub): Add target_is_16_bit_code_p
parameter, add switch case for R_MIPS16_26.
(mips_elf_calculate_relocation): Redirect relocation to point to the
LA25 stub if it exists, instead of the MIPS16 stub. Update arguments
of call to mips_elf_relocation_needs_la25_stub(), don't use la25 stub
for mips16->mips16 calls.
(_bfd_mips_elf_check_relocs): Update arguments of call to
mips_elf_relocation_needs_la25_stub().
(mips_elf_create_la25_stub): Change to use mips_elf_get_la25_target().
2011-12-16 Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
* mach-o-i386.c (TARGET_PRIORITY): Define as 0 (top priority)

View File

@ -1575,9 +1575,10 @@ _bfd_mips_elf_init_stubs (struct bfd_link_info *info,
}
/* Return true if H is a locally-defined PIC function, in the sense
that it might need $25 to be valid on entry. Note that MIPS16
functions never need $25 to be valid on entry; they set up $gp
using PC-relative instructions instead. */
that it or its fn_stub might need $25 to be valid on entry.
Note that MIPS16 functions set up $gp using PC-relative instructions,
so they themselves never need $25 to be valid. Only non-MIPS16
entry points are of interest here. */
static bfd_boolean
mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
@ -1586,11 +1587,32 @@ mips_elf_local_pic_function_p (struct mips_elf_link_hash_entry *h)
|| h->root.root.type == bfd_link_hash_defweak)
&& h->root.def_regular
&& !bfd_is_abs_section (h->root.root.u.def.section)
&& !ELF_ST_IS_MIPS16 (h->root.other)
&& (!ELF_ST_IS_MIPS16 (h->root.other)
|| (h->fn_stub && h->need_fn_stub))
&& (PIC_OBJECT_P (h->root.root.u.def.section->owner)
|| ELF_ST_IS_MIPS_PIC (h->root.other)));
}
/* Set *SEC to the input section that contains the target of STUB.
Return the offset of the target from the start of that section. */
static bfd_vma
mips_elf_get_la25_target (struct mips_elf_la25_stub *stub,
asection **sec)
{
if (ELF_ST_IS_MIPS16 (stub->h->root.other))
{
BFD_ASSERT (stub->h->need_fn_stub);
*sec = stub->h->fn_stub;
return 0;
}
else
{
*sec = stub->h->root.root.u.def.section;
return stub->h->root.root.u.def.value;
}
}
/* STUB describes an la25 stub that we have decided to implement
by inserting an LUI/ADDIU pair before the target function.
Create the section and redirect the function symbol to it. */
@ -1615,7 +1637,7 @@ mips_elf_add_la25_intro (struct mips_elf_la25_stub *stub,
sprintf (name, ".text.stub.%d", (int) htab_elements (htab->la25_stubs));
/* Create the section. */
input_section = stub->h->root.root.u.def.section;
mips_elf_get_la25_target (stub, &input_section);
s = htab->add_stub_section (name, input_section,
input_section->output_section);
if (s == NULL)
@ -1689,12 +1711,6 @@ mips_elf_add_la25_stub (struct bfd_link_info *info,
bfd_vma value;
void **slot;
/* Prefer to use LUI/ADDIU stubs if the function is at the beginning
of the section and if we would need no more than 2 nops. */
s = h->root.root.u.def.section;
value = h->root.root.u.def.value;
use_trampoline_p = (value != 0 || s->alignment_power > 4);
/* Describe the stub we want. */
search.stub_section = NULL;
search.offset = 0;
@ -1724,6 +1740,11 @@ mips_elf_add_la25_stub (struct bfd_link_info *info,
*stub = search;
*slot = stub;
/* Prefer to use LUI/ADDIU stubs if the function is at the beginning
of the section and if we would need no more than 2 nops. */
value = mips_elf_get_la25_target (stub, &s);
use_trampoline_p = (value != 0 || s->alignment_power > 4);
h->la25_stub = stub;
return (use_trampoline_p
? mips_elf_add_la25_trampoline (stub, info)
@ -4911,7 +4932,8 @@ is_gott_symbol (struct bfd_link_info *info, struct elf_link_hash_entry *h)
stub. */
static bfd_boolean
mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type,
bfd_boolean target_is_16_bit_code_p)
{
/* We specifically ignore branches and jumps from EF_PIC objects,
where the onus is on the compiler or programmer to perform any
@ -4925,7 +4947,6 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
{
case R_MIPS_26:
case R_MIPS_PC16:
case R_MIPS16_26:
case R_MICROMIPS_26_S1:
case R_MICROMIPS_PC7_S1:
case R_MICROMIPS_PC10_S1:
@ -4933,6 +4954,9 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
case R_MICROMIPS_PC23_S2:
return TRUE;
case R_MIPS16_26:
return !target_is_16_bit_code_p;
default:
return FALSE;
}
@ -5193,14 +5217,28 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
have already noticed that we were going to need the
stub. */
if (local_p)
sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
{
sec = elf_tdata (input_bfd)->local_stubs[r_symndx];
value = 0;
}
else
{
BFD_ASSERT (h->need_fn_stub);
sec = h->fn_stub;
if (h->la25_stub)
{
/* If a LA25 header for the stub itself exists, point to the
prepended LUI/ADDIU sequence. */
sec = h->la25_stub->stub_section;
value = h->la25_stub->offset;
}
else
{
sec = h->fn_stub;
value = 0;
}
}
symbol = sec->output_section->vma + sec->output_offset;
symbol = sec->output_section->vma + sec->output_offset + value;
/* The target is 16-bit, but the stub isn't. */
target_is_16_bit_code_p = FALSE;
}
@ -5250,7 +5288,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
/* If this is a direct call to a PIC function, redirect to the
non-PIC stub. */
else if (h != NULL && h->la25_stub
&& mips_elf_relocation_needs_la25_stub (input_bfd, r_type))
&& mips_elf_relocation_needs_la25_stub (input_bfd, r_type,
target_is_16_bit_code_p))
symbol = (h->la25_stub->stub_section->output_section->vma
+ h->la25_stub->stub_section->output_offset
+ h->la25_stub->offset);
@ -7926,7 +7965,9 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
return FALSE;
}
if (h != NULL && mips_elf_relocation_needs_la25_stub (abfd, r_type))
if (h != NULL
&& mips_elf_relocation_needs_la25_stub (abfd, r_type,
ELF_ST_IS_MIPS16 (h->other)))
((struct mips_elf_link_hash_entry *) h)->has_nonpic_branches = TRUE;
switch (r_type)
@ -9623,9 +9664,9 @@ mips_elf_create_la25_stub (void **slot, void *data)
offset = stub->offset;
/* Work out the target address. */
target = (stub->h->root.root.u.def.section->output_section->vma
+ stub->h->root.root.u.def.section->output_offset
+ stub->h->root.root.u.def.value);
target = mips_elf_get_la25_target (stub, &s);
target += s->output_section->vma + s->output_offset;
target_high = ((target + 0x8000) >> 16) & 0xffff;
target_low = (target & 0xffff);