[PATCH, ARM]: Fix SB group relocations

John Tytgat john@bass-software.com
Sun Jul 14 17:50:00 GMT 2013


ARM's IHI0044E document specifies the B(S) for the
R_ARM_{ALU|LDR|LDC|LDRS}_SB_G{0|1|2} relocations as:

B(S) is the addressing origin of the output segment defining the symbol S.
The origin is not required to be the base address of the segment. This
value must always be word-aligned.

However currently in bfd/elf32-arm.c the sb value gets calculated as:

	/* sb should be the origin of the *segment* containing the symbol.
	   It is not clear how to obtain this OS-dependent value, so we
	   make an arbitrary choice of zero.  */
	bfd_vma sb = 0;

IMHO this is wrong and this is not about the origin of the output segment
at run time but about the one which gets determined at linking time.  As
sb group relocations are static ones they are most probably the same so we
better use sym_sec->output_section->vma instead of a fixed value 0.

Please find patch attached.

Tested binutils, ld and gas with target arm-unknown-eabi, no regressions.

I've a copyright assignment but no write acccess.

bfd

John Tytgat  <john@bass-software.com>

	* elf32-arm.c (elf32_arm_final_link_relocate): Use origin of output
	segment containing the relocating symbol instead of assuming 0 for
	sb group relocations.

ld/testsuite

John Tytgat  <john@bass-software.com>

	* ld-arm/group-relocs.s: Add comments.  Move symbols used for sb
	group relocations into .data section.  Drop section zero.  Use pc/r0
	as base register when pc/sb group relocations are used.
	* ld-arm/group-relocs.d: Adjust expected result.
	* ld-arm/group-relocs-ldr-bad.s: Use pc_g0/pc_g1 relocs instead of
	sb_g0/sb_g1.
	* ld-arm/group-relocs-ldrs-bad.s: Likewise.
	* ld-arm/group-relocs-ldr-bad.d: Adjust expected result.
	* ld-arm/group-relocs-ldrs-bad.d: Likewise.
	* ld-arm/group-relocs-alu-bad-2.d: New test for sb group relocation.
	* ld-arm/group-relocs-ldr-bad-2.d: Likewise.
	* ld-arm/group-relocs-ldrs-bad-2.d: Likewise.
	* ld-arm/group-relocs-ldc-bad-2.d: Likewise.
	* ld-arm/group-relocs-alu-bad-2.s: New test source.
	* ld-arm/group-relocs-ldr-bad-2.s: Likewise.
	* ld-arm/group-relocs-ldrs-bad-2.s: Likewise.
	* ld-arm/group-relocs-ldc-bad-2.s: Likewise.
	* ld-arm/arm-elf.exp: For group-relocs, drop section zero start
	definition.  Run the new tests.

John.
-- 
John Tytgat                                                             BASS
John@bass-software.com
-------------- next part --------------
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.319
diff -u -r1.319 elf32-arm.c
--- bfd/elf32-arm.c	28 Jun 2013 12:22:42 -0000	1.319
+++ bfd/elf32-arm.c	14 Jul 2013 16:44:37 -0000
@@ -9799,10 +9799,8 @@
 	bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
 	bfd_vma pc = input_section->output_section->vma
 		     + input_section->output_offset + rel->r_offset;
-	/* sb should be the origin of the *segment* containing the symbol.
-	   It is not clear how to obtain this OS-dependent value, so we
-	   make an arbitrary choice of zero.  */
-	bfd_vma sb = 0;
+	/* sb is the origin of the *segment* containing the symbol.  */
+	bfd_vma sb = sym_sec->output_section->vma;
 	bfd_vma residual;
 	bfd_vma g_n;
 	bfd_signed_vma signed_value;
@@ -9935,7 +9933,8 @@
 	bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
 	bfd_vma pc = input_section->output_section->vma
 		     + input_section->output_offset + rel->r_offset;
-	bfd_vma sb = 0; /* See note above.  */
+	/* sb is the origin of the *segment* containing the symbol.  */
+	bfd_vma sb = sym_sec->output_section->vma;
 	bfd_vma residual;
 	bfd_signed_vma signed_value;
 	int group = 0;
