From 12c5f3231e480988c47a8c912ba2ea2ca0a95a0d Mon Sep 17 00:00:00 2001 From: Nick Briggs Date: Fri, 1 Jan 2021 14:08:41 -0800 Subject: [PATCH] Correct handling of return value of N_OP_unwind() The return value of N_OP_unwind is really of type LispPTR *, however it was declared as UNSIGNED (effectively uintptr_t) so that the ERROR_EXIT macro could be used to return an error indication (-1, =UINT_MAX). The call site checked for the error condition with (int)result < 0, not accounting for the case where a native pointer may have the high-order bit set. We correct this problem by declaring the return type as LispPTR *, and expand the ERROR_EXIT macro in place substituting (LispPTR *)(-1) as the error return value, and at the single call site check for equality with that same value. The test case was executing the opcode tester on a Raspberry Pi or a BeagleBone Black/Debian 10.3 where the non-error result was > 0xB0000000 modified: inc/inlineC.h modified: inc/unwinddefs.h modified: src/unwind.c --- inc/inlineC.h | 3 +-- inc/unwinddefs.h | 2 +- src/unwind.c | 9 ++++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/inc/inlineC.h b/inc/inlineC.h index 5950829..9d09aaf 100755 --- a/inc/inlineC.h +++ b/inc/inlineC.h @@ -852,8 +852,7 @@ nextop2; \ #define UNWIND(n, m) \ { \ - if ((INT)(CSTKPTRL = (LispPTR *) \ - N_OP_unwind(CSTKPTR, TOPOFSTACK, n, m)) < 0) \ + if ((CSTKPTRL = N_OP_unwind(CSTKPTR, TOPOFSTACK, n, m)) == (LispPTR *)-1) \ goto unwind_err; \ POP; \ nextop3; \ diff --git a/inc/unwinddefs.h b/inc/unwinddefs.h index 07789aa..cf8caaf 100644 --- a/inc/unwinddefs.h +++ b/inc/unwinddefs.h @@ -1,4 +1,4 @@ #ifndef UNWINDDEFS_H #define UNWINDDEFS_H 1 -UNSIGNED N_OP_unwind(register LispPTR *cstkptr, register LispPTR tos, int n, int keep); +LispPTR *N_OP_unwind(register LispPTR *cstkptr, register LispPTR tos, int n, int keep); #endif diff --git a/src/unwind.c b/src/unwind.c index f9d02af..b32b189 100644 --- a/src/unwind.c +++ b/src/unwind.c @@ -28,7 +28,7 @@ #include "unwinddefs.h" -UNSIGNED N_OP_unwind(register LispPTR *cstkptr, register LispPTR tos, int n, int keep) { +LispPTR *N_OP_unwind(register LispPTR *cstkptr, register LispPTR tos, int n, int keep) { register int num; /* number of UNBOUND slot */ register LispPTR *endptr; /* unwind limit */ register LispPTR *lastpvar; /* points PVar slot that is unbounded. */ @@ -64,7 +64,10 @@ UNSIGNED N_OP_unwind(register LispPTR *cstkptr, register LispPTR tos, int n, int if (endptr > cstkptr) { CurrentStackPTR = (DLword *)cstkptr; - ERROR_EXIT(tos); + /* this would be ERROR_EXIT(tos); but for having to return a pointer */ + TopOfStack = tos; + Error_Exit = 1; + return (LispPTR *)(-1); } *cstkptr++ = tos; @@ -85,7 +88,7 @@ UNSIGNED N_OP_unwind(register LispPTR *cstkptr, register LispPTR tos, int n, int /* endptr = cstkptr */ if (keep) { *(cstkptr++) = tos; } - return ((UNSIGNED)cstkptr); + return (cstkptr); } /* N_OP_unwind */