[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