| Index: runtime/szrt_asan.c
|
| diff --git a/runtime/szrt_asan.c b/runtime/szrt_asan.c
|
| index 449226b69bdc3dff023f416669838d9d9832854e..25ce60ea4df1def073344f5011b9174c541631b6 100644
|
| --- a/runtime/szrt_asan.c
|
| +++ b/runtime/szrt_asan.c
|
| @@ -59,11 +59,14 @@ static char *shadow_offset = NULL;
|
|
|
| static void __asan_error(char *, int);
|
| static void __asan_check(char *, int, bool);
|
| +static void __asan_get_redzones(char *, char **, char **);
|
|
|
| void __asan_init(int, void **, int *);
|
| void __asan_check_load(char *, int);
|
| void __asan_check_store(char *, int);
|
| void *__asan_malloc(size_t);
|
| +void *__asan_calloc(size_t, size_t);
|
| +void *__asan_realloc(char *, size_t);
|
| void __asan_free(char *);
|
| void __asan_poison(char *, int);
|
| void __asan_unpoison(char *, int);
|
| @@ -89,6 +92,15 @@ static void __asan_check(char *ptr, int size, bool strict) {
|
| }
|
| }
|
|
|
| +static void __asan_get_redzones(char *ptr, char **left, char **right) {
|
| + char *rz_left = ptr - RZ_SIZE;
|
| + char *rz_right = *(char **)rz_left;
|
| + if (left != NULL)
|
| + *left = rz_left;
|
| + if (right != NULL)
|
| + *right = rz_right;
|
| +}
|
| +
|
| void __asan_check_load(char *ptr, int size) {
|
| // aligned single word accesses may be widened single byte accesses, but for
|
| // all else use strict check
|
| @@ -161,10 +173,31 @@ void *__asan_calloc(size_t nmemb, size_t size) {
|
| return ret;
|
| }
|
|
|
| +void *__asan_realloc(char *ptr, size_t size) {
|
| + if (ptr == NULL)
|
| + return __asan_malloc(size);
|
| + if (size == 0) {
|
| + __asan_free(ptr);
|
| + return NULL;
|
| + }
|
| + char *rz_right;
|
| + __asan_get_redzones(ptr, NULL, &rz_right);
|
| + size_t old_size = rz_right - ptr;
|
| + if (size == old_size)
|
| + return ptr;
|
| + char *new_alloc = __asan_malloc(size);
|
| + if (new_alloc == NULL)
|
| + return NULL;
|
| + size_t copyable = (size < old_size) ? size : old_size;
|
| + memcpy(new_alloc, ptr, copyable);
|
| + __asan_free(ptr);
|
| + return new_alloc;
|
| +}
|
| +
|
| void __asan_free(char *ptr) {
|
| DUMP("free() called on %p\n", ptr);
|
| - void *rz_left = ptr - RZ_SIZE;
|
| - void *rz_right = *(void **)rz_left;
|
| + void *rz_left, *rz_right;
|
| + __asan_get_redzones(ptr, &rz_left, &rz_right);
|
| size_t rz_right_size = *(size_t *)rz_right;
|
| __asan_unpoison(rz_left, RZ_SIZE);
|
| __asan_unpoison(rz_right, rz_right_size);
|
|
|