This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Fix PR ld/17277: bogus dynamic relocs and TEXTREL for ARM PC-relative relocs
- From: Roland McGrath <mcgrathr at google dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Fri, 15 Aug 2014 15:04:51 -0700
- Subject: [PATCH] Fix PR ld/17277: bogus dynamic relocs and TEXTREL for ARM PC-relative relocs
- Authentication-results: sourceware.org; auth=none
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