diff options
author | Siddhesh Poyarekar <siddesh.poyarekar@arm.com> | 2020-09-11 09:18:11 +0530 |
---|---|---|
committer | Luis Machado <luis.machado@linaro.org> | 2020-10-20 15:04:23 -0300 |
commit | fa6ca5e254bb95725389f8eb87cd426def4e23f1 (patch) | |
tree | 8fd16613754d909f407b2e12b82bcd54135395c1 /bfd | |
parent | 50e192f0f26433193ae7f82cbc7ec98109e4fb8f (diff) | |
download | binutils-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/ChangeLog | 14 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 2 | ||||
-rw-r--r-- | bfd/elf-eh-frame.c | 17 | ||||
-rw-r--r-- | bfd/elfnn-aarch64.c | 11 | ||||
-rw-r--r-- | bfd/elfxx-target.h | 4 |
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, |