diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/ChangeLog | 168 | ||||
-rw-r--r-- | libgcc/Makefile.in | 6 | ||||
-rw-r--r-- | libgcc/config.host | 29 | ||||
-rw-r--r-- | libgcc/config/aarch64/aarch64-asm.h | 4 | ||||
-rw-r--r-- | libgcc/config/aarch64/aarch64-unwind-def.h | 41 | ||||
-rw-r--r-- | libgcc/config/aarch64/aarch64-unwind.h | 152 | ||||
-rw-r--r-- | libgcc/config/i386/t-darwin | 3 | ||||
-rw-r--r-- | libgcc/config/mips/lib1funcs.S | 2 | ||||
-rw-r--r-- | libgcc/config/no-unwind.h | 3 | ||||
-rw-r--r-- | libgcc/config/riscv/save-restore.S | 7 | ||||
-rw-r--r-- | libgcc/config/rs6000/t-darwin | 3 | ||||
-rw-r--r-- | libgcc/config/t-darwin-libgccs1 | 3 | ||||
-rw-r--r-- | libgcc/config/t-darwin-min-11 | 3 | ||||
-rwxr-xr-x | libgcc/configure | 2 | ||||
-rw-r--r-- | libgcc/configure.ac | 1 | ||||
-rw-r--r-- | libgcc/gthr-posix.h | 136 | ||||
-rw-r--r-- | libgcc/gthr-single.h | 45 | ||||
-rw-r--r-- | libgcc/unwind-dw2-execute_cfa.h | 26 | ||||
-rw-r--r-- | libgcc/unwind-dw2.c | 24 | ||||
-rw-r--r-- | libgcc/unwind-dw2.h | 19 |
20 files changed, 544 insertions, 133 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 7c24757..518cef3 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,171 @@ +2024-09-27 Matthieu Longo <matthieu.longo@arm.com> + + * config/aarch64/aarch64-unwind.h: Fix header path. + +2024-09-27 Mark Mentovai <mark@mentovai.com> + + PR target/116809 + * config.host: Don't build legacy libgcc_s.1 on macOS 14. + +2024-09-27 Jim Lin <jim@andestech.com> + + * config/riscv/save-restore.S: Check with __riscv_abi_rve rather than + __riscv_32e. + +2024-09-26 Nathaniel Shead <nathanieloshead@gmail.com> + + PR libstdc++/115126 + * gthr-posix.h (__GTHREAD_ALWAYS_INLINE): New macro. + (__GTHREAD_INLINE): New macro. + (__gthread_active): Convert from variable to (hidden) function. + (__gthread_active_p): Mark as __GTHREAD_INLINE instead of + static; make visibility("hidden") when it has a static local + variable. + (__gthread_trigger): Mark as __GTHREAD_INLINE instead of static. + (__gthread_create): Likewise. + (__gthread_join): Likewise. + (__gthread_detach): Likewise. + (__gthread_equal): Likewise. + (__gthread_self): Likewise. + (__gthread_yield): Likewise. + (__gthread_once): Likewise. + (__gthread_key_create): Likewise. + (__gthread_key_delete): Likewise. + (__gthread_getspecific): Likewise. + (__gthread_setspecific): Likewise. + (__gthread_mutex_init_function): Likewise. + (__gthread_mutex_destroy): Likewise. + (__gthread_mutex_lock): Likewise. + (__gthread_mutex_trylock): Likewise. + (__gthread_mutex_timedlock): Likewise. + (__gthread_mutex_unlock): Likewise. + (__gthread_recursive_mutex_init_function): Likewise. + (__gthread_recursive_mutex_lock): Likewise. + (__gthread_recursive_mutex_trylock): Likewise. + (__gthread_recursive_mutex_timedlock): Likewise. + (__gthread_recursive_mutex_unlock): Likewise. + (__gthread_recursive_mutex_destroy): Likewise. + (__gthread_cond_init_function): Likewise. + (__gthread_cond_broadcast): Likewise. + (__gthread_cond_signal): Likewise. + (__gthread_cond_wait): Likewise. + (__gthread_cond_timedwait): Likewise. + (__gthread_cond_wait_recursive): Likewise. + (__gthread_cond_destroy): Likewise. + (__gthread_rwlock_rdlock): Likewise. + (__gthread_rwlock_tryrdlock): Likewise. + (__gthread_rwlock_wrlock): Likewise. + (__gthread_rwlock_trywrlock): Likewise. + (__gthread_rwlock_unlock): Likewise. + * gthr-single.h: (__GTHREAD_ALWAYS_INLINE): New macro. + (__GTHREAD_INLINE): New macro. + (__gthread_active_p): Mark as __GTHREAD_INLINE instead of static. + (__gthread_once): Likewise. + (__gthread_key_create): Likewise. + (__gthread_key_delete): Likewise. + (__gthread_getspecific): Likewise. + (__gthread_setspecific): Likewise. + (__gthread_mutex_destroy): Likewise. + (__gthread_mutex_lock): Likewise. + (__gthread_mutex_trylock): Likewise. + (__gthread_mutex_unlock): Likewise. + (__gthread_recursive_mutex_lock): Likewise. + (__gthread_recursive_mutex_trylock): Likewise. + (__gthread_recursive_mutex_unlock): Likewise. + (__gthread_recursive_mutex_destroy): Likewise. + +2024-09-24 Iain Sandoe <iain@sandoe.co.uk> + + PR target/116809 + * config.host: Build legacy libgcc_s.1 on hosts before macOS 15. + * config/i386/t-darwin: Remove reference to legacy libgcc_s.1 + * config/rs6000/t-darwin: Likewise. + * config/t-darwin-libgccs1: New file. + +2024-09-23 Matthieu Longo <matthieu.longo@arm.com> + + * config/aarch64/aarch64-asm.h (PACIASP): Replace SPARC CFI + directive by AArch64 one. + (AUTIASP): Same. + +2024-09-23 Matthieu Longo <matthieu.longo@arm.com> + + * Makefile.in: New target for symbolic link to md-unwind-def.h + * config.host: New parameter md_unwind_def_header. Set it to + aarch64/aarch64-unwind-def.h for AArch64 targets, or no-unwind.h + by default. + * config/aarch64/aarch64-unwind.h + (aarch64_pointer_auth_key): Move to aarch64-unwind-def.h + (aarch64_cie_aug_handler): Update. + (aarch64_arch_extension_frame_init): Update. + (aarch64_demangle_return_addr): Update. + * configure.ac: New substitute variable md_unwind_def_header. + * unwind-dw2.h (defined): MD_ARCH_FRAME_STATE_T. + * config/aarch64/aarch64-unwind-def.h: New file. + * configure: Regenerate. + * config/no-unwind.h: Updated comment + +2024-09-23 Matthieu Longo <matthieu.longo@arm.com> + + * config/aarch64/aarch64-unwind.h + (MD_FRAME_LOCAL_REGISTER_P): new handler checking whether a register + from the current context needs to be skipped before installation into + the target context. + (aarch64_frame_local_register): Likewise. + * unwind-dw2.c (uw_install_context_1): use MD_FRAME_LOCAL_REGISTER_P. + +2024-09-23 Matthieu Longo <matthieu.longo@arm.com> + + * config/aarch64/aarch64-unwind.h + (AARCH64_DWARF_RA_STATE_MASK): The mask for RA state register. + (aarch64_ra_signing_method_t): The diversifiers used to sign a + function's return address. + (aarch64_pointer_auth_key): The key used to sign a function's + return address. + (aarch64_cie_signed_with_b_key): Deleted as the signing key is + available now in _Unwind_FrameState. + (MD_ARCH_EXTENSION_CIE_AUG_HANDLER): New CIE augmentation string + handler for architecture extensions. + (MD_ARCH_EXTENSION_FRAME_INIT): New architecture-extension + initialization routine for DWARF frame state and context before + execution of DWARF instructions. + (aarch64_context_ra_state_get): Read RA state register from CONTEXT. + (aarch64_ra_state_get): Read RA state register from FS. + (aarch64_ra_state_set): Write RA state register into FS. + (aarch64_ra_state_toggle): Toggle RA state register in FS. + (aarch64_cie_aug_handler): Handler AArch64 augmentation strings. + (aarch64_arch_extension_frame_init): Initialize defaults for the + signing key (PAUTH_KEY_A), and RA state register (RA_no_signing). + (aarch64_demangle_return_addr): Rely on the frame registers and + the signing_key attribute in _Unwind_FrameState. + * unwind-dw2-execute_cfa.h: + Use the right alias DW_CFA_AARCH64_negate_ra_state for __aarch64__ + instead of DW_CFA_GNU_window_save. + (DW_CFA_AARCH64_negate_ra_state): Save the signing method in RA + state register. Toggle RA state register without resetting 'how' + to REG_UNSAVED. + * unwind-dw2.c: + (extract_cie_info): Save the signing key in the current + _Unwind_FrameState while parsing the augmentation data. + (uw_frame_state_for): Reset some attributes related to architecture + extensions in _Unwind_FrameState. + (uw_update_context): Move authentication code to AArch64 unwinding. + * unwind-dw2.h (enum register_rule): Give a name to the existing + enum for the register rules, and replace 'unsigned char' by 'enum + register_rule' to facilitate debugging in GDB. + (_Unwind_FrameState): Add a new architecture-extension attribute + to store the signing key. + +2024-09-22 Iain Sandoe <iain@sandoe.co.uk> + + * config.host: From macOS 11, limit earliest macOS support + to macOS 11. + * config/t-darwin-min-11: New file. + +2024-08-27 YunQiang Su <syq@gcc.gnu.org> + + * config/mips/lib1funcs.S: Includes mips16.S. + 2024-06-10 Jan Beulich <jbeulich@suse.com> * config/aarch64/cpuinfo.c: Provide AT_HWCAP2. diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in index 0e46e9e..ffc45f2 100644 --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -47,6 +47,7 @@ with_aix_soname = @with_aix_soname@ solaris_ld_v2_maps = @solaris_ld_v2_maps@ enable_execute_stack = @enable_execute_stack@ unwind_header = @unwind_header@ +md_unwind_def_header = @md_unwind_def_header@ md_unwind_header = @md_unwind_header@ sfp_machine_header = @sfp_machine_header@ thread_header = @thread_header@ @@ -358,13 +359,16 @@ SHLIBUNWIND_INSTALL = # Create links to files specified in config.host. -LIBGCC_LINKS = enable-execute-stack.c unwind.h md-unwind-support.h \ +LIBGCC_LINKS = enable-execute-stack.c \ + unwind.h md-unwind-def.h md-unwind-support.h \ sfp-machine.h gthr-default.h enable-execute-stack.c: $(srcdir)/$(enable_execute_stack) -$(LN_S) $< $@ unwind.h: $(srcdir)/$(unwind_header) -$(LN_S) $< $@ +md-unwind-def.h: $(srcdir)/config/$(md_unwind_def_header) + -$(LN_S) $< $@ md-unwind-support.h: $(srcdir)/config/$(md_unwind_header) -$(LN_S) $< $@ sfp-machine.h: $(srcdir)/config/$(sfp_machine_header) diff --git a/libgcc/config.host b/libgcc/config.host index 9fae51d..fa001c5 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -51,8 +51,10 @@ # If either is set, EXTRA_PARTS and # EXTRA_MULTILIB_PARTS inherited from the GCC # subdirectory will be ignored. -# md_unwind_header The name of a header file defining -# MD_FALLBACK_FRAME_STATE_FOR. +# md_unwind_def_header The name of a header file defining architecture +# -specific frame information types for unwinding. +# md_unwind_header The name of a header file defining architecture +# -specific handlers used in the unwinder. # sfp_machine_header The name of a sfp-machine.h header file for soft-fp. # Defaults to "$cpu_type/sfp-machine.h" if it exists, # no-sfp-machine.h otherwise. @@ -72,6 +74,7 @@ extra_parts= tmake_file= tm_file= tm_define= +md_unwind_def_header=no-unwind.h md_unwind_header=no-unwind.h unwind_header=unwind-generic.h @@ -236,19 +239,25 @@ case ${host} in esac tmake_file="$tmake_file t-slibgcc-darwin" case ${host} in - *-*-darwin1[89]* | *-*-darwin2* ) - tmake_file="t-darwin-min-8 $tmake_file" + x86_64-*-darwin2[0-2]*) + tmake_file="t-darwin-min-11 t-darwin-libgccs1 $tmake_file" + ;; + *-*-darwin2*) + tmake_file="t-darwin-min-11 $tmake_file" + ;; + *-*-darwin1[89]*) + tmake_file="t-darwin-min-8 t-darwin-libgccs1 $tmake_file" ;; *-*-darwin9* | *-*-darwin1[0-7]*) - tmake_file="t-darwin-min-5 $tmake_file" + tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file" ;; *-*-darwin[4-8]*) - tmake_file="t-darwin-min-1 $tmake_file" + tmake_file="t-darwin-min-1 t-darwin-libgccs1 $tmake_file" ;; *) # Fall back to configuring for the oldest system known to work with # all archs and the current sources. - tmake_file="t-darwin-min-5 $tmake_file" + tmake_file="t-darwin-min-5 t-darwin-libgccs1 $tmake_file" echo "Warning: libgcc configured to support macOS 10.5" 1>&2 ;; esac @@ -403,6 +412,7 @@ aarch64*-*-elf | aarch64*-*-rtems*) tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" tmake_file="${tmake_file} t-dfprules" + md_unwind_def_header=aarch64/aarch64-unwind-def.h md_unwind_header=aarch64/aarch64-unwind.h ;; aarch64*-*-freebsd*) @@ -411,6 +421,7 @@ aarch64*-*-freebsd*) tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" tmake_file="${tmake_file} t-dfprules" + md_unwind_def_header=aarch64/aarch64-unwind-def.h md_unwind_header=aarch64/freebsd-unwind.h ;; aarch64*-*-netbsd*) @@ -418,6 +429,7 @@ aarch64*-*-netbsd*) tmake_file="${tmake_file} ${cpu_type}/t-aarch64" tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" tmake_file="${tmake_file} t-dfprules" + md_unwind_def_header=aarch64/aarch64-unwind-def.h md_unwind_header=aarch64/aarch64-unwind.h ;; aarch64*-*-fuchsia*) @@ -428,6 +440,7 @@ aarch64*-*-fuchsia*) ;; aarch64*-*-linux*) extra_parts="$extra_parts crtfastmath.o" + md_unwind_def_header=aarch64/aarch64-unwind-def.h md_unwind_header=aarch64/linux-unwind.h tmake_file="${tmake_file} ${cpu_type}/t-aarch64" tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" @@ -437,6 +450,7 @@ aarch64*-*-linux*) ;; aarch64*-*-gnu*) extra_parts="$extra_parts crtfastmath.o" + md_unwind_def_header=aarch64/aarch64-unwind-def.h md_unwind_header=aarch64/gnu-unwind.h tmake_file="${tmake_file} ${cpu_type}/t-aarch64" tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" @@ -446,6 +460,7 @@ aarch64*-*-gnu*) ;; aarch64*-*-vxworks7*) extra_parts="$extra_parts crtfastmath.o" + md_unwind_def_header=aarch64/aarch64-unwind-def.h md_unwind_header=aarch64/aarch64-unwind.h tmake_file="${tmake_file} ${cpu_type}/t-aarch64" tmake_file="${tmake_file} ${cpu_type}/t-lse" diff --git a/libgcc/config/aarch64/aarch64-asm.h b/libgcc/config/aarch64/aarch64-asm.h index 83c2e59..d8ab91d 100644 --- a/libgcc/config/aarch64/aarch64-asm.h +++ b/libgcc/config/aarch64/aarch64-asm.h @@ -50,8 +50,8 @@ #if __ARM_FEATURE_PAC_DEFAULT & 3 # define PAC_FLAG FEATURE_1_PAC -# define PACIASP hint 25; .cfi_window_save -# define AUTIASP hint 29; .cfi_window_save +# define PACIASP hint 25; .cfi_negate_ra_state +# define AUTIASP hint 29; .cfi_negate_ra_state #else # define PAC_FLAG 0 # define PACIASP diff --git a/libgcc/config/aarch64/aarch64-unwind-def.h b/libgcc/config/aarch64/aarch64-unwind-def.h new file mode 100644 index 0000000..c84ec3e --- /dev/null +++ b/libgcc/config/aarch64/aarch64-unwind-def.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2024 Free Software Foundation, Inc. + Contributed by Arm Ltd. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +<http://www.gnu.org/licenses/>. */ + +#if !defined (AARCH64_UNWIND_DEF_H) && !defined (__ILP32__) +#define AARCH64_UNWIND_DEF_H + +/* The key used to sign a function's return address. */ +typedef enum { + AARCH64_PAUTH_KEY_A, + AARCH64_PAUTH_KEY_B, +} __attribute__((packed)) aarch64_pointer_auth_key; + +typedef struct +{ + aarch64_pointer_auth_key signing_key; +} _AArch64Ext_Unwind_FrameState; + +#define MD_ARCH_FRAME_STATE_T _AArch64Ext_Unwind_FrameState + +#endif /* defined AARCH64_UNWIND_DEF_H && defined __ILP32__ */ diff --git a/libgcc/config/aarch64/aarch64-unwind.h b/libgcc/config/aarch64/aarch64-unwind.h index daf9662..4d36f0b 100644 --- a/libgcc/config/aarch64/aarch64-unwind.h +++ b/libgcc/config/aarch64/aarch64-unwind.h @@ -25,52 +25,152 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #if !defined (AARCH64_UNWIND_H) && !defined (__ILP32__) #define AARCH64_UNWIND_H -#define DWARF_REGNUM_AARCH64_RA_STATE 34 +#include "config/aarch64/aarch64-unwind-def.h" + +#include "ansidecl.h" +#include <stdbool.h> + +#define AARCH64_DWARF_REGNUM_RA_STATE 34 +#define AARCH64_DWARF_RA_STATE_MASK 0x1 + +/* The diversifiers used to sign a function's return address. */ +typedef enum +{ + aarch64_ra_no_signing = 0x0, + aarch64_ra_signing_sp = 0x1, +} __attribute__((packed)) aarch64_ra_signing_method_t; + +#define MD_ARCH_EXTENSION_CIE_AUG_HANDLER(fs, aug) \ + aarch64_cie_aug_handler (fs, aug) + +#define MD_ARCH_EXTENSION_FRAME_INIT(context, fs) \ + aarch64_arch_extension_frame_init (context, fs) #define MD_DEMANGLE_RETURN_ADDR(context, fs, addr) \ aarch64_demangle_return_addr (context, fs, addr) -static inline int -aarch64_cie_signed_with_b_key (struct _Unwind_Context *context) +#define MD_FRAME_LOCAL_REGISTER_P(reg) \ + aarch64_frame_local_register (reg) + +static inline aarch64_ra_signing_method_t +aarch64_context_ra_state_get (struct _Unwind_Context *context) { - const struct dwarf_fde *fde = _Unwind_Find_FDE (context->bases.func, - &context->bases); - if (fde != NULL) + const int index = AARCH64_DWARF_REGNUM_RA_STATE; + return _Unwind_GetGR (context, index) & AARCH64_DWARF_RA_STATE_MASK; +} + +static inline aarch64_ra_signing_method_t +aarch64_fs_ra_state_get (_Unwind_FrameState const *fs) +{ + const int index = AARCH64_DWARF_REGNUM_RA_STATE; + return fs->regs.reg[index].loc.offset & AARCH64_DWARF_RA_STATE_MASK; +} + +static inline void +aarch64_fs_ra_state_set (_Unwind_FrameState *fs, + aarch64_ra_signing_method_t signing_method) +{ + fs->regs.reg[AARCH64_DWARF_REGNUM_RA_STATE].loc.offset = signing_method; +} + +static inline void +aarch64_fs_ra_state_toggle (_Unwind_FrameState *fs) +{ + /* /!\ Mixing DW_CFA_val_expression with DW_CFA_AARCH64_negate_ra_state will + result in undefined behavior (likely an unwinding failure), as the + chronology of the DWARF directives will be broken. */ + gcc_assert (fs->regs.how[AARCH64_DWARF_REGNUM_RA_STATE] == REG_ARCHEXT); + + aarch64_ra_signing_method_t signing_method = aarch64_fs_ra_state_get (fs); + gcc_assert (signing_method == aarch64_ra_no_signing + || signing_method == aarch64_ra_signing_sp); + aarch64_fs_ra_state_set (fs, (signing_method == aarch64_ra_no_signing) + ? aarch64_ra_signing_sp + : aarch64_ra_no_signing); +} + +/* CIE handler for custom augmentation string. */ +static inline bool +aarch64_cie_aug_handler (_Unwind_FrameState *fs, unsigned char aug) +{ + /* AArch64 B-key pointer authentication. */ + if (aug == 'B') { - const struct dwarf_cie *cie = get_cie (fde); - if (cie != NULL) - { - const unsigned char *aug_str = cie->augmentation; - return __builtin_strchr ((const char *) aug_str, - 'B') == NULL ? 0 : 1; - } + fs->regs.arch_fs.signing_key = AARCH64_PAUTH_KEY_B; + return true; } - return 0; + return false; +} + +/* At the entrance of a new frame, some cached information from the CIE/FDE, + and registers values related to architectural extensions require a default + initialization. + If any of those values related to architecture extensions had to be saved + for the next frame, it should be done via the architecture extensions handler + MD_FROB_UPDATE_CONTEXT in uw_update_context_1 (libgcc/unwind-dw2.c). */ +static inline void +aarch64_arch_extension_frame_init (struct _Unwind_Context *context ATTRIBUTE_UNUSED, + _Unwind_FrameState *fs) +{ + /* By default, DW_CFA_AARCH64_negate_ra_state assumes key A is being used + for signing. This can be overridden by adding 'B' to the augmentation + string. */ + fs->regs.arch_fs.signing_key = AARCH64_PAUTH_KEY_A; + + /* All registers are initially in state REG_UNSAVED, which indicates that + they inherit register values from the previous frame. However, the + return address starts every frame in the "unsigned" state. It also + starts every frame in a state that supports the original toggle-based + DW_CFA_AARCH64_negate_ra_state method of controlling RA signing. */ + fs->regs.how[AARCH64_DWARF_REGNUM_RA_STATE] = REG_ARCHEXT; + aarch64_fs_ra_state_set (fs, aarch64_ra_no_signing); +} + +/* Before copying the current context to the target context, check whether + the register is local to this context and should not be forwarded. */ +static inline bool +aarch64_frame_local_register(long reg) +{ + return (reg == AARCH64_DWARF_REGNUM_RA_STATE); } /* Do AArch64 private extraction on ADDR_WORD based on context info CONTEXT and unwind frame info FS. If ADDR_WORD is signed, we do address authentication - on it using CFA of current frame. */ + on it using CFA of current frame. + Note: when DW_CFA_val_expression is used, FS only records the location of the + associated CFI program, rather than the value of the expression itself. + The CFI program is executed by uw_update_context when updating the context, + so the value of the expression must be taken from CONTEXT rather than FS. */ static inline void * aarch64_demangle_return_addr (struct _Unwind_Context *context, _Unwind_FrameState *fs, _Unwind_Word addr_word) { void *addr = (void *)addr_word; - const int reg = DWARF_REGNUM_AARCH64_RA_STATE; - - if (fs->regs.how[reg] == REG_UNSAVED) - return addr; - - /* Return-address signing state is toggled by DW_CFA_GNU_window_save (where - REG_UNSAVED/REG_UNSAVED_ARCHEXT means RA signing is disabled/enabled), - or set by a DW_CFA_expression. */ - if (fs->regs.how[reg] == REG_UNSAVED_ARCHEXT - || (_Unwind_GetGR (context, reg) & 0x1) != 0) + const int reg = AARCH64_DWARF_REGNUM_RA_STATE; + + /* In libgcc, REG_ARCHEXT means that the RA state register was set by an + AArch64 DWARF instruction and contains a valid value, or is used to + describe the initial state set in aarch64_arch_extension_frame_init. + Return-address signing state is normally toggled by DW_CFA_AARCH64_negate + _ra_state (also knwon by its alias as DW_CFA_GNU_window_save). + However, RA state register can be set directly via DW_CFA_val_expression + too. GCC does not generate such CFI but some other compilers reportedly + do (see PR104689 for more details). + Any other value than REG_ARCHEXT should be interpreted as if the RA state + register is set by another DWARF instruction, and the value is fetchable + via _Unwind_GetGR. */ + aarch64_ra_signing_method_t signing_method = aarch64_ra_no_signing; + if (fs->regs.how[reg] == REG_ARCHEXT) + signing_method = aarch64_fs_ra_state_get (fs); + else if (fs->regs.how[reg] != REG_UNSAVED) + signing_method = aarch64_context_ra_state_get (context); + + if (signing_method == aarch64_ra_signing_sp) { _Unwind_Word salt = (_Unwind_Word) context->cfa; - if (aarch64_cie_signed_with_b_key (context) != 0) + if (fs->regs.arch_fs.signing_key == AARCH64_PAUTH_KEY_B) return __builtin_aarch64_autib1716 (addr, salt); return __builtin_aarch64_autia1716 (addr, salt); } diff --git a/libgcc/config/i386/t-darwin b/libgcc/config/i386/t-darwin index 4c18da1..c6b3aca 100644 --- a/libgcc/config/i386/t-darwin +++ b/libgcc/config/i386/t-darwin @@ -4,6 +4,3 @@ LIB2FUNCS_EXCLUDE = _fixtfdi _fixunstfdi _floatditf _floatunditf # Extra symbols for this port. SHLIB_MAPFILES += $(srcdir)/config/i386/libgcc-darwin.ver - -# Build a legacy libgcc_s.1 -BUILD_LIBGCCS1 = YES diff --git a/libgcc/config/mips/lib1funcs.S b/libgcc/config/mips/lib1funcs.S index fa8114b..324a84e 100644 --- a/libgcc/config/mips/lib1funcs.S +++ b/libgcc/config/mips/lib1funcs.S @@ -19,7 +19,7 @@ a copy of the GCC Runtime Library Exception along with this program; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ -//#include "mips16.S" +#include "mips16.S" #ifdef L_speculation_barrier diff --git a/libgcc/config/no-unwind.h b/libgcc/config/no-unwind.h index 0ecd78a..7400fd4 100644 --- a/libgcc/config/no-unwind.h +++ b/libgcc/config/no-unwind.h @@ -1,2 +1,3 @@ /* Dummy header for targets without a definition of - MD_FALLBACK_FRAME_STATE_FOR. */ + architecture-specific frame information types, or + handlers used in the unwinder. */ diff --git a/libgcc/config/riscv/save-restore.S b/libgcc/config/riscv/save-restore.S index 9bf42d1..30d06cc 100644 --- a/libgcc/config/riscv/save-restore.S +++ b/libgcc/config/riscv/save-restore.S @@ -295,7 +295,7 @@ FUNC_END (__riscv_restore_0) #else -#ifdef __riscv_32e +#ifdef __riscv_abi_rve FUNC_BEGIN(__riscv_save_2) FUNC_BEGIN(__riscv_save_1) FUNC_BEGIN(__riscv_save_0) @@ -421,8 +421,9 @@ FUNC_BEGIN (__riscv_save_0) addi sp, sp, -16 .cfi_def_cfa_offset 16 sw s2, 0(sp) + .cfi_offset 18, -16 sw s1, 4(sp) - .cfi_offset 9, -16 + .cfi_offset 9, -12 sw s0, 8(sp) .cfi_offset 8, -8 sw ra, 12(sp) @@ -529,6 +530,6 @@ FUNC_END (__riscv_restore_2) FUNC_END (__riscv_restore_1) FUNC_END (__riscv_restore_0) -#endif /* __riscv_32e */ +#endif /* __riscv_abi_rve */ #endif /* __riscv_xlen == 64 */ diff --git a/libgcc/config/rs6000/t-darwin b/libgcc/config/rs6000/t-darwin index 183d0df..8b513bd 100644 --- a/libgcc/config/rs6000/t-darwin +++ b/libgcc/config/rs6000/t-darwin @@ -56,6 +56,3 @@ unwind-dw2_s.o: HOST_LIBGCC2_CFLAGS += -maltivec unwind-dw2.o: HOST_LIBGCC2_CFLAGS += -maltivec LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c - -# Build a legacy libgcc_s.1 -BUILD_LIBGCCS1 = YES diff --git a/libgcc/config/t-darwin-libgccs1 b/libgcc/config/t-darwin-libgccs1 new file mode 100644 index 0000000..b88b1a5 --- /dev/null +++ b/libgcc/config/t-darwin-libgccs1 @@ -0,0 +1,3 @@ + +# Build a legacy libgcc_s.1 +BUILD_LIBGCCS1 = YES diff --git a/libgcc/config/t-darwin-min-11 b/libgcc/config/t-darwin-min-11 new file mode 100644 index 0000000..4009d41 --- /dev/null +++ b/libgcc/config/t-darwin-min-11 @@ -0,0 +1,3 @@ +# Support building with -mmacosx-version-min back to macOS 11. +DARWIN_MIN_LIB_VERSION = -mmacosx-version-min=11 +DARWIN_MIN_CRT_VERSION = -mmacosx-version-min=11 diff --git a/libgcc/configure b/libgcc/configure index a69d314..15a0be2 100755 --- a/libgcc/configure +++ b/libgcc/configure @@ -587,6 +587,7 @@ ac_includes_default='/* none */' ac_subst_vars='LTLIBOBJS LIBOBJS md_unwind_header +md_unwind_def_header unwind_header enable_execute_stack asm_hidden_op @@ -5786,6 +5787,7 @@ fi + # We need multilib support. ac_config_files="$ac_config_files Makefile" diff --git a/libgcc/configure.ac b/libgcc/configure.ac index c2749fe..ca34147 100644 --- a/libgcc/configure.ac +++ b/libgcc/configure.ac @@ -727,6 +727,7 @@ AC_SUBST(extra_parts) AC_SUBST(asm_hidden_op) AC_SUBST(enable_execute_stack) AC_SUBST(unwind_header) +AC_SUBST(md_unwind_def_header) AC_SUBST(md_unwind_header) AC_SUBST(sfp_machine_header) AC_SUBST(thread_header) diff --git a/libgcc/gthr-posix.h b/libgcc/gthr-posix.h index 82e8f9f..478bcf4 100644 --- a/libgcc/gthr-posix.h +++ b/libgcc/gthr-posix.h @@ -44,6 +44,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see # endif #endif +#ifdef __has_attribute +# if __has_attribute(__always_inline__) +# define __GTHREAD_ALWAYS_INLINE __attribute__((__always_inline__)) +# endif +#endif +#ifndef __GTHREAD_ALWAYS_INLINE +# define __GTHREAD_ALWAYS_INLINE +#endif + +#ifdef __cplusplus +# define __GTHREAD_INLINE inline __GTHREAD_ALWAYS_INLINE +#else +# define __GTHREAD_INLINE static inline +#endif + typedef pthread_t __gthread_t; typedef pthread_key_t __gthread_key_t; typedef pthread_once_t __gthread_once_t; @@ -182,22 +197,30 @@ __gthrw(pthread_setschedparam) #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__)) -static volatile int __gthread_active = -1; +#pragma GCC visibility push(hidden) +__GTHREAD_INLINE volatile int * +__gthread_active (void) +{ + static volatile int __gthread_active_var = -1; + return &__gthread_active_var; +} +#pragma GCC visibility pop -static void +__GTHREAD_INLINE void __gthread_trigger (void) { - __gthread_active = 1; + *__gthread_active () = 1; } -static inline int +#pragma GCC visibility push(hidden) +__GTHREAD_INLINE int __gthread_active_p (void) { static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT; /* Avoid reading __gthread_active twice on the main code path. */ - int __gthread_active_latest_value = __gthread_active; + int __gthread_active_latest_value = *__gthread_active (); /* This test is not protected to avoid taking a lock on the main code path so every update of __gthread_active in a threaded program must @@ -214,14 +237,15 @@ __gthread_active_p (void) } /* Make sure we'll never enter this block again. */ - if (__gthread_active < 0) - __gthread_active = 0; + if (*__gthread_active () < 0) + *__gthread_active () = 0; - __gthread_active_latest_value = __gthread_active; + __gthread_active_latest_value = *__gthread_active (); } return __gthread_active_latest_value != 0; } +#pragma GCC visibility pop #else /* neither FreeBSD nor Solaris */ @@ -257,13 +281,15 @@ __gthrw2(__gthrw_(__pthread_key_create), # define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel) #endif -static inline int +#pragma GCC visibility push(hidden) +__GTHREAD_INLINE int __gthread_active_p (void) { static void *const __gthread_active_ptr = __extension__ (void *) >HR_ACTIVE_PROXY; return __gthread_active_ptr != 0; } +#pragma GCC visibility pop #endif /* FreeBSD or Solaris */ @@ -288,20 +314,27 @@ __gthread_active_p (void) #if defined(__hppa__) && defined(__hpux__) -static volatile int __gthread_active = -1; +#pragma GCC visibility push(hidden) +__GTHREAD_INLINE volatile int * +__gthread_active (void) +{ + static volatile int __gthread_active_var = -1; + return &__gthread_active_var; +} +#pragma GCC visibility pop -static inline int +__GTHREAD_INLINE int __gthread_active_p (void) { /* Avoid reading __gthread_active twice on the main code path. */ - int __gthread_active_latest_value = __gthread_active; + int __gthread_active_latest_value = *__gthread_active (); size_t __s; if (__builtin_expect (__gthread_active_latest_value < 0, 0)) { pthread_default_stacksize_np (0, &__s); - __gthread_active = __s ? 1 : 0; - __gthread_active_latest_value = __gthread_active; + *__gthread_active () = __s ? 1 : 0; + __gthread_active_latest_value = *__gthread_active (); } return __gthread_active_latest_value != 0; @@ -309,7 +342,7 @@ __gthread_active_p (void) #else /* not hppa-hpux */ -static inline int +__GTHREAD_INLINE int __gthread_active_p (void) { return 1; @@ -669,44 +702,44 @@ __gthread_objc_condition_signal (objc_condition_t condition) #else /* _LIBOBJC */ -static inline int +__GTHREAD_INLINE int __gthread_create (__gthread_t *__threadid, void *(*__func) (void*), void *__args) { return __gthrw_(pthread_create) (__threadid, NULL, __func, __args); } -static inline int +__GTHREAD_INLINE int __gthread_join (__gthread_t __threadid, void **__value_ptr) { return __gthrw_(pthread_join) (__threadid, __value_ptr); } -static inline int +__GTHREAD_INLINE int __gthread_detach (__gthread_t __threadid) { return __gthrw_(pthread_detach) (__threadid); } -static inline int +__GTHREAD_INLINE int __gthread_equal (__gthread_t __t1, __gthread_t __t2) { return __gthrw_(pthread_equal) (__t1, __t2); } -static inline __gthread_t +__GTHREAD_INLINE __gthread_t __gthread_self (void) { return __gthrw_(pthread_self) (); } -static inline int +__GTHREAD_INLINE int __gthread_yield (void) { return __gthrw_(sched_yield) (); } -static inline int +__GTHREAD_INLINE int __gthread_once (__gthread_once_t *__once, void (*__func) (void)) { if (__gthread_active_p ()) @@ -715,38 +748,38 @@ __gthread_once (__gthread_once_t *__once, void (*__func) (void)) return -1; } -static inline int +__GTHREAD_INLINE int __gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *)) { return __gthrw_(pthread_key_create) (__key, __dtor); } -static inline int +__GTHREAD_INLINE int __gthread_key_delete (__gthread_key_t __key) { return __gthrw_(pthread_key_delete) (__key); } -static inline void * +__GTHREAD_INLINE void * __gthread_getspecific (__gthread_key_t __key) { return __gthrw_(pthread_getspecific) (__key); } -static inline int +__GTHREAD_INLINE int __gthread_setspecific (__gthread_key_t __key, const void *__ptr) { return __gthrw_(pthread_setspecific) (__key, __ptr); } -static inline void +__GTHREAD_INLINE void __gthread_mutex_init_function (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) __gthrw_(pthread_mutex_init) (__mutex, NULL); } -static inline int +__GTHREAD_INLINE int __gthread_mutex_destroy (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) @@ -755,7 +788,7 @@ __gthread_mutex_destroy (__gthread_mutex_t *__mutex) return 0; } -static inline int +__GTHREAD_INLINE int __gthread_mutex_lock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) @@ -764,7 +797,7 @@ __gthread_mutex_lock (__gthread_mutex_t *__mutex) return 0; } -static inline int +__GTHREAD_INLINE int __gthread_mutex_trylock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) @@ -774,7 +807,7 @@ __gthread_mutex_trylock (__gthread_mutex_t *__mutex) } #if _GTHREAD_USE_MUTEX_TIMEDLOCK -static inline int +__GTHREAD_INLINE int __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { @@ -785,7 +818,7 @@ __gthread_mutex_timedlock (__gthread_mutex_t *__mutex, } #endif -static inline int +__GTHREAD_INLINE int __gthread_mutex_unlock (__gthread_mutex_t *__mutex) { if (__gthread_active_p ()) @@ -796,7 +829,7 @@ __gthread_mutex_unlock (__gthread_mutex_t *__mutex) #if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \ || defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) { if (__gthread_active_p ()) @@ -818,20 +851,20 @@ __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex) } #endif -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } #if _GTHREAD_USE_MUTEX_TIMEDLOCK -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { @@ -839,20 +872,20 @@ __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex, } #endif -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); } #ifdef _GTHREAD_USE_COND_INIT_FUNC -static inline void +__GTHREAD_INLINE void __gthread_cond_init_function (__gthread_cond_t *__cond) { if (__gthread_active_p ()) @@ -860,46 +893,46 @@ __gthread_cond_init_function (__gthread_cond_t *__cond) } #endif -static inline int +__GTHREAD_INLINE int __gthread_cond_broadcast (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_broadcast) (__cond); } -static inline int +__GTHREAD_INLINE int __gthread_cond_signal (__gthread_cond_t *__cond) { return __gthrw_(pthread_cond_signal) (__cond); } -static inline int +__GTHREAD_INLINE int __gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex) { return __gthrw_(pthread_cond_wait) (__cond, __mutex); } -static inline int +__GTHREAD_INLINE int __gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex, const __gthread_time_t *__abs_timeout) { return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout); } -static inline int +__GTHREAD_INLINE int __gthread_cond_wait_recursive (__gthread_cond_t *__cond, __gthread_recursive_mutex_t *__mutex) { return __gthread_cond_wait (__cond, __mutex); } -static inline int +__GTHREAD_INLINE int __gthread_cond_destroy (__gthread_cond_t* __cond) { return __gthrw_(pthread_cond_destroy) (__cond); } #ifndef __cplusplus -static inline int +__GTHREAD_INLINE int __gthread_rwlock_rdlock (__gthread_rwlock_t *__rwlock) { if (__gthread_active_p ()) @@ -908,7 +941,7 @@ __gthread_rwlock_rdlock (__gthread_rwlock_t *__rwlock) return 0; } -static inline int +__GTHREAD_INLINE int __gthread_rwlock_tryrdlock (__gthread_rwlock_t *__rwlock) { if (__gthread_active_p ()) @@ -917,7 +950,7 @@ __gthread_rwlock_tryrdlock (__gthread_rwlock_t *__rwlock) return 0; } -static inline int +__GTHREAD_INLINE int __gthread_rwlock_wrlock (__gthread_rwlock_t *__rwlock) { if (__gthread_active_p ()) @@ -926,7 +959,7 @@ __gthread_rwlock_wrlock (__gthread_rwlock_t *__rwlock) return 0; } -static inline int +__GTHREAD_INLINE int __gthread_rwlock_trywrlock (__gthread_rwlock_t *__rwlock) { if (__gthread_active_p ()) @@ -935,7 +968,7 @@ __gthread_rwlock_trywrlock (__gthread_rwlock_t *__rwlock) return 0; } -static inline int +__GTHREAD_INLINE int __gthread_rwlock_unlock (__gthread_rwlock_t *__rwlock) { if (__gthread_active_p ()) @@ -947,4 +980,7 @@ __gthread_rwlock_unlock (__gthread_rwlock_t *__rwlock) #endif /* _LIBOBJC */ +#undef __GTHREAD_INLINE +#undef __GTHREAD_ALWAYS_INLINE + #endif /* ! GCC_GTHR_POSIX_H */ diff --git a/libgcc/gthr-single.h b/libgcc/gthr-single.h index 8ee6b17..2a799ad 100644 --- a/libgcc/gthr-single.h +++ b/libgcc/gthr-single.h @@ -38,6 +38,21 @@ typedef int __gthread_recursive_mutex_t; #define __GTHREAD_MUTEX_INIT_FUNCTION(mx) do {} while (0) #define __GTHREAD_RECURSIVE_MUTEX_INIT 0 +#ifdef __has_attribute +# if __has_attribute(__always_inline__) +# define __GTHREAD_ALWAYS_INLINE __attribute__((__always_inline__)) +# endif +#endif +#ifndef __GTHREAD_ALWAYS_INLINE +# define __GTHREAD_ALWAYS_INLINE +#endif + +#ifdef __cplusplus +# define __GTHREAD_INLINE inline __GTHREAD_ALWAYS_INLINE +#else +# define __GTHREAD_INLINE static inline +#endif + #define UNUSED __attribute__((__unused__)) #ifdef _LIBOBJC @@ -207,85 +222,85 @@ __gthread_objc_condition_signal (objc_condition_t condition UNUSED) #else /* _LIBOBJC */ -static inline int +__GTHREAD_INLINE int __gthread_active_p (void) { return 0; } -static inline int +__GTHREAD_INLINE int __gthread_once (__gthread_once_t *__once UNUSED, void (*__func) (void) UNUSED) { return 0; } -static inline int UNUSED +__GTHREAD_INLINE int UNUSED __gthread_key_create (__gthread_key_t *__key UNUSED, void (*__func) (void *) UNUSED) { return 0; } -static int UNUSED +__GTHREAD_INLINE int UNUSED __gthread_key_delete (__gthread_key_t __key UNUSED) { return 0; } -static inline void * +__GTHREAD_INLINE void * __gthread_getspecific (__gthread_key_t __key UNUSED) { return 0; } -static inline int +__GTHREAD_INLINE int __gthread_setspecific (__gthread_key_t __key UNUSED, const void *__v UNUSED) { return 0; } -static inline int +__GTHREAD_INLINE int __gthread_mutex_destroy (__gthread_mutex_t *__mutex UNUSED) { return 0; } -static inline int +__GTHREAD_INLINE int __gthread_mutex_lock (__gthread_mutex_t *__mutex UNUSED) { return 0; } -static inline int +__GTHREAD_INLINE int __gthread_mutex_trylock (__gthread_mutex_t *__mutex UNUSED) { return 0; } -static inline int +__GTHREAD_INLINE int __gthread_mutex_unlock (__gthread_mutex_t *__mutex UNUSED) { return 0; } -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_lock (__mutex); } -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_trylock (__mutex); } -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_unlock (__mutex); } -static inline int +__GTHREAD_INLINE int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) { return __gthread_mutex_destroy (__mutex); @@ -294,5 +309,7 @@ __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex) #endif /* _LIBOBJC */ #undef UNUSED +#undef __GTHREAD_INLINE +#undef __GTHREAD_ALWAYS_INLINE #endif /* ! GCC_GTHR_SINGLE_H */ diff --git a/libgcc/unwind-dw2-execute_cfa.h b/libgcc/unwind-dw2-execute_cfa.h index a6b249f..5d73e04 100644 --- a/libgcc/unwind-dw2-execute_cfa.h +++ b/libgcc/unwind-dw2-execute_cfa.h @@ -271,23 +271,25 @@ fs->regs.how[reg] = REG_SAVED_VAL_EXP; fs->regs.reg[reg].loc.exp = insn_ptr; } + /* Don't execute the expression, but jump over it by adding + DW_FORM_block's size to insn_ptr. */ insn_ptr = read_uleb128 (insn_ptr, &utmp); insn_ptr += utmp; break; - case DW_CFA_GNU_window_save: #if defined (__aarch64__) && !defined (__ILP32__) - /* This CFA is multiplexed with Sparc. On AArch64 it's used to toggle - return address signing status. REG_UNSAVED/REG_UNSAVED_ARCHEXT - mean RA signing is disabled/enabled. */ - reg = DWARF_REGNUM_AARCH64_RA_STATE; - gcc_assert (fs->regs.how[reg] == REG_UNSAVED - || fs->regs.how[reg] == REG_UNSAVED_ARCHEXT); - if (fs->regs.how[reg] == REG_UNSAVED) - fs->regs.how[reg] = REG_UNSAVED_ARCHEXT; - else - fs->regs.how[reg] = REG_UNSAVED; + case DW_CFA_AARCH64_negate_ra_state: + /* This CFA is multiplexed with SPARC. + On AArch64 it's used to toggle the status of return address signing + with SP as a diversifier. + - REG_ARCHEXT means that the RA state register in FS contains a + valid value, and that no other DWARF directive has changed the + value of this register. + - any other value is not compatible with negating the RA state. */ + aarch64_fs_ra_state_toggle (fs); + break; #else + case DW_CFA_GNU_window_save: /* ??? Hardcoded for SPARC register window configuration. */ if (__LIBGCC_DWARF_FRAME_REGISTERS__ >= 32) for (reg = 16; reg < 32; ++reg) @@ -295,8 +297,8 @@ fs->regs.how[reg] = REG_SAVED_OFFSET; fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *); } -#endif break; +#endif case DW_CFA_GNU_args_size: insn_ptr = read_uleb128 (insn_ptr, &utmp); diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c index 0849e89..5f33f80 100644 --- a/libgcc/unwind-dw2.c +++ b/libgcc/unwind-dw2.c @@ -501,11 +501,11 @@ extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context, fs->signal_frame = 1; aug += 1; } - /* aarch64 B-key pointer authentication. */ - else if (aug[0] == 'B') - { - aug += 1; - } + +#if defined(MD_ARCH_EXTENSION_CIE_AUG_HANDLER) + else if (MD_ARCH_EXTENSION_CIE_AUG_HANDLER (fs, aug[0])) + aug += 1; +#endif /* Otherwise we have an unknown augmentation string. Bail unless we saw a 'z' prefix. */ @@ -996,6 +996,9 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) memset (&fs->regs.how[0], 0, sizeof (*fs) - offsetof (_Unwind_FrameState, regs.how[0])); +#if defined(MD_ARCH_EXTENSION_FRAME_INIT) + MD_ARCH_EXTENSION_FRAME_INIT (context, fs); +#endif context->args_size = 0; context->lsda = 0; @@ -1197,7 +1200,11 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) { case REG_UNSAVED: case REG_UNDEFINED: - case REG_UNSAVED_ARCHEXT: + /* If the value depends on an augmenter, then there is no processing + to do here, and the value computation should be delayed until the + architecture handler computes the value correctly based on the + augmenter information. */ + case REG_ARCHEXT: break; case REG_SAVED_OFFSET: @@ -1416,6 +1423,11 @@ uw_install_context_1 (struct _Unwind_Context *current, void *c = (void *) (_Unwind_Internal_Ptr) current->reg[i]; void *t = (void *) (_Unwind_Internal_Ptr)target->reg[i]; +#ifdef MD_FRAME_LOCAL_REGISTER_P + if (MD_FRAME_LOCAL_REGISTER_P (i)) + continue; +#endif + gcc_assert (current->by_value[i] == 0); if (target->by_value[i] && c) { diff --git a/libgcc/unwind-dw2.h b/libgcc/unwind-dw2.h index 0dd8611..8e3bdbd 100644 --- a/libgcc/unwind-dw2.h +++ b/libgcc/unwind-dw2.h @@ -22,16 +22,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ -enum { +#include "md-unwind-def.h" + +enum register_rule +{ REG_UNSAVED, REG_SAVED_OFFSET, REG_SAVED_REG, REG_SAVED_EXP, REG_SAVED_VAL_OFFSET, REG_SAVED_VAL_EXP, - REG_UNSAVED_ARCHEXT, /* Target specific extension. */ + REG_ARCHEXT, /* Target specific extension. */ REG_UNDEFINED -}; +} __attribute__((packed)); /* The result of interpreting the frame unwind info for a frame. This is all symbolic at this point, as none of the values can @@ -49,7 +52,7 @@ typedef struct const unsigned char *exp; } loc; } reg[__LIBGCC_DWARF_FRAME_REGISTERS__+1]; - unsigned char how[__LIBGCC_DWARF_FRAME_REGISTERS__+1]; + enum register_rule how[__LIBGCC_DWARF_FRAME_REGISTERS__+1]; enum { CFA_UNSET, @@ -65,6 +68,14 @@ typedef struct _Unwind_Sword cfa_offset; _Unwind_Word cfa_reg; const unsigned char *cfa_exp; + + /* Architecture extensions information from CIE/FDE. + Note: this information has to be saved in struct frame_state_reg_info + instead of _Unwind_FrameState as DW_CFA_restore_state has to be able to + restore them. */ +#if defined(MD_ARCH_FRAME_STATE_T) + MD_ARCH_FRAME_STATE_T arch_fs; +#endif } regs; /* The PC described by the current frame state. */ |