ix86: wrap constants
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.
This commit is contained in:
parent
6bee34a1dc
commit
a442cac508
6 changed files with 165 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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) */
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
23
gas/testsuite/gas/i386/wrap32-data.d
Normal file
23
gas/testsuite/gas/i386/wrap32-data.d
Normal file
|
@ -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 .*
|
43
gas/testsuite/gas/i386/wrap32-text.d
Normal file
43
gas/testsuite/gas/i386/wrap32-text.d
Normal file
|
@ -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
|
60
gas/testsuite/gas/i386/wrap32.s
Normal file
60
gas/testsuite/gas/i386/wrap32.s
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue