From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1984) id 0622A3857C4C; Tue, 2 Aug 2022 08:21:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0622A3857C4C Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tamar Christina To: bfd-cvs@sourceware.org Subject: [binutils-gdb] arm: Use DWARF numbering convention for pseudo-register representation X-Act-Checkin: binutils-gdb X-Git-Author: Victor Do Nascimento X-Git-Refname: refs/heads/master X-Git-Oldrev: 217cbb0055391809d6dfb56cec053fdd3cf08b75 X-Git-Newrev: 3a368c4c248f6e9f4bda3a5369befa17a4560293 Message-Id: <20220802082118.0622A3857C4C@sourceware.org> Date: Tue, 2 Aug 2022 08:21:18 +0000 (GMT) X-BeenThere: binutils-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 02 Aug 2022 08:21:18 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D3a368c4c248f= 6e9f4bda3a5369befa17a4560293 commit 3a368c4c248f6e9f4bda3a5369befa17a4560293 Author: Victor Do Nascimento Date: Mon Aug 1 22:07:27 2022 +0100 arm: Use DWARF numbering convention for pseudo-register representation =20 This patch modifies the internal `struct reg_entry' numbering of DWARF pseudo-registers to match values assigned in DWARF standards (see "4.1 DWARF register names" in [1])so ra_auth_code goes from 12 to 143 and amends the unwinder .save directive-processing code to correctly handle mixed register-type save directives. =20 The mechanism for splitting the register list is also re-written to comply with register ordering on push statements, being that registers are stored on the stack in numerical order, with the lowest numbered register at the lowest address [2]. =20 Consequently, the parsing of the hypothetical directive =20 .save{r4-r7, r10, ra_auth_core, lr} =20 has been changed such as rather than producing =20 .save{r4-r7, r10} .save{ra_auth_code} .save{lr} =20 as was the case with previous implementation, now produces: =20 .save{lr} .save{ra_auth_code} .save{r4-r7, r10} =20 [1] [2] =20 gas/Changelog: =20 * config/tc-arm.c (REG_RA_AUTH_CODE): New. (parse_dot_save): Likewise. (parse_reg_list): Remove obsolete code. (reg_names): Set ra_auth_code to 143. (s_arm_unwind_save): Handle core and pseudo-register lists via parse_dot_save. (s_arm_unwind_save_mixed): Deleted. (s_arm_unwind_save_pseudo): Handle one register at a time. * testsuite/gas/arm/unwind-pacbti-m-readelf.d: Fix test. * testsuite/gas/arm/unwind-pacbti-m.d: Likewise. Diff: --- gas/config/tc-arm.c | 159 ++++++++++++++------= ---- gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d | 4 +- gas/testsuite/gas/arm/unwind-pacbti-m.d | 2 +- 3 files changed, 95 insertions(+), 70 deletions(-) diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index e28085310c8..f1dc4eb2d5e 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -742,6 +742,7 @@ const char * const reg_expected_msgs[] =3D #define REG_SP 13 #define REG_LR 14 #define REG_PC 15 +#define REG_RA_AUTH_CODE 143 =20 /* ARM instructions take 4bytes in the object file, Thumb instructions take 2: */ @@ -1943,21 +1944,6 @@ parse_reg_list (char ** strp, enum reg_list_els etyp= e) =20 reg =3D arm_reg_parse (&str, rt); =20 - /* Skip over allowed registers of alternative types in mixed-type - register lists. */ - if (reg =3D=3D FAIL && rt =3D=3D REG_TYPE_PSEUDO - && ((reg =3D arm_reg_parse (&str, REG_TYPE_RN)) !=3D FAIL)) - { - cur_reg =3D reg; - continue; - } - else if (reg =3D=3D FAIL && rt =3D=3D REG_TYPE_RN - && ((reg =3D arm_reg_parse (&str, REG_TYPE_PSEUDO)) !=3D FAIL)) - { - cur_reg =3D reg; - continue; - } - if (etype =3D=3D REGLIST_CLRM) { if (reg =3D=3D REG_SP || reg =3D=3D REG_PC) @@ -4139,7 +4125,6 @@ s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED) unwind.sp_restored =3D 0; } =20 - /* Parse a handlerdata directive. Creates the exception handling table en= try for the function. */ =20 @@ -4297,15 +4282,19 @@ s_arm_unwind_personality (int ignored ATTRIBUTE_UNU= SED) /* Parse a directive saving pseudo registers. */ =20 static void -s_arm_unwind_save_pseudo (long range) +s_arm_unwind_save_pseudo (int regno) { valueT op; =20 - if (range & (1 << 12)) + switch (regno) { + case REG_RA_AUTH_CODE: /* Opcode for restoring RA_AUTH_CODE. */ op =3D 0xb4; add_unwind_opcode (op, 1); + break; + default: + as_bad (_("Unknown register no. encountered: %d\n"), regno); } } =20 @@ -4375,6 +4364,80 @@ s_arm_unwind_save_core (long range) } } =20 +/* Implement correct handling of .save lists enabling the split into +sublists where necessary, while preserving correct sublist ordering. */ + +static void +parse_dot_save (char **str_p, int prev_reg) +{ + long core_regs =3D 0; + int reg; + int in_range =3D 0; + + if (**str_p =3D=3D ',') + *str_p +=3D 1; + if (**str_p =3D=3D '}') + { + *str_p +=3D 1; + return; + } + + while ((reg =3D arm_reg_parse (str_p, REG_TYPE_RN)) !=3D FAIL) + { + if (!in_range) + { + if (core_regs & (1 << reg)) + as_tsktsk (_("Warning: duplicated register (r%d) in register list"), + reg); + else if (reg <=3D prev_reg) + as_tsktsk (_("Warning: register list not in ascending order")); + + core_regs |=3D (1 << reg); + prev_reg =3D reg; + if (skip_past_char(str_p, '-') !=3D FAIL) + in_range =3D 1; + else if (skip_past_comma(str_p) =3D=3D FAIL) + first_error (_("bad register list")); + } + else + { + int i; + if (reg <=3D prev_reg) + first_error (_("bad range in register list")); + for (i =3D prev_reg + 1; i <=3D reg; i++) + { + if (core_regs & (1 << i)) + as_tsktsk (_("Warning: duplicated register (r%d) in register list"), + i); + else + core_regs |=3D 1 << i; + } + in_range =3D 0; + } + } + if (core_regs) + { + /* Higher register numbers go in higher memory addresses. When split= ting a list, + right-most sublist should therefore be .saved first. Use recursion for t= his. */ + parse_dot_save (str_p, reg); + /* We're back from recursion, so emit .save insn for sublist. */ + s_arm_unwind_save_core (core_regs); + return; + } + /* Handle pseudo-regs, under assumption these are emitted singly. */ + else if ((reg =3D arm_reg_parse (str_p, REG_TYPE_PSEUDO)) !=3D FAIL) + { + /* recurse for remainder of input. Note: No assumption is made regar= ding which + register in core register set holds pseudo-register. It's not considered= in + ordering check beyond ensuring it's not sandwiched between 2 consecutive + registers. */ + parse_dot_save (str_p, prev_reg + 1); + s_arm_unwind_save_pseudo (reg); + return; + } + else + as_bad (BAD_SYNTAX); +} =20 /* Parse a directive saving FPA registers. */ =20 @@ -4716,39 +4779,13 @@ s_arm_unwind_save_mmxwcg (void) ignore_rest_of_line (); } =20 -/* Convert range and mask_range into a sequence of s_arm_unwind_core - and s_arm_unwind_pseudo operations. We assume that mask_range will - not have consecutive bits set, or that one operation per bit is - acceptable. */ - -static void -s_arm_unwind_save_mixed (long range, long mask_range) -{ - while (mask_range) - { - long mask_bit =3D mask_range & -mask_range; - long subrange =3D range & (mask_bit - 1); - - if (subrange) - s_arm_unwind_save_core (subrange); - - s_arm_unwind_save_pseudo (mask_bit); - range &=3D ~subrange; - mask_range &=3D ~mask_bit; - } - - if (range) - s_arm_unwind_save_core (range); -} - /* Parse an unwind_save directive. If the argument is non-zero, this is a .vsave directive. */ =20 static void s_arm_unwind_save (int arch_v6) { - char *peek, *mask_peek; - long range, mask_range; + char *peek; struct reg_entry *reg; bool had_brace =3D false; =20 @@ -4756,7 +4793,7 @@ s_arm_unwind_save (int arch_v6) as_bad (MISSING_FNSTART); =20 /* Figure out what sort of save we have. */ - peek =3D mask_peek =3D input_line_pointer; + peek =3D input_line_pointer; =20 if (*peek =3D=3D '{') { @@ -4788,20 +4825,13 @@ s_arm_unwind_save (int arch_v6) =20 case REG_TYPE_PSEUDO: case REG_TYPE_RN: - mask_range =3D parse_reg_list (&mask_peek, REGLIST_PSEUDO); - range =3D parse_reg_list (&input_line_pointer, REGLIST_RN); - - if (range =3D=3D FAIL || mask_range =3D=3D FAIL) - { - as_bad (_("expected register list")); - ignore_rest_of_line (); - return; - } - - demand_empty_rest_of_line (); - - s_arm_unwind_save_mixed (range, mask_range); - return; + { + if (had_brace) + input_line_pointer++; + parse_dot_save (&input_line_pointer, -1); + demand_empty_rest_of_line (); + return; + } =20 case REG_TYPE_VFD: if (arch_v6) @@ -23993,12 +24023,8 @@ static const struct reg_entry reg_names[] =3D /* XScale accumulator registers. */ REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE), =20 - /* DWARF ABI defines RA_AUTH_CODE to 143. It also reserves 134-142 for f= uture - expansion. RA_AUTH_CODE here is given the value 143 % 134 to make it= easy - for tc_arm_regname_to_dw2regnum to translate to DWARF reg number using - 134 + reg_number should the range 134 to 142 be used for more pseudo = regs - in the future. This also helps fit RA_AUTH_CODE into a bitmask. */ - REGDEF(ra_auth_code,12,PSEUDO), + /* DWARF ABI defines RA_AUTH_CODE to 143. */ + REGDEF(ra_auth_code,143,PSEUDO), }; #undef REGDEF #undef REGNUM @@ -27905,7 +27931,6 @@ create_unwind_entry (int have_data) return 0; } =20 - /* Initialize the DWARF-2 unwind information for this procedure. */ =20 void diff --git a/gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d b/gas/testsuit= e/gas/arm/unwind-pacbti-m-readelf.d index d8d647bb7f0..c40544a5a94 100644 --- a/gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d +++ b/gas/testsuite/gas/arm/unwind-pacbti-m-readelf.d @@ -10,11 +10,11 @@ Unwind section '.ARM.exidx' at offset 0x60 contains 1 e= ntry: =20 0x0 : @0x0 Compact model index: 1 - 0x84 0x00 pop {r14} 0xb4 pop {ra_auth_code} 0x84 0x00 pop {r14} - 0xb4 pop {ra_auth_code} 0xa3 pop {r4, r5, r6, r7} 0xb4 pop {ra_auth_code} + 0x84 0x00 pop {r14} + 0xb4 pop {ra_auth_code} 0xa8 pop {r4, r14} 0xb0 finish diff --git a/gas/testsuite/gas/arm/unwind-pacbti-m.d b/gas/testsuite/gas/ar= m/unwind-pacbti-m.d index d178e4c0a44..b021c007b33 100644 --- a/gas/testsuite/gas/arm/unwind-pacbti-m.d +++ b/gas/testsuite/gas/arm/unwind-pacbti-m.d @@ -8,4 +8,4 @@ .*: file format.* =20 Contents of section .ARM.extab: - 0000 (00840281 b40084b4 b0a8b4a3|81028400 b48400b4 a3b4a8b0) 00000000 .* + 0000 (84b40281 84b4a300 b0a8b400|8102b484 00a3b484 00b4a8b0) 00000000 .*