~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/lib/kunit/static_stub.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * KUnit function redirection (static stubbing) API.
  4  *
  5  * Copyright (C) 2022, Google LLC.
  6  * Author: David Gow <davidgow@google.com>
  7  */
  8 
  9 #include <kunit/test.h>
 10 #include <kunit/static_stub.h>
 11 #include "hooks-impl.h"
 12 
 13 
 14 /* Context for a static stub. This is stored in the resource data. */
 15 struct kunit_static_stub_ctx {
 16         void *real_fn_addr;
 17         void *replacement_addr;
 18 };
 19 
 20 static void __kunit_static_stub_resource_free(struct kunit_resource *res)
 21 {
 22         kfree(res->data);
 23 }
 24 
 25 /* Matching function for kunit_find_resource(). match_data is real_fn_addr. */
 26 static bool __kunit_static_stub_resource_match(struct kunit *test,
 27                                                 struct kunit_resource *res,
 28                                                 void *match_real_fn_addr)
 29 {
 30         /* This pointer is only valid if res is a static stub resource. */
 31         struct kunit_static_stub_ctx *ctx = res->data;
 32 
 33         /* Make sure the resource is a static stub resource. */
 34         if (res->free != &__kunit_static_stub_resource_free)
 35                 return false;
 36 
 37         return ctx->real_fn_addr == match_real_fn_addr;
 38 }
 39 
 40 /* Hook to return the address of the replacement function. */
 41 void *__kunit_get_static_stub_address_impl(struct kunit *test, void *real_fn_addr)
 42 {
 43         struct kunit_resource *res;
 44         struct kunit_static_stub_ctx *ctx;
 45         void *replacement_addr;
 46 
 47         res = kunit_find_resource(test,
 48                                   __kunit_static_stub_resource_match,
 49                                   real_fn_addr);
 50 
 51         if (!res)
 52                 return NULL;
 53 
 54         ctx = res->data;
 55         replacement_addr = ctx->replacement_addr;
 56         kunit_put_resource(res);
 57         return replacement_addr;
 58 }
 59 
 60 void kunit_deactivate_static_stub(struct kunit *test, void *real_fn_addr)
 61 {
 62         struct kunit_resource *res;
 63 
 64         KUNIT_ASSERT_PTR_NE_MSG(test, real_fn_addr, NULL,
 65                                 "Tried to deactivate a NULL stub.");
 66 
 67         /* Look up the existing stub for this function. */
 68         res = kunit_find_resource(test,
 69                                   __kunit_static_stub_resource_match,
 70                                   real_fn_addr);
 71 
 72         /* Error out if the stub doesn't exist. */
 73         KUNIT_ASSERT_PTR_NE_MSG(test, res, NULL,
 74                                 "Tried to deactivate a nonexistent stub.");
 75 
 76         /* Free the stub. We 'put' twice, as we got a reference
 77          * from kunit_find_resource()
 78          */
 79         kunit_remove_resource(test, res);
 80         kunit_put_resource(res);
 81 }
 82 EXPORT_SYMBOL_GPL(kunit_deactivate_static_stub);
 83 
 84 /* Helper function for kunit_activate_static_stub(). The macro does
 85  * typechecking, so use it instead.
 86  */
 87 void __kunit_activate_static_stub(struct kunit *test,
 88                                   void *real_fn_addr,
 89                                   void *replacement_addr)
 90 {
 91         struct kunit_static_stub_ctx *ctx;
 92         struct kunit_resource *res;
 93 
 94         KUNIT_ASSERT_PTR_NE_MSG(test, real_fn_addr, NULL,
 95                                 "Tried to activate a stub for function NULL");
 96 
 97         /* If the replacement address is NULL, deactivate the stub. */
 98         if (!replacement_addr) {
 99                 kunit_deactivate_static_stub(test, replacement_addr);
100                 return;
101         }
102 
103         /* Look up any existing stubs for this function, and replace them. */
104         res = kunit_find_resource(test,
105                                   __kunit_static_stub_resource_match,
106                                   real_fn_addr);
107         if (res) {
108                 ctx = res->data;
109                 ctx->replacement_addr = replacement_addr;
110 
111                 /* We got an extra reference from find_resource(), so put it. */
112                 kunit_put_resource(res);
113         } else {
114                 ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
115                 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
116                 ctx->real_fn_addr = real_fn_addr;
117                 ctx->replacement_addr = replacement_addr;
118                 res = kunit_alloc_resource(test, NULL,
119                                      &__kunit_static_stub_resource_free,
120                                      GFP_KERNEL, ctx);
121         }
122 }
123 EXPORT_SYMBOL_GPL(__kunit_activate_static_stub);
124 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php