summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddesh.poyarekar@arm.com>2020-09-11 09:18:11 +0530
committerLuis Machado <luis.machado@linaro.org>2020-10-20 15:04:23 -0300
commitfa6ca5e254bb95725389f8eb87cd426def4e23f1 (patch)
tree8fd16613754d909f407b2e12b82bcd54135395c1 /bfd
parent50e192f0f26433193ae7f82cbc7ec98109e4fb8f (diff)
downloadbinutils-gdb-fa6ca5e254bb95725389f8eb87cd426def4e23f1.tar.gz
[Morello] Capability support for exception headers
- Identify and mark C64 frames - Identify C64 registers including DDC. - Identify 'purecap' argument to .cfi_startproc for C64 frames - Emit 'C' in augmentation string for C64 frames - Recognise the 'C' in the CIE augmentation string when parsing exception headers Difference from LLVM: The llvm assembler only uses purecap to add C to the augmentation string. The GNU assembler on the other hand uses -march and validates that purecap is passed to .cfi_startproc only for -morello+c64. This means that for code compiled for A64, if llvm sees `.cfi_startproc purecap`, it sets 'C' whereas the GNU assembler flags an error. bfd/ChangeLog: 2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com> * elf-bfd.h (elf_backend_data): New callback elf_backend_eh_frame_augmentation_char. * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Use it. * elfnn-aarch64.c (elf64_aarch64_eh_frame_augmentation_char): New function. (elf_backend_eh_frame_augmentation_char): New macro. * elfxx-target.h [!elf_backend_eh_frame_augmentation_char]: Set elf_backend_eh_frame_augmentation_char to NULL. (elfNN_bed): Initialise elf_backend_eh_frame_augmentation_char. binutils/ChangeLog: 2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com> * dwarf.c (dwarf_regnames_aarch64): Add capability registers. gas/ChangeLog: 2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com> * config/tc-aarch64.c (REG_DW_CSP, REG_DW_CLR): New macros. (s_aarch64_cfi_b_key_frame): Adjust for new entry_extras struct. (tc_aarch64_frame_initial_instructions): Adjust for C64. (tc_aarch64_fde_entry_init_extra, tc_aarch64_cfi_startproc_exp): New functions. (tc_aarch64_regname_to_dw2regnum): Support capability registers. * config/tc-aarch64.h (fde_entry): Forward declaration. (eh_entry_extras): New struct. (tc_fde_entry_extras, tc_cie_entry_extras): Use it. (tc_fde_entry_init_extra): Set to tc_aarch64_fde_entry_init_extra. (tc_output_cie_extra): Emit 'C' for C64. (tc_cie_fde_equivalent_extra): Adjust for C64. (tc_cie_entry_init_extra): Likewise. (tc_cfi_startproc_exp): New macro. (tc_aarch64_cfi_startproc_exp, tc_aarch64_fde_entry_init_extra): New function declarations. * dw2gencfi.c (tc_cfi_startproc_exp): New macro. (dot_cfi_startproc): Use it. * testsuite/gas/aarch64/morello-eh.d: New test. * testsuite/gas/aarch64/morello-eh.s: New test.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog14
-rw-r--r--bfd/elf-bfd.h2
-rw-r--r--bfd/elf-eh-frame.c17
-rw-r--r--bfd/elfnn-aarch64.c11
-rw-r--r--bfd/elfxx-target.h4
5 files changed, 41 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 54abe00f310..e714ede5d33 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,19 @@
2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+ * elf-bfd.h (elf_backend_data): New callback
+ elf_backend_eh_frame_augmentation_char.
+ * elf-eh-frame.c (_bfd_elf_parse_eh_frame): Use it.
+ * elfnn-aarch64.c (elf64_aarch64_eh_frame_augmentation_char):
+ New function.
+ (elf_backend_eh_frame_augmentation_char): New macro.
+
+ * elfxx-target.h [!elf_backend_eh_frame_augmentation_char]:
+ Set elf_backend_eh_frame_augmentation_char to NULL.
+ (elfNN_bed): Initialise
+ elf_backend_eh_frame_augmentation_char.
+
+2020-10-20 Siddhesh Poyarekar <siddesh.poyarekar@arm.com>
+
* elfnn-aarch64.c (STUB_ENTRY_NAME): Add format specifier for
veneer type.
(C64_MAX_ADRP_IMM, C64_MIN_ADRP_IMM): New macros.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 98165af1335..f383cd8bf6e 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1390,6 +1390,8 @@ struct elf_backend_data
(bfd *, struct bfd_link_info *, asection *);
bfd_boolean (*elf_backend_can_make_lsda_relative_eh_frame)
(bfd *, struct bfd_link_info *, asection *);
+ bfd_boolean (*elf_backend_eh_frame_augmentation_char)
+ (char);
/* This function returns an encoding after computing the encoded
value (and storing it in ENCODED) for the given OFFSET into OSEC,
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 7a129b00f8d..54da9bec11f 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -597,6 +597,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
unsigned int num_cies;
unsigned int num_entries;
elf_gc_mark_hook_fn gc_mark_hook;
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
htab = elf_hash_table (info);
hdr_info = &htab->eh_info;
@@ -623,8 +624,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
it (it would need to use 64-bit .eh_frame format anyway). */
REQUIRE (sec->size == (unsigned int) sec->size);
- ptr_size = (get_elf_backend_data (abfd)
- ->elf_backend_eh_frame_address_size (abfd, sec));
+ ptr_size = bed->elf_backend_eh_frame_address_size (abfd, sec);
REQUIRE (ptr_size != 0);
/* Go through the section contents and work out how many FDEs and
@@ -692,7 +692,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
buf = ehbuf;
cie_count = 0;
- gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
+ gc_mark_hook = bed->gc_mark_hook;
while ((bfd_size_type) (buf - ehbuf) != sec->size)
{
char *aug;
@@ -840,8 +840,12 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
}
break;
default:
- /* Unrecognized augmentation. Better bail out. */
- goto free_no_table;
+ /* Unrecognized augmentation. Better bail out if the target
+ cannot recognised it. */
+ if (bed->elf_backend_eh_frame_augmentation_char == NULL
+ || (!bed->elf_backend_eh_frame_augmentation_char
+ (*(aug - 1))))
+ goto free_no_table;
}
}
this_inf->u.cie.aug_data_len
@@ -850,8 +854,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
/* For shared libraries, try to get rid of as many RELATIVE relocs
as possible. */
if (bfd_link_pic (info)
- && (get_elf_backend_data (abfd)
- ->elf_backend_can_make_relative_eh_frame
+ && (bed->elf_backend_can_make_relative_eh_frame
(abfd, info, sec)))
{
if ((cie->fde_encoding & 0x70) == DW_EH_PE_absptr)
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index bd7da1610a7..f1a43e18e0e 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -10934,6 +10934,14 @@ elfNN_aarch64_got_header_size (struct bfd_link_info *info)
return GOT_ENTRY_SIZE (htab) * GOT_RESERVED_HEADER_SLOTS;
}
+/* Identify the 'C' in the CIE augmentation string. */
+
+static bfd_boolean
+elf64_aarch64_eh_frame_augmentation_char (const char aug)
+{
+ return aug == 'C';
+}
+
/* We use this so we can override certain functions
(though currently we don't). */
@@ -11084,6 +11092,9 @@ const struct elf_size_info elfNN_aarch64_size_info =
#define elf_backend_got_elt_size \
elfNN_aarch64_got_elt_size
+#define elf_backend_eh_frame_augmentation_char \
+ elf64_aarch64_eh_frame_augmentation_char
+
#define elf_backend_can_refcount 1
#define elf_backend_can_gc_sections 1
#define elf_backend_plt_readonly 1
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index d527a604f0f..ad8322e1596 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -654,6 +654,9 @@
#ifndef elf_backend_can_make_lsda_relative_eh_frame
#define elf_backend_can_make_lsda_relative_eh_frame _bfd_elf_can_make_relative
#endif
+#ifndef elf_backend_eh_frame_augmentation_char
+#define elf_backend_eh_frame_augmentation_char NULL
+#endif
#ifndef elf_backend_encode_eh_address
#define elf_backend_encode_eh_address _bfd_elf_encode_eh_address
#endif
@@ -885,6 +888,7 @@ static struct elf_backend_data elfNN_bed =
elf_backend_eh_frame_address_size,
elf_backend_can_make_relative_eh_frame,
elf_backend_can_make_lsda_relative_eh_frame,
+ elf_backend_eh_frame_augmentation_char,
elf_backend_encode_eh_address,
elf_backend_write_section,
elf_backend_elfsym_local_is_section,