This is the mail archive of the binutils@sourceware.cygnus.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]

[patch] m32r gas relocation processing


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;

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