This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH, binutils/ARM] Fix ld --gc-section segfault with ARMv8-M Security Extensions entry function in absolute section
- From: Thomas Preudhomme <thomas dot preudhomme at foss dot arm dot com>
- To: binutils at sourceware dot org
- Date: Tue, 6 Sep 2016 14:49:47 +0100
- Subject: [PATCH, binutils/ARM] Fix ld --gc-section segfault with ARMv8-M Security Extensions entry function in absolute section
- Authentication-results: sourceware.org; auth=none
Hi,
As per the title, ld crashes when linking an object file with an ARMv8-M
Security Extensions entry function that is placed in the absolute section. The
reason for the crash is that elf32_arm_gc_mark_extra_sections marks section with
an entry function unconditionally. This fails with the absolute section since
the marking function check for information about other sections in the same
group which does not exist for the absolute section. The patch is simple: only
mark a section if not already mark, as done elsewhere in bfd.
A testcase is added and fails without the code change and succeeds with.
ChangeLog entries are as follow:
*** bfd/ChangeLog ***
2016-09-02 Thomas Preud'homme <thomas.preudhomme@arm.com>
* elf32-arm.c (elf32_arm_gc_mark_extra_sections): Only mark section
not already marked.
*** ld/ChangeLog ***
2016-09-02 Thomas Preud'homme <thomas.preudhomme@arm.com>
* testsuite/ld-arm/cmse-veneers.s: Add a test for ARMv8-M Security
Extensions entry functions in absolute section.
* testsuite/ld-arm/cmse-veneers.rd: Adapt expected output accordingly.
Regression testsuite when run for arm-none-eabi shows no regression.
Is this ok for the master branch?
Best regards,
Thomas
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 5275caef164c948f8b73abadf6fb80012e4ea2f2..6e68be1c09d3668e62aed9d6243de01fa23f8f2f 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -14906,7 +14906,8 @@ elf32_arm_gc_mark_extra_sections (struct bfd_link_info *info,
if (ARM_GET_SYM_CMSE_SPCL (cmse_hash->root.target_internal))
{
cmse_sec = cmse_hash->root.root.u.def.section;
- if (!_bfd_elf_gc_mark (info, cmse_sec, gc_mark_hook))
+ if (!cmse_sec->gc_mark &&
+ !_bfd_elf_gc_mark (info, cmse_sec, gc_mark_hook))
return FALSE;
}
}
diff --git a/ld/testsuite/ld-arm/cmse-veneers.rd b/ld/testsuite/ld-arm/cmse-veneers.rd
index 20fad961bd8803109c3cf57ef22e3b36da5b1500..2f0fa5f9472298650bba51bed2f23b3806fcb894 100644
--- a/ld/testsuite/ld-arm/cmse-veneers.rd
+++ b/ld/testsuite/ld-arm/cmse-veneers.rd
@@ -1,4 +1,6 @@
#...
+[0-9a-f]+ A abs_entry_fct
+#...
[0-9a-f]+ T glob_entry_fct
#...
[0-9a-f]+ T glob_entry_veneer1
diff --git a/ld/testsuite/ld-arm/cmse-veneers.s b/ld/testsuite/ld-arm/cmse-veneers.s
index d5c57f646a78c4736e4f084d8ad6aff7efea554f..8346888909cb5f9781e0dd3dce1d57c5988514e6 100644
--- a/ld/testsuite/ld-arm/cmse-veneers.s
+++ b/ld/testsuite/ld-arm/cmse-veneers.s
@@ -53,6 +53,16 @@ __acle_se_\name:
@ Valid setup for entry function without SG veneer
entry glob_entry_fct, function, global, entry_fct=nop
+ @ Valid setup for entry function with absolute address
+ .align 2
+ .global __acle_se_abs_entry_fct
+ .global abs_entry_fct
+ .type __acle_se_abs_entry_fct, %function
+ .type abs_entry_fct, %function
+__acle_se_abs_entry_fct = 0x10000
+abs_entry_fct = 0x10004
+ .size abs_entry_fct, 0
+ .size __acle_se_abs_entry_fct, 0
.else
@ Invalid setups for veneer generation (visibility)
entry loc_entry_veneer1, function, local