This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR ld/17277: bogus dynamic relocs and TEXTREL for ARM PC-relative relocs


I ran into another case where the linker is generating R_ARM_NONE relocs in
the dynamic reloc section, and a TEXTREL marker that is a lie.  Unlike the
case with .eh_frame, I can see no excuses whatsoever for these ones--there
is nothing "not yet known" about the situation at all (that I know of).  I
also seem to have found an easy fix, and it doesn't cause any regressions
on 'make check-ld' for --target=arm-linux-gnueabi.  But I'm far from
confident that it is definitely correct in all cases, so I seek wisdom.
(If it's incorrect, then please help me understand how to add test cases
that will be broken by my change.)

In my actual situation, the references (movw/movt pair using
"data_symbol-local_pc_symbol" sort of expression) are in one file and the
definition of "data_symbol" in another.  But just the cross-section
reference seems to do it, whether or not the two sections come from the
same input file.  So I made the test case simpler to write by having just
one input file.

OK for trunk and 2.24?


Thanks,
Roland


bfd/
2014-08-15  Roland McGrath  <mcgrathr@google.com>

	PR ld/17277
	* elf32-arm.c (elf32_arm_check_relocs): Increment P->pc_count for
	all reloc types with pc_relative set in the howto, not just for
	R_ARM_REL32 and R_ARM_REL32_NOI.
	(allocate_dynrelocs_for_symbol): Update comment.

ld/testsuite/
2014-08-15  Roland McGrath  <mcgrathr@google.com>

	PR ld/17277
	* ld-arm/pcrel-shared.s: New file.
	* ld-arm/pcrel-shared.rd: New file.
	* ld-arm/arm-elf.exp (armelftests_common): Add it.

--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -12972,7 +12972,7 @@ elf32_arm_check_relocs (bfd *abfd, struct
bfd_link_info *info,
 	      p->pc_count = 0;
 	    }

-	  if (r_type == R_ARM_REL32 || r_type == R_ARM_REL32_NOI)
+	  if (elf32_arm_howto_from_type (r_type)->pc_relative)
 	    p->pc_count += 1;
 	  p->count += 1;
 	}
@@ -13551,12 +13551,12 @@ allocate_dynrelocs_for_symbol (struct
elf_link_hash_entry *h, void * inf)

   if (info->shared || htab->root.is_relocatable_executable)
     {
-      /* The only relocs that use pc_count are R_ARM_REL32 and
-	 R_ARM_REL32_NOI, which will appear on something like
-	 ".long foo - .".  We want calls to protected symbols to resolve
-	 directly to the function rather than going via the plt.  If people
-	 want function pointer comparisons to work as expected then they
-	 should avoid writing assembly like ".long foo - .".  */
+      /* Relocs that use pc_count are PC-relative forms, which will appear
+	 on something like ".long foo - ." or "movw REG, foo - .".  We want
+	 calls to protected symbols to resolve directly to the function
+	 rather than going via the plt.  If people want function pointer
+	 comparisons to work as expected then they should avoid writing
+	 assembly like ".long foo - .".  */
       if (SYMBOL_CALLS_LOCAL (info, h))
 	{
 	  struct elf_dyn_relocs **pp;
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -203,6 +203,10 @@ set armelftests_common {
     {"EABI ABI flags ld -r" "-r" "" "-mfloat-abi=soft -meabi=5"
{eabi-soft-float.s}
      {{readelf -h eabi-soft-float-r.d}}
      "eabi-soft-float-r.o"}
+    {"PC-relative in -shared" "-shared" ""
+     "" {pcrel-shared.s}
+     {{readelf -dr pcrel-shared.rd}}
+     "pcrel-shared.so"}
 }

 set armelftests_nonacl {
--- /dev/null
+++ b/ld/testsuite/ld-arm/pcrel-shared.rd
@@ -0,0 +1,16 @@
+Dynamic section at offset 0x[0-9a-f]+ contains \d+ entries:
+\s+Tag\s+Type\s+Name/Value
+\s*0x[0-9a-f]+ \(HASH\).*
+\s*0x[0-9a-f]+ \(STRTAB\).*
+\s*0x[0-9a-f]+ \(SYMTAB\).*
+\s*0x[0-9a-f]+ \(STRSZ\).*
+\s*0x[0-9a-f]+ \(SYMENT\).*
+# Specifically want *not* to see here:
+# (REL)
+# (RELSZ)
+# (RELENT)
+# (TEXTREL)
+#...
+\s*0x[0-9a-f]+ \(NULL\).*
+
+There are no relocations in this file\.
--- /dev/null
+++ b/ld/testsuite/ld-arm/pcrel-shared.s
@@ -0,0 +1,20 @@
+# This tests PR ld/17277, wherein ld -shared for cross-section PC-relative
+# relocs (other than plain R_ARM_REL32, as in data) produce bogus dynamic
+# relocs and TEXTREL markers.
+
+	.syntax unified
+	.arm
+	.arch armv7-a
+
+	.text
+	.globl foo
+	.type foo,%function
+foo:	movw r0, #:lower16:symbol - 1f - 8
+	movt r0, #:upper16:symbol - 1f - 8
+1:	add r0, pc
+	bx lr
+
+.data
+	.globl symbol
+	.hidden symbol
+symbol:	.long 22


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]