This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [committed] Fix R_MIPS_JALR handling for o32
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Cc: gingold at adacore dot com
- Date: Sat, 19 Sep 2009 09:01:04 +0100
- Subject: Re: [committed] Fix R_MIPS_JALR handling for o32
- References: <87eiqazm8u.fsf@firetop.home>
Hi Tristan,
Sorry to nag, but is this patch OK for the branch too?
Richard Sandiford <rdsandiford@googlemail.com> writes:
> I updated my binutils in order to test the .eh_frame changes that
> Mark and I were talking about, and noticed that the recent R_MIPS_JALR
> patches had broken o32 libstdc++.so. Every C++ problem called
> std::terminate() when libstdc++.so's DT_INIT routine was called.
>
> The problem was that we had a call to a local function (frame_dummy),
> and GAS reduced the R_MIPS_JALR against frame_dummy to an R_MIPS_JALR
> against ".text + OFFSET". That's fine for RELA, but doesn't work for
> REL, since there's nowhere to put the addend.
>
> Fixed by making sure that we don't reduce R_MIPS_JALRs on targets
> with in-place addends. For completeness, we should also check that
> the original target is a bare symbol.
>
> Tested on mips64octeon-linux-gnu and applied. Tristan, this a pretty
> severe regression, so is the patch OK for the branch too?
>
> Richard
>
>
> gas/
> * config/tc-mips.c (MIPS_JALR_HINT_P): Take an expr argument.
> Require the target to be a bare symbol on targets with
> in-place addends.
> (macro_build_jalr): Update accordingly.
> (mips_fix_adjustable): Don't reduce R_MIPS_JALRs on targets
> with in-place addends.
>
> gas/testsuite/
> * gas/mips/jalr2.s, gas/mips/jalr2.d: New test.
> * gas/mips/jal-svr4pic.d: Don't expect R_MIPS_JALRs to be reduced.
> * gas/mips/jal-xgot.d: Likewise.
> * gas/mips/mips-abi32-pic2.d: Likewise.
> * gas/mips/mips.exp: Run it.
>
> Index: gas/config/tc-mips.c
> ===================================================================
> --- gas/config/tc-mips.c 2009-09-13 20:14:53.000000000 +0100
> +++ gas/config/tc-mips.c 2009-09-13 20:15:43.000000000 +0100
> @@ -292,10 +292,14 @@ #define ISA_SUPPORTS_MIPS16E (mips_opts.
>
> /* True if we want to create R_MIPS_JALR for jalr $25. */
> #ifdef TE_IRIX
> -#define MIPS_JALR_HINT_P HAVE_NEWABI
> +#define MIPS_JALR_HINT_P(EXPR) HAVE_NEWABI
> #else
> -/* As a GNU extension, we use R_MIPS_JALR for o32 too. */
> -#define MIPS_JALR_HINT_P 1
> +/* As a GNU extension, we use R_MIPS_JALR for o32 too. However,
> + because there's no place for any addend, the only acceptable
> + expression is a bare symbol. */
> +#define MIPS_JALR_HINT_P(EXPR) \
> + (!HAVE_IN_PLACE_ADDENDS \
> + || ((EXPR)->X_op == O_symbol && (EXPR)->X_add_number == 0))
> #endif
>
> /* True if -mips3d was passed or implied by arguments passed on the
> @@ -3930,13 +3934,13 @@ macro_build_jalr (expressionS *ep)
> {
> char *f = NULL;
>
> - if (MIPS_JALR_HINT_P)
> + if (MIPS_JALR_HINT_P (ep))
> {
> frag_grow (8);
> f = frag_more (0);
> }
> macro_build (NULL, "jalr", "d,s", RA, PIC_CALL_REG);
> - if (MIPS_JALR_HINT_P)
> + if (MIPS_JALR_HINT_P (ep))
> fix_new_exp (frag_now, f - frag_now->fr_literal,
> 4, ep, FALSE, BFD_RELOC_MIPS_JALR);
> }
> @@ -14097,6 +14101,10 @@ mips_fix_adjustable (fixS *fixp)
> && (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0)
> return 0;
>
> + /* There is no place to store an in-place offset for JALR relocations. */
> + if (fixp->fx_r_type == BFD_RELOC_MIPS_JALR && HAVE_IN_PLACE_ADDENDS)
> + return 0;
> +
> #ifdef OBJ_ELF
> /* R_MIPS16_26 relocations against non-MIPS16 functions might resolve
> to a floating-point stub. The same is true for non-R_MIPS16_26
> Index: gas/testsuite/gas/mips/jalr2.s
> ===================================================================
> --- /dev/null 2009-09-12 23:43:45.501816639 +0100
> +++ gas/testsuite/gas/mips/jalr2.s 2009-09-13 20:15:43.000000000 +0100
> @@ -0,0 +1,15 @@
> + .ent test
> +test:
> + .frame $sp,32,$31
> + .cprestore 16
> + jal local
> + jal local+12
> + jal global
> + jal global+12
> + .end test
> +
> +local:
> + nop
> + nop
> + nop
> + nop
> Index: gas/testsuite/gas/mips/jalr2.d
> ===================================================================
> --- /dev/null 2009-09-12 23:43:45.501816639 +0100
> +++ gas/testsuite/gas/mips/jalr2.d 2009-09-13 20:15:43.000000000 +0100
> @@ -0,0 +1,41 @@
> +#as: -mips2 -32 -KPIC
> +#objdump: -dr
> +
> +.*
> +
> +
> +Disassembly of section \.text:
> +
> +.* <test>:
> +.*: afbc0010 sw gp,16\(sp\)
> +.*: 8f990000 lw t9,0\(gp\)
> +.*: R_MIPS_GOT16 \.text
> +.*: 2739004c addiu t9,t9,76
> +.*: R_MIPS_LO16 \.text
> +.*: 0320f809 jalr t9
> +.*: R_MIPS_JALR local
> +.*: 00000000 nop
> +.*: 8fbc0010 lw gp,16\(sp\)
> +.*: 8f990000 lw t9,0\(gp\)
> +.*: R_MIPS_GOT16 \.text
> +.*: 27390058 addiu t9,t9,88
> +.*: R_MIPS_LO16 \.text
> +# No R_MIPS_JALR here, because the target address had an addend.
> +.*: 0320f809 jalr t9
> +.*: 00000000 nop
> +.*: 8fbc0010 lw gp,16\(sp\)
> +.*: 8f990000 lw t9,0\(gp\)
> +.*: R_MIPS_CALL16 global
> +.*: 0320f809 jalr t9
> +.*: R_MIPS_JALR global
> +.*: 00000000 nop
> +.*: 8fbc0010 lw gp,16\(sp\)
> +.*: 8f99000c lw t9,12\(gp\)
> +.*: R_MIPS_CALL16 global
> +# No R_MIPS_JALR here either, for the same reason.
> +.*: 0320f809 jalr t9
> +.*: 00000000 nop
> +.*: 8fbc0010 lw gp,16\(sp\)
> +
> +.* <local>:
> + \.\.\.
> Index: gas/testsuite/gas/mips/jal-svr4pic.d
> ===================================================================
> --- gas/testsuite/gas/mips/jal-svr4pic.d 2009-09-13 20:14:53.000000000 +0100
> +++ gas/testsuite/gas/mips/jal-svr4pic.d 2009-09-13 20:15:43.000000000 +0100
> @@ -26,7 +26,7 @@ Disassembly of section .text:
> 0+0034 <[^>]*> addiu t9,t9,0
> [ ]*34: R_MIPS_LO16 .text
> 0+0038 <[^>]*> jalr t9
> -[ ]*38: R_MIPS_JALR .text
> +[ ]*38: R_MIPS_JALR text_label
> 0+003c <[^>]*> nop
> 0+0040 <[^>]*> lw gp,0\(sp\)
> 0+0044 <[^>]*> nop
> Index: gas/testsuite/gas/mips/jal-xgot.d
> ===================================================================
> --- gas/testsuite/gas/mips/jal-xgot.d 2009-09-13 20:14:53.000000000 +0100
> +++ gas/testsuite/gas/mips/jal-xgot.d 2009-09-13 20:15:43.000000000 +0100
> @@ -27,7 +27,7 @@ Disassembly of section .text:
> 0+0034 <[^>]*> addiu t9,t9,0
> [ ]*34: R_MIPS_LO16 .text
> 0+0038 <[^>]*> jalr t9
> -[ ]*38: R_MIPS_JALR .text
> +[ ]*38: R_MIPS_JALR text_label
> 0+003c <[^>]*> nop
> 0+0040 <[^>]*> lw gp,0\(sp\)
> 0+0044 <[^>]*> lui t9,0x0
> Index: gas/testsuite/gas/mips/mips-abi32-pic2.d
> ===================================================================
> --- gas/testsuite/gas/mips/mips-abi32-pic2.d 2009-09-13 20:14:53.000000000 +0100
> +++ gas/testsuite/gas/mips/mips-abi32-pic2.d 2009-09-13 20:15:43.000000000 +0100
> @@ -16,7 +16,7 @@ Disassembly of section \.text:
> 0+014 <[^>]*> 273900cc addiu t9,t9,204
> 14: R_MIPS_LO16 \.text
> 0+018 <[^>]*> 0320f809 jalr t9
> - 18: R_MIPS_JALR \.text
> + 18: R_MIPS_JALR end
> 0+01c <[^>]*> 00000000 nop
> 0+020 <[^>]*> 8fbc0008 lw gp,8\(sp\)
> 0+024 <[^>]*> 00000000 nop
> @@ -36,7 +36,7 @@ Disassembly of section \.text:
> 0+050 <[^>]*> 273900cc addiu t9,t9,204
> 50: R_MIPS_LO16 \.text
> 0+054 <[^>]*> 0320f809 jalr t9
> - 54: R_MIPS_JALR \.text
> + 54: R_MIPS_JALR end
> 0+058 <[^>]*> 00000000 nop
> 0+05c <[^>]*> 3c010001 lui at,0x1
> 0+060 <[^>]*> 003d0821 addu at,at,sp
> @@ -60,7 +60,7 @@ Disassembly of section \.text:
> 0+09c <[^>]*> 273900cc addiu t9,t9,204
> 9c: R_MIPS_LO16 \.text
> 0+0a0 <[^>]*> 0320f809 jalr t9
> - a0: R_MIPS_JALR \.text
> + a0: R_MIPS_JALR end
> 0+0a4 <[^>]*> 00000000 nop
> 0+0a8 <[^>]*> 3c010001 lui at,0x1
> 0+0ac <[^>]*> 003d0821 addu at,at,sp
> Index: gas/testsuite/gas/mips/mips.exp
> ===================================================================
> --- gas/testsuite/gas/mips/mips.exp 2009-09-13 20:14:53.000000000 +0100
> +++ gas/testsuite/gas/mips/mips.exp 2009-09-13 20:15:43.000000000 +0100
> @@ -706,6 +706,7 @@ if { [istarget mips*-*-vxworks*] } {
>
> run_list_test "tls-ill" "-32"
> run_dump_test "tls-o32"
> + run_dump_test "jalr2"
> }
>
> if $has_newabi {