[patch] ARM pcrel function relocs

Paul Brook paul@codesourcery.com
Thu Nov 30 23:55:00 GMT 2006


The ARM abi has special semantics for relocations against function symbols. To 
avoid having to duplicate this we want gas to always output relocations 
against function symbols, even when it would normally be able to resolve them 
locally.

arm_fix_adjustable contains a special case for function symbols.  However 
arm_force_relocation does not.

This confuses md_pcrel_from_section, and results in incorrect addends for 
pc-relative relocations against local function symbols in the same section. 
One example of this is the code that gcc generates for C++ virtual function 
thunks when COMDAT sections are disabled.

Global function symbols are not effected because generic_force_reloc already 
returns true for those.

Patch below fixes this.
Tested with cross to arm-none-eabi.
Ok?

Paul

2006-11-30  Paul Brook  <paul@codesourcery.com>

	gas/
	* config/tc-arm.c (arm_force_relocation): Return 1 for relocs against
	function symbols.

	gas/testsuite/
	* gas/arm/thumbrel.s: New test.
	* gas/arm/thumbrel.d: New test.

Index: gas/config/tc-arm.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.c,v
retrieving revision 1.250.2.44
diff -u -p -r1.250.2.44 tc-arm.c
--- gas/config/tc-arm.c	31 Oct 2006 16:46:37 -0000	1.250.2.44
+++ gas/config/tc-arm.c	30 Nov 2006 18:01:11 -0000
@@ -18905,6 +18905,12 @@ arm_force_relocation (struct fix * fixp)
       || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
     return 1;
 
+  /* Always generate relocations against function symbols.  */
+  if (fixp->fx_r_type == BFD_RELOC_32
+      && fixp->fx_addsy
+      && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
+    return 1;
+
   return generic_force_reloc (fixp);
 }
 
Index: gas/testsuite/gas/arm/thumbrel.d
===================================================================
RCS file: gas/testsuite/gas/arm/thumbrel.d
diff -N gas/testsuite/gas/arm/thumbrel.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/thumbrel.d	30 Nov 2006 19:15:06 -0000
@@ -0,0 +1,14 @@
+#objdump: -sr
+# This test is only valid on ELF based ports.
+#not-target: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+
+.*:     file format.*
+
+RELOCATION RECORDS FOR \[.text\]:
+OFFSET   TYPE              VALUE 
+00000004 R_ARM_REL32       b
+
+Contents of section .text:
+ 0000 00000000 (00000004|04000000) 00000000 00000000  .*
+# Ignore .ARM.attributes section
+#...
Index: gas/testsuite/gas/arm/thumbrel.s
===================================================================
RCS file: gas/testsuite/gas/arm/thumbrel.s
diff -N gas/testsuite/gas/arm/thumbrel.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gas/testsuite/gas/arm/thumbrel.s	30 Nov 2006 19:12:23 -0000
@@ -0,0 +1,11 @@
+@ Check that PC-relative relocs against local function symbols are
+@ generated correctly.
+.text
+.thumb
+a:
+.word 0
+.word b - a
+.word 0
+.word 0
+.type b, %function
+b:



More information about the Binutils mailing list