RFA: Prevent split REL relocations against mergeable section symbols

Richard Sandiford rsandifo@redhat.com
Thu Jul 8 12:47:00 GMT 2004


This patch is a repost of:

   http://sources.redhat.com/ml/binutils/2004-06/msg00557.html

The idea is to stop gas from adjusting REL high/low relocations to be
against mergeable section symbols.  It allows us to fix Maciej's testcase
without having to change the linker (although the patch would still work
if we do decide to change the linker).

As mentioned in the message above, I've tested this on:

   mips64-elf  mips64el-elf  mips-elf  mipsel-elf  mips-ecoff
   mips-linux-gnu  mipsel-linux-gnu mips64-linux-gnu  mips64el-linux-gnu

no regressions.  I've also reattached Maciej's testcase with a couple
of trivial changes to the *.d file.  I'll commit it (under his name,
of course) if approved.

OK to install?

Richard


	* config/tc-mips.c (mips_fix_adjustable): If the full addend is going
	to split into more than one in-place addend, return 0 for relocations
	against mergeable sections.  Associate comments with code.

testsuite/
	* gas/mips/elf-rel7.d: Expect relocations against bar to refer to bar.
	* gas/mips/elf-refl19.d: Likewise L2.

Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.266
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.266 tc-mips.c
*** gas/config/tc-mips.c	15 Jun 2004 01:16:35 -0000	1.266
--- gas/config/tc-mips.c	29 Jun 2004 11:28:15 -0000
*************** md_estimate_size_before_relax (fragS *fr
*** 12693,12707 ****
  }
  
  /* This is called to see whether a reloc against a defined symbol
!    should be converted into a reloc against a section.  Don't adjust
!    MIPS16 jump relocations, so we don't have to worry about the format
!    of the offset in the .o file.  Don't adjust relocations against
!    mips16 symbols, so that the linker can find them if it needs to set
!    up a stub.  */
  
  int
  mips_fix_adjustable (fixS *fixp)
  {
    if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
      return 0;
  
--- 12696,12708 ----
  }
  
  /* This is called to see whether a reloc against a defined symbol
!    should be converted into a reloc against a section.  */
  
  int
  mips_fix_adjustable (fixS *fixp)
  {
+   /* Don't adjust MIPS16 jump relocations, so we don't have to worry
+      about the format of the offset in the .o file. */
    if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
      return 0;
  
*************** mips_fix_adjustable (fixS *fixp)
*** 12712,12718 ****
--- 12713,12740 ----
    if (fixp->fx_addsy == NULL)
      return 1;
  
+   /* If symbol SYM is in a mergeable section, relocations of the form
+      SYM + 0 can usually be made section-relative.  The mergeable data
+      is then identified by the section offset rather than by the symbol.
+ 
+      However, if we're generating REL LO16 relocations, the offset is split
+      between the LO16 and parterning high part relocation.  The linker will
+      need to recalculate the complete offset in order to correctly identify
+      the merge data.
+ 
+      The linker has traditionally not looked for the parterning high part
+      relocation, and has thus allowed orphaned R_MIPS_LO16 relocations to be
+      placed anywhere.  Rather than break backwards compatibility by changing
+      this, it seems better not to force the issue, and instead keep the
+      original symbol.  This will work with either linker behavior.  */
+   if ((fixp->fx_r_type == BFD_RELOC_LO16 || reloc_needs_lo_p (fixp->fx_r_type))
+       && HAVE_IN_PLACE_OFFSETS
+       && (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0)
+     return 0;
+ 
  #ifdef OBJ_ELF
+   /* Don't adjust relocations against mips16 symbols, so that the linker
+      can find them if it needs to set up a stub.  */
    if (OUTPUT_FLAVOR == bfd_target_elf_flavour
        && S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16
        && fixp->fx_subsy == NULL)
Index: gas/testsuite/gas/mips/elf-rel7.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/elf-rel7.d,v
retrieving revision 1.2
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.2 elf-rel7.d
*** gas/testsuite/gas/mips/elf-rel7.d	7 May 2003 05:08:20 -0000	1.2
--- gas/testsuite/gas/mips/elf-rel7.d	29 Jun 2004 11:28:15 -0000
***************
*** 6,14 ****
  
  Disassembly of section \.text:
  0+00 <.*> lui	a0,0x0
! 			0: R_MIPS_HI16	.barsec
! 0+04 <.*> lw	a0,8\(a0\)
! 			4: R_MIPS_LO16	.barsec
  0+08 <.*> lui	a0,0x0
  			8: R_MIPS_HI16	bar
  0+0c <.*> lw	a0,4\(a0\)
--- 6,14 ----
  
  Disassembly of section \.text:
  0+00 <.*> lui	a0,0x0
! 			0: R_MIPS_HI16	bar
! 0+04 <.*> lw	a0,0\(a0\)
! 			4: R_MIPS_LO16	bar
  0+08 <.*> lui	a0,0x0
  			8: R_MIPS_HI16	bar
  0+0c <.*> lw	a0,4\(a0\)
Index: gas/testsuite/gas/mips/elf-rel19.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/mips/elf-rel19.d,v
retrieving revision 1.1
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.1 elf-rel19.d
*** gas/testsuite/gas/mips/elf-rel19.d	23 Jan 2004 12:58:22 -0000	1.1
--- gas/testsuite/gas/mips/elf-rel19.d	29 Jun 2004 11:28:15 -0000
*************** 00000000 <.*>:
*** 10,19 ****
  # Relocation agsinst .rodata.str1.1
  #
  .*:	8f840000 	lw	a0,0\(gp\)
! 			.*: R_MIPS_GOT16	\.rodata\.str1\.1
  .*:	00000000 	nop
! .*:	24840004 	addiu	a0,a0,4
! 			.*: R_MIPS_LO16	\.rodata\.str1\.1
  #
  # Relocation agsinst L2 + 2
  #
--- 10,19 ----
  # Relocation agsinst .rodata.str1.1
  #
  .*:	8f840000 	lw	a0,0\(gp\)
! 			.*: R_MIPS_GOT16	L2
  .*:	00000000 	nop
! .*:	24840000 	addiu	a0,a0,0
! 			.*: R_MIPS_LO16	L2
  #
  # Relocation agsinst L2 + 2
  #
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mips-elf/mips-elf.exp,v
retrieving revision 1.17
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.17 mips-elf.exp
*** ld/testsuite/ld-mips-elf/mips-elf.exp	24 Apr 2004 00:20:13 -0000	1.17
--- ld/testsuite/ld-mips-elf/mips-elf.exp	29 Jun 2004 11:28:15 -0000
*************** if $has_newabi {
*** 74,76 ****
--- 74,77 ----
      }
  }
  run_dump_test "reloc-2"
+ run_dump_test "reloc-merge-lo16"
*** /dev/null	Fri Apr 23 00:21:55 2004
--- ld/testsuite/ld-mips-elf/reloc-merge-lo16.d	Tue Jun 29 12:20:30 2004
***************
*** 0 ****
--- 1,16 ----
+ #name: MIPS ELF lo16 merge
+ #source: reloc-merge-lo16.s
+ #ld: -Treloc-merge-lo16.ld
+ #objdump: -td --prefix-addresses --show-raw-insn
+ 
+ # Test lo16 reloc calculation with string merging.
+ 
+ .*: +file format .*mips.*
+ #...
+ 0+80fe70 l       .rodata	0+000000 g
+ 0+400000 g     F .text	0+000000 __start
+ #...
+ 0+400000 <[^>]*> 3c020081 	lui	v0,0x81
+ 0+400004 <[^>]*> 2443fe70 	addiu	v1,v0,-400
+ 0+400008 <[^>]*> 2442fe70 	addiu	v0,v0,-400
+ 	\.\.\.
*** /dev/null	Fri Apr 23 00:21:55 2004
--- ld/testsuite/ld-mips-elf/reloc-merge-lo16.ld	Tue Jun 29 08:32:48 2004
***************
*** 0 ****
--- 1,9 ----
+ ENTRY(__start)
+ SECTIONS
+ {
+   . = 0x0400000;
+   .text : { *(.text) }
+   . = 0x0800000;
+   .rodata : { *(.rodata.*) }
+   /DISCARD/ : { *(*) }
+ }
*** /dev/null	Fri Apr 23 00:21:55 2004
--- ld/testsuite/ld-mips-elf/reloc-merge-lo16.s	Tue Jun 29 08:32:48 2004
***************
*** 0 ****
--- 1,28 ----
+ 	.section .rodata.str1.4,"aMS", @progbits, 1
+ 	.macro	fillstr char
+ 	.rept	0x3fff - \char
+ 	.byte	\char
+ 	.endr
+ 	.byte	0
+ 	.endm
+ 	fillstr	'a'
+ 	fillstr	'h'
+ 	fillstr	'c'
+ 	fillstr	'd'
+ 	fillstr	'g'
+ 	fillstr	'f'
+ g:
+ 	fillstr	'g'
+ 	fillstr	'h'
+ 
+ 	.text
+ 	.globl	__start
+ 	.ent	__start
+ 	.type	__start, @function
+ __start:
+ 	lui	$2, %hi(g)
+ 	addiu	$3, $2, %lo(g)
+ 	addiu	$2, $2, %lo(g)
+ 	.end	__start
+ 
+ 	.space	16



More information about the Binutils mailing list