[PATCH][ARM] Fix handling of GOT_PREL in gas.
Doug Kwan (關振德)
dougkwan@google.com
Thu Sep 16 08:45:00 GMT 2010
Hi
This patch fixes a problem in which gas fails to assemble data
expression in the form:
symbol(GOT_PREL) + (. - (.LPIC0 + 4))
where .LPIC0 is a local label defined in the same function after the
data expression. Currently, LPIC0 is undefined when the data
expression is processed and that causes an error in the function
expr() because the two operands of the addition have different
segments. The patch adds code to handle this situation. This is
tested by the running the gas test suite and the new test case in this
patch.
-Doug
gas/ChangeLog:
2010-09-16 Doug Kwan <dougkwan@google.com>
* config/tc-arm.c (s_arm_elf_cons): Handle R_ARM_GOT_PREL specially.
gas/testsuite/ChangeLog:
2010-09-16 Doug Kwan <dougkwan@google.com>
* gas/arm/got_prel2.d: New.
* gas/arm/got_prel2.s: New.
-------------- next part --------------
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.458
diff -u -u -p -r1.458 tc-arm.c
--- gas/config/tc-arm.c 9 Sep 2010 12:08:12 -0000 1.458
+++ gas/config/tc-arm.c 16 Sep 2010 08:25:37 -0000
@@ -3212,20 +3212,54 @@ s_arm_elf_cons (int nbytes)
howto->name, nbytes);
else
{
- /* We've parsed an expression stopping at O_symbol.
- But there may be more expression left now that we
- have parsed the relocation marker. Parse it again.
- XXX Surely there is a cleaner way to do this. */
- char *p = input_line_pointer;
int offset;
- char *save_buf = (char *) alloca (input_line_pointer - base);
- memcpy (save_buf, base, input_line_pointer - base);
- memmove (base + (input_line_pointer - before_reloc),
- base, before_reloc - base);
-
- input_line_pointer = base + (input_line_pointer-before_reloc);
- expression (&exp);
- memcpy (base, save_buf, p - base);
+ char *p, *save_buf;
+
+ SKIP_WHITESPACE();
+
+ /* This could be an expression of the form:
+
+ foo(GOT_PREL) + (. - (.LPIC0 + 8))
+
+ and .LPIC0 might be a forward reference. Generate
+ an add-expression for fixing up. We cannot use the
+ code handling other relocation types below becasue
+ .LPIC0 may be undefined at this point. We would get
+ an error in expression() since foo and .LPIC0 might
+ have different segments. */
+
+ if (reloc == BFD_RELOC_ARM_GOT_PREL
+ && *input_line_pointer == '+'
+ && exp.X_op == O_symbol
+ && exp.X_op_symbol == NULL)
+ {
+ expressionS right;
+ symbolS *right_symbol;
+
+ right.X_md = 0;
+ expression (&right);
+ right_symbol = make_expr_symbol(&right);
+ exp.X_op = O_add;
+ exp.X_op_symbol = right_symbol;
+ }
+ else
+ {
+ /* We've parsed an expression stopping at O_symbol.
+ But there may be more expression left now that we
+ have parsed the relocation marker. Parse it again.
+ XXX Surely there is a cleaner way to do this. */
+ p = input_line_pointer;
+ save_buf =
+ (char *) alloca (input_line_pointer - base);
+ memcpy (save_buf, base, input_line_pointer - base);
+ memmove (base + (input_line_pointer - before_reloc),
+ base, before_reloc - base);
+
+ input_line_pointer =
+ base + (input_line_pointer-before_reloc);
+ expression (&exp);
+ memcpy (base, save_buf, p - base);
+ }
offset = nbytes - size;
p = frag_more ((int) nbytes);
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 16 Sep 2010 08:25:41 -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 16 Sep 2010 08:25:41 -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