Thanks to Andreas Schwab for the pointer on how to fix this properly. This re-enables -msave-restore for shared libraries, and uses the t-slibgcc-libgcc file to get the save-restore routines included directly in shared libraries so that we don't need to indirect through the PLT to reach them, which doesn't work.
This was tested with 32-bit/elf and 64-bit/linux cross toolchain builds and checks, with a patch to force -msave-restore on if not specified on the command line. There are no g++ or gfortran regressions. There are 4 gcc regressions, but 3 are sibling call tests that can't work with the save-restore routines, and the other is non-obvious, but for a feature we haven't been testing I think this is pretty good. Before these patches, there were thousands of regressions when I turned -msave-restore on. I didn't test freebsd as I don't have any easy way to test it, but its libgcc config is identical to linux except for the linux specific unwinder file, so I don't expect problems. Committed. Jim gcc/ * config/riscv/riscv.c (riscv_option_override): Revert 2019-08-30 change. libgcc/ * config.host (riscv*-*-linux*): Add t-slibgcc-libgcc to tmake_file. (riscv*-*-freebsd*): Likewise. --- gcc/config/riscv/riscv.c | 10 ---------- libgcc/config.host | 4 ++-- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 1e7528f1cb9..9b16a1eb9c2 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -4636,16 +4636,6 @@ riscv_option_override (void) error ("%<-mriscv-attribute%> RISC-V ELF attribute requires GNU as 2.32" " [%<-mriscv-attribute%>]"); #endif - - /* The save-restore routines use t0 which is clobbered by the plt header, - so we can't use them when building shared libraries. */ - if (TARGET_SAVE_RESTORE && flag_pic && TARGET_PLT) - { - target_flags &= ~MASK_SAVE_RESTORE; - if (target_flags_explicit & MASK_SAVE_RESTORE) - warning (0, "%<-msave-restore%> disabled; not supported with PLT " - "based shared libraries"); - } } /* Implement TARGET_CONDITIONAL_REGISTER_USAGE. */ diff --git a/libgcc/config.host b/libgcc/config.host index a3976702ab5..1db52878a5e 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -1201,12 +1201,12 @@ pru-*-*) tm_file="$tm_file pru/pru-abi.h" ;; riscv*-*-linux*) - tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}" + tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address} t-slibgcc-libgcc" extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o" md_unwind_header=riscv/linux-unwind.h ;; riscv*-*-freebsd*) - tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address}" + tmake_file="${tmake_file} riscv/t-softfp${host_address} t-softfp riscv/t-elf riscv/t-elf${host_address} t-slibgcc-libgcc" extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o" ;; riscv*-*-*) -- 2.17.1