Attempt to support MTE on Android arm64

This commit is contained in:
K. Lange 2022-10-20 09:57:53 +09:00
parent a77a040d22
commit aec19e61ec
2 changed files with 31 additions and 2 deletions

View File

@ -72,6 +72,10 @@ ifdef KRK_NO_STRESS_GC
CFLAGS += -DKRK_NO_STRESS_GC=1 CFLAGS += -DKRK_NO_STRESS_GC=1
endif endif
ifdef KRK_HEAP_TAG_BYTE
CFLAGS += -DKRK_HEAP_TAG_BYTE=${KRK_HEAP_TAG_BYTE}
endif
.PHONY: help .PHONY: help
help: help:

View File

@ -188,12 +188,37 @@ typedef union {
double dbl; double dbl;
} KrkValueDbl; } KrkValueDbl;
#ifdef KRK_SANITIZE_OBJECT_POINTERS
/**
* Debugging tool for verifying we aren't trying to box NULL, which is not a valid object.
* Enable this and run the test suite and whatever else you can find.
*/
#include <assert.h>
static inline uintptr_t _krk_sanitize(uintptr_t input) {
assert(input != 0);
return input;
}
#else
#define _krk_sanitize(ptr) (ptr)
#endif
/**
* On platforms where heap pointers are tagged, we can try to force the tag bytes
* back into our truncated object pointers. On arm64 Android, you can try setting
* this to 0xb4 to fix issues with MTE.
*/
#ifdef KRK_HEAP_TAG_BYTE
#define KRK_HEAP_TAG ((uintptr_t)KRK_HEAP_TAG_BYTE << 56)
#else
#define KRK_HEAP_TAG 0
#endif
#define NONE_VAL(value) ((KrkValue)(KRK_VAL_MASK_LOW | KRK_VAL_MASK_NONE)) #define NONE_VAL(value) ((KrkValue)(KRK_VAL_MASK_LOW | KRK_VAL_MASK_NONE))
#define NOTIMPL_VAL(value) ((KrkValue)(KRK_VAL_MASK_LOW | KRK_VAL_MASK_NOTIMPL)) #define NOTIMPL_VAL(value) ((KrkValue)(KRK_VAL_MASK_LOW | KRK_VAL_MASK_NOTIMPL))
#define BOOLEAN_VAL(value) ((KrkValue)(((uint64_t)(value) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_BOOLEAN)) #define BOOLEAN_VAL(value) ((KrkValue)(((uint64_t)(value) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_BOOLEAN))
#define INTEGER_VAL(value) ((KrkValue)(((uint64_t)(value) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_INTEGER)) #define INTEGER_VAL(value) ((KrkValue)(((uint64_t)(value) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_INTEGER))
#define KWARGS_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_KWARGS)) #define KWARGS_VAL(value) ((KrkValue)((uint32_t)(value) | KRK_VAL_MASK_KWARGS))
#define OBJECT_VAL(value) ((KrkValue)(((uintptr_t)(value) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_OBJECT)) #define OBJECT_VAL(value) ((KrkValue)((_krk_sanitize((uintptr_t)(value)) & KRK_VAL_MASK_LOW) | KRK_VAL_MASK_OBJECT))
#define HANDLER_VAL(ty,ta) ((KrkValue)((uint32_t)((((uint16_t)ty) << 16) | ((uint16_t)ta)) | KRK_VAL_MASK_HANDLER)) #define HANDLER_VAL(ty,ta) ((KrkValue)((uint32_t)((((uint16_t)ty) << 16) | ((uint16_t)ta)) | KRK_VAL_MASK_HANDLER))
#define FLOATING_VAL(value) (((KrkValueDbl){.dbl = (value)}).val) #define FLOATING_VAL(value) (((KrkValueDbl){.dbl = (value)}).val)
@ -206,7 +231,7 @@ typedef union {
#define AS_NOTIMPL(value) ((krk_integer_type)((value) & KRK_VAL_MASK_LOW)) #define AS_NOTIMPL(value) ((krk_integer_type)((value) & KRK_VAL_MASK_LOW))
#define AS_HANDLER(value) ((uint32_t)((value) & KRK_VAL_MASK_LOW)) #define AS_HANDLER(value) ((uint32_t)((value) & KRK_VAL_MASK_LOW))
#define AS_OBJECT(value) ((KrkObj*)(uintptr_t)((value) & KRK_VAL_MASK_LOW)) #define AS_OBJECT(value) ((KrkObj*)(uintptr_t)(((value) & KRK_VAL_MASK_LOW) | KRK_HEAP_TAG))
#define AS_FLOATING(value) (((KrkValueDbl){.val = (value)}).dbl) #define AS_FLOATING(value) (((KrkValueDbl){.val = (value)}).dbl)
/* This is a silly optimization: because of the arrangement of the identifying /* This is a silly optimization: because of the arrangement of the identifying