This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
[patch] m32r gas relocation processing
- To: binutils at sourceware dot cygnus dot com
- Subject: [patch] m32r gas relocation processing
- From: Catherine Moore <clm at cygnus dot com>
- Date: Thu, 09 Mar 2000 14:04:42 -0800
- cc: clm at cygnus dot com
I would like to propose the following patch which fixes a problem in
gas/cgen.c. This problem shows up in the m32r port and can be
demonstrated with the following test case:
.global stra
.section .data
.balign 4
.type stra,@object
.size stra,4
stra:
.word 7
.word 8
.word 9
.global Nest
.weak Nest
.balign 4
.type Nest,@object
.size Nest,8
Nest:
.word 1
.word 2
.word 3
.word 4
.word 5
.word 6
.section .text
.balign 4
.global main
.type main,@function
main:
seth r4,#shigh(Nest+4)
ld r1,@(low(Nest+4),r4)
jmp lr
Disassembly of section .text:
00000000 <main>:
0: d4 c0 00 00 seth r4,#0x0
0: R_M32R_HI16_SLO Nest
4: a1 c4 00 10 ld r1,@(16,r4)
4: R_M32R_LO16 Nest
8: 1f ce f0 00 jmp lr || nop
An objdump -dr on the resulting object files reveals that an offset of
16 has been generated for the second reloc. This would be correct if
we were relocating against the data section. In this case, we are
relocating against the symbol Nest. The correct offset should be 4.
This problem would probably show up in any port that uses gas/cgen.c
and REL type relocations. I don't know if there is an accepted way
to determine that a particular port uses REL relocations in the
generic portion of gas. This patch does this extra processing only
if TC_M32R is defined. I am open to suggestions for coding this in
a more target-independent fashion.
The relocation processing for the m32r was based on the mips port.
This patch was modified from similar processing that is done for mips.
Okay to install?
2000-03-09 Catherine Moore <clm@cygnus.com>
* cgen.c (gas_cgen_md_apply_fix3): Adjust value if we are
not relocating against a section symbol.
Index: cgen.c
===================================================================
RCS file: /cvs/src/src/gas/cgen.c,v
retrieving revision 1.2
diff -p -r1.2 cgen.c
*** cgen.c 1999/06/03 12:51:21 1.2
- --- cgen.c 2000/03/09 21:36:38
*************** gas_cgen_md_apply_fix3 (fixP, valueP, se
*** 492,500 ****
{
char * where = fixP->fx_frag->fr_literal + fixP->fx_where;
valueT value;
/* canonical name, since used a lot */
CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
!
/* FIXME FIXME FIXME: The value we are passed in *valuep includes
the symbol values. Since we are using BFD_ASSEMBLER, if we are
doing this relocation the code in write.c is going to call
- --- 492,501 ----
{
char * where = fixP->fx_frag->fr_literal + fixP->fx_where;
valueT value;
+
/* canonical name, since used a lot */
CGEN_CPU_DESC cd = gas_cgen_cpu_desc;
!
/* FIXME FIXME FIXME: The value we are passed in *valuep includes
the symbol values. Since we are using BFD_ASSEMBLER, if we are
doing this relocation the code in write.c is going to call
*************** gas_cgen_md_apply_fix3 (fixP, valueP, se
*** 513,518 ****
- --- 514,543 ----
}
else if (fixP->fx_pcrel)
value = * valueP;
+ #ifdef TC_M32R
+ /* If this fixup is against a symbol rather than a section symbol,
+ the value needs to be adjusted. */
+ else if (S_IS_WEAK (fixP->fx_addsy)
+ || (symbol_used_in_reloc_p (fixP->fx_addsy)
+ && (((bfd_get_section_flags (stdoutput,
+ S_GET_SEGMENT (fixP->fx_addsy))
+ & SEC_LINK_ONCE) != 0)
+ || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
+ ".gnu.linkonce",
+ sizeof (".gnu.linkonce") - 1))))
+
+ {
+ value = *valueP;
+ value -= S_GET_VALUE (fixP->fx_addsy);
+ if (value != 0 && ! fixP->fx_pcrel)
+ {
+ /* In this case, the bfd_install_relocation routine will
+ incorrectly add the symbol value back in. We just want
+ the addend to appear in the object file. */
+ value -= S_GET_VALUE (fixP->fx_addsy);
+ }
+ }
+ #endif
else
{
value = fixP->fx_offset;