@@ -10018,7 +10017,8 @@
 	bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
 	bfd_vma pc = input_section->output_section->vma
 		     + input_section->output_offset + rel->r_offset;
-	bfd_vma sb = 0; /* See note above.  */
+	/* sb is the origin of the *segment* containing the symbol.  */
+	bfd_vma sb = sym_sec->output_section->vma;
 	bfd_vma residual;
 	bfd_signed_vma signed_value;
 	int group = 0;
@@ -10101,7 +10101,8 @@
 	bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
 	bfd_vma pc = input_section->output_section->vma
 		     + input_section->output_offset + rel->r_offset;
-	bfd_vma sb = 0; /* See note above.  */
+	/* sb is the origin of the *segment* containing the symbol.  */
+	bfd_vma sb = sym_sec->output_section->vma;
 	bfd_vma residual;
 	bfd_signed_vma signed_value;
 	int group = 0;
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.104
diff -u -r1.104 arm-elf.exp
--- ld/testsuite/ld-arm/arm-elf.exp	13 Jun 2013 12:36:01 -0000	1.104
+++ ld/testsuite/ld-arm/arm-elf.exp	14 Jul 2013 16:45:03 -0000
@@ -67,7 +67,7 @@
 # readelf: Apply readelf options on result.  Compare with regex (last arg).
 
 set armelftests_common {
-    {"Group relocations" "-Ttext 0x8000 --section-start zero=0x0 --section-start alpha=0xeef0 --section-start beta=0xffeef0" "" "" {group-relocs.s}
+    {"Group relocations" "-Ttext 0x8000 -Tdata 0x3000000 --section-start alpha=0xeef0 --section-start beta=0xffeef0" "" "" {group-relocs.s}
      {{objdump -dr group-relocs.d}}
      "group-relocs"}
     {"Thumb-1 BL" "-Ttext 0x1000 --section-start .foo=0x401000" "" "" {thumb1-bl.s}
@@ -463,9 +463,13 @@
 }
 
 run_dump_test "group-relocs-alu-bad"
+run_dump_test "group-relocs-alu-bad-2"
 run_dump_test "group-relocs-ldr-bad"
+run_dump_test "group-relocs-ldr-bad-2"
 run_dump_test "group-relocs-ldrs-bad"
+run_dump_test "group-relocs-ldrs-bad-2"
 run_dump_test "group-relocs-ldc-bad"
+run_dump_test "group-relocs-ldc-bad-2"
 run_dump_test "thumb2-bl-undefweak"
 run_dump_test "thumb2-bl-undefweak1"
 run_dump_test "emit-relocs1"
Index: ld/testsuite/ld-arm/group-relocs-ldr-bad.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/group-relocs-ldr-bad.d,v
retrieving revision 1.1
diff -u -r1.1 group-relocs-ldr-bad.d
--- ld/testsuite/ld-arm/group-relocs-ldr-bad.d	15 Jun 2006 11:03:02 -0000	1.1
+++ ld/testsuite/ld-arm/group-relocs-ldr-bad.d	14 Jul 2013 16:45:03 -0000
@@ -1,4 +1,4 @@
 #name: LDR group relocations failure test
 #source: group-relocs-ldr-bad.s
 #ld: -Ttext 0x8000 --section-start foo=0x8001000
-#error: .*Overflow whilst splitting 0x8001000 for group relocation.*
+#error: .*Overflow whilst splitting 0x7ff9000 for group relocation.*
Index: ld/testsuite/ld-arm/group-relocs-ldr-bad.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/group-relocs-ldr-bad.s,v
retrieving revision 1.1
diff -u -r1.1 group-relocs-ldr-bad.s
--- ld/testsuite/ld-arm/group-relocs-ldr-bad.s	15 Jun 2006 11:03:02 -0000	1.1
+++ ld/testsuite/ld-arm/group-relocs-ldr-bad.s	14 Jul 2013 16:45:03 -0000
@@ -6,8 +6,8 @@
 	.globl _start
 
 _start:
-	add	r0, r0, #:sb_g0_nc:(bar)
-	ldr	r1, [r0, #:sb_g1:(bar)]
+	add	r0, r0, #:pc_g0_nc:(bar)
+	ldr	r1, [r0, #:pc_g1:(bar + 4)]
 
 @ We will place the section foo at 0x8001000.
 
Index: ld/testsuite/ld-arm/group-relocs-ldrs-bad.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/group-relocs-ldrs-bad.d,v
retrieving revision 1.1
diff -u -r1.1 group-relocs-ldrs-bad.d
--- ld/testsuite/ld-arm/group-relocs-ldrs-bad.d	15 Jun 2006 11:03:02 -0000	1.1
+++ ld/testsuite/ld-arm/group-relocs-ldrs-bad.d	14 Jul 2013 16:45:03 -0000
@@ -1,4 +1,4 @@
 #name: LDRS group relocations failure test
 #source: group-relocs-ldrs-bad.s
 #ld: -Ttext 0x8000 --section-start foo=0x8000100
-#error: Overflow whilst splitting 0x8000100 for group relocation
+#error: Overflow whilst splitting 0x7ff8100 for group relocation
Index: ld/testsuite/ld-arm/group-relocs-ldrs-bad.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/group-relocs-ldrs-bad.s,v
retrieving revision 1.1
diff -u -r1.1 group-relocs-ldrs-bad.s
--- ld/testsuite/ld-arm/group-relocs-ldrs-bad.s	15 Jun 2006 11:03:02 -0000	1.1
+++ ld/testsuite/ld-arm/group-relocs-ldrs-bad.s	14 Jul 2013 16:45:03 -0000
@@ -6,8 +6,8 @@
 	.globl _start
 
 _start:
-	add	r0, r0, #:sb_g0_nc:(bar)
-	ldrd	r2, [r0, #:sb_g1:(bar)]
+	add	r0, r0, #:pc_g0_nc:(bar)
+	ldrd	r2, [r0, #:pc_g1:(bar + 4)]
 
 @ We will place the section foo at 0x8000100.
 
Index: ld/testsuite/ld-arm/group-relocs.d
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/group-relocs.d,v
retrieving revision 1.4
diff -u -r1.4 group-relocs.d
--- ld/testsuite/ld-arm/group-relocs.d	12 Apr 2012 13:01:10 -0000	1.4
+++ ld/testsuite/ld-arm/group-relocs.d	14 Jul 2013 16:45:03 -0000
@@ -10,42 +10,42 @@
     800c:	e28f08ff 	add	r0, pc, #16711680	; 0xff0000
     8010:	e2800c6e 	add	r0, r0, #28160	; 0x6e00
     8014:	e28000e4 	add	r0, r0, #228	; 0xe4
-    8018:	e2800000 	add	r0, r0, #0
-    801c:	e28f0cee 	add	r0, pc, #60928	; 0xee00
+    8018:	e280000c 	add	r0, r0, #12
+    801c:	e2800cee 	add	r0, r0, #60928	; 0xee00
     8020:	e28000f0 	add	r0, r0, #240	; 0xf0
     8024:	e28008ff 	add	r0, r0, #16711680	; 0xff0000
     8028:	e2800cee 	add	r0, r0, #60928	; 0xee00
     802c:	e28000f0 	add	r0, r0, #240	; 0xf0
-    8030:	e2800c6e 	add	r0, r0, #28160	; 0x6e00
+    8030:	e28f0c6e 	add	r0, pc, #28160	; 0x6e00
     8034:	e59010c0 	ldr	r1, \[r0, #192\].*
-    8038:	e28008ff 	add	r0, r0, #16711680	; 0xff0000
+    8038:	e28f08ff 	add	r0, pc, #16711680	; 0xff0000
     803c:	e2800c6e 	add	r0, r0, #28160	; 0x6e00
     8040:	e59010b8 	ldr	r1, \[r0, #184\].*
-    8044:	e5901000 	ldr	r1, \[r0\]
+    8044:	e590100c 	ldr	r1, \[r0, #12\]
     8048:	e2800cee 	add	r0, r0, #60928	; 0xee00
     804c:	e59010f0 	ldr	r1, \[r0, #240\].*
     8050:	e28008ff 	add	r0, r0, #16711680	; 0xff0000
     8054:	e2800cee 	add	r0, r0, #60928	; 0xee00
     8058:	e59010f0 	ldr	r1, \[r0, #240\].*
-    805c:	e1c026d0 	ldrd	r2, \[r0, #96\].*
-    8060:	e2800c6e 	add	r0, r0, #28160	; 0x6e00
+    805c:	e1cf26d0 	ldrd	r2, \[pc, #96\].*
+    8060:	e28f0c6e 	add	r0, pc, #28160	; 0x6e00
     8064:	e1c029d0 	ldrd	r2, \[r0, #144\].*
-    8068:	e28008ff 	add	r0, r0, #16711680	; 0xff0000
+    8068:	e28f08ff 	add	r0, pc, #16711680	; 0xff0000
     806c:	e2800c6e 	add	r0, r0, #28160	; 0x6e00
     8070:	e1c028d8 	ldrd	r2, \[r0, #136\].*
-    8074:	e1c020d0 	ldrd	r2, \[r0\]
+    8074:	e1c020dc 	ldrd	r2, \[r0, #12\]
     8078:	e2800cee 	add	r0, r0, #60928	; 0xee00
     807c:	e1c02fd0 	ldrd	r2, \[r0, #240\].*
     8080:	e28008ff 	add	r0, r0, #16711680	; 0xff0000
     8084:	e2800cee 	add	r0, r0, #60928	; 0xee00
     8088:	e1c02fd0 	ldrd	r2, \[r0, #240\].*
-    808c:	ed90000c 	ldc	0, cr0, \[r0, #48\].*
-    8090:	e2800c6e 	add	r0, r0, #28160	; 0x6e00
+    808c:	ed9f000c 	ldc	0, cr0, \[pc, #48\].*
+    8090:	e28f0c6e 	add	r0, pc, #28160	; 0x6e00
     8094:	ed900018 	ldc	0, cr0, \[r0, #96\].*
-    8098:	e28008ff 	add	r0, r0, #16711680	; 0xff0000
+    8098:	e28f08ff 	add	r0, pc, #16711680	; 0xff0000
     809c:	e2800c6e 	add	r0, r0, #28160	; 0x6e00
     80a0:	ed900016 	ldc	0, cr0, \[r0, #88\].*
-    80a4:	ed900000 	ldc	0, cr0, \[r0\]
+    80a4:	ed900003 	ldc	0, cr0, \[r0, #12\]
     80a8:	e2800cee 	add	r0, r0, #60928	; 0xee00
     80ac:	ed90003c 	ldc	0, cr0, \[r0, #240\].*
     80b0:	e28008ff 	add	r0, r0, #16711680	; 0xff0000
@@ -54,14 +54,12 @@
 
 000080bc <one_group_needed_alu_pc>:
     80bc:	e3a00000 	mov	r0, #0
-Disassembly of section zero:
 
-00000000 <one_group_needed_alu_sb>:
-   0:	e3a00000 	mov	r0, #0
 Disassembly of section alpha:
 
 0000eef0 <two_groups_needed_alu_pc>:
     eef0:	e3a00000 	mov	r0, #0
+
 Disassembly of section beta:
 
 00ffeef0 <three_groups_needed_alu_pc>:
Index: ld/testsuite/ld-arm/group-relocs.s
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/group-relocs.s,v
retrieving revision 1.2
diff -u -r1.2 group-relocs.s
--- ld/testsuite/ld-arm/group-relocs.s	24 Feb 2010 11:15:11 -0000	1.2
+++ ld/testsuite/ld-arm/group-relocs.s	14 Jul 2013 16:45:03 -0000
@@ -28,11 +28,14 @@
 
 	@ ALU, SB-relative
 
+	@ Instructions start at .text + 0x18
 	add	r0, r0, #:sb_g0:(one_group_needed_alu_sb)
 
-	add	r0, r15, #:sb_g0_nc:(two_groups_needed_alu_sb)
+	@ Instructions start at .text + 0x1c
+	add	r0, r0, #:sb_g0_nc:(two_groups_needed_alu_sb)
 	add	r0, r0, #:sb_g1:(two_groups_needed_alu_sb)
 
+	@ Instructions start at .text + 0x24
 	add	r0, r0, #:sb_g0_nc:(three_groups_needed_alu_sb)
 	add	r0, r0, #:sb_g1_nc:(three_groups_needed_alu_sb)
 	add	r0, r0, #:sb_g2:(three_groups_needed_alu_sb)
@@ -40,21 +43,24 @@
 	@ LDR, PC-relative
 
 	@ Instructions start at .text + 0x30
-	add	r0, r0, #:pc_g0_nc:(two_groups_needed_ldr_pc)
+	add	r0, pc, #:pc_g0_nc:(two_groups_needed_ldr_pc)
 	ldr	r1, [r0, #:pc_g1:(two_groups_needed_ldr_pc + 4)]
 
 	@ Instructions start at .text + 0x38
-	add	r0, r0, #:pc_g0_nc:(three_groups_needed_ldr_pc)
+	add	r0, pc, #:pc_g0_nc:(three_groups_needed_ldr_pc)
 	add	r0, r0, #:pc_g1_nc:(three_groups_needed_ldr_pc + 4)
 	ldr	r1, [r0, #:pc_g2:(three_groups_needed_ldr_pc + 8)]
 
 	@ LDR, SB-relative
 
+	@ Instructions start at .text + 0x44
 	ldr	r1, [r0, #:sb_g0:(one_group_needed_ldr_sb)]
 
+	@ Instructions start at .text + 0x48
 	add	r0, r0, #:sb_g0_nc:(two_groups_needed_ldr_sb)
 	ldr	r1, [r0, #:sb_g1:(two_groups_needed_ldr_sb)]
 
+	@ Instructions start at .text + 0x50
 	add	r0, r0, #:sb_g0_nc:(three_groups_needed_ldr_sb)
 	add	r0, r0, #:sb_g1_nc:(three_groups_needed_ldr_sb)
 	ldr	r1, [r0, #:sb_g2:(three_groups_needed_ldr_sb)]
@@ -62,24 +68,27 @@
 	@ LDRS, PC-relative
 
 	@ Instructions start at .text + 0x5c
-	ldrd	r2, [r0, #:pc_g0:(one_group_needed_ldrs_pc)]
+	ldrd	r2, [pc, #:pc_g0:(one_group_needed_ldrs_pc)]
 
 	@ Instructions start at .text + 0x60
-	add	r0, r0, #:pc_g0_nc:(two_groups_needed_ldrs_pc)
+	add	r0, pc, #:pc_g0_nc:(two_groups_needed_ldrs_pc)
 	ldrd	r2, [r0, #:pc_g1:(two_groups_needed_ldrs_pc + 4)]
 
 	@ Instructions start at .text + 0x68
-	add	r0, r0, #:pc_g0_nc:(three_groups_needed_ldrs_pc)
+	add	r0, pc, #:pc_g0_nc:(three_groups_needed_ldrs_pc)
 	add	r0, r0, #:pc_g1_nc:(three_groups_needed_ldrs_pc + 4)
 	ldrd	r2, [r0, #:pc_g2:(three_groups_needed_ldrs_pc + 8)]
 
 	@ LDRS, SB-relative
 
+	@ Instructions start at .text + 0x74
 	ldrd	r2, [r0, #:sb_g0:(one_group_needed_ldrs_sb)]
 
+	@ Instructions start at .text + 0x78
 	add	r0, r0, #:sb_g0_nc:(two_groups_needed_ldrs_sb)
 	ldrd	r2, [r0, #:sb_g1:(two_groups_needed_ldrs_sb)]
 
+	@ Instructions start at .text + 0x80
 	add	r0, r0, #:sb_g0_nc:(three_groups_needed_ldrs_sb)
 	add	r0, r0, #:sb_g1_nc:(three_groups_needed_ldrs_sb)
 	ldrd	r2, [r0, #:sb_g2:(three_groups_needed_ldrs_sb)]
@@ -87,24 +96,27 @@
 	@ LDC, PC-relative
 
 	@ Instructions start at .text + 0x8c
-	ldc	0, c0, [r0, #:pc_g0:(one_group_needed_ldc_pc)]
+	ldc	0, c0, [pc, #:pc_g0:(one_group_needed_ldc_pc)]
 
 	@ Instructions start at .text + 0x90
-	add	r0, r0, #:pc_g0_nc:(two_groups_needed_ldc_pc)
+	add	r0, pc, #:pc_g0_nc:(two_groups_needed_ldc_pc)
 	ldc	0, c0, [r0, #:pc_g1:(two_groups_needed_ldc_pc + 4)]
 
 	@ Instructions start at .text + 0x98
-	add	r0, r0, #:pc_g0_nc:(three_groups_needed_ldc_pc)
+	add	r0, pc, #:pc_g0_nc:(three_groups_needed_ldc_pc)
 	add	r0, r0, #:pc_g1_nc:(three_groups_needed_ldc_pc + 4)
 	ldc	0, c0, [r0, #:pc_g2:(three_groups_needed_ldc_pc + 8)]
 
 	@ LDC, SB-relative
 
+	@ Instructions start at .text + 0xa4
 	ldc	0, c0, [r0, #:sb_g0:(one_group_needed_ldc_sb)]
 
+	@ Instructions start at .text + 0xa8
 	add	r0, r0, #:sb_g0_nc:(two_groups_needed_ldc_sb)
 	ldc	0, c0, [r0, #:sb_g1:(two_groups_needed_ldc_sb)]
 
+	@ Instructions start at .text + 0xb0
 	add	r0, r0, #:sb_g0_nc:(three_groups_needed_ldc_sb)
 	add	r0, r0, #:sb_g1_nc:(three_groups_needed_ldc_sb)
 	ldc	0, c0, [r0, #:sb_g2:(three_groups_needed_ldc_sb)]
@@ -116,24 +128,33 @@
 one_group_needed_ldc_pc:
 	mov	r0, #0
 
-@ We will place the section zero at 0x0.
+@ We will place the section .data at 0x03000000
 
-	.section zero, "x"
+	.data
 
+	.word 0, 0, 0
 one_group_needed_alu_sb:
 one_group_needed_ldr_sb:
 one_group_needed_ldrs_sb:
 one_group_needed_ldc_sb:
-	mov	r0, #0
+	.word 1				@ Offset 0xc
+	.fill 0xeef0 - 16, 1, 0
+two_groups_needed_alu_sb:
+two_groups_needed_ldr_sb:
+two_groups_needed_ldrs_sb:
+two_groups_needed_ldc_sb:
+	.word 2				@ Offset 0xeef0
+	.fill 0xffeef0 - 0xeef0 - 4, 1, 0
+three_groups_needed_alu_sb:
+three_groups_needed_ldr_sb:
+three_groups_needed_ldrs_sb:
+three_groups_needed_ldc_sb:
+	.word 3				@ Offset 0xffeef0
 
 @ We will place the section alpha at 0xeef0.
 
 	.section alpha, "x"
 
-two_groups_needed_alu_sb:
-two_groups_needed_ldr_sb:
-two_groups_needed_ldrs_sb:
-two_groups_needed_ldc_sb:
 two_groups_needed_alu_pc:
 two_groups_needed_ldr_pc:
 two_groups_needed_ldrs_pc:
@@ -144,10 +165,6 @@
 
 	.section beta, "x"
 
-three_groups_needed_alu_sb:
-three_groups_needed_ldr_sb:
-three_groups_needed_ldrs_sb:
-three_groups_needed_ldc_sb:
 three_groups_needed_alu_pc:
 three_groups_needed_ldr_pc:
 three_groups_needed_ldrs_pc:


More information about the Binutils mailing list