Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Ian Rogers | 215 | 100.00% | 4 | 100.00% |
Total | 215 | 4 |
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ #ifndef __LIBPERF_INTERNAL_RC_CHECK_H #define __LIBPERF_INTERNAL_RC_CHECK_H #include <stdlib.h> #include <linux/zalloc.h> /* * Enable reference count checking implicitly with leak checking, which is * integrated into address sanitizer. */ #if defined(__SANITIZE_ADDRESS__) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) #define REFCNT_CHECKING 1 #elif defined(__has_feature) #if __has_feature(address_sanitizer) || __has_feature(leak_sanitizer) #define REFCNT_CHECKING 1 #endif #endif /* * Shared reference count checking macros. * * Reference count checking is an approach to sanitizing the use of reference * counted structs. It leverages address and leak sanitizers to make sure gets * are paired with a put. Reference count checking adds a malloc-ed layer of * indirection on a get, and frees it on a put. A missed put will be reported as * a memory leak. A double put will be reported as a double free. Accessing * after a put will cause a use-after-free and/or a segfault. */ #ifndef REFCNT_CHECKING /* Replaces "struct foo" so that the pointer may be interposed. */ #define DECLARE_RC_STRUCT(struct_name) \ struct struct_name /* Declare a reference counted struct variable. */ #define RC_STRUCT(struct_name) struct struct_name /* * Interpose the indirection. Result will hold the indirection and object is the * reference counted struct. */ #define ADD_RC_CHK(result, object) (result = object, object) /* Strip the indirection layer. */ #define RC_CHK_ACCESS(object) object /* Frees the object and the indirection layer. */ #define RC_CHK_FREE(object) free(object) /* A get operation adding the indirection layer. */ #define RC_CHK_GET(result, object) ADD_RC_CHK(result, object) /* A put operation removing the indirection layer. */ #define RC_CHK_PUT(object) {} /* Pointer equality when the indirection may or may not be there. */ #define RC_CHK_EQUAL(object1, object2) (object1 == object2) #else /* Replaces "struct foo" so that the pointer may be interposed. */ #define DECLARE_RC_STRUCT(struct_name) \ struct original_##struct_name; \ struct struct_name { \ struct original_##struct_name *orig; \ }; \ struct original_##struct_name /* Declare a reference counted struct variable. */ #define RC_STRUCT(struct_name) struct original_##struct_name /* * Interpose the indirection. Result will hold the indirection and object is the * reference counted struct. */ #define ADD_RC_CHK(result, object) \ ( \ object ? (result = malloc(sizeof(*result)), \ result ? (result->orig = object, result) \ : (result = NULL, NULL)) \ : (result = NULL, NULL) \ ) /* Strip the indirection layer. */ #define RC_CHK_ACCESS(object) object->orig /* Frees the object and the indirection layer. */ #define RC_CHK_FREE(object) \ do { \ zfree(&object->orig); \ free(object); \ } while(0) /* A get operation adding the indirection layer. */ #define RC_CHK_GET(result, object) ADD_RC_CHK(result, (object ? object->orig : NULL)) /* A put operation removing the indirection layer. */ #define RC_CHK_PUT(object) \ do { \ if (object) { \ object->orig = NULL; \ free(object); \ } \ } while(0) /* Pointer equality when the indirection may or may not be there. */ #define RC_CHK_EQUAL(object1, object2) (object1 == object2 || \ (object1 && object2 && object1->orig == object2->orig)) #endif #endif /* __LIBPERF_INTERNAL_RC_CHECK_H */
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1