From f77bb6c56b4091ed863d8cd03333a79a8d554ce1 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Mon, 6 Nov 2017 16:32:08 -0800 Subject: [PATCH] RISC-V: Fix riscv g++ testsuite EH failures. This fixes some EH failures for the medany code model in the g++ testsuite. The problem is that the assembler is computing some values in the eh_frame section as constants, that instead should have had relocs to be resolved by the linker. This happens in output_cfi_insn in the DW_CFA_advance_loc case where it compares label frags and immediately simplifies if they are the same. We can fix that by forcing a new frag after every instruction that the linker can reduce in size. I've also added a testcase to verify the fix. This was tested with binutils make check, and gcc/g++ make checks on qemu for medlow and medany code models. gas/ * config/tc-riscv.c (append_insn): Call frag_wane and frag_new at end for linker optimizable relocs. * testsuite/gas/riscv/eh-relocs.d: New. * testsuite/gas/riscv/eh-relocs.s: New. * testsuite/gas/riscv/riscv.exp: Run eh-relocs test. --- gas/ChangeLog | 8 ++++++++ gas/config/tc-riscv.c | 15 +++++++++++++++ gas/testsuite/gas/riscv/eh-relocs.d | 12 ++++++++++++ gas/testsuite/gas/riscv/eh-relocs.s | 11 +++++++++++ gas/testsuite/gas/riscv/riscv.exp | 1 + 5 files changed, 47 insertions(+) create mode 100644 gas/testsuite/gas/riscv/eh-relocs.d create mode 100644 gas/testsuite/gas/riscv/eh-relocs.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 85f0664a6d7..80e9ea751cf 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2017-11-07 Jim Wilson + + * config/tc-riscv.c (append_insn): Call frag_wane and frag_new at + end for linker optimizable relocs. + * testsuite/gas/riscv/eh-relocs.d: New. + * testsuite/gas/riscv/eh-relocs.s: New. + * testsuite/gas/riscv/riscv.exp: Run eh-relocs test. + 2017-11-07 Palmer Dabbelt * testsuite/gas/riscv/satp.d: New test. diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index c8955a69ecd..bdaf270470a 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -716,6 +716,21 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr, add_fixed_insn (ip); install_insn (ip); + + /* We need to start a new frag after any instruction that can be + optimized away or compressed by the linker during relaxation, to prevent + the assembler from computing static offsets across such an instruction. + This is necessary to get correct EH info. */ + if (reloc_type == BFD_RELOC_RISCV_CALL + || reloc_type == BFD_RELOC_RISCV_CALL_PLT + || reloc_type == BFD_RELOC_RISCV_HI20 + || reloc_type == BFD_RELOC_RISCV_PCREL_HI20 + || reloc_type == BFD_RELOC_RISCV_TPREL_HI20 + || reloc_type == BFD_RELOC_RISCV_TPREL_ADD) + { + frag_wane (frag_now); + frag_new (0); + } } /* Build an instruction created by a macro expansion. This is passed diff --git a/gas/testsuite/gas/riscv/eh-relocs.d b/gas/testsuite/gas/riscv/eh-relocs.d new file mode 100644 index 00000000000..94fa1439de2 --- /dev/null +++ b/gas/testsuite/gas/riscv/eh-relocs.d @@ -0,0 +1,12 @@ +#as: +#objdump: --section=.eh_frame -r + +.*:[ ]+file format .* + +RELOCATION RECORDS FOR .* +.* +0+1c R_RISCV_32_PCREL.* +0+20 R_RISCV_ADD32.* +0+20 R_RISCV_SUB32.* +0+25 R_RISCV_SET6.* +0+25 R_RISCV_SUB6.* diff --git a/gas/testsuite/gas/riscv/eh-relocs.s b/gas/testsuite/gas/riscv/eh-relocs.s new file mode 100644 index 00000000000..4e96e7e6afb --- /dev/null +++ b/gas/testsuite/gas/riscv/eh-relocs.s @@ -0,0 +1,11 @@ + .text + .align 2 + .globl _func1 + .type _func1, @function +_func1: + .cfi_startproc + lla a1,_func2 + add sp,sp,-16 + .cfi_def_cfa_offset 16 + .cfi_endproc + .size _func1, .-_func1 diff --git a/gas/testsuite/gas/riscv/riscv.exp b/gas/testsuite/gas/riscv/riscv.exp index 2ab885ad87a..8a128acdcf0 100644 --- a/gas/testsuite/gas/riscv/riscv.exp +++ b/gas/testsuite/gas/riscv/riscv.exp @@ -25,4 +25,5 @@ if [istarget riscv*-*-*] { run_dump_test "c-addi4spn-fail" run_dump_test "c-addi16sp-fail" run_dump_test "satp" + run_dump_test "eh-relocs" } -- 2.30.2