From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7867) id 865DE3858C62; Mon, 24 Jul 2023 03:45:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 865DE3858C62 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: liu & zhensong To: bfd-cvs@sourceware.org Subject: [binutils-gdb] LoongArch: Fix immediate overflow check bug X-Act-Checkin: binutils-gdb X-Git-Author: mengqinggang X-Git-Refname: refs/heads/master X-Git-Oldrev: 378535f277b31e28f74cc65df6876c616beb04b4 X-Git-Newrev: a38b0c05b6e9444d94e8a4dd090584a8dcc313ad Message-Id: <20230724034535.865DE3858C62@sourceware.org> Date: Mon, 24 Jul 2023 03:45:35 +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: Mon, 24 Jul 2023 03:45:35 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Da38b0c05b6e9= 444d94e8a4dd090584a8dcc313ad commit a38b0c05b6e9444d94e8a4dd090584a8dcc313ad Author: mengqinggang Date: Sat Jul 15 17:56:07 2023 +0800 LoongArch: Fix immediate overflow check bug =20 For B16/B21/B26/PCREL20_S2 relocations, if immediate overflow check aft= er rightshift, and the mask need to include sign bit. =20 Now, the immediate overflow check before rightshift for easier understa= nd. =20 bfd/ChangeLog: =20 * elfxx-loongarch.c (reloc_bits_pcrel20_s2): Delete. (reloc_bits_b16): Delete. (reloc_bits_b21): Delete. (reloc_bits_b26): Delete. (reloc_sign_bits): New. Diff: --- bfd/elfxx-loongarch.c | 162 +++++++++++-----------------------------------= ---- 1 file changed, 34 insertions(+), 128 deletions(-) diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c index da440d55c3c..f27c9fdba6a 100644 --- a/bfd/elfxx-loongarch.c +++ b/bfd/elfxx-loongarch.c @@ -54,13 +54,7 @@ typedef struct loongarch_reloc_howto_type_struct static bool reloc_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *val); static bool -reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_va= l); -static bool -reloc_bits_b16 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val); -static bool -reloc_bits_b21 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val); -static bool -reloc_bits_b26 (bfd *abfd, reloc_howto_type *howto, bfd_vma *val); +reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val); =20 static bfd_reloc_status_type loongarch_elf_add_sub_reloc (bfd *, arelent *, asymbol *, void *, @@ -457,7 +451,7 @@ static loongarch_reloc_howto_type loongarch_howto_table= [] =3D 0x3fffc00, /* dst_mask */ false, /* pcrel_offset */ BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2, /* bfd_reloc_code_real_type */ - reloc_bits_b16, /* adjust_reloc_bits */ + reloc_sign_bits, /* adjust_reloc_bits */ NULL), /* larch_reloc_type_name */ =20 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ @@ -493,7 +487,7 @@ static loongarch_reloc_howto_type loongarch_howto_table= [] =3D false, /* pcrel_offset */ BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2, /* bfd_reloc_code_real_type */ - reloc_bits_b21, /* adjust_reloc_bits */ + reloc_sign_bits, /* adjust_reloc_bits */ NULL), /* larch_reloc_type_name */ =20 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* type (45). */ @@ -511,7 +505,7 @@ static loongarch_reloc_howto_type loongarch_howto_table= [] =3D false, /* pcrel_offset */ BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2, /* bfd_reloc_code_real_type */ - reloc_bits_b26, /* adjust_reloc_bits */ + reloc_sign_bits, /* adjust_reloc_bits */ NULL), /* larch_reloc_type_name */ =20 LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ @@ -766,7 +760,7 @@ static loongarch_reloc_howto_type loongarch_howto_table= [] =3D 0x3fffc00, /* dst_mask. */ false, /* pcrel_offset. */ BFD_RELOC_LARCH_B16, /* bfd_reloc_code_real_type. */ - reloc_bits_b16, /* adjust_reloc_bits. */ + reloc_sign_bits, /* adjust_reloc_bits. */ "b16"), /* larch_reloc_type_name. */ =20 LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ @@ -783,7 +777,7 @@ static loongarch_reloc_howto_type loongarch_howto_table= [] =3D 0x3fffc1f, /* dst_mask. */ false, /* pcrel_offset. */ BFD_RELOC_LARCH_B21, /* bfd_reloc_code_real_type. */ - reloc_bits_b21, /* adjust_reloc_bits. */ + reloc_sign_bits, /* adjust_reloc_bits. */ "b21"), /* larch_reloc_type_name. */ =20 LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ @@ -800,7 +794,7 @@ static loongarch_reloc_howto_type loongarch_howto_table= [] =3D 0x03ffffff, /* dst_mask. */ false, /* pcrel_offset. */ BFD_RELOC_LARCH_B26, /* bfd_reloc_code_real_type. */ - reloc_bits_b26, /* adjust_reloc_bits. */ + reloc_sign_bits, /* adjust_reloc_bits. */ "b26"), /* larch_reloc_type_name. */ =20 LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ @@ -1436,7 +1430,7 @@ static loongarch_reloc_howto_type loongarch_howto_tab= le[] =3D 0x1ffffe0, /* dst_mask. */ false, /* pcrel_offset. */ BFD_RELOC_LARCH_PCREL20_S2, /* bfd_reloc_code_real_type. */ - reloc_bits_pcrel20_s2, /* adjust_reloc_bits. */ + reloc_sign_bits, /* adjust_reloc_bits. */ NULL), /* larch_reloc_type_name. */ =20 /* Canonical Frame Address. */ @@ -1677,12 +1671,14 @@ reloc_bits (bfd *abfd ATTRIBUTE_UNUSED, } =20 static bool -reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_va= l) +reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) { + if (howto->complain_on_overflow !=3D complain_overflow_signed) + return false; + bfd_signed_vma val =3D (bfd_signed_vma)(*fix_val); - bfd_signed_vma mask =3D ((bfd_signed_vma)0x1 << howto->bitsize) - 1; =20 - /* Check rightshift. */ + /* Check alignment. FIXME: if rightshift is not alingment. */ if (howto->rightshift && (val & ((((bfd_signed_vma) 1) << howto->rightshift) - 1))) { @@ -1692,8 +1688,12 @@ reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *= howto, bfd_vma *fix_val) return false; } =20 - val =3D val >> howto->rightshift; + bfd_signed_vma mask =3D ((bfd_signed_vma)0x1 << (howto->bitsize + + howto->rightshift - 1)) - 1; =20 + /* Positive number: high part is all 0; + Negative number: if high part is not all 0, high part must be all 1. + high part: from sign bit to highest bit. */ if ((val & ~mask) && ((val & ~mask) !=3D ~mask)) { (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), @@ -1702,123 +1702,29 @@ reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type= *howto, bfd_vma *fix_val) return false; } =20 - /* Perform insn bits field. */ - val =3D val & mask; - val <<=3D howto->bitpos; - - *fix_val =3D (bfd_vma)val; - - return true; -} - - -/* Adjust val to perform insn - R_LARCH_SOP_POP_32_S_10_16_S2 - R_LARCH_B16. */ -static bool -reloc_bits_b16 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) -{ - bfd_signed_vma val =3D *fix_val; - bfd_signed_vma mask =3D ((bfd_signed_vma)0x1 << howto->bitsize) - 1; - - if (howto->complain_on_overflow !=3D complain_overflow_signed) - return false; - - /* Judge whether 4 bytes align. */ - if (val & ((0x1UL << howto->rightshift) - 1)) - return false; - - val =3D val >> howto->rightshift; - - if ((val & ~mask) && ((val & ~mask) !=3D ~mask)) - { - (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), - abfd, howto->name, (long) val); - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Perform insn bits field. */ - val =3D val & mask; - val <<=3D howto->bitpos; - - *fix_val =3D val; - - return true; -} - -/* Reloc type : - R_LARCH_SOP_POP_32_S_0_5_10_16_S2 - R_LARCH_B21. */ -static bool -reloc_bits_b21 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) -{ - bfd_signed_vma val =3D *fix_val; - bfd_signed_vma mask =3D ((bfd_signed_vma)0x1 << howto->bitsize) - 1; - - if (howto->complain_on_overflow !=3D complain_overflow_signed) - return false; - - /* Judge whether 4 bytes align. */ - if (val & ((0x1UL << howto->rightshift) - 1)) - return false; - val =3D val >> howto->rightshift; - - if ((val & ~mask) && ((val & ~mask) !=3D ~mask)) - { - (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), - abfd, howto->name, (long) val); - bfd_set_error (bfd_error_bad_value); - return false; - } - - /* Perform insn bits field. */ + /* can delete? */ + mask =3D ((bfd_signed_vma)0x1 << howto->bitsize) - 1; val =3D val & mask; =20 - /* Perform insn bits field. 15:0<<10, 20:16>>16. */ - val =3D ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); - - *fix_val =3D val; - - return true; -} - -/* Reloc type: - R_LARCH_SOP_POP_32_S_0_10_10_16_S2 - R_LARCH_B26. */ -static bool -reloc_bits_b26 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) -{ - bfd_signed_vma val =3D *fix_val; - bfd_signed_vma mask =3D ((bfd_signed_vma)0x1 << howto->bitsize) - 1; - - if (howto->complain_on_overflow !=3D complain_overflow_signed) - return false; - - /* Judge whether 4 bytes align. */ - if (val & ((0x1UL << howto->rightshift) - 1)) - return false; - - val =3D val >> howto->rightshift; - - if ((val & ~mask) && ((val & ~mask) !=3D ~mask)) + switch (howto->type) { - (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), - abfd, howto->name, (long) val); - bfd_set_error (bfd_error_bad_value); - return false; + case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: + case R_LARCH_B26: + /* Perform insn bits field. 15:0<<10, 25:16>>16. */ + val =3D ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); + break; + case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: + case R_LARCH_B21: + /* Perform insn bits field. 15:0<<10, 20:16>>16. */ + val =3D ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); + break; + default: + val <<=3D howto->bitpos; + break; } =20 - - /* Perform insn bits field. */ - val =3D val & mask; - - /* Perform insn bits field. 25:16>>16, 15:0<<10. */ - val =3D ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); - *fix_val =3D val; - return true; }