2010-01-13 Chao-ying Fu <fu@mips.com>
* elfxx-mips.c (JR_TO_B_P): New define to transform JR to B. It is true for all CPUs. (jal_reloc_p): New function. (mips_elf_calculate_relocation): Rename require_jalxp to cross_mode_jump_p. Update comment for CROSS_MODE_JUMP_P. Set up cross_mode_jump_p based on the mode change. (mips_elf_perform_relocation): Rename require_jalx to cross_mode_jump_p. Update comment for CROSS_MODE_JUMP_P. Test cross_mode_jump_p and jal_reloc_p to turn jal to jalx. Use !cross_mode_jump_p to guard conversion. Convert "jr t9" to "b", if possible. (_bfd_mips_elf_relocate_section): Rename require_jalx to cross_mode_jump_p. Pass &cross_mode_jump_p to call mips_elf_calculate_relocation. Pass cross_mode_jump_p to call mips_elf_perform_relocation.
This commit is contained in:
parent
4427219284
commit
38a7df635c
@ -1,3 +1,22 @@
|
||||
2010-01-13 Chao-ying Fu <fu@mips.com>
|
||||
|
||||
* elfxx-mips.c (JR_TO_B_P): New define to transform JR to B.
|
||||
It is true for all CPUs.
|
||||
(jal_reloc_p): New function.
|
||||
(mips_elf_calculate_relocation): Rename require_jalxp to
|
||||
cross_mode_jump_p.
|
||||
Update comment for CROSS_MODE_JUMP_P.
|
||||
Set up cross_mode_jump_p based on the mode change.
|
||||
(mips_elf_perform_relocation): Rename require_jalx to cross_mode_jump_p.
|
||||
Update comment for CROSS_MODE_JUMP_P.
|
||||
Test cross_mode_jump_p and jal_reloc_p to turn jal to jalx.
|
||||
Use !cross_mode_jump_p to guard conversion.
|
||||
Convert "jr t9" to "b", if possible.
|
||||
(_bfd_mips_elf_relocate_section): Rename require_jalx to
|
||||
cross_mode_jump_p.
|
||||
Pass &cross_mode_jump_p to call mips_elf_calculate_relocation.
|
||||
Pass cross_mode_jump_p to call mips_elf_perform_relocation.
|
||||
|
||||
2010-01-13 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* cpu-m32c.c (m32c_scan): New function. Ensures that a scan for
|
||||
|
@ -680,6 +680,11 @@ static bfd *reldyn_sorting_bfd;
|
||||
all CPUs. */
|
||||
#define JALR_TO_BAL_P(abfd) 1
|
||||
|
||||
/* True if ABFD is for CPUs that are faster if JR is converted to B.
|
||||
This should be safe for all architectures. We enable this predicate for
|
||||
all CPUs. */
|
||||
#define JR_TO_B_P(abfd) 1
|
||||
|
||||
/* True if ABFD is a PIC object. */
|
||||
#define PIC_OBJECT_P(abfd) \
|
||||
((elf_elfheader (abfd)->e_flags & EF_MIPS_PIC) != 0)
|
||||
@ -1871,6 +1876,12 @@ mips16_call_reloc_p (int r_type)
|
||||
return r_type == R_MIPS16_26 || r_type == R_MIPS16_CALL16;
|
||||
}
|
||||
|
||||
static inline bfd_boolean
|
||||
jal_reloc_p (int r_type)
|
||||
{
|
||||
return r_type == R_MIPS_26 || r_type == R_MIPS16_26;
|
||||
}
|
||||
|
||||
void
|
||||
_bfd_mips16_elf_reloc_unshuffle (bfd *abfd, int r_type,
|
||||
bfd_boolean jal_shuffle, bfd_byte *data)
|
||||
@ -4771,8 +4782,8 @@ mips_elf_relocation_needs_la25_stub (bfd *input_bfd, int r_type)
|
||||
RELOCATION; RELOCATION->R_ADDEND is ignored.
|
||||
|
||||
The result of the relocation calculation is stored in VALUEP.
|
||||
REQUIRE_JALXP indicates whether or not the opcode used with this
|
||||
relocation must be JALX.
|
||||
On exit, set *CROSS_MODE_JUMP_P to true if the relocation field
|
||||
is a MIPS16 jump to non-MIPS16 code, or vice versa.
|
||||
|
||||
This function returns bfd_reloc_continue if the caller need take no
|
||||
further action regarding this relocation, bfd_reloc_notsupported if
|
||||
@ -4787,7 +4798,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||
bfd_vma addend, reloc_howto_type *howto,
|
||||
Elf_Internal_Sym *local_syms,
|
||||
asection **local_sections, bfd_vma *valuep,
|
||||
const char **namep, bfd_boolean *require_jalxp,
|
||||
const char **namep,
|
||||
bfd_boolean *cross_mode_jump_p,
|
||||
bfd_boolean save_addend)
|
||||
{
|
||||
/* The eventual value we will return. */
|
||||
@ -5076,10 +5088,11 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||
+ h->la25_stub->offset);
|
||||
|
||||
/* Calls from 16-bit code to 32-bit code and vice versa require the
|
||||
special jalx instruction. */
|
||||
*require_jalxp = (!info->relocatable
|
||||
&& (((r_type == R_MIPS16_26) && !target_is_16_bit_code_p)
|
||||
|| ((r_type == R_MIPS_26) && target_is_16_bit_code_p)));
|
||||
mode change. */
|
||||
*cross_mode_jump_p = !info->relocatable
|
||||
&& ((r_type == R_MIPS16_26 && !target_is_16_bit_code_p)
|
||||
|| ((r_type == R_MIPS_26 || r_type == R_MIPS_JALR)
|
||||
&& target_is_16_bit_code_p));
|
||||
|
||||
local_p = mips_elf_local_relocation_p (input_bfd, relocation,
|
||||
local_sections, TRUE);
|
||||
@ -5533,9 +5546,9 @@ mips_elf_obtain_contents (reloc_howto_type *howto,
|
||||
/* It has been determined that the result of the RELOCATION is the
|
||||
VALUE. Use HOWTO to place VALUE into the output file at the
|
||||
appropriate position. The SECTION is the section to which the
|
||||
relocation applies. If REQUIRE_JALX is TRUE, then the opcode used
|
||||
for the relocation must be either JAL or JALX, and it is
|
||||
unconditionally converted to JALX.
|
||||
relocation applies.
|
||||
CROSS_MODE_JUMP_P is true if the relocation field
|
||||
is a MIPS16 jump to non-MIPS16 code, or vice versa.
|
||||
|
||||
Returns FALSE if anything goes wrong. */
|
||||
|
||||
@ -5545,7 +5558,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
|
||||
const Elf_Internal_Rela *relocation,
|
||||
bfd_vma value, bfd *input_bfd,
|
||||
asection *input_section, bfd_byte *contents,
|
||||
bfd_boolean require_jalx)
|
||||
bfd_boolean cross_mode_jump_p)
|
||||
{
|
||||
bfd_vma x;
|
||||
bfd_byte *location;
|
||||
@ -5566,7 +5579,7 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
|
||||
x |= (value & howto->dst_mask);
|
||||
|
||||
/* If required, turn JAL into JALX. */
|
||||
if (require_jalx)
|
||||
if (cross_mode_jump_p && jal_reloc_p (r_type))
|
||||
{
|
||||
bfd_boolean ok;
|
||||
bfd_vma opcode = x >> 26;
|
||||
@ -5600,15 +5613,19 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
|
||||
x = (x & ~(0x3f << 26)) | (jalx_opcode << 26);
|
||||
}
|
||||
|
||||
/* Try converting JAL and JALR to BAL, if the target is in range. */
|
||||
/* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
|
||||
range. */
|
||||
if (!info->relocatable
|
||||
&& !require_jalx
|
||||
&& !cross_mode_jump_p
|
||||
&& ((JAL_TO_BAL_P (input_bfd)
|
||||
&& r_type == R_MIPS_26
|
||||
&& (x >> 26) == 0x3) /* jal addr */
|
||||
|| (JALR_TO_BAL_P (input_bfd)
|
||||
&& r_type == R_MIPS_JALR
|
||||
&& x == 0x0320f809))) /* jalr t9 */
|
||||
&& x == 0x0320f809) /* jalr t9 */
|
||||
|| (JR_TO_B_P (input_bfd)
|
||||
&& r_type == R_MIPS_JALR
|
||||
&& x == 0x03200008))) /* jr t9 */
|
||||
{
|
||||
bfd_vma addr;
|
||||
bfd_vma dest;
|
||||
@ -5624,7 +5641,12 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
|
||||
dest = value;
|
||||
off = dest - addr;
|
||||
if (off <= 0x1ffff && off >= -0x20000)
|
||||
x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff); /* bal addr */
|
||||
{
|
||||
if (x == 0x03200008) /* jr t9 */
|
||||
x = 0x10000000 | (((bfd_vma) off >> 2) & 0xffff); /* b addr */
|
||||
else
|
||||
x = 0x04110000 | (((bfd_vma) off >> 2) & 0xffff); /* bal addr */
|
||||
}
|
||||
}
|
||||
|
||||
/* Put the value into the output. */
|
||||
@ -8886,7 +8908,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||
const char *name;
|
||||
bfd_vma value = 0;
|
||||
reloc_howto_type *howto;
|
||||
bfd_boolean require_jalx;
|
||||
bfd_boolean cross_mode_jump_p;
|
||||
/* TRUE if the relocation is a RELA relocation, rather than a
|
||||
REL relocation. */
|
||||
bfd_boolean rela_relocation_p = TRUE;
|
||||
@ -9086,7 +9108,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||
input_section, info, rel,
|
||||
addend, howto, local_syms,
|
||||
local_sections, &value,
|
||||
&name, &require_jalx,
|
||||
&name, &cross_mode_jump_p,
|
||||
use_saved_addend_p))
|
||||
{
|
||||
case bfd_reloc_continue:
|
||||
@ -9198,7 +9220,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||||
/* Actually perform the relocation. */
|
||||
if (! mips_elf_perform_relocation (info, howto, rel, value,
|
||||
input_bfd, input_section,
|
||||
contents, require_jalx))
|
||||
contents, cross_mode_jump_p))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user