// SPDX-License-Identifier: GPL-2.0
/*
 * KUnit function redirection (static stubbing) API.
 *
 * Copyright (C) 2022, Google LLC.
 * Author: David Gow <davidgow@google.com>
 */

#include <kunit/test.h>
#include <kunit/static_stub.h>
#include "hooks-impl.h"


/* Context for a static stub. This is stored in the resource data. */
struct kunit_static_stub_ctx {
	void *real_fn_addr;
	void *replacement_addr;
};

static void __kunit_static_stub_resource_free(struct kunit_resource *res)
{
	kfree(res->data);
}

/* Matching function for kunit_find_resource(). match_data is real_fn_addr. */
static bool __kunit_static_stub_resource_match(struct kunit *test,
						struct kunit_resource *res,
						void *match_real_fn_addr)
{
	/* This pointer is only valid if res is a static stub resource. */
	struct kunit_static_stub_ctx *ctx = res->data;

	/* Make sure the resource is a static stub resource. */
	if (res->free != &__kunit_static_stub_resource_free)
		return false;

	return ctx->real_fn_addr == match_real_fn_addr;
}

/* Hook to return the address of the replacement function. */
void *__kunit_get_static_stub_address_impl(struct kunit *test, void *real_fn_addr)
{
	struct kunit_resource *res;
	struct kunit_static_stub_ctx *ctx;
	void *replacement_addr;

	res = kunit_find_resource(test,
				  __kunit_static_stub_resource_match,
				  real_fn_addr);

	if (!res)
		return NULL;

	ctx = res->data;
	replacement_addr = ctx->replacement_addr;
	kunit_put_resource(res);
	return replacement_addr;
}

void kunit_deactivate_static_stub(struct kunit *test, void *real_fn_addr)
{
	struct kunit_resource *res;

	KUNIT_ASSERT_PTR_NE_MSG(test, real_fn_addr, NULL,
				"Tried to deactivate a NULL stub.");

	/* Look up the existing stub for this function. */
	res = kunit_find_resource(test,
				  __kunit_static_stub_resource_match,
				  real_fn_addr);

	/* Error out if the stub doesn't exist. */
	KUNIT_ASSERT_PTR_NE_MSG(test, res, NULL,
				"Tried to deactivate a nonexistent stub.");

	/* Free the stub. We 'put' twice, as we got a reference
	 * from kunit_find_resource()
	 */
	kunit_remove_resource(test, res);
	kunit_put_resource(res);
}
EXPORT_SYMBOL_GPL(kunit_deactivate_static_stub);

/* Helper function for kunit_activate_static_stub(). The macro does
 * typechecking, so use it instead.
 */
void __kunit_activate_static_stub(struct kunit *test,
				  void *real_fn_addr,
				  void *replacement_addr)
{
	struct kunit_static_stub_ctx *ctx;
	struct kunit_resource *res;

	KUNIT_ASSERT_PTR_NE_MSG(test, real_fn_addr, NULL,
				"Tried to activate a stub for function NULL");

	/* If the replacement address is NULL, deactivate the stub. */
	if (!replacement_addr) {
		kunit_deactivate_static_stub(test, real_fn_addr);
		return;
	}

	/* Look up any existing stubs for this function, and replace them. */
	res = kunit_find_resource(test,
				  __kunit_static_stub_resource_match,
				  real_fn_addr);
	if (res) {
		ctx = res->data;
		ctx->replacement_addr = replacement_addr;

		/* We got an extra reference from find_resource(), so put it. */
		kunit_put_resource(res);
	} else {
		ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
		ctx->real_fn_addr = real_fn_addr;
		ctx->replacement_addr = replacement_addr;
		res = kunit_alloc_resource(test, NULL,
				     &__kunit_static_stub_resource_free,
				     GFP_KERNEL, ctx);
	}
}
EXPORT_SYMBOL_GPL(__kunit_activate_static_stub);
