Path: blob/master/tools/lib/perf/include/internal/rc_check.h
26302 views
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */1#ifndef __LIBPERF_INTERNAL_RC_CHECK_H2#define __LIBPERF_INTERNAL_RC_CHECK_H34#include <stdlib.h>5#include <linux/zalloc.h>67/*8* Enable reference count checking implicitly with leak checking, which is9* integrated into address sanitizer.10*/11#if defined(__SANITIZE_ADDRESS__) || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)12#define REFCNT_CHECKING 113#elif defined(__has_feature)14#if __has_feature(address_sanitizer) || __has_feature(leak_sanitizer)15#define REFCNT_CHECKING 116#endif17#endif1819/*20* Shared reference count checking macros.21*22* Reference count checking is an approach to sanitizing the use of reference23* counted structs. It leverages address and leak sanitizers to make sure gets24* are paired with a put. Reference count checking adds a malloc-ed layer of25* indirection on a get, and frees it on a put. A missed put will be reported as26* a memory leak. A double put will be reported as a double free. Accessing27* after a put will cause a use-after-free and/or a segfault.28*/2930#ifndef REFCNT_CHECKING31/* Replaces "struct foo" so that the pointer may be interposed. */32#define DECLARE_RC_STRUCT(struct_name) \33struct struct_name3435/* Declare a reference counted struct variable. */36#define RC_STRUCT(struct_name) struct struct_name3738/*39* Interpose the indirection. Result will hold the indirection and object is the40* reference counted struct.41*/42#define ADD_RC_CHK(result, object) (result = object, object)4344/* Strip the indirection layer. */45#define RC_CHK_ACCESS(object) object4647/* Frees the object and the indirection layer. */48#define RC_CHK_FREE(object) free(object)4950/* A get operation adding the indirection layer. */51#define RC_CHK_GET(result, object) ADD_RC_CHK(result, object)5253/* A put operation removing the indirection layer. */54#define RC_CHK_PUT(object) {}5556/* Pointer equality when the indirection may or may not be there. */57#define RC_CHK_EQUAL(object1, object2) (object1 == object2)5859#else6061/* Replaces "struct foo" so that the pointer may be interposed. */62#define DECLARE_RC_STRUCT(struct_name) \63struct original_##struct_name; \64struct struct_name { \65struct original_##struct_name *orig; \66}; \67struct original_##struct_name6869/* Declare a reference counted struct variable. */70#define RC_STRUCT(struct_name) struct original_##struct_name7172/*73* Interpose the indirection. Result will hold the indirection and object is the74* reference counted struct.75*/76#define ADD_RC_CHK(result, object) \77( \78object ? (result = malloc(sizeof(*result)), \79result ? (result->orig = object, result) \80: (result = NULL, NULL)) \81: (result = NULL, NULL) \82)8384/* Strip the indirection layer. */85#define RC_CHK_ACCESS(object) object->orig8687/* Frees the object and the indirection layer. */88#define RC_CHK_FREE(object) \89do { \90zfree(&object->orig); \91free(object); \92} while(0)9394/* A get operation adding the indirection layer. */95#define RC_CHK_GET(result, object) ADD_RC_CHK(result, (object ? object->orig : NULL))9697/* A put operation removing the indirection layer. */98#define RC_CHK_PUT(object) \99do { \100if (object) { \101object->orig = NULL; \102free(object); \103} \104} while(0)105106/* Pointer equality when the indirection may or may not be there. */107#define RC_CHK_EQUAL(object1, object2) (object1 == object2 || \108(object1 && object2 && object1->orig == object2->orig))109110#endif111112#endif /* __LIBPERF_INTERNAL_RC_CHECK_H */113114115