bfd/
* elfxx-mips.c (mips_elf_calculate_relocation): Allow local stubs to be used for calls from MIPS16 code. gas/ * config/tc-mips.h (TC_SYMFIELD_TYPE): New. * config/tc-mips.c (append_insn): Record which symbols have R_MIPS16_26 relocations against them. (mips_fix_adjustable): Don't reduce relocations against such symbols. ld/testsuite/ * ld-mips-elf/mips16-local-stubs-1.s, * ld-mips-elf/mips16-local-stubs-1.d: New tests. * ld-mips-elf/mips-elf.exp: Run them.
This commit is contained in:
parent
b6fd0dfb46
commit
b314ec0eae
9 changed files with 235 additions and 6 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2007-06-25 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
|
* elfxx-mips.c (mips_elf_calculate_relocation): Allow local stubs
|
||||||
|
to be used for calls from MIPS16 code.
|
||||||
|
|
||||||
2007-06-23 Andreas Schwab <schwab@suse.de>
|
2007-06-23 Andreas Schwab <schwab@suse.de>
|
||||||
|
|
||||||
* configure.in (--with-separate-debug-dir): New option.
|
* configure.in (--with-separate-debug-dir): New option.
|
||||||
|
|
|
@ -4092,8 +4092,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
|
||||||
/* If this is a 16-bit call to a 32- or 64-bit function with a stub, we
|
/* If this is a 16-bit call to a 32- or 64-bit function with a stub, we
|
||||||
need to redirect the call to the stub. */
|
need to redirect the call to the stub. */
|
||||||
else if (r_type == R_MIPS16_26 && !info->relocatable
|
else if (r_type == R_MIPS16_26 && !info->relocatable
|
||||||
&& h != NULL
|
&& ((h != NULL && (h->call_stub != NULL || h->call_fp_stub != NULL))
|
||||||
&& ((h->call_stub != NULL || h->call_fp_stub != NULL)
|
|
||||||
|| (local_p
|
|| (local_p
|
||||||
&& elf_tdata (input_bfd)->local_call_stubs != NULL
|
&& elf_tdata (input_bfd)->local_call_stubs != NULL
|
||||||
&& elf_tdata (input_bfd)->local_call_stubs[r_symndx] != NULL))
|
&& elf_tdata (input_bfd)->local_call_stubs[r_symndx] != NULL))
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2007-06-25 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
|
* config/tc-mips.h (TC_SYMFIELD_TYPE): New.
|
||||||
|
* config/tc-mips.c (append_insn): Record which symbols have
|
||||||
|
R_MIPS16_26 relocations against them.
|
||||||
|
(mips_fix_adjustable): Don't reduce relocations against such symbols.
|
||||||
|
|
||||||
2007-06-22 Sterling Augustine <sterling@tensilica.com>
|
2007-06-22 Sterling Augustine <sterling@tensilica.com>
|
||||||
|
|
||||||
* config/tc-xtensa.c (xg_assembly_relax): Comment termination rules.
|
* config/tc-xtensa.c (xg_assembly_relax): Comment termination rules.
|
||||||
|
|
|
@ -2792,6 +2792,11 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
|
||||||
reloc_type[0] == BFD_RELOC_16_PCREL_S2,
|
reloc_type[0] == BFD_RELOC_16_PCREL_S2,
|
||||||
reloc_type[0]);
|
reloc_type[0]);
|
||||||
|
|
||||||
|
/* Tag symbols that have a R_MIPS16_26 relocation against them. */
|
||||||
|
if (reloc_type[0] == BFD_RELOC_MIPS16_JMP
|
||||||
|
&& ip->fixp[0]->fx_addsy)
|
||||||
|
*symbol_get_tc (ip->fixp[0]->fx_addsy) = 1;
|
||||||
|
|
||||||
/* These relocations can have an addend that won't fit in
|
/* These relocations can have an addend that won't fit in
|
||||||
4 octets for 64bit assembly. */
|
4 octets for 64bit assembly. */
|
||||||
if (HAVE_64BIT_GPRS
|
if (HAVE_64BIT_GPRS
|
||||||
|
@ -13612,11 +13617,50 @@ mips_fix_adjustable (fixS *fixp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef OBJ_ELF
|
#ifdef OBJ_ELF
|
||||||
/* Don't adjust relocations against mips16 symbols, so that the linker
|
/* R_MIPS16_26 relocations against non-MIPS16 functions might resolve
|
||||||
can find them if it needs to set up a stub. */
|
to a floating-point stub. The same is true for non-R_MIPS16_26
|
||||||
|
relocations against MIPS16 functions; in this case, the stub becomes
|
||||||
|
the function's canonical address.
|
||||||
|
|
||||||
|
Floating-point stubs are stored in unique .mips16.call.* or
|
||||||
|
.mips16.fn.* sections. If a stub T for function F is in section S,
|
||||||
|
the first relocation in section S must be against F; this is how the
|
||||||
|
linker determines the target function. All relocations that might
|
||||||
|
resolve to T must also be against F. We therefore have the following
|
||||||
|
restrictions, which are given in an intentionally-redundant way:
|
||||||
|
|
||||||
|
1. We cannot reduce R_MIPS16_26 relocations against non-MIPS16
|
||||||
|
symbols.
|
||||||
|
|
||||||
|
2. We cannot reduce a stub's relocations against non-MIPS16 symbols
|
||||||
|
if that stub might be used.
|
||||||
|
|
||||||
|
3. We cannot reduce non-R_MIPS16_26 relocations against MIPS16
|
||||||
|
symbols.
|
||||||
|
|
||||||
|
4. We cannot reduce a stub's relocations against MIPS16 symbols if
|
||||||
|
that stub might be used.
|
||||||
|
|
||||||
|
There is a further restriction:
|
||||||
|
|
||||||
|
5. We cannot reduce R_MIPS16_26 relocations against MIPS16 symbols
|
||||||
|
on targets with in-place addends; the relocation field cannot
|
||||||
|
encode the low bit.
|
||||||
|
|
||||||
|
For simplicity, we deal with (3)-(5) by not reducing _any_ relocation
|
||||||
|
against a MIPS16 symbol.
|
||||||
|
|
||||||
|
We deal with (1)-(2) by saying that, if there's a R_MIPS16_26
|
||||||
|
relocation against some symbol R, no relocation against R may be
|
||||||
|
reduced. (Note that this deals with (2) as well as (1) because
|
||||||
|
relocations against global symbols will never be reduced on ELF
|
||||||
|
targets.) This approach is a little simpler than trying to detect
|
||||||
|
stub sections, and gives the "all or nothing" per-symbol consistency
|
||||||
|
that we have for MIPS16 symbols. */
|
||||||
if (IS_ELF
|
if (IS_ELF
|
||||||
&& S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16
|
&& fixp->fx_subsy == NULL
|
||||||
&& fixp->fx_subsy == NULL)
|
&& (S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16
|
||||||
|
|| *symbol_get_tc (fixp->fx_addsy)))
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,9 @@ extern void mips_handle_align (struct frag *);
|
||||||
struct insn_label_list;
|
struct insn_label_list;
|
||||||
#define TC_SEGMENT_INFO_TYPE struct insn_label_list *
|
#define TC_SEGMENT_INFO_TYPE struct insn_label_list *
|
||||||
|
|
||||||
|
/* This field is nonzero if the symbol is the target of a MIPS16 jump. */
|
||||||
|
#define TC_SYMFIELD_TYPE int
|
||||||
|
|
||||||
/* Tell assembler that we have an itbl_mips.h header file to include. */
|
/* Tell assembler that we have an itbl_mips.h header file to include. */
|
||||||
#define HAVE_ITBL_CPU
|
#define HAVE_ITBL_CPU
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2007-06-25 Richard Sandiford <richard@codesourcery.com>
|
||||||
|
|
||||||
|
* ld-mips-elf/mips16-local-stubs-1.s,
|
||||||
|
* ld-mips-elf/mips16-local-stubs-1.d: New tests.
|
||||||
|
* ld-mips-elf/mips-elf.exp: Run them.
|
||||||
|
|
||||||
2007-06-19 H.J. Lu <hongjiu.lu@intel.com>
|
2007-06-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
PR ld/4590
|
PR ld/4590
|
||||||
|
|
|
@ -269,3 +269,5 @@ set mips16_intermix_test {
|
||||||
}
|
}
|
||||||
|
|
||||||
run_ld_link_tests $mips16_intermix_test
|
run_ld_link_tests $mips16_intermix_test
|
||||||
|
|
||||||
|
run_dump_test "mips16-local-stubs-1"
|
||||||
|
|
114
ld/testsuite/ld-mips-elf/mips16-local-stubs-1.d
Normal file
114
ld/testsuite/ld-mips-elf/mips16-local-stubs-1.d
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#name: MIPS16 interlinking for local functions 1
|
||||||
|
#source: mips16-local-stubs-1.s
|
||||||
|
#as: -mips4
|
||||||
|
#ld: -Ttext 0x20000000 -e caller1
|
||||||
|
#objdump: -dr
|
||||||
|
#...
|
||||||
|
Disassembly of section \.text:
|
||||||
|
|
||||||
|
20000000 <f1>:
|
||||||
|
20000000: 03e00008 jr ra
|
||||||
|
20000004: 00000000 nop
|
||||||
|
|
||||||
|
20000008 <g1>:
|
||||||
|
20000008: 03e00008 jr ra
|
||||||
|
2000000c: 00000000 nop
|
||||||
|
|
||||||
|
20000010 <h1>:
|
||||||
|
20000010: e820 jr ra
|
||||||
|
20000012: 6500 nop
|
||||||
|
|
||||||
|
20000014 <f2>:
|
||||||
|
20000014: 03e00008 jr ra
|
||||||
|
20000018: 00000000 nop
|
||||||
|
|
||||||
|
2000001c <g2>:
|
||||||
|
2000001c: 03e00008 jr ra
|
||||||
|
20000020: 00000000 nop
|
||||||
|
|
||||||
|
20000024 <h2>:
|
||||||
|
20000024: e820 jr ra
|
||||||
|
20000026: 6500 nop
|
||||||
|
|
||||||
|
20000028 <f3>:
|
||||||
|
20000028: 03e00008 jr ra
|
||||||
|
2000002c: 00000000 nop
|
||||||
|
|
||||||
|
20000030 <g3>:
|
||||||
|
20000030: 03e00008 jr ra
|
||||||
|
20000034: 00000000 nop
|
||||||
|
|
||||||
|
20000038 <h3>:
|
||||||
|
20000038: e820 jr ra
|
||||||
|
2000003a: 6500 nop
|
||||||
|
|
||||||
|
2000003c <caller1>:
|
||||||
|
2000003c: 0c000000 jal 20000000 <f1>
|
||||||
|
20000040: 00000000 nop
|
||||||
|
20000044: 0c000005 jal 20000014 <f2>
|
||||||
|
20000048: 00000000 nop
|
||||||
|
2000004c: 0c000002 jal 20000008 <g1>
|
||||||
|
20000050: 00000000 nop
|
||||||
|
20000054: 0c000007 jal 2000001c <g2>
|
||||||
|
20000058: 00000000 nop
|
||||||
|
2000005c: 0c000024 jal 20000090 <stub_for_h1>
|
||||||
|
20000060: 00000000 nop
|
||||||
|
20000064: 0c000028 jal 200000a0 <stub_for_h2>
|
||||||
|
20000068: 00000000 nop
|
||||||
|
|
||||||
|
2000006c <caller2>:
|
||||||
|
2000006c: 1c00 0030 jalx 200000c0 <stub_for_f1>
|
||||||
|
20000070: 6500 nop
|
||||||
|
20000072: 1c00 0038 jalx 200000e0 <stub_for_f2>
|
||||||
|
20000076: 6500 nop
|
||||||
|
20000078: 1c00 0034 jalx 200000d0 <stub_for_g1>
|
||||||
|
2000007c: 6500 nop
|
||||||
|
2000007e: 1c00 003c jalx 200000f0 <stub_for_g2>
|
||||||
|
20000082: 6500 nop
|
||||||
|
20000084: 1800 0004 jal 20000010 <h1>
|
||||||
|
20000088: 6500 nop
|
||||||
|
2000008a: 1800 0009 jal 20000024 <h2>
|
||||||
|
2000008e: 6500 nop
|
||||||
|
|
||||||
|
20000090 <stub_for_h1>:
|
||||||
|
20000090: 3c012000 lui at,0x2000
|
||||||
|
20000094: 24210011 addiu at,at,17
|
||||||
|
20000098: 00200008 jr at
|
||||||
|
2000009c: 00000000 nop
|
||||||
|
|
||||||
|
200000a0 <stub_for_h2>:
|
||||||
|
200000a0: 3c012000 lui at,0x2000
|
||||||
|
200000a4: 24210025 addiu at,at,37
|
||||||
|
200000a8: 00200008 jr at
|
||||||
|
200000ac: 00000000 nop
|
||||||
|
|
||||||
|
# This isn't actually called, but is referenced from the .pdr section.
|
||||||
|
200000b0 <stub_for_h3>:
|
||||||
|
200000b0: 3c012000 lui at,0x2000
|
||||||
|
200000b4: 24210039 addiu at,at,57
|
||||||
|
200000b8: 00200008 jr at
|
||||||
|
200000bc: 00000000 nop
|
||||||
|
|
||||||
|
200000c0 <stub_for_f1>:
|
||||||
|
200000c0: 3c012000 lui at,0x2000
|
||||||
|
200000c4: 24210000 addiu at,at,0
|
||||||
|
200000c8: 00200008 jr at
|
||||||
|
200000cc: 00000000 nop
|
||||||
|
|
||||||
|
200000d0 <stub_for_g1>:
|
||||||
|
200000d0: 3c012000 lui at,0x2000
|
||||||
|
200000d4: 24210008 addiu at,at,8
|
||||||
|
200000d8: 00200008 jr at
|
||||||
|
200000dc: 00000000 nop
|
||||||
|
|
||||||
|
200000e0 <stub_for_f2>:
|
||||||
|
200000e0: 3c012000 lui at,0x2000
|
||||||
|
200000e4: 24210014 addiu at,at,20
|
||||||
|
200000e8: 00200008 jr at
|
||||||
|
200000ec: 00000000 nop
|
||||||
|
|
||||||
|
200000f0 <stub_for_g2>:
|
||||||
|
200000f0: 3c012000 lui at,0x2000
|
||||||
|
200000f4: 2421001c addiu at,at,28
|
||||||
|
200000f8: 00200008 jr at
|
||||||
|
200000fc: 00000000 nop
|
49
ld/testsuite/ld-mips-elf/mips16-local-stubs-1.s
Normal file
49
ld/testsuite/ld-mips-elf/mips16-local-stubs-1.s
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
.macro makestub,type,func,section
|
||||||
|
.text
|
||||||
|
.set \type
|
||||||
|
.type \func,@function
|
||||||
|
.ent \func
|
||||||
|
\func:
|
||||||
|
jr $31
|
||||||
|
.end \func
|
||||||
|
|
||||||
|
.section \section,"ax",@progbits
|
||||||
|
.set nomips16
|
||||||
|
.type stub_for_\func,@function
|
||||||
|
.ent stub_for_\func
|
||||||
|
stub_for_\func:
|
||||||
|
.set noat
|
||||||
|
la $1,\func
|
||||||
|
jr $1
|
||||||
|
.set at
|
||||||
|
.end stub_for_\func
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro makestubs,id
|
||||||
|
makestub nomips16,f\id,.mips16.call.F\id
|
||||||
|
makestub nomips16,g\id,.mips16.call.fp.G\id
|
||||||
|
makestub mips16,h\id,.mips16.fn.H\id
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro makecaller,type,func
|
||||||
|
.text
|
||||||
|
.set \type
|
||||||
|
.globl \func
|
||||||
|
.type \func,@function
|
||||||
|
.ent \func
|
||||||
|
\func:
|
||||||
|
jal f1
|
||||||
|
jal f2
|
||||||
|
jal g1
|
||||||
|
jal g2
|
||||||
|
jal h1
|
||||||
|
jal h2
|
||||||
|
.end \func
|
||||||
|
.endm
|
||||||
|
|
||||||
|
makestubs 1
|
||||||
|
makestubs 2
|
||||||
|
makestubs 3
|
||||||
|
|
||||||
|
makecaller nomips16,caller1
|
||||||
|
makecaller mips16,caller2
|
Loading…
Reference in a new issue