diff --git a/gas/config/tc-s390.c b/gas/config/tc-s390.c index 7d7c56dc8a9..535c424ca04 100644 --- a/gas/config/tc-s390.c +++ b/gas/config/tc-s390.c @@ -2910,7 +2910,7 @@ s390_sframe_ra_tracking_p (void) bool s390_support_flex_fde_p (void) { - return false; + return true; } /* Specify the fixed offset to recover RA from CFA. diff --git a/gas/gen-sframe.c b/gas/gen-sframe.c index 071d26baf31..931c14c4b02 100644 --- a/gas/gen-sframe.c +++ b/gas/gen-sframe.c @@ -1487,43 +1487,6 @@ sframe_xlate_do_val_offset (const struct sframe_xlate_ctx *xlate_ctx ATTRIBUTE_U return SFRAME_XLATE_OK; } -/* S390-specific translate DW_CFA_register into SFrame context. - Return SFRAME_XLATE_OK if success. */ - -static int -s390_sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx, - const struct cfi_insn_data *cfi_insn) -{ - /* The scratchpad FRE currently being updated with each cfi_insn - being interpreted. This FRE eventually gets linked in into the - list of FREs for the specific function. */ - struct sframe_row_entry *cur_fre = xlate_ctx->cur_fre; - - gas_assert (cur_fre); - - /* Change the rule for the register indicated by the register number to - be the specified register. Encode the register number as offset by - shifting it to the left by one and setting the least-significant bit - (LSB). The LSB can be used to differentiate offsets from register - numbers, as offsets from CFA are always a multiple of -8 on s390x. */ - if (cfi_insn->u.rr.reg1 == SFRAME_CFA_FP_REG) - sframe_fre_set_fp_track (cur_fre, - SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2)); - else if (sframe_ra_tracking_p () - && cfi_insn->u.rr.reg1 == SFRAME_CFA_RA_REG) - sframe_fre_set_ra_track (cur_fre, - SFRAME_V2_S390X_OFFSET_ENCODE_REGNUM (cfi_insn->u.rr.reg2)); - /* SFrame does not track SP explicitly. */ - else if (cfi_insn->u.rr.reg1 == SFRAME_CFA_SP_REG) - { - as_warn (_("no SFrame FDE emitted; %s register %u in .cfi_register"), - sframe_register_name (cfi_insn->u.rr.reg1), cfi_insn->u.rr.reg1); - return SFRAME_XLATE_ERR_NOTREPRESENTED; /* Not represented. */ - } - - return SFRAME_XLATE_OK; -} - /* Translate DW_CFA_register into SFrame context. This opcode indicates: Previous value of register1 is register2. This is @@ -1543,10 +1506,7 @@ static int sframe_xlate_do_register (struct sframe_xlate_ctx *xlate_ctx, const struct cfi_insn_data *cfi_insn) { - /* Conditionally invoke S390-specific implementation. */ - if (sframe_get_abi_arch () == SFRAME_ABI_S390X_ENDIAN_BIG) - return s390_sframe_xlate_do_register (xlate_ctx, cfi_insn); - else if (sframe_support_flex_fde_p ()) + if (sframe_support_flex_fde_p ()) { struct sframe_row_entry *cur_fre = xlate_ctx->cur_fre; diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-1.d deleted file mode 100644 index 5cd31c7da00..00000000000 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-1.d +++ /dev/null @@ -1,15 +0,0 @@ -#name: SFrame generation on s390x - .cfi_def_cfa_register with non-SP/FP register -#as: --gsframe -#warning: non-SP/FP register 10 in \.cfi_def_cfa_register -#objdump: --sframe=.sframe -#... -Contents of the SFrame section .sframe: - - Header : - - Version: SFRAME_VERSION_3 - Flags: SFRAME_F_FDE_FUNC_START_PCREL - Num FDEs: 0 - Num FREs: 0 - -#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-2.d deleted file mode 100644 index 0397cd84c05..00000000000 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-2.d +++ /dev/null @@ -1,15 +0,0 @@ -#name: SFrame generation on s390x - .cfi_def_cfa with non-SP/FP register -#as: --gsframe -#warning: non-SP/FP register 10 in \.cfi_def_cfa -#objdump: --sframe=.sframe -#... -Contents of the SFrame section .sframe: - - Header : - - Version: SFRAME_VERSION_3 - Flags: SFRAME_F_FDE_FUNC_START_PCREL - Num FDEs: 0 - Num FREs: 0 - -#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d index c53b2477cdc..63219dcae99 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-1.d @@ -1,4 +1,4 @@ -#name: SFrame generation on s390x - RA and then FP saved in registers +#name: SFrame generation on s390x - RA and then FP saved in FPR registers #objdump: --sframe=.sframe #... Contents of the SFrame section .sframe: @@ -12,11 +12,11 @@ Contents of the SFrame section .sframe: Function Index : - func idx \[0\]: pc = 0x0, size = 26 bytes + func idx \[0\]: pc = 0x0, size = 26 bytes, attr = "F" STARTPC +CFA +FP +RA + 0+0000 +sp\+160 +u +u + - 0+0004 +sp\+160 +u +r16 + - 0+0008 +sp\+160 +r17 +r16 + - 0+0014 +sp\+160 +u +r16 + + 0+0004 +sp\+160 +u +r16\+0 + + 0+0008 +sp\+160 +r17\+0 +r16\+0 + + 0+0014 +sp\+160 +u +r16\+0 + 0+0018 +sp\+160 +u +u + #pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d index f781fb1dee9..d82b4557d94 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-fpra-register-2.d @@ -12,11 +12,11 @@ Contents of the SFrame section .sframe: Function Index : - func idx \[0\]: pc = 0x0, size = 26 bytes + func idx \[0\]: pc = 0x0, size = 26 bytes, attr = "F" STARTPC +CFA +FP +RA + 0+0000 +sp\+160 +u +u + - 0+0004 +sp\+160 +r17 +U + - 0+0008 +sp\+160 +r17 +r16 + - 0+0014 +sp\+160 +r17 +U + + 0+0004 +sp\+160 +r17\+0 +U + + 0+0008 +sp\+160 +r17\+0 +r16\+0 + + 0+0014 +sp\+160 +r17\+0 +U + 0+0018 +sp\+160 +u +u + #pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.d new file mode 100644 index 00000000000..adf92e13232 --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.d @@ -0,0 +1,24 @@ +#name: SFrame generation on s390x - .cfi_def_cfa_register with non-SP/FP register +#as: --gsframe +#objdump: --sframe=.sframe +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_3 + Flags: SFRAME_F_FDE_FUNC_START_PCREL + Num FDEs: 1 + Num FREs: 6 + + Function Index : + + func idx \[0\]: pc = 0x0, size = 40 bytes, attr = "F" + STARTPC +CFA +FP +RA + + 0+0000 +sp\+160 +u +u + + 0+0006 +sp\+160 +c\-72 +c\-48 + + 0+000c +sp\+320 +c\-72 +c\-48 + + 0+0010 +r10\+320 +c\-72 +c\-48 + + 0+001c +sp\+160 +u +u + + 0+001e +r10\+320 +c\-72 +c\-48 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-1.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.s similarity index 100% rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-1.s rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-1.s diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.d b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.d new file mode 100644 index 00000000000..5415d8431fc --- /dev/null +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.d @@ -0,0 +1,24 @@ +#name: SFrame generation on s390x - .cfi_def_cfa with non-SP/FP register +#as: --gsframe +#objdump: --sframe=.sframe +#... +Contents of the SFrame section .sframe: + + Header : + + Version: SFRAME_VERSION_3 + Flags: SFRAME_F_FDE_FUNC_START_PCREL + Num FDEs: 1 + Num FREs: 6 + + Function Index : + + func idx \[0\]: pc = 0x0, size = 40 bytes, attr = "F" + STARTPC +CFA +FP +RA + + 0+0000 +sp\+160 +u +u + + 0+0006 +sp\+160 +c\-72 +c\-48 + + 0+000c +sp\+320 +c\-72 +c\-48 + + 0+0010 +r10\+320 +c\-72 +c\-48 + + 0+001c +sp\+160 +u +u + + 0+001e +r10\+320 +c\-72 +c\-48 + +#pass diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-2.s b/gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.s similarity index 100% rename from gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-err-2.s rename to gas/testsuite/gas/cfi-sframe/cfi-sframe-s390x-non-spfp-cfa-2.s diff --git a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp index 98af7297b2d..3f246d2da24 100644 --- a/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp +++ b/gas/testsuite/gas/cfi-sframe/cfi-sframe.exp @@ -99,8 +99,6 @@ if { [istarget "s390x*-*-*"] && [gas_sframe_check] } then { run_dump_test "cfi-sframe-s390x-1" run_dump_test "cfi-sframe-s390x-2" run_dump_test "cfi-sframe-s390x-3" - run_dump_test "cfi-sframe-s390x-err-1" - run_dump_test "cfi-sframe-s390x-err-2" run_dump_test "cfi-sframe-s390x-err-3" run_dump_test "cfi-sframe-s390x-err-4" run_dump_test "cfi-sframe-s390x-fpra-offset-1" @@ -109,4 +107,6 @@ if { [istarget "s390x*-*-*"] && [gas_sframe_check] } then { run_dump_test "cfi-sframe-s390x-fpra-register-2" run_dump_test "cfi-sframe-s390x-ra-undefined-1" run_dump_test "cfi-sframe-s390x-pr33756" + run_dump_test "cfi-sframe-s390x-non-spfp-cfa-1" + run_dump_test "cfi-sframe-s390x-non-spfp-cfa-2" } diff --git a/include/sframe.h b/include/sframe.h index 1c026d51472..2d47cc73ae8 100644 --- a/include/sframe.h +++ b/include/sframe.h @@ -452,9 +452,10 @@ typedef struct sframe_fre_info offset2 (intrepreted as FP = CFA + offset2) fi fi - Note that in s390x, if a FP/RA offset2/offset3 value has the least- - significant bit set it represents a DWARF register number shifted to the - left by 1 to restore the FP/RA value from. + Note that in s390x, if a FP/RA is to be restored from a register, flex FDEs + are used in SFrame V3. In SFrame V2, default FDEs were used: the + least-significant bit of the offset was set to indicate that the encoded + value is a DWARF register number shifted to the left by 1. */ /* Used when SFRAME_FRE_TYPE_ADDR1 is specified as FRE type. */ diff --git a/libsframe/sframe-dump.c b/libsframe/sframe-dump.c index 742b60b6f4f..3d7bbafcdbc 100644 --- a/libsframe/sframe-dump.c +++ b/libsframe/sframe-dump.c @@ -116,6 +116,28 @@ is_sframe_abi_arch_s390x (const sframe_decoder_ctx *sfd_ctx) return sframe_decoder_get_abi_arch (sfd_ctx) == SFRAME_ABI_S390X_ENDIAN_BIG; } +static bool +sframe_s390x_offset_regnum_p (int32_t offset, uint8_t ver) +{ + if (ver == SFRAME_VERSION_2) + return SFRAME_V2_S390X_OFFSET_IS_REGNUM (offset); + else if (ver == SFRAME_VERSION_3) + return false; + else + /* No other version is supported yet. */ + sframe_assert (false); +} + +static int +sframe_s390x_offset_decode_regnum (int32_t offset, uint8_t ver) +{ + if (ver == SFRAME_VERSION_2) + return SFRAME_V2_S390X_OFFSET_DECODE_REGNUM (offset); + else + /* No other version is supported yet. */ + sframe_assert (false); +} + static void dump_sframe_header_flags (const sframe_decoder_ctx *sfd_ctx) { @@ -249,8 +271,9 @@ dump_sframe_func_fres_simple (const sframe_decoder_ctx *sfd_ctx, if (err[1] == 0) { if (is_sframe_abi_arch_s390x (sfd_ctx) - && SFRAME_V2_S390X_OFFSET_IS_REGNUM (fp_offset)) - sprintf (temp, "r%d", SFRAME_V2_S390X_OFFSET_DECODE_REGNUM (fp_offset)); + && sframe_s390x_offset_regnum_p (fp_offset, ver)) + sprintf (temp, "r%d", + sframe_s390x_offset_decode_regnum (fp_offset, ver)); else sprintf (temp, "c%+d", fp_offset); } @@ -271,8 +294,9 @@ dump_sframe_func_fres_simple (const sframe_decoder_ctx *sfd_ctx, else if (err[2] == 0) { if (is_sframe_abi_arch_s390x (sfd_ctx) - && SFRAME_V2_S390X_OFFSET_IS_REGNUM (ra_offset)) - sprintf (temp, "r%d", SFRAME_V2_S390X_OFFSET_DECODE_REGNUM (ra_offset)); + && sframe_s390x_offset_regnum_p (ra_offset, ver)) + sprintf (temp, "r%d", + sframe_s390x_offset_decode_regnum (ra_offset, ver)); else sprintf (temp, "c%+d", ra_offset); }