Attachment "0004-tclExecute-Fix-for-CHERI-by-not-assuming-ptrdiff_t-i.patch" to
ticket [37108037b9]
added by
jrtc27
2022-08-12 23:20:46.
From 2d7a6cedc5eeed32adfe4cff14cba175f8b46c2a Mon Sep 17 00:00:00 2001
From: Jessica Clarke <[email protected]>
Date: Fri, 12 Aug 2022 19:59:24 +0100
Subject: [PATCH 4/8] tclExecute: Fix for CHERI by not assuming ptrdiff_t is a
pointer
This is needed to support CHERI, and thus Arm's experimental Morello
prototype, where pointers are implemented using unforgeable capabilities
that include bounds and permissions metadata to provide fine-grained
spatial and referential memory safety, as well as revocation by sweeping
memory to provide heap temporal memory safety.
ptrdiff_t is an integer type that can hold a signed offset within an
object. On CHERI, this is a word-sized integer, but pointers are
capabilities, twice the size of that. The type pointed to by catchTop
must be the same size as the actual object stack entries (Tcl_Obj *) but
catchTop is currently a ptrdiff_t * so on CHERI this does not currently
hold, giving similar behaviour as sen on 64-bit Windows with the initial
backed-out fix for bug 3274728.
Instead, use a pointer type for catchTop's pointee type. We could use
intptr_t and that would work on CHERI, but the C standard does not in
fact guarantee that (u)intptr_t are the same size as object pointers,
merely that a pointer can be cast to (u)intptr_t and back losslessly
(thus, (u)int64_t would be a conforming, if foolish, implementation of
(u)intptr_t on a system where pointers themselves are represented as
32-bit integers). To be sure the sizes agree, use Tcl_Obj * as the
pointee type for catchTop as well and (un)wrap with PTR2INT/INT2PTR as
needed; this also allows stack to be a Tcl_Obj *[1] and removes casting
in initCatchTop and initTosPtr, making it clear these types are meant to
be the same.
---
generic/tclExecute.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index c8d2869ae..eccf0e1ee 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -111,11 +111,11 @@ size_t tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
typedef struct {
ByteCode *codePtr; /* Constant until the BC returns */
/* -----------------------------------------*/
- ptrdiff_t *catchTop; /* These fields are used on return TO this */
+ Tcl_Obj **catchTop; /* These fields are used on return TO this */
Tcl_Obj *auxObjList; /* this level: they record the state when a */
CmdFrame cmdFrame; /* new codePtr was received for NR */
/* execution. */
- void *stack[1]; /* Start of the actual combined catch and obj
+ Tcl_Obj *stack[1]; /* Start of the actual combined catch and obj
* stacks; the struct will be expanded as
* necessary */
} TEBCdata;
@@ -1878,8 +1878,8 @@ ArgumentBCEnter(
*----------------------------------------------------------------------
*/
#define bcFramePtr (&TD->cmdFrame)
-#define initCatchTop ((ptrdiff_t *) (TD->stack-1))
-#define initTosPtr ((Tcl_Obj **) (initCatchTop+codePtr->maxExceptDepth))
+#define initCatchTop (TD->stack-1)
+#define initTosPtr (initCatchTop+codePtr->maxExceptDepth)
#define esPtr (iPtr->execEnvPtr->execStackPtr)
int
@@ -6411,7 +6411,7 @@ TEBCresume(
* stack.
*/
- *(++catchTop) = CURR_DEPTH;
+ *(++catchTop) = INT2PTR(CURR_DEPTH);
TRACE(("%u => catchTop=%d, stackTop=%d\n",
TclGetUInt4AtPtr(pc+1), (int) (catchTop - initCatchTop - 1),
(int) CURR_DEPTH));
@@ -7326,8 +7326,8 @@ TEBCresume(
while (auxObjList) {
if ((catchTop != initCatchTop)
- && (*catchTop > (ptrdiff_t)
- auxObjList->internalRep.twoPtrValue.ptr2)) {
+ && (PTR2INT(*catchTop) >
+ PTR2INT(auxObjList->internalRep.twoPtrValue.ptr2))) {
break;
}
POP_TAUX_OBJ();
@@ -7402,7 +7402,7 @@ TEBCresume(
*/
processCatch:
- while (CURR_DEPTH > *catchTop) {
+ while (CURR_DEPTH > PTR2INT(*catchTop)) {
valuePtr = POP_OBJECT();
TclDecrRefCount(valuePtr);
}
@@ -7411,7 +7411,7 @@ TEBCresume(
fprintf(stdout, " ... found catch at %" TCL_Z_MODIFIER "u, catchTop=%d, "
"unwound to %ld, new pc %" TCL_Z_MODIFIER "u\n",
rangePtr->codeOffset, (int) (catchTop - initCatchTop - 1),
- (long)*catchTop, rangePtr->catchOffset);
+ (long)PTR2INT(*catchTop), rangePtr->catchOffset);
}
#endif
pc = (codePtr->codeStart + rangePtr->catchOffset);
--
2.34.GIT