diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 9 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 34 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/i386.exp | 2 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/wrap32-data.d | 23 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/wrap32-text.d | 43 | ||||
-rw-r--r-- | gas/testsuite/gas/i386/wrap32.s | 60 |
6 files changed, 165 insertions, 6 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 67b4583..b1d6556 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2021-06-07 Jan Beulich <jbeulich@suse.com> + + * config/tc-i386.c (extend_to_32bit_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. + 2021-06-03 Alan Modra <amodra@gmail.com> PR 1202 diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index d344198..a6bc597 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2457,6 +2457,19 @@ fits_in_unsigned_long (addressT num ATTRIBUTE_UNUSED) #endif } /* fits_in_unsigned_long() */ +static INLINE valueT extend_to_32bit_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 + + 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_32bit_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 ATTRIBUTE_UNUSED, expressionS *exp, { /* 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_32bit_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, segT seg ATTRIBUTE_UNUSED) 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_32bit_address (value); + *valP = value; #endif /* !defined (TE_Mach) */ diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index a459c6f..efcccaf 100644 --- 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" diff --git a/gas/testsuite/gas/i386/wrap32-data.d b/gas/testsuite/gas/i386/wrap32-data.d new file mode 100644 index 0000000..bebec98 --- /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 .* diff --git a/gas/testsuite/gas/i386/wrap32-text.d b/gas/testsuite/gas/i386/wrap32-text.d new file mode 100644 index 0000000..3ebbd85 --- /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 diff --git a/gas/testsuite/gas/i386/wrap32.s b/gas/testsuite/gas/i386/wrap32.s new file mode 100644 index 0000000..0198484 --- /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 |