aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-i386.c34
-rw-r--r--gas/testsuite/gas/i386/i386.exp2
-rw-r--r--gas/testsuite/gas/i386/wrap32-data.d23
-rw-r--r--gas/testsuite/gas/i386/wrap32-text.d43
-rw-r--r--gas/testsuite/gas/i386/wrap32.s60
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