[PATCH] ix86: wrap constants

H.J. Lu hjl.tools@gmail.com
Fri Jun 4 12:26:10 GMT 2021


On Fri, Jun 4, 2021 at 5:14 AM Jan Beulich <jbeulich@suse.com> wrote:
>
> Non-64-bit code should get handled the same with or without BFD64. This
> wasn't the case though in a number of situations (and quite likely there
> are more that I haven't spotted yet).
>
> It's not very nice to tie the check in md_apply_fix() to object_64bit,
> but afaict at that time we have no record anymore of the mode an insn
> was assembled in (it might also have been data). This doesn't look to be
> the first inconsistency of this kind, though. In x86_cons() it's even
> less clear what the right approach would be: flag_code shouldn't matter
> for data emission, but instead we'd need to know from which mode(s) the
> data actually gets accessed. On this basis, signed_cons() also gets
> adjusted.
>
> gas/
> 2021-06-XX  Jan Beulich  <jbeulich@suse.com>
>
>         * config/tc-i386.c (extend_to_address): New.
>         (x86_cons, i386_finalize_immediate, md_apply_fix): Use it.
>         (signed_cons): Use object_64bit.
>         * testsuite/gas/i386/wrap32.s, testsuite/gas/i386/wrap32-data.d,
>         testsuite/gas/i386/wrap32-text.d: New.
>         * testsuite/gas/i386/i386.exp: Run new tests.
>
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -2457,6 +2457,19 @@ fits_in_unsigned_long (addressT num ATTR
>  #endif
>  }                              /* fits_in_unsigned_long() */
>
> +static INLINE valueT extend_to_address (addressT num)
> +{
> +#ifdef BFD64
> +  if (fits_in_unsigned_long(num))
> +    return (num ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
> +
> +  if (!fits_in_signed_long (num))
> +    return num & 0xffffffff;
> +#endif

Shouldn't this check apply only to 32-bit objects?

> +  return num;
> +}
> +
>  static INLINE int
>  fits_in_disp8 (offsetT num)
>  {
> @@ -10457,13 +10470,17 @@ x86_cons (expressionS *exp, int size)
>    if (intel_syntax)
>      i386_intel_simplify (exp);
>
> +  /* If not 64bit, massage value, to account for wraparound when !BFD64.  */
> +  if (size == 4 && exp->X_op == O_constant && !object_64bit)
> +    exp->X_add_number = extend_to_address (exp->X_add_number);
> +
>    return got_reloc;
>  }
>
>  static void
>  signed_cons (int size)
>  {
> -  if (flag_code == CODE_64BIT)
> +  if (object_64bit)
>      cons_sign = 1;
>    cons (size);
>    cons_sign = -1;
> @@ -10718,11 +10735,11 @@ i386_finalize_immediate (segT exp_seg AT
>      {
>        /* Size it properly later.  */
>        i.types[this_operand].bitfield.imm64 = 1;
> -      /* If not 64bit, sign extend val.  */
> -      if (flag_code != CODE_64BIT
> -         && (exp->X_add_number & ~(((addressT) 2 << 31) - 1)) == 0)
> -       exp->X_add_number
> -         = (exp->X_add_number ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31);
> +
> +      /* If not 64bit, sign/zero extend val, to account for wraparound
> +        when !BFD64.  */
> +      if (flag_code != CODE_64BIT)
> +       exp->X_add_number = extend_to_address (exp->X_add_number);
>      }
>  #if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
>    else if (OUTPUT_FLAVOR == bfd_target_aout_flavour
> @@ -12640,6 +12657,11 @@ md_apply_fix (fixS *fixP, valueT *valP,
>         break;
>        }
>  #endif /* defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)  */
> +
> +  /* If not 64bit, massage value, to account for wraparound when !BFD64.  */
> +  if (!object_64bit)
> +    value = extend_to_address (value);
> +
>    *valP = value;
>  #endif /* !defined (TE_Mach)  */
>
> --- a/gas/testsuite/gas/i386/i386.exp
> +++ b/gas/testsuite/gas/i386/i386.exp
> @@ -148,6 +148,8 @@ if [gas_32_check] then {
>      run_dump_test "addr32"
>      run_dump_test "code16"
>      run_list_test "oversized16" "-al"
> +    run_dump_test "wrap32-text"
> +    run_dump_test "wrap32-data"
>      run_dump_test "sse4_1"
>      run_dump_test "sse4_1-intel"
>      run_dump_test "sse4_2"
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/wrap32-data.d
> @@ -0,0 +1,23 @@
> +#name: i386 32-bit wrapping calculations (data/ELF)
> +#source: wrap32.s
> +#objdump: -rsj .data
> +
> +.*: +file format .*
> +
> +RELOCATION RECORDS FOR \[\.data\]:
> +
> +OFFSET +TYPE +VALUE *
> +0*10 (R_386_32|dir32) *sym
> +0*14 (R_386_32|dir32) *sym
> +0*18 (R_386_32|dir32) *sym
> +0*1c (R_386_32|dir32) *sym
> +0*30 (R_386_32|dir32) *sym
> +0*34 (R_386_32|dir32) *sym
> +0*38 (R_386_32|dir32) *sym
> +0*3c (R_386_32|dir32) *sym
> +
> +Contents of section .data:
> + 0+00 f4 ?00 ?00 ?00 f4 ?00 ?00 ?00 90 ?00 ?00 ?00 90 ?00 ?00 ?00 .*
> + 0+10 00 ?ff ?ff ?ff 00 ?ff ?ff ?ff f4 ?00 ?00 ?00 f4 ?00 ?00 ?00 .*
> + 0+20 f4 ?02 ?00 ?70 f4 ?00 ?00 ?80 90 ?02 ?00 ?70 90 ?00 ?00 ?80 .*
> + 0+30 00 ?01 ?00 ?70 00 ?ff ?ff ?7f f4 ?02 ?00 ?70 f4 ?00 ?00 ?80 .*
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/wrap32-text.d
> @@ -0,0 +1,43 @@
> +#name: i386 32-bit wrapping calculations (text)
> +#source: wrap32.s
> +#objdump: -dwr
> +
> +.*: +file format .*
> +
> +Disassembly of section .text:
> +
> +0+ <wrap>:
> +[      ]*[0-9a-f]+:[   ]+b8 f4 00 00 00        mov    \$0xf4,%eax
> +[      ]*[0-9a-f]+:[   ]+ba f4 00 00 00        mov    \$0xf4,%edx
> +[      ]*[0-9a-f]+:[   ]+b8 90 00 00 00        mov    \$0x90,%eax
> +[      ]*[0-9a-f]+:[   ]+ba 90 00 00 00        mov    \$0x90,%edx
> +[      ]*[0-9a-f]+:[   ]+b8 00 ff ff ff        mov    \$0xffffff00,%eax[       ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+ba 00 ff ff ff        mov    \$0xffffff00,%edx[       ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+b8 f4 00 00 00        mov    \$0xf4,%eax[     ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+ba f4 00 00 00        mov    \$0xf4,%edx[     ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+c7 00 f4 00 00 00     movl   \$0xf4,\(%eax\)
> +[      ]*[0-9a-f]+:[   ]+c7 02 f4 00 00 00     movl   \$0xf4,\(%edx\)
> +[      ]*[0-9a-f]+:[   ]+c7 00 90 00 00 00     movl   \$0x90,\(%eax\)
> +[      ]*[0-9a-f]+:[   ]+c7 02 90 00 00 00     movl   \$0x90,\(%edx\)
> +[      ]*[0-9a-f]+:[   ]+c7 00 00 ff ff ff     movl   \$0xffffff00,\(%eax\)[   ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+c7 02 00 ff ff ff     movl   \$0xffffff00,\(%edx\)[   ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+c7 00 f4 00 00 00     movl   \$0xf4,\(%eax\)[         ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+c7 02 f4 00 00 00     movl   \$0xf4,\(%edx\)[         ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 c1 f4 00 00 00     add    \$0xf4,%ecx
> +[      ]*[0-9a-f]+:[   ]+81 c2 f4 00 00 00     add    \$0xf4,%edx
> +[      ]*[0-9a-f]+:[   ]+81 c1 90 00 00 00     add    \$0x90,%ecx
> +[      ]*[0-9a-f]+:[   ]+81 c2 90 00 00 00     add    \$0x90,%edx
> +[      ]*[0-9a-f]+:[   ]+81 c1 00 ff ff ff     add    \$0xffffff00,%ecx[       ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 c2 00 ff ff ff     add    \$0xffffff00,%edx[       ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 c1 f4 00 00 00     add    \$0xf4,%ecx[     ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 c2 f4 00 00 00     add    \$0xf4,%edx[     ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 00 f4 00 00 00     addl   \$0xf4,\(%eax\)
> +[      ]*[0-9a-f]+:[   ]+81 02 f4 00 00 00     addl   \$0xf4,\(%edx\)
> +[      ]*[0-9a-f]+:[   ]+81 00 90 00 00 00     addl   \$0x90,\(%eax\)
> +[      ]*[0-9a-f]+:[   ]+81 02 90 00 00 00     addl   \$0x90,\(%edx\)
> +[      ]*[0-9a-f]+:[   ]+81 00 00 ff ff ff     addl   \$0xffffff00,\(%eax\)[   ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 02 00 ff ff ff     addl   \$0xffffff00,\(%edx\)[   ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 00 f4 00 00 00     addl   \$0xf4,\(%eax\)[         ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+81 02 f4 00 00 00     addl   \$0xf4,\(%edx\)[         ]+[0-9a-f]+: (R_386_32|dir32)[  ]+sym
> +[      ]*[0-9a-f]+:[   ]+c3                    ret *
> +#pass
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/wrap32.s
> @@ -0,0 +1,60 @@
> +       .text
> +wrap:
> +       mov     $500 - 0x100, %eax
> +       mov     $500 + 0xffffff00, %edx
> +       mov     $val - 0x100, %eax
> +       mov     $val + 0xffffff00, %edx
> +       mov     $sym - 0x100, %eax
> +       mov     $sym + 0xffffff00, %edx
> +       mov     $sym + 500 - 0x100, %eax
> +       mov     $sym + 500 + 0xffffff00, %edx
> +
> +       movl    $500 - 0x100, (%eax)
> +       movl    $500 + 0xffffff00, (%edx)
> +       movl    $val - 0x100, (%eax)
> +       movl    $val + 0xffffff00, (%edx)
> +       movl    $sym - 0x100, (%eax)
> +       movl    $sym + 0xffffff00, (%edx)
> +       movl    $sym + 500 - 0x100, (%eax)
> +       movl    $sym + 500 + 0xffffff00, (%edx)
> +
> +       add     $500 - 0x100, %ecx
> +       add     $500 + 0xffffff00, %edx
> +       add     $val - 0x100, %ecx
> +       add     $val + 0xffffff00, %edx
> +       add     $sym - 0x100, %ecx
> +       add     $sym + 0xffffff00, %edx
> +       add     $sym + 500 - 0x100, %ecx
> +       add     $sym + 500 + 0xffffff00, %edx
> +
> +       addl    $500 - 0x100, (%eax)
> +       addl    $500 + 0xffffff00, (%edx)
> +       addl    $val - 0x100, (%eax)
> +       addl    $val + 0xffffff00, (%edx)
> +       addl    $sym - 0x100, (%eax)
> +       addl    $sym + 0xffffff00, (%edx)
> +       addl    $sym + 500 - 0x100, (%eax)
> +       addl    $sym + 500 + 0xffffff00, (%edx)
> +
> +       ret
> +
> +       .data
> +       .long 500 - 0x100
> +       .long 500 + 0xffffff00
> +       .long val - 0x100
> +       .long val + 0xffffff00
> +       .long sym - 0x100
> +       .long sym + 0xffffff00
> +       .long sym + 500 - 0x100
> +       .long sym + 500 + 0xffffff00
> +
> +       .slong 500 - 0x8fffff00
> +       .slong 500 + 0x7fffff00
> +       .slong val - 0x8fffff00
> +       .slong val + 0x7fffff00
> +       .slong sym - 0x8fffff00
> +       .slong sym + 0x7fffff00
> +       .slong sym + 500 - 0x8fffff00
> +       .slong sym + 500 + 0x7fffff00
> +
> +       .equ val, 400
>


-- 
H.J.


More information about the Binutils mailing list