* [PATCH 1/2] LoongArch: Fix instruction immediate bug caused by sign-extend @ 2023-07-17 8:22 mengqinggang 2023-07-17 8:22 ` [PATCH 2/2] LoongArch: Fix immediate overflow check bug mengqinggang 0 siblings, 1 reply; 7+ messages in thread From: mengqinggang @ 2023-07-17 8:22 UTC (permalink / raw) To: binutils Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray, hejinyang, mengqinggang For extreme code mode, the instruction sequences is pcalau12i $t0, hi20 addi.d $t1, $zero, lo12 lu32i.d $t1, lo20 lu52i.d $t1, hi12 add.d $t1, $t0, $t1 If lo12 > 0x7ff, hi20 need to add 0x1, lo20 need to sub 0x1. If hi20 > 0x7ffff, lo20 need to add 0x1. bfd/ChangeLog: * elfnn-loongarch.c (RELOCATE_CALC_PC32_HI20): Redefined. (RELOCATE_CALC_PC64_HI32): Redefined. --- bfd/elfnn-loongarch.c | 59 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index d3d8419d80b..e9c408b2dff 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -2284,26 +2284,65 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info, return fatal; } +/* If lo12 immediate > 0x7ff, because sign-extend caused by addi.d/ld.d, + hi20 immediate need to add 0x1. + For example: pc 0x120000000, symbol 0x120000812 + lo12 immediate is 0x812, 0x120000812 & 0xfff = 0x812 + hi20 immediate is 1, because lo12 imm > 0x7ff, symbol need to add 0x1000 + (((0x120000812 + 0x1000) & ~0xfff) - (0x120000000 & ~0xfff)) >> 12 = 0x1 + + At run: + pcalau12i $t0, hi20 (0x1) + $t0 = 0x120000000 + (0x1 << 12) = 0x120001000 + addi.d $t0, $t0, lo12 (0x812) + $t0 = 0x120001000 + 0xfffffffffffff812 (-(0x1000 - 0x812) = -0x7ee) + = 0x120001000 - 0x7ee (0x1000 - 0x7ee = 0x812) + = 0x120000812 + Without hi20 add 0x1000, the result 0x120000000 - 0x7ee = 0x11ffff812 is + error. + 0x1000 + sign-extend-to64(0x8xx) = 0x8xx. */ #define RELOCATE_CALC_PC32_HI20(relocation, pc) \ ({ \ bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \ - pc = pc & (~(bfd_vma)0xfff); \ + relocation = (relocation & ~(bfd_vma)0xfff) \ + - (pc & ~(bfd_vma)0xfff); \ if (__lo > 0x7ff) \ - { \ relocation += 0x1000; \ - } \ - relocation &= ~(bfd_vma)0xfff; \ - relocation -= pc; \ }) +/* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812 + offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff) + = 0x712347ffff000 + lo12: 0x1812348ffff812 & 0xfff = 0x812 + hi20: 0x7ffff + 0x1(lo12 > 0x7ff) = 0x80000 + lo20: 0x71234 - 0x1(lo12 > 0x7ff) + 0x1(hi20 > 0x7ffff) + hi12: 0x0 + + pcalau12i $t1, hi20 (0x80000) + $t1 = 0x11000010000100 + sign-extend(0x80000 << 12) + = 0x11000010000100 + 0xffffffff80000000 + = 0x10ffff90000000 + addi.d $t0, $zero, lo12 (0x812) + $t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend, + lo20 need to sub 0x1) + lu32i.d $t0, lo12 (0x71234) + $t0 = {0x71234, 0xfffff812} + = 0x71234fffff812 + lu52i.d $t0, hi12 (0x0) + $t0 = {0x0, 0x71234fffff812} + = 0x71234fffff812 + add.d $t1, $t1, $t0 + $t1 = 0x10ffff90000000 + 0x71234fffff812 + = 0x1812348ffff812. */ #define RELOCATE_CALC_PC64_HI32(relocation, pc) \ ({ \ - bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \ + bfd_vma __lo = (relocation & (bfd_vma)0xfff); \ + relocation = (relocation & ~(bfd_vma)0xfff) \ + - (pc & ~(bfd_vma)0xfff); \ if (__lo > 0x7ff) \ - { \ - relocation -= 0x100000000; \ - } \ - relocation -= (pc & ~(bfd_vma)0xffffffff); \ + relocation += (0x1000 - 0x100000000); \ + if (relocation & 0x80000000) \ + relocation += 0x100000000; \ }) static int -- 2.36.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] LoongArch: Fix immediate overflow check bug 2023-07-17 8:22 [PATCH 1/2] LoongArch: Fix instruction immediate bug caused by sign-extend mengqinggang @ 2023-07-17 8:22 ` mengqinggang 2023-07-21 3:56 ` mengqinggang 0 siblings, 1 reply; 7+ messages in thread From: mengqinggang @ 2023-07-17 8:22 UTC (permalink / raw) To: binutils Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray, hejinyang, mengqinggang For B16/B21/B26/PCREL20_S2 relocations, if immediate overflow check after rightshift, and the mask need to include sign bit. Now, the immediate overflow check before rightshift for easier understand. bfd/ChangeLog: * elfxx-loongarch.c (reloc_bits_pcrel20_s2): Delete. (reloc_bits_b16): Delete. (reloc_bits_b21): Delete. (reloc_bits_b26): Delete. (reloc_sign_bits): New. --- bfd/elfxx-loongarch.c | 160 +++++++++--------------------------------- 1 file changed, 32 insertions(+), 128 deletions(-) diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c index da440d55c3c..2d299050c12 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_val); -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); 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[] = 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 */ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ @@ -493,7 +487,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 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 */ 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[] = 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 */ LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ @@ -766,7 +760,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 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. */ LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ @@ -783,7 +777,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 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. */ LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ @@ -800,7 +794,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 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. */ LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ @@ -1436,7 +1430,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = 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. */ /* Canonical Frame Address. */ @@ -1677,12 +1671,14 @@ reloc_bits (bfd *abfd ATTRIBUTE_UNUSED, } static bool -reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) +reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) { + if (howto->complain_on_overflow != complain_overflow_signed) + return false; + bfd_signed_vma val = (bfd_signed_vma)(*fix_val); - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; - /* 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; } - val = val >> howto->rightshift; + bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize + + howto->rightshift - 1)) - 1; + /* 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) != ~mask)) { (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), @@ -1702,123 +1702,27 @@ reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) return false; } - /* Perform insn bits field. */ - val = val & mask; - val <<= howto->bitpos; - - *fix_val = (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 = *fix_val; - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; - - if (howto->complain_on_overflow != complain_overflow_signed) - return false; - - /* Judge whether 4 bytes align. */ - if (val & ((0x1UL << howto->rightshift) - 1)) - return false; - - val = val >> howto->rightshift; - - if ((val & ~mask) && ((val & ~mask) != ~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 = val & mask; - val <<= howto->bitpos; - - *fix_val = 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 = *fix_val; - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; - - if (howto->complain_on_overflow != complain_overflow_signed) - return false; - - /* Judge whether 4 bytes align. */ - if (val & ((0x1UL << howto->rightshift) - 1)) - return false; - val = val >> howto->rightshift; - - if ((val & ~mask) && ((val & ~mask) != ~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 = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; val = val & mask; - /* Perform insn bits field. 15:0<<10, 20:16>>16. */ - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); - - *fix_val = 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 = *fix_val; - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; - - if (howto->complain_on_overflow != complain_overflow_signed) - return false; - - /* Judge whether 4 bytes align. */ - if (val & ((0x1UL << howto->rightshift) - 1)) - return false; - - val = val >> howto->rightshift; - - if ((val & ~mask) && ((val & ~mask) != ~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. 25:16>>16, 15:0<<10. */ + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); + break; + case R_LARCH_B21: + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); + break; + default: + val <<= howto->bitpos; + break; } - - /* Perform insn bits field. */ - val = val & mask; - - /* Perform insn bits field. 25:16>>16, 15:0<<10. */ - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); - *fix_val = val; - return true; } -- 2.36.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] LoongArch: Fix immediate overflow check bug 2023-07-17 8:22 ` [PATCH 2/2] LoongArch: Fix immediate overflow check bug mengqinggang @ 2023-07-21 3:56 ` mengqinggang 2023-07-22 7:47 ` Xi Ruoyao 2023-07-22 7:52 ` Xi Ruoyao 0 siblings, 2 replies; 7+ messages in thread From: mengqinggang @ 2023-07-21 3:56 UTC (permalink / raw) To: binutils Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray, hejinyang Hi These two patches also need to be merged into the 2.41 branch. Thanks. 在 2023/7/17 下午4:22, mengqinggang 写道: > For B16/B21/B26/PCREL20_S2 relocations, if immediate overflow check after > rightshift, and the mask need to include sign bit. > > Now, the immediate overflow check before rightshift for easier understand. > > bfd/ChangeLog: > > * elfxx-loongarch.c (reloc_bits_pcrel20_s2): Delete. > (reloc_bits_b16): Delete. > (reloc_bits_b21): Delete. > (reloc_bits_b26): Delete. > (reloc_sign_bits): New. > --- > bfd/elfxx-loongarch.c | 160 +++++++++--------------------------------- > 1 file changed, 32 insertions(+), 128 deletions(-) > > diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c > index da440d55c3c..2d299050c12 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_val); > -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); > > 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[] = > 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 */ > > LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ > @@ -493,7 +487,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > 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 */ > > 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[] = > 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 */ > > LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ > @@ -766,7 +760,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > 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. */ > > LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ > @@ -783,7 +777,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > 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. */ > > LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ > @@ -800,7 +794,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > 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. */ > > LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ > @@ -1436,7 +1430,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > 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. */ > > /* Canonical Frame Address. */ > @@ -1677,12 +1671,14 @@ reloc_bits (bfd *abfd ATTRIBUTE_UNUSED, > } > > static bool > -reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > +reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > { > + if (howto->complain_on_overflow != complain_overflow_signed) > + return false; > + > bfd_signed_vma val = (bfd_signed_vma)(*fix_val); > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > - /* 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; > } > > - val = val >> howto->rightshift; > + bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize > + + howto->rightshift - 1)) - 1; > > + /* 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) != ~mask)) > { > (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), > @@ -1702,123 +1702,27 @@ reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > return false; > } > > - /* Perform insn bits field. */ > - val = val & mask; > - val <<= howto->bitpos; > - > - *fix_val = (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 = *fix_val; > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > - > - if (howto->complain_on_overflow != complain_overflow_signed) > - return false; > - > - /* Judge whether 4 bytes align. */ > - if (val & ((0x1UL << howto->rightshift) - 1)) > - return false; > - > - val = val >> howto->rightshift; > - > - if ((val & ~mask) && ((val & ~mask) != ~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 = val & mask; > - val <<= howto->bitpos; > - > - *fix_val = 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 = *fix_val; > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > - > - if (howto->complain_on_overflow != complain_overflow_signed) > - return false; > - > - /* Judge whether 4 bytes align. */ > - if (val & ((0x1UL << howto->rightshift) - 1)) > - return false; > - > val = val >> howto->rightshift; > - > - if ((val & ~mask) && ((val & ~mask) != ~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 = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > val = val & mask; > > - /* Perform insn bits field. 15:0<<10, 20:16>>16. */ > - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); > - > - *fix_val = 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 = *fix_val; > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > - > - if (howto->complain_on_overflow != complain_overflow_signed) > - return false; > - > - /* Judge whether 4 bytes align. */ > - if (val & ((0x1UL << howto->rightshift) - 1)) > - return false; > - > - val = val >> howto->rightshift; > - > - if ((val & ~mask) && ((val & ~mask) != ~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. 25:16>>16, 15:0<<10. */ > + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); > + break; > + case R_LARCH_B21: > + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); > + break; > + default: > + val <<= howto->bitpos; > + break; > } > > - > - /* Perform insn bits field. */ > - val = val & mask; > - > - /* Perform insn bits field. 25:16>>16, 15:0<<10. */ > - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); > - > *fix_val = val; > - > return true; > } > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] LoongArch: Fix immediate overflow check bug 2023-07-21 3:56 ` mengqinggang @ 2023-07-22 7:47 ` Xi Ruoyao 2023-07-22 7:52 ` Xi Ruoyao 1 sibling, 0 replies; 7+ messages in thread From: Xi Ruoyao @ 2023-07-22 7:47 UTC (permalink / raw) To: mengqinggang, binutils, Nick Clifton Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, hejinyang On Fri, 2023-07-21 at 11:56 +0800, mengqinggang wrote: > Hi > > These two patches also need to be merged into the 2.41 branch. Thanks. +Nick too. For 1/2 it should be OK to backport. For 2/2 the subject and the commit message do not add up: the subject says "Fix immediate overflow check bug", but the message says "for easier understand". So does 2/2 really fix a bug? If true we should backport it, otherwise we should not. > 在 2023/7/17 下午4:22, mengqinggang 写道: > > For B16/B21/B26/PCREL20_S2 relocations, if immediate overflow check after > > rightshift, and the mask need to include sign bit. > > > > Now, the immediate overflow check before rightshift for easier understand. > > > > bfd/ChangeLog: > > > > * elfxx-loongarch.c (reloc_bits_pcrel20_s2): Delete. > > (reloc_bits_b16): Delete. > > (reloc_bits_b21): Delete. > > (reloc_bits_b26): Delete. > > (reloc_sign_bits): New. > > --- > > bfd/elfxx-loongarch.c | 160 +++++++++--------------------------------- > > 1 file changed, 32 insertions(+), 128 deletions(-) > > > > diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c > > index da440d55c3c..2d299050c12 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_val); > > -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); > > > > 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[] = > > 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 */ > > > > LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ > > @@ -493,7 +487,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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 */ > > > > 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[] = > > 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 */ > > > > LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ > > @@ -766,7 +760,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ > > @@ -783,7 +777,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ > > @@ -800,7 +794,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ > > @@ -1436,7 +1430,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > /* Canonical Frame Address. */ > > @@ -1677,12 +1671,14 @@ reloc_bits (bfd *abfd ATTRIBUTE_UNUSED, > > } > > > > static bool > > -reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > > +reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > > { > > + if (howto->complain_on_overflow != complain_overflow_signed) > > + return false; > > + > > bfd_signed_vma val = (bfd_signed_vma)(*fix_val); > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > > > - /* 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; > > } > > > > - val = val >> howto->rightshift; > > + bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize > > + + howto->rightshift - 1)) - 1; > > > > + /* 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) != ~mask)) > > { > > (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), > > @@ -1702,123 +1702,27 @@ reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > > return false; > > } > > > > - /* Perform insn bits field. */ > > - val = val & mask; > > - val <<= howto->bitpos; > > - > > - *fix_val = (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 = *fix_val; > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > - > > - if (howto->complain_on_overflow != complain_overflow_signed) > > - return false; > > - > > - /* Judge whether 4 bytes align. */ > > - if (val & ((0x1UL << howto->rightshift) - 1)) > > - return false; > > - > > - val = val >> howto->rightshift; > > - > > - if ((val & ~mask) && ((val & ~mask) != ~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 = val & mask; > > - val <<= howto->bitpos; > > - > > - *fix_val = 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 = *fix_val; > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > - > > - if (howto->complain_on_overflow != complain_overflow_signed) > > - return false; > > - > > - /* Judge whether 4 bytes align. */ > > - if (val & ((0x1UL << howto->rightshift) - 1)) > > - return false; > > - > > val = val >> howto->rightshift; > > - > > - if ((val & ~mask) && ((val & ~mask) != ~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 = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > val = val & mask; > > > > - /* Perform insn bits field. 15:0<<10, 20:16>>16. */ > > - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); > > - > > - *fix_val = 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 = *fix_val; > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > - > > - if (howto->complain_on_overflow != complain_overflow_signed) > > - return false; > > - > > - /* Judge whether 4 bytes align. */ > > - if (val & ((0x1UL << howto->rightshift) - 1)) > > - return false; > > - > > - val = val >> howto->rightshift; > > - > > - if ((val & ~mask) && ((val & ~mask) != ~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. 25:16>>16, 15:0<<10. */ > > + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); > > + break; > > + case R_LARCH_B21: > > + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); > > + break; > > + default: > > + val <<= howto->bitpos; > > + break; > > } > > > > - > > - /* Perform insn bits field. */ > > - val = val & mask; > > - > > - /* Perform insn bits field. 25:16>>16, 15:0<<10. */ > > - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); > > - > > *fix_val = val; > > - > > return true; > > } > > > -- Xi Ruoyao <xry111@xry111.site> School of Aerospace Science and Technology, Xidian University ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] LoongArch: Fix immediate overflow check bug 2023-07-21 3:56 ` mengqinggang 2023-07-22 7:47 ` Xi Ruoyao @ 2023-07-22 7:52 ` Xi Ruoyao 2023-07-22 8:23 ` Jinyang He 1 sibling, 1 reply; 7+ messages in thread From: Xi Ruoyao @ 2023-07-22 7:52 UTC (permalink / raw) To: mengqinggang, binutils, Nick Clifton Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, hejinyang On Fri, 2023-07-21 at 11:56 +0800, mengqinggang wrote: > Hi > > These two patches also need to be merged into the 2.41 branch. Thanks. +Nick too. For 1/2 it should be OK to backport. For 2/2 the subject and the commit message do not add up: the subject says "Fix immediate overflow check bug", but the message says "for easier understand". So does 2/2 really fix a bug? If true we should backport it, otherwise we should not. > 在 2023/7/17 下午4:22, mengqinggang 写道: > > For B16/B21/B26/PCREL20_S2 relocations, if immediate overflow check after > > rightshift, and the mask need to include sign bit. > > > > Now, the immediate overflow check before rightshift for easier understand. > > > > bfd/ChangeLog: > > > > * elfxx-loongarch.c (reloc_bits_pcrel20_s2): Delete. > > (reloc_bits_b16): Delete. > > (reloc_bits_b21): Delete. > > (reloc_bits_b26): Delete. > > (reloc_sign_bits): New. > > --- > > bfd/elfxx-loongarch.c | 160 +++++++++--------------------------------- > > 1 file changed, 32 insertions(+), 128 deletions(-) > > > > diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c > > index da440d55c3c..2d299050c12 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_val); > > -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); > > > > 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[] = > > 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 */ > > > > LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ > > @@ -493,7 +487,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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 */ > > > > 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[] = > > 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 */ > > > > LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ > > @@ -766,7 +760,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ > > @@ -783,7 +777,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ > > @@ -800,7 +794,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ > > @@ -1436,7 +1430,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = > > 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. */ > > > > /* Canonical Frame Address. */ > > @@ -1677,12 +1671,14 @@ reloc_bits (bfd *abfd ATTRIBUTE_UNUSED, > > } > > > > static bool > > -reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > > +reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > > { > > + if (howto->complain_on_overflow != complain_overflow_signed) > > + return false; > > + > > bfd_signed_vma val = (bfd_signed_vma)(*fix_val); > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > > > - /* 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; > > } > > > > - val = val >> howto->rightshift; > > + bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize > > + + howto->rightshift - 1)) - 1; > > > > + /* 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) != ~mask)) > > { > > (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), > > @@ -1702,123 +1702,27 @@ reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) > > return false; > > } > > > > - /* Perform insn bits field. */ > > - val = val & mask; > > - val <<= howto->bitpos; > > - > > - *fix_val = (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 = *fix_val; > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > - > > - if (howto->complain_on_overflow != complain_overflow_signed) > > - return false; > > - > > - /* Judge whether 4 bytes align. */ > > - if (val & ((0x1UL << howto->rightshift) - 1)) > > - return false; > > - > > - val = val >> howto->rightshift; > > - > > - if ((val & ~mask) && ((val & ~mask) != ~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 = val & mask; > > - val <<= howto->bitpos; > > - > > - *fix_val = 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 = *fix_val; > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > - > > - if (howto->complain_on_overflow != complain_overflow_signed) > > - return false; > > - > > - /* Judge whether 4 bytes align. */ > > - if (val & ((0x1UL << howto->rightshift) - 1)) > > - return false; > > - > > val = val >> howto->rightshift; > > - > > - if ((val & ~mask) && ((val & ~mask) != ~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 = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > val = val & mask; > > > > - /* Perform insn bits field. 15:0<<10, 20:16>>16. */ > > - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); > > - > > - *fix_val = 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 = *fix_val; > > - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; > > - > > - if (howto->complain_on_overflow != complain_overflow_signed) > > - return false; > > - > > - /* Judge whether 4 bytes align. */ > > - if (val & ((0x1UL << howto->rightshift) - 1)) > > - return false; > > - > > - val = val >> howto->rightshift; > > - > > - if ((val & ~mask) && ((val & ~mask) != ~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. 25:16>>16, 15:0<<10. */ > > + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); > > + break; > > + case R_LARCH_B21: > > + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); > > + break; > > + default: > > + val <<= howto->bitpos; > > + break; > > } > > > > - > > - /* Perform insn bits field. */ > > - val = val & mask; > > - > > - /* Perform insn bits field. 25:16>>16, 15:0<<10. */ > > - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); > > - > > *fix_val = val; > > - > > return true; > > } > > > -- Xi Ruoyao <xry111@xry111.site> School of Aerospace Science and Technology, Xidian University ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] LoongArch: Fix immediate overflow check bug 2023-07-22 7:52 ` Xi Ruoyao @ 2023-07-22 8:23 ` Jinyang He 2023-07-24 9:14 ` Nick Clifton 0 siblings, 1 reply; 7+ messages in thread From: Jinyang He @ 2023-07-22 8:23 UTC (permalink / raw) To: Xi Ruoyao, mengqinggang, binutils, Nick Clifton Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray 在 2023/7/22 下午3:52, Xi Ruoyao 写道: > On Fri, 2023-07-21 at 11:56 +0800, mengqinggang wrote: >> Hi >> >> These two patches also need to be merged into the 2.41 branch. Thanks. > +Nick too. > > For 1/2 it should be OK to backport. For 2/2 the subject and the commit > message do not add up: the subject says "Fix immediate overflow check > bug", but the message says "for easier understand". So does 2/2 really > fix a bug? If true we should backport it, otherwise we should not. It is because we want fix bug related to ralaxation. I found it links succeed when relaxation may be wrong due to imm overflow [1]. I think the imm-overflow reporting is urgent and effective way to let we know something wrongs rather than nothing being reported. And for relaxation fixing, mengqinggang has a better way to fix it (, which difficult for me). [1] https://sourceware.org/pipermail/binutils/2023-July/128379.html > >> 在 2023/7/17 下午4:22, mengqinggang 写道: >>> For B16/B21/B26/PCREL20_S2 relocations, if immediate overflow check after >>> rightshift, and the mask need to include sign bit. >>> >>> Now, the immediate overflow check before rightshift for easier understand. >>> >>> bfd/ChangeLog: >>> >>> * elfxx-loongarch.c (reloc_bits_pcrel20_s2): Delete. >>> (reloc_bits_b16): Delete. >>> (reloc_bits_b21): Delete. >>> (reloc_bits_b26): Delete. >>> (reloc_sign_bits): New. >>> --- >>> bfd/elfxx-loongarch.c | 160 +++++++++--------------------------------- >>> 1 file changed, 32 insertions(+), 128 deletions(-) >>> >>> diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c >>> index da440d55c3c..2d299050c12 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_val); >>> -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); >>> >>> 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[] = >>> 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 */ >>> >>> LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_S_5_20, /* type (43). */ >>> @@ -493,7 +487,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = >>> 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 */ >>> >>> 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[] = >>> 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 */ >>> >>> LOONGARCH_HOWTO (R_LARCH_SOP_POP_32_U, /* type (46). */ >>> @@ -766,7 +760,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = >>> 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. */ >>> >>> LOONGARCH_HOWTO (R_LARCH_B21, /* type (65). */ >>> @@ -783,7 +777,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = >>> 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. */ >>> >>> LOONGARCH_HOWTO (R_LARCH_B26, /* type (66). */ >>> @@ -800,7 +794,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = >>> 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. */ >>> >>> LOONGARCH_HOWTO (R_LARCH_ABS_HI20, /* type (67). */ >>> @@ -1436,7 +1430,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = >>> 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. */ >>> >>> /* Canonical Frame Address. */ >>> @@ -1677,12 +1671,14 @@ reloc_bits (bfd *abfd ATTRIBUTE_UNUSED, >>> } >>> >>> static bool >>> -reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) >>> +reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) >>> { >>> + if (howto->complain_on_overflow != complain_overflow_signed) >>> + return false; >>> + >>> bfd_signed_vma val = (bfd_signed_vma)(*fix_val); >>> - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; >>> >>> - /* 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; >>> } >>> >>> - val = val >> howto->rightshift; >>> + bfd_signed_vma mask = ((bfd_signed_vma)0x1 << (howto->bitsize >>> + + howto->rightshift - 1)) - 1; >>> >>> + /* 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) != ~mask)) >>> { >>> (*_bfd_error_handler) (_("%pB: relocation %s overflow 0x%lx"), >>> @@ -1702,123 +1702,27 @@ reloc_bits_pcrel20_s2 (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val) >>> return false; >>> } >>> >>> - /* Perform insn bits field. */ >>> - val = val & mask; >>> - val <<= howto->bitpos; >>> - >>> - *fix_val = (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 = *fix_val; >>> - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; >>> - >>> - if (howto->complain_on_overflow != complain_overflow_signed) >>> - return false; >>> - >>> - /* Judge whether 4 bytes align. */ >>> - if (val & ((0x1UL << howto->rightshift) - 1)) >>> - return false; >>> - >>> - val = val >> howto->rightshift; >>> - >>> - if ((val & ~mask) && ((val & ~mask) != ~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 = val & mask; >>> - val <<= howto->bitpos; >>> - >>> - *fix_val = 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 = *fix_val; >>> - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; >>> - >>> - if (howto->complain_on_overflow != complain_overflow_signed) >>> - return false; >>> - >>> - /* Judge whether 4 bytes align. */ >>> - if (val & ((0x1UL << howto->rightshift) - 1)) >>> - return false; >>> - >>> val = val >> howto->rightshift; >>> - >>> - if ((val & ~mask) && ((val & ~mask) != ~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 = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; >>> val = val & mask; >>> >>> - /* Perform insn bits field. 15:0<<10, 20:16>>16. */ >>> - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); >>> - >>> - *fix_val = 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 = *fix_val; >>> - bfd_signed_vma mask = ((bfd_signed_vma)0x1 << howto->bitsize) - 1; >>> - >>> - if (howto->complain_on_overflow != complain_overflow_signed) >>> - return false; >>> - >>> - /* Judge whether 4 bytes align. */ >>> - if (val & ((0x1UL << howto->rightshift) - 1)) >>> - return false; >>> - >>> - val = val >> howto->rightshift; >>> - >>> - if ((val & ~mask) && ((val & ~mask) != ~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. 25:16>>16, 15:0<<10. */ >>> + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); >>> + break; >>> + case R_LARCH_B21: >>> + val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f); >>> + break; >>> + default: >>> + val <<= howto->bitpos; >>> + break; >>> } >>> >>> - >>> - /* Perform insn bits field. */ >>> - val = val & mask; >>> - >>> - /* Perform insn bits field. 25:16>>16, 15:0<<10. */ >>> - val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff); >>> - >>> *fix_val = val; >>> - >>> return true; >>> } >>> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] LoongArch: Fix immediate overflow check bug 2023-07-22 8:23 ` Jinyang He @ 2023-07-24 9:14 ` Nick Clifton 0 siblings, 0 replies; 7+ messages in thread From: Nick Clifton @ 2023-07-24 9:14 UTC (permalink / raw) To: Jinyang He, Xi Ruoyao, mengqinggang Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, Binutils Hi Jinyang He, Xi Ruoyao, Mengqingang, I have decided to apply both patches to the 2.41 branch. I agree that patch 1/2 was a needed bug fix, and whilst 2/2 is not a real bug-fix, it will help to alter users to the fact that there is a problem and that they need to do something to fix their code. (Also since I was applying patch 1/2 it was easy for me to apply 2/2 at at the same time). Luckily the 2.41 release has not happened yet. It was due to go out today but I have been asked to delay it whilst a problem with another port is resolved. But the delay will not be for long, and the release will happen soon. All of which is to say - please do not expect to get any more LoongArch bug fixes into the 2.41 release... Cheers Nick ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-07-24 9:14 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-07-17 8:22 [PATCH 1/2] LoongArch: Fix instruction immediate bug caused by sign-extend mengqinggang 2023-07-17 8:22 ` [PATCH 2/2] LoongArch: Fix immediate overflow check bug mengqinggang 2023-07-21 3:56 ` mengqinggang 2023-07-22 7:47 ` Xi Ruoyao 2023-07-22 7:52 ` Xi Ruoyao 2023-07-22 8:23 ` Jinyang He 2023-07-24 9:14 ` Nick Clifton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).