This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[ARM] Relocation counting during check_relocs
- From: Richard Sandiford <richard dot sandiford at linaro dot org>
- To: binutils at sourceware dot org
- Cc: Nick Clifton <nickc at redhat dot com>, Richard Earnshaw <rearnsha at arm dot com>, Paul Brook <paul at codesourcery dot com>
- Date: Wed, 15 Dec 2010 10:56:40 +0000
- Subject: [ARM] Relocation counting during check_relocs
When linked with -shared, this testcase:
.globl foo
foo:
mov pc,lr
.data
.word foo-.
.word foo-.+0x100
produces two dynamic R_ARM_REL32s against the data section, but this one:
.globl foo
foo:
mov pc,lr
bal foo(PLT)
.data
.word foo-.
.word foo-.+0x100
gives the error:
(.data+0x0): dangerous relocation: unsupported relocation
(.data+0x4): dangerous relocation: unsupported relocation
The problem is that elf32_arm_check_relocs only registers a relocation
for R_ARM_REL32 when h->needs_plt is false:
if ((info->shared || htab->root.is_relocatable_executable)
&& (sec->flags & SEC_ALLOC) != 0
&& ((r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI)
|| (h != NULL && ! h->needs_plt
&& (! info->symbolic || ! h->def_regular))))
But even if h->needs_plt is true, we will only resolve certain types
of relocation to the PLT. The local "needs_plt" variable says which
types those are, so I think we should be checking that instead.
I thought this might overcount for PIEs, where things like R_ARM_REL32
could in theory refer to the PLT and avoid a dynamic reloc. However,
it seems that we try to generate a dynamic reloc even there:
.text
.globl _start
_start:
bl foo(PLT)
.data
.word foo-.
(linked with -pie) so I think the patch is correct for that case too.
Emitting unnecessary relocs in the PIE case is a separate bug that
I'll try to fix if this patch is OK. Checking h->needs_plt isn't
enough even then, because we might decide to use a PLT after processing
the current reloc. I think the right fix is to include a PLT check
in the SYMBOL_CALLS_LOCAL code in elf32_arm_final_link_relocate
and allocate_dynrelocs.
Tested on arm-linux-gnueabi and arm-eabi. OK to install?
Richard
bfd/
* elf32-arm.c (elf32_arm_check_relocs): Check needs_plt rather than
h->needs_plt when deciding whether to record a possible dynamic reloc.
ld/testsuite/
* ld-arm/arm-rel32.s, ld-arm/arm-rel32.d: New testcase.
* ld-arm/arm-elf.exp: Run it.
Index: bfd/elf32-arm.c
===================================================================
--- bfd/elf32-arm.c 2010-12-14 15:52:50.000000000 +0000
+++ bfd/elf32-arm.c 2010-12-14 15:56:00.000000000 +0000
@@ -10946,7 +10946,7 @@ elf32_arm_check_relocs (bfd *abfd, struc
if ((info->shared || htab->root.is_relocatable_executable)
&& (sec->flags & SEC_ALLOC) != 0
&& ((r_type == R_ARM_ABS32 || r_type == R_ARM_ABS32_NOI)
- || (h != NULL && ! h->needs_plt
+ || (h != NULL && ! needs_plt
&& (! info->symbolic || ! h->def_regular))))
{
struct elf_dyn_relocs *p, **head;
Index: ld/testsuite/ld-arm/arm-rel32.s
===================================================================
--- /dev/null 2010-12-14 12:47:12.274544604 +0000
+++ ld/testsuite/ld-arm/arm-rel32.s 2010-12-14 15:56:00.000000000 +0000
@@ -0,0 +1,8 @@
+ .globl foo
+foo:
+ mov pc,lr
+ bal foo(PLT)
+
+ .data
+ .word foo-.
+ .word foo-.+0x100
Index: ld/testsuite/ld-arm/arm-rel32.d
===================================================================
--- /dev/null 2010-12-14 12:47:12.274544604 +0000
+++ ld/testsuite/ld-arm/arm-rel32.d 2010-12-14 15:56:00.000000000 +0000
@@ -0,0 +1,12 @@
+
+.*: file format .*
+
+DYNAMIC RELOCATION RECORDS
+OFFSET +TYPE +VALUE
+[^ ]+ R_ARM_REL32 +foo
+[^ ]+ R_ARM_REL32 +foo
+[^ ]+ R_ARM_JUMP_SLOT +foo
+
+
+Contents of section \.data:
+ [^ ]+ 00000000 00010000 .*
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
--- ld/testsuite/ld-arm/arm-elf.exp 2010-12-14 15:52:50.000000000 +0000
+++ ld/testsuite/ld-arm/arm-elf.exp 2010-12-14 15:56:11.000000000 +0000
@@ -126,6 +126,9 @@ set armelftests {
{"arm-rel31" "-static -T arm.ld" "" {arm-rel31.s}
{{objdump -s arm-rel31.d}}
"arm-rel31"}
+ {"arm-rel32" "-shared -T arm-dyn.ld" "" {arm-rel32.s}
+ {{objdump -Rsj.data arm-rel32.d}}
+ "arm-rel32"}
{"arm-call" "-static -T arm.ld" "-meabi=4" {arm-call1.s arm-call2.s}
{{objdump -d arm-call.d}}
"arm-call"}