From 9a01ec4c0368048fb5ea1ba1b3af9afbd651b529 Mon Sep 17 00:00:00 2001 From: Sergey Belyashov Date: Thu, 20 May 2021 16:14:10 +0100 Subject: [PATCH] Fix overflow detection in the Z80 assembler. * config/tc-z80.c (emit_data_val): Warn on constant overflow. (signed_overflow): New function. (unsigned_overflow): New function. (is_overflow): Use new functions. (md_apply_fix): Use signed_overflow. * testsuite/gas/z80/ez80_adl_suf.d: Fix test. * testsuite/gas/z80/ez80_isuf.s: Likewise. * testsuite/gas/z80/ez80_z80_suf.d: Likewise. --- gas/ChangeLog | 11 + gas/config/tc-z80.c | 32 ++- gas/testsuite/gas/z80/ez80_adl_suf.d | 2 +- gas/testsuite/gas/z80/ez80_isuf.s | 380 +++++++++++++-------------- gas/testsuite/gas/z80/ez80_z80_suf.d | 2 +- 5 files changed, 227 insertions(+), 200 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 75eb501cf7b..b9a59b66b80 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2021-05-20 Sergey Belyashov + + * config/tc-z80.c (emit_data_val): Warn on constant overflow. + (signed_overflow): New function. + (unsigned_overflow): New function. + (is_overflow): Use new functions. + (md_apply_fix): Use signed_overflow. + * testsuite/gas/z80/ez80_adl_suf.d: Fix test. + * testsuite/gas/z80/ez80_isuf.s: Likewise. + * testsuite/gas/z80/ez80_z80_suf.d: Likewise. + 2021-05-20 Nicolas Boulenguez PR 27888 diff --git a/gas/config/tc-z80.c b/gas/config/tc-z80.c index 2146e675672..47d1405c2b6 100644 --- a/gas/config/tc-z80.c +++ b/gas/config/tc-z80.c @@ -175,6 +175,11 @@ match_ext_table [] = {"xdcb", INS_ROT_II_LD, 0, 0, "instructions like RL (IX+d),R (DD/FD CB dd oo)" } }; + +static int signed_overflow (signed long value, unsigned bitsize); +static int unsigned_overflow (unsigned long value, unsigned bitsize); +static int is_overflow (long value, unsigned bitsize); + static void setup_march (const char *name, int *ok, int *err, int *mode) { @@ -1129,6 +1134,8 @@ emit_data_val (expressionS * val, int size) if (val->X_op == O_constant) { int i; + if (is_overflow (val->X_add_number, size*8)) + as_warn ( _("%d-bit overflow (%+ld)"), size*8, val->X_add_number); for (i = 0; i < size; ++i) p[i] = (char)(val->X_add_number >> (i*8)); return; @@ -3693,16 +3700,25 @@ md_assemble (char *str) input_line_pointer = old_ptr; } +static int +signed_overflow (signed long value, unsigned bitsize) +{ + signed long max = (signed long)(1UL << (bitsize-1)); + return value < -max || value >= max; +} + +static int +unsigned_overflow (unsigned long value, unsigned bitsize) +{ + return (value >> bitsize) != 0; +} + static int is_overflow (long value, unsigned bitsize) { - long fieldmask = (2UL << (bitsize - 1)) - 1; - long signmask = ~fieldmask; - long a = value & fieldmask; - long ss = a & signmask; - if (ss != 0 && ss != (signmask & fieldmask)) - return 1; - return 0; + if (value < 0) + return signed_overflow (value, bitsize); + return unsigned_overflow ((unsigned long)value, bitsize); } void @@ -3743,7 +3759,7 @@ md_apply_fix (fixS * fixP, valueT* valP, segT seg) { case BFD_RELOC_8_PCREL: case BFD_RELOC_Z80_DISP8: - if (fixP->fx_done && (val < -0x80 || val > 0x7f)) + if (fixP->fx_done && signed_overflow (val, 8)) as_bad_where (fixP->fx_file, fixP->fx_line, _("8-bit signed offset out of range (%+ld)"), val); *p_lit++ = val; diff --git a/gas/testsuite/gas/z80/ez80_adl_suf.d b/gas/testsuite/gas/z80/ez80_adl_suf.d index 0e223624d63..6b92b1daa56 100644 --- a/gas/testsuite/gas/z80/ez80_adl_suf.d +++ b/gas/testsuite/gas/z80/ez80_adl_suf.d @@ -1,4 +1,4 @@ -#as: -march=ez80+adl +#as: -march=ez80+adl --defsym VALUE=0x123456 #objdump: -d #name: eZ80 instructions with sufficies in ADL cpu mode #source: ez80_isuf.s diff --git a/gas/testsuite/gas/z80/ez80_isuf.s b/gas/testsuite/gas/z80/ez80_isuf.s index 8b20852a28f..145b56e9b84 100644 --- a/gas/testsuite/gas/z80/ez80_isuf.s +++ b/gas/testsuite/gas/z80/ez80_isuf.s @@ -1,121 +1,121 @@ - call.s 0x123456 - call.s c,0x123456 - call.s m,0x123456 - call.s nc,0x123456 - call.s nz,0x123456 - call.s p,0x123456 - call.s pe,0x123456 - call.s po,0x123456 - call.s z,0x123456 - jp.s 0x123456 - jp.s c,0x123456 - jp.s m,0x123456 - jp.s nc,0x123456 - jp.s nz,0x123456 - jp.s p,0x123456 - jp.s pe,0x123456 - jp.s po,0x123456 - jp.s z,0x123456 - ld.s (0x123456),a - ld.s (0x123456),bc - ld.s (0x123456),de - ld.s (0x123456),hl - ld.s (0x123456),ix - ld.s (0x123456),iy - ld.s (0x123456),sp - ld.s a,(0x123456) - ld.s bc,(0x123456) - ld.s bc,0x123456 - ld.s de,(0x123456) - ld.s de,0x123456 - ld.s hl,(0x123456) - ld.s hl,0x123456 - ld.s ix,(0x123456) - ld.s ix,0x123456 - ld.s iy,(0x123456) - ld.s iy,0x123456 - ld.s sp,(0x123456) - ld.s sp,0x123456 + call.s VALUE + call.s c,VALUE + call.s m,VALUE + call.s nc,VALUE + call.s nz,VALUE + call.s p,VALUE + call.s pe,VALUE + call.s po,VALUE + call.s z,VALUE + jp.s VALUE + jp.s c,VALUE + jp.s m,VALUE + jp.s nc,VALUE + jp.s nz,VALUE + jp.s p,VALUE + jp.s pe,VALUE + jp.s po,VALUE + jp.s z,VALUE + ld.s (VALUE),a + ld.s (VALUE),bc + ld.s (VALUE),de + ld.s (VALUE),hl + ld.s (VALUE),ix + ld.s (VALUE),iy + ld.s (VALUE),sp + ld.s a,(VALUE) + ld.s bc,(VALUE) + ld.s bc,VALUE + ld.s de,(VALUE) + ld.s de,VALUE + ld.s hl,(VALUE) + ld.s hl,VALUE + ld.s ix,(VALUE) + ld.s ix,VALUE + ld.s iy,(VALUE) + ld.s iy,VALUE + ld.s sp,(VALUE) + ld.s sp,VALUE .page - call.l 0x123456 - call.l c,0x123456 - call.l m,0x123456 - call.l nc,0x123456 - call.l nz,0x123456 - call.l p,0x123456 - call.l pe,0x123456 - call.l po,0x123456 - call.l z,0x123456 - jp.l 0x123456 - jp.l c,0x123456 - jp.l m,0x123456 - jp.l nc,0x123456 - jp.l nz,0x123456 - jp.l p,0x123456 - jp.l pe,0x123456 - jp.l po,0x123456 - jp.l z,0x123456 - ld.l (0x123456),a - ld.l (0x123456),bc - ld.l (0x123456),de - ld.l (0x123456),hl - ld.l (0x123456),ix - ld.l (0x123456),iy - ld.l (0x123456),sp - ld.l a,(0x123456) - ld.l bc,(0x123456) - ld.l bc,0x123456 - ld.l de,(0x123456) - ld.l de,0x123456 - ld.l hl,(0x123456) - ld.l hl,0x123456 - ld.l ix,(0x123456) - ld.l ix,0x123456 - ld.l iy,(0x123456) - ld.l iy,0x123456 - ld.l sp,(0x123456) - ld.l sp,0x123456 + call.l VALUE + call.l c,VALUE + call.l m,VALUE + call.l nc,VALUE + call.l nz,VALUE + call.l p,VALUE + call.l pe,VALUE + call.l po,VALUE + call.l z,VALUE + jp.l VALUE + jp.l c,VALUE + jp.l m,VALUE + jp.l nc,VALUE + jp.l nz,VALUE + jp.l p,VALUE + jp.l pe,VALUE + jp.l po,VALUE + jp.l z,VALUE + ld.l (VALUE),a + ld.l (VALUE),bc + ld.l (VALUE),de + ld.l (VALUE),hl + ld.l (VALUE),ix + ld.l (VALUE),iy + ld.l (VALUE),sp + ld.l a,(VALUE) + ld.l bc,(VALUE) + ld.l bc,VALUE + ld.l de,(VALUE) + ld.l de,VALUE + ld.l hl,(VALUE) + ld.l hl,VALUE + ld.l ix,(VALUE) + ld.l ix,VALUE + ld.l iy,(VALUE) + ld.l iy,VALUE + ld.l sp,(VALUE) + ld.l sp,VALUE .page - call.is 0x123456 - call.is c,0x123456 - call.is m,0x123456 - call.is nc,0x123456 - call.is nz,0x123456 - call.is p,0x123456 - call.is pe,0x123456 - call.is po,0x123456 - call.is z,0x123456 - jp.is 0x123456 - jp.is c,0x123456 - jp.is m,0x123456 - jp.is nc,0x123456 - jp.is nz,0x123456 - jp.is p,0x123456 - jp.is pe,0x123456 - jp.is po,0x123456 - jp.is z,0x123456 - ld.is (0x123456),a - ld.is (0x123456),bc - ld.is (0x123456),de - ld.is (0x123456),hl - ld.is (0x123456),ix - ld.is (0x123456),iy - ld.is (0x123456),sp - ld.is a,(0x123456) - ld.is bc,(0x123456) - ld.is bc,0x123456 - ld.is de,(0x123456) - ld.is de,0x123456 - ld.is hl,(0x123456) - ld.is hl,0x123456 - ld.is ix,(0x123456) - ld.is ix,0x123456 - ld.is iy,(0x123456) - ld.is iy,0x123456 - ld.is sp,(0x123456) - ld.is sp,0x123456 + call.is 0x3456 + call.is c,0x3456 + call.is m,0x3456 + call.is nc,0x3456 + call.is nz,0x3456 + call.is p,0x3456 + call.is pe,0x3456 + call.is po,0x3456 + call.is z,0x3456 + jp.is 0x3456 + jp.is c,0x3456 + jp.is m,0x3456 + jp.is nc,0x3456 + jp.is nz,0x3456 + jp.is p,0x3456 + jp.is pe,0x3456 + jp.is po,0x3456 + jp.is z,0x3456 + ld.is (0x3456),a + ld.is (0x3456),bc + ld.is (0x3456),de + ld.is (0x3456),hl + ld.is (0x3456),ix + ld.is (0x3456),iy + ld.is (0x3456),sp + ld.is a,(0x3456) + ld.is bc,(0x3456) + ld.is bc,0x3456 + ld.is de,(0x3456) + ld.is de,0x3456 + ld.is hl,(0x3456) + ld.is hl,0x3456 + ld.is ix,(0x3456) + ld.is ix,0x3456 + ld.is iy,(0x3456) + ld.is iy,0x3456 + ld.is sp,(0x3456) + ld.is sp,0x3456 .page call.il 0x123456 @@ -158,84 +158,84 @@ ld.il sp,0x123456 .page - call.sis 0x123456 - call.sis c,0x123456 - call.sis m,0x123456 - call.sis nc,0x123456 - call.sis nz,0x123456 - call.sis p,0x123456 - call.sis pe,0x123456 - call.sis po,0x123456 - call.sis z,0x123456 - jp.sis 0x123456 - jp.sis c,0x123456 - jp.sis m,0x123456 - jp.sis nc,0x123456 - jp.sis nz,0x123456 - jp.sis p,0x123456 - jp.sis pe,0x123456 - jp.sis po,0x123456 - jp.sis z,0x123456 - ld.sis (0x123456),a - ld.sis (0x123456),bc - ld.sis (0x123456),de - ld.sis (0x123456),hl - ld.sis (0x123456),ix - ld.sis (0x123456),iy - ld.sis (0x123456),sp - ld.sis a,(0x123456) - ld.sis bc,(0x123456) - ld.sis bc,0x123456 - ld.sis de,(0x123456) - ld.sis de,0x123456 - ld.sis hl,(0x123456) - ld.sis hl,0x123456 - ld.sis ix,(0x123456) - ld.sis ix,0x123456 - ld.sis iy,(0x123456) - ld.sis iy,0x123456 - ld.sis sp,(0x123456) - ld.sis sp,0x123456 + call.sis 0x3456 + call.sis c,0x3456 + call.sis m,0x3456 + call.sis nc,0x3456 + call.sis nz,0x3456 + call.sis p,0x3456 + call.sis pe,0x3456 + call.sis po,0x3456 + call.sis z,0x3456 + jp.sis 0x3456 + jp.sis c,0x3456 + jp.sis m,0x3456 + jp.sis nc,0x3456 + jp.sis nz,0x3456 + jp.sis p,0x3456 + jp.sis pe,0x3456 + jp.sis po,0x3456 + jp.sis z,0x3456 + ld.sis (0x3456),a + ld.sis (0x3456),bc + ld.sis (0x3456),de + ld.sis (0x3456),hl + ld.sis (0x3456),ix + ld.sis (0x3456),iy + ld.sis (0x3456),sp + ld.sis a,(0x3456) + ld.sis bc,(0x3456) + ld.sis bc,0x3456 + ld.sis de,(0x3456) + ld.sis de,0x3456 + ld.sis hl,(0x3456) + ld.sis hl,0x3456 + ld.sis ix,(0x3456) + ld.sis ix,0x3456 + ld.sis iy,(0x3456) + ld.sis iy,0x3456 + ld.sis sp,(0x3456) + ld.sis sp,0x3456 .page - call.lis 0x123456 - call.lis c,0x123456 - call.lis m,0x123456 - call.lis nc,0x123456 - call.lis nz,0x123456 - call.lis p,0x123456 - call.lis pe,0x123456 - call.lis po,0x123456 - call.lis z,0x123456 - jp.lis 0x123456 - jp.lis c,0x123456 - jp.lis m,0x123456 - jp.lis nc,0x123456 - jp.lis nz,0x123456 - jp.lis p,0x123456 - jp.lis pe,0x123456 - jp.lis po,0x123456 - jp.lis z,0x123456 - ld.lis (0x123456),a - ld.lis (0x123456),bc - ld.lis (0x123456),de - ld.lis (0x123456),hl - ld.lis (0x123456),ix - ld.lis (0x123456),iy - ld.lis (0x123456),sp - ld.lis a,(0x123456) - ld.lis bc,(0x123456) - ld.lis bc,0x123456 - ld.lis de,(0x123456) - ld.lis de,0x123456 - ld.lis hl,(0x123456) - ld.lis hl,0x123456 - ld.lis ix,(0x123456) - ld.lis ix,0x123456 - ld.lis iy,(0x123456) - ld.lis iy,0x123456 - ld.lis sp,(0x123456) - ld.lis sp,0x123456 + call.lis 0x3456 + call.lis c,0x3456 + call.lis m,0x3456 + call.lis nc,0x3456 + call.lis nz,0x3456 + call.lis p,0x3456 + call.lis pe,0x3456 + call.lis po,0x3456 + call.lis z,0x3456 + jp.lis 0x3456 + jp.lis c,0x3456 + jp.lis m,0x3456 + jp.lis nc,0x3456 + jp.lis nz,0x3456 + jp.lis p,0x3456 + jp.lis pe,0x3456 + jp.lis po,0x3456 + jp.lis z,0x3456 + ld.lis (0x3456),a + ld.lis (0x3456),bc + ld.lis (0x3456),de + ld.lis (0x3456),hl + ld.lis (0x3456),ix + ld.lis (0x3456),iy + ld.lis (0x3456),sp + ld.lis a,(0x3456) + ld.lis bc,(0x3456) + ld.lis bc,0x3456 + ld.lis de,(0x3456) + ld.lis de,0x3456 + ld.lis hl,(0x3456) + ld.lis hl,0x3456 + ld.lis ix,(0x3456) + ld.lis ix,0x3456 + ld.lis iy,(0x3456) + ld.lis iy,0x3456 + ld.lis sp,(0x3456) + ld.lis sp,0x3456 .page call.sil 0x123456 diff --git a/gas/testsuite/gas/z80/ez80_z80_suf.d b/gas/testsuite/gas/z80/ez80_z80_suf.d index 4fa7cd9c153..126940271d6 100644 --- a/gas/testsuite/gas/z80/ez80_z80_suf.d +++ b/gas/testsuite/gas/z80/ez80_z80_suf.d @@ -1,4 +1,4 @@ -#as: -march=ez80 +#as: -march=ez80 --defsym VALUE=0x3456 #objdump: -d #name: eZ80 instructions with sufficies in Z80 cpu mode #source: ez80_isuf.s