This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH : sh-elf-as fix for SEC_MERGE


Hi,
	Following testcase produces incorrect results when
	compiled with -O2 (sh-elf-gcc).  I'm using 
		-GCC 3.1.1  (reproducible with GCC mainline too)
		-binutils 2.12
		-newlib 1.10.0
	No new regressions found in make check-gcc with following
	fix of the problem.

TEST CASE:
------------------
	char *t ="w";
	int main()
	{
	  char *p = "abc";

	  if(*++p != 'b')
	    {
	      printf("ERROR at line %d\n", __LINE__ - 2);
	    }
	    return 0;
	}
	
GCC OUTPUT (With -O2)
------------------------------------
		.global	_t
		.section	.rodata.str1.4,"aMS",@progbits,1
		.align 2
	.LC0:
		.string	"w"
		.data
		.align 2
		.type	_t,@object
		.size	_t,4
	_t:
		.long	.LC0
		.section	.rodata.str1.4
		.align 2
	.LC1:
		.string	"abc"
		.align 2
	.LC2:
		.string	"ERROR at line %d\n"
		.text
		.align 2
		.global	_main
		.type	_main,@function
	_main:
		mov.l	r14,@-r15
		mov.l	.L3,r1
		sts.l	pr,@-r15
		mov.b	@r1,r0
		mov	r15,r14
		cmp/eq	#98,r0
		bt	.L2
		mov.l	.L4,r0
		mov.l	.L5,r4
		jsr	@r0
		mov	#6,r5
	.L2:
		mov	#0,r0
		mov	r14,r15
		lds.l	@r15+,pr
		rts	
		mov.l	@r15+,r14
	.L6:
		.align 2
	.L3:
		.long	.LC1+1
	.L4:
		.long	_printf


CAUSE:
---------
	in bug.o relocation entry of the .L3 is 
	'.rela.text'
  	    00000020  00000701 R_SH_DIR32            00000004  .LC1     + 0
	  ...
	Hence .L3 is at offset 0x20 in .text section of bug.o

	Symtab contains
	...
	     6: 00000000     0 NOTYPE  LOCAL  DEFAULT    6 .LC0
	     7: 00000004     0 NOTYPE  LOCAL  DEFAULT    6 .LC1
	     8: 00000008     0 NOTYPE  LOCAL  DEFAULT    6 .LC2
	...
	Hence value of .LC1 is 4 that is correct.

	However the value at offset 0x20 in text section is 5, which is 
	the "relaxed" value of .L1 + 1.

	Now when linking the linker would add the 
		* The offset to which the rodata.str section is relocated.
		* value of symbol .LC1 (=4)
		* value at offset 0x20 in .text section (which same as .L3)
	This would evaluate to .rodata.str + 4 + 5 
	However it should have been .rodata + 4 + 1

FIX:
-----
	The assembler should not relax the expression of .L3. Keeping 
	relocation entry and symtab same it should emit  1 at offset 0x20 
	in text section (the offset corresponding to .L3).


PATCH: The following patch is generated with binutils 2.12
-------------
	         
	*** src/gas/config/tc-sh.c.orig      Fri Dec  6 13:53:56 2002
	--- src/gas/config/tc-sh.c.modi  Tue Dec 10 19:59:10 2002
	*************** sh_fix_adjustable (fixP)
	*** 3242,3247 ****
	--- 3242,3251 ----
	    if (fixP->fx_addsy == NULL)
	      return 1;

	+   if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE)
	+       &&!S_IS_COMMON (fixP->fx_addsy))
	+     return 0;
	+
	    if (fixP->fx_r_type == BFD_RELOC_SH_PCDISP8BY2
	        || fixP->fx_r_type == BFD_RELOC_SH_PCDISP12BY2
	        || fixP->fx_r_type == BFD_RELOC_SH_PCRELIMM8BY2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]