aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-arm.c
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@linaro.org>2019-07-02 13:09:02 +0000
committerChristophe Lyon <christophe.lyon@linaro.org>2019-07-02 13:09:02 +0000
commit4d83e8d97e3b15dcd7b5c58f4199e9f5bd6fca3d (patch)
treeea3ffc06faef177c6e90bc74851fcaf34023846a /bfd/elf32-arm.c
parentbb32413ff7247f5ac3685ca9075b3432bca69a82 (diff)
downloadgdb-4d83e8d97e3b15dcd7b5c58f4199e9f5bd6fca3d.zip
gdb-4d83e8d97e3b15dcd7b5c58f4199e9f5bd6fca3d.tar.gz
gdb-4d83e8d97e3b15dcd7b5c58f4199e9f5bd6fca3d.tar.bz2
PR ld/24709 [arm] linker crash and assertion failure with CMSE
As discussed in the PR, we do not support the case where CMSE stubs are inserted too far from their destination. This would require an intermediate long-branch stub, which is tricky in this context. Instead of crashing, this patch emit an error message and exits. 2019-07-02 Christophe Lyon <christophe.lyon@linaro.org> * bfd/elf32-arm.c (CMSE_STUB_NAME): New define. (elf32_arm_get_stub_entry): Do not try to emit long-branch stubs for CMSE stubs. (arm_dedicated_stub_output_section_name): Use CMSE_STUB_NAME. Change-Id: I6d4e1c0fdee6bb9f4b07e5e1b46700b5ba31c62e
Diffstat (limited to 'bfd/elf32-arm.c')
-rw-r--r--bfd/elf32-arm.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index fc7a41c..6b689769 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -2300,6 +2300,8 @@ typedef unsigned short int insn16;
#define CMSE_PREFIX "__acle_se_"
+#define CMSE_STUB_NAME ".gnu.sgstubs"
+
/* The name of the dynamic interpreter. This is put in the .interp
section. */
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
@@ -4583,6 +4585,27 @@ elf32_arm_get_stub_entry (const asection *input_section,
if ((input_section->flags & SEC_CODE) == 0)
return NULL;
+ /* If the input section is the CMSE stubs one and it needs a long
+ branch stub to reach it's final destination, give up with an
+ error message: this is not supported. See PR ld/24709. */
+ if (!strncmp (input_section->name, CMSE_STUB_NAME, strlen(CMSE_STUB_NAME)))
+ {
+ bfd *output_bfd = htab->obfd;
+ asection *out_sec = bfd_get_section_by_name (output_bfd, CMSE_STUB_NAME);
+
+ _bfd_error_handler (_("ERROR: CMSE stub (%s section) too far "
+ "(%#" PRIx64 ") from destination (%#" PRIx64 ")"),
+ CMSE_STUB_NAME,
+ (uint64_t)out_sec->output_section->vma
+ + out_sec->output_offset,
+ (uint64_t)sym_sec->output_section->vma
+ + sym_sec->output_offset
+ + h->root.root.u.def.value);
+ /* Exit, rather than leave incompletely processed
+ relocations. */
+ xexit(1);
+ }
+
/* If this input section is part of a group of sections sharing one
stub section, then use the id of the first section in the group.
Stub names need to include a section id, as there may well be
@@ -4676,7 +4699,7 @@ arm_dedicated_stub_output_section_name (enum elf32_arm_stub_type stub_type)
switch (stub_type)
{
case arm_stub_cmse_branch_thumb_only:
- return ".gnu.sgstubs";
+ return CMSE_STUB_NAME;
default:
BFD_ASSERT (!arm_dedicated_stub_output_section_required (stub_type));