[PATCH][GAS/ARM] Better handling of difference between a symbol and an undefined symbol.

Doug Kwan (關振德) dougkwan@google.com
Mon Sep 27 21:37:00 GMT 2010


Hi,

   This patch handles difference expression between a symbol and an
undefined symbol better so that we can assemble something like:


        .section        .data.i,"a"
i:
        .long   0

        .section        .data.j,"a"
j:
        .long   i - (. - .L1)
.L1:


The problem with the above code is that .L1 in "i - (. - L1)" is a
forward reference.  The current code in expr() evaluate this to
something belonging to section .data.j,  That causes a subsequent
failure in segment check because i is defined in another section.

-Doug

gas/ChangeLog:
2010-09-27  Doug Kwan  <dougkwan@google.com>

        * expr.c (expr): Handle difference between a symbol and an undefined
        symbol specially.

gas/testsuite/ChangeLog:

2010-09-27  Doug Kwan  <dougkwan@google.com>

        * gas/arm/got_prel2.d: New.
        * gas/arm/got_prel2.s: New.
-------------- next part --------------
? gold/autom4te.cache
Index: gas/expr.c
===================================================================
RCS file: /cvs/src/src/gas/expr.c,v
retrieving revision 1.84
diff -u -u -p -r1.84 expr.c
--- gas/expr.c	2 Aug 2010 13:19:44 -0000	1.84
+++ gas/expr.c	27 Sep 2010 21:22:23 -0000
@@ -1954,6 +1954,22 @@ expr (int rankarg,		/* Larger # is highe
 		  retval = absolute_section;
 		  rightseg = absolute_section;
 		}
+	      else if (retval == undefined_section
+		       || rightseg == undefined_section)
+		{
+		  /* Difference of two symbols, one of which
+		     is undefined.  Create expression symbols so that
+		     we can resolve values later.  We need to undo
+		     modifications to *resultP made above.   */
+		  resultP->X_op = O_symbol;
+		  resultP->X_add_number += right.X_add_number;
+		  resultP->X_add_symbol = make_expr_symbol (resultP);
+		  resultP->X_op_symbol = make_expr_symbol (&right);
+		  resultP->X_op = O_subtract;
+		  resultP->X_add_number = 0;
+		  resultP->X_unsigned = 1;
+		  retval = undefined_section;
+		}
 	    }
 	}
       else
Index: gas/testsuite/gas/arm/got_prel2.d
===================================================================
RCS file: gas/testsuite/gas/arm/got_prel2.d
diff -N gas/testsuite/gas/arm/got_prel2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/got_prel2.d	27 Sep 2010 21:22:23 -0000
@@ -0,0 +1,20 @@
+# name: R_ARM_GOT_PREL relocation with forward PIC reference
+# source: got_prel2.s
+# as: -march=armv5te -meabi=5
+# objdump: -dr --prefix-addresses --show-raw-insn
+# target: *-*-*eabi *-*-symbianelf *-*-linux-* *-*-elf
+
+.*.o: +file format .*arm.*
+
+
+Disassembly of section \.text\.foo:
+0+00 <foo> ea000000 ? 	b	0+08 <foo\+0x8>
+0+04 <foo\+0x4> fffffff4 ?	\.word	0xfffffff4
+			4: R_ARM_GOT_PREL	i
+0+08 <foo\+0x8> e51f300c ?	ldr	r3, \[pc, #\-12\]	; 0+04 <foo\+0x4>
+0+0c <foo\+0xc> e08f3003 ?	add	r3, pc, r3
+0+10 <foo\+0x10> e5933000 ?	ldr	r3, \[r3\]
+0+14 <foo\+0x14> e5932000 ?	ldr	r2, \[r3\]
+0+18 <foo\+0x18> e5830000 ?	str	r0, \[r3\]
+0+1c <foo\+0x1c> e1a00002 ?	mov	r0, r2
+0+20 <foo\+0x20> e12fff1e ?	bx	lr
Index: gas/testsuite/gas/arm/got_prel2.s
===================================================================
RCS file: gas/testsuite/gas/arm/got_prel2.s
diff -N gas/testsuite/gas/arm/got_prel2.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/got_prel2.s	27 Sep 2010 21:22:23 -0000
@@ -0,0 +1,22 @@
+        .text
+.Ltext0:
+        .section        .text.foo,"ax",%progbits
+        .align  2
+        .global foo
+        .type   foo, %function
+foo:
+        .fnstart
+	b	.L3
+.L2:
+        .word   i(GOT_PREL) + (. - (.LPIC0+4))
+.L3:
+        ldr     r3, .L2
+.LPIC0:
+        add     r3, pc, r3
+        ldr     r3, [r3]
+        ldr     r2, [r3]
+        str     r0, [r3]
+        mov     r0, r2
+        bx      lr
+        .align  2
+        .fnend


More information about the Binutils mailing list