This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH : sh-elf-as fix for SEC_MERGE
- From: "Nitin Gupta, Noida" <niting at noida dot hcltech dot com>
- To: binutils at sources dot redhat dot com
- Cc: gcc at gcc dot gnu dot org
- Date: Tue, 10 Dec 2002 20:23:24 +0530
- Subject: 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