From c64fa52f7cd434953ba1eced8a6489429e8fcff0 Mon Sep 17 00:00:00 2001 From: dawg Date: Wed, 21 Sep 2011 01:01:07 +0200 Subject: [PATCH 1/3] check for under/overflows when calculating block displacement - instructions like loop only allow 1-byte displacements and silently wrap currently --- src/backend/cc.h | 2 +- src/backend/cod3.c | 28 ++++++++++++++++++++++++---- test/fail_compilation/fail353.d | 14 ++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 test/fail_compilation/fail353.d diff --git a/src/backend/cc.h b/src/backend/cc.h index 5eb15d717599..6fcd07168e7e 100644 --- a/src/backend/cc.h +++ b/src/backend/cc.h @@ -212,7 +212,7 @@ typedef struct Srcpos #endif #if MARS const char *Sfilename; - #define srcpos_name(p) ((p).SFname) + #define srcpos_name(p) ((p)->Sfilename) #endif #if M_UNIX short Sfilnum; // file number diff --git a/src/backend/cod3.c b/src/backend/cod3.c index e515d1b4eb42..1094a7303b99 100644 --- a/src/backend/cod3.c +++ b/src/backend/cod3.c @@ -5419,7 +5419,6 @@ STATIC void do64bit(enum FL fl,union evc *uev,int flags) { char *p; symbol *s; targ_size_t ad; - long tmp; assert(I64); switch (fl) @@ -5505,7 +5504,6 @@ STATIC void do32bit(enum FL fl,union evc *uev,int flags, targ_size_t val) { char *p; symbol *s; targ_size_t ad; - long tmp; //printf("do32bit(flags = x%x)\n", flags); switch (fl) @@ -5615,6 +5613,7 @@ STATIC void do16bit(enum FL fl,union evc *uev,int flags) { char *p; symbol *s; targ_size_t ad; + targ_ptrdiff_t delta; switch (fl) { @@ -5669,7 +5668,17 @@ STATIC void do16bit(enum FL fl,union evc *uev,int flags) } break; case FLblock: /* displacement to another block */ - ad = uev->Vblock->Boffset - OFFSET() - 2; + delta = uev->Vblock->Boffset - OFFSET() - 2; + if (delta > 0x7FFF || delta < (short)0x8000) + { + if (uev->Vblock->Bsrcpos.Slinnum) + fprintf(stderr, "%s(%d): overflow %d for block displacement.\n", + uev->Vblock->Bsrcpos.Sfilename, uev->Vblock->Bsrcpos.Slinnum, delta); + else + fprintf(stderr, "Error: overflow %d for block displacement.\n", delta); + err_exit(); + } + ad = delta; L1: GENP(2,&ad); // displacement return; @@ -5690,6 +5699,7 @@ STATIC void do16bit(enum FL fl,union evc *uev,int flags) STATIC void do8bit(enum FL fl,union evc *uev) { char c; + targ_ptrdiff_t delta; switch (fl) { @@ -5697,7 +5707,17 @@ STATIC void do8bit(enum FL fl,union evc *uev) c = uev->Vuns; break; case FLblock: - c = uev->Vblock->Boffset - OFFSET() - 1; + delta = uev->Vblock->Boffset - OFFSET() - 1; + if (delta > 0x7F || delta < (char)0x80) + { + if (uev->Vblock->Bsrcpos.Slinnum) + fprintf(stderr, "%s(%d): overflow %d for block displacement.\n", + uev->Vblock->Bsrcpos.Sfilename, uev->Vblock->Bsrcpos.Slinnum, delta); + else + fprintf(stderr, "Error: overflow %d for block displacement.\n", delta); + err_exit(); + } + c = delta; #ifdef DEBUG assert(uev->Vblock->Boffset > OFFSET() || c != 0x7F); #endif diff --git a/test/fail_compilation/fail353.d b/test/fail_compilation/fail353.d new file mode 100644 index 000000000000..38d512e06f4d --- /dev/null +++ b/test/fail_compilation/fail353.d @@ -0,0 +1,14 @@ +void foo() +{ + enum NOP = 0x9090_9090_9090_9090; + + asm + { + L1: + dq NOP,NOP,NOP,NOP; // 32 + dq NOP,NOP,NOP,NOP; // 64 + dq NOP,NOP,NOP,NOP; // 96 + dq NOP,NOP,NOP,NOP; // 128 + loop L1; // signed underflow of rel8 + } +} From 0b9368504f2d3d21ab24db3bf16a3c66a8c40062 Mon Sep 17 00:00:00 2001 From: dawg Date: Wed, 21 Sep 2011 09:48:03 +0200 Subject: [PATCH 2/3] code review fixes - made 16-bit check an assertion (jump should be handled properly) - use ((narrow type)delta != delta) for checking overflow - fix printf long long - improve error message --- src/backend/cod3.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/backend/cod3.c b/src/backend/cod3.c index 1094a7303b99..0f2a404f8159 100644 --- a/src/backend/cod3.c +++ b/src/backend/cod3.c @@ -5613,7 +5613,6 @@ STATIC void do16bit(enum FL fl,union evc *uev,int flags) { char *p; symbol *s; targ_size_t ad; - targ_ptrdiff_t delta; switch (fl) { @@ -5668,17 +5667,13 @@ STATIC void do16bit(enum FL fl,union evc *uev,int flags) } break; case FLblock: /* displacement to another block */ - delta = uev->Vblock->Boffset - OFFSET() - 2; - if (delta > 0x7FFF || delta < (short)0x8000) + ad = uev->Vblock->Boffset - OFFSET() - 2; +#ifdef DEBUG { - if (uev->Vblock->Bsrcpos.Slinnum) - fprintf(stderr, "%s(%d): overflow %d for block displacement.\n", - uev->Vblock->Bsrcpos.Sfilename, uev->Vblock->Bsrcpos.Slinnum, delta); - else - fprintf(stderr, "Error: overflow %d for block displacement.\n", delta); - err_exit(); + targ_ptrdiff_t delta = uev->Vblock->Boffset - OFFSET() - 2; + assert((signed short)delta == delta); } - ad = delta; +#endif L1: GENP(2,&ad); // displacement return; @@ -5708,13 +5703,11 @@ STATIC void do8bit(enum FL fl,union evc *uev) break; case FLblock: delta = uev->Vblock->Boffset - OFFSET() - 1; - if (delta > 0x7F || delta < (char)0x80) + if ((signed char)delta != delta) { if (uev->Vblock->Bsrcpos.Slinnum) - fprintf(stderr, "%s(%d): overflow %d for block displacement.\n", - uev->Vblock->Bsrcpos.Sfilename, uev->Vblock->Bsrcpos.Slinnum, delta); - else - fprintf(stderr, "Error: overflow %d for block displacement.\n", delta); + fprintf(stderr, "%s(%d): ", uev->Vblock->Bsrcpos.Sfilename, uev->Vblock->Bsrcpos.Slinnum); + fprintf(stderr, "block displacement of %lld exceeds the maximum offset of -128 to 127.\n", (long long)delta); err_exit(); } c = delta; From c5e22f5f026fc0804794918d86302f8fb5d89b8f Mon Sep 17 00:00:00 2001 From: dawg Date: Wed, 21 Sep 2011 10:59:08 +0200 Subject: [PATCH 3/3] add reference to DMD version --- test/fail_compilation/fail353.d | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/fail_compilation/fail353.d b/test/fail_compilation/fail353.d index 38d512e06f4d..ba92bec5319e 100644 --- a/test/fail_compilation/fail353.d +++ b/test/fail_compilation/fail353.d @@ -9,6 +9,7 @@ void foo() dq NOP,NOP,NOP,NOP; // 64 dq NOP,NOP,NOP,NOP; // 96 dq NOP,NOP,NOP,NOP; // 128 - loop L1; // signed underflow of rel8 + // unnoticed signed underflow of rel8 with DMD2.056 + loop L1; } }