// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/* Includes */
#include "gcc-common.h"
#include "cache.h"

/* Macros */
#define STAGE1_INT "/tmp/rai_int"
#define STAGE1_CHK "/tmp/rai_chk"
#define STAGE2_FINAL "/tmp/rai_final"
#define LINELEN 100

#define STAGE1_PG_COUNT 30
#define STAGE2_PG_COUNT 60

#define __init ".init.text"
#define __initdata ".init.data"
#define __ro_after_init ".data..ro_after_init"

#define IS_RECORD_TYPE(T) (TREE_CODE(T) == RECORD_TYPE)
#define FOR_EACH_STRUCT_MEMBER(T, MEM) \
	for (MEM = TYPE_VALUES((T)); (MEM); MEM = TREE_CHAIN(MEM))
#define FOR_EACH_ATTR_VALUE(SEC, AV) \
	for (AV = TREE_VALUE((SEC)); (AV); AV = TREE_CHAIN(AV))

#define PASS_NAME roafteriniter
#define NO_WRITE_SUMMARY
#define NO_GENERATE_SUMMARY
#define NO_READ_SUMMARY
#define NO_READ_OPTIMIZATION_SUMMARY
#define NO_WRITE_OPTIMIZATION_SUMMARY
#define NO_STMT_FIXUP
#define NO_FUNCTION_TRANSFORM
#define NO_VARIABLE_TRANSFORM
#define NO_GATE

/* GCC Callbacks */
__visible int plugin_init(struct plugin_name_args *,
			  struct plugin_gcc_version *);
static unsigned int roafteriniter_execute(void);
static void rai_callback_finish(void *, void *);

/* Local GCC helper include(Needs to be placed after some macros,
 * callbacks).
 */
#include "gcc-generate-gimple-pass.h"

/* Static declarations */
static struct cache interesting, checked, results;
static const char *blacklisted_typenames[] = {
	"atomic_t",
	"atomic64_t",
	"arch_spinlock_t",
	"spinlock_t",
	"cpumask_t",
	"sk_buff_head",
	NULL
};

static bool stage2 = false;

static void die(const char *format, ...);
static void rai_map_cache(void);
static const char *rai_structtype_str(tree);
static bool rai_check_interesting_sttype(tree, const char *);
static bool rai_hardcoded_blacklist_typename(const char *);
static bool rai_interesting_struct_type(tree);
static void rai_stage1_execute(void);
static bool is_global(tree);
static bool is_fn_annotated(tree);
static bool is_var_annotated(tree);
static void rai_check_assign_stmt(gimple);
static void rai_stage2_execute(void);

/* Externs */
__visible int plugin_is_GPL_compatible = 1;

__visible int plugin_init(struct plugin_name_args *info,
			  struct plugin_gcc_version *ver __unused)
{
	int i;
	const char *plugin_name = info->base_name;
	const int argc = info->argc;
	struct plugin_argument *argv = info->argv;

	PASS_INFO(roafteriniter, "ssa", 1, PASS_POS_INSERT_AFTER);

	for (i = 0; i < argc; i++) {
		if (!(strcmp(argv[i].key, "stage2"))) {
			stage2 = true;
			continue;
		}
		fprintf(stderr, "unknown plugin option(%s)\n", argv[i].key);
		return -1;
	}

	/* Map cache */
	rai_map_cache();

	register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
			  &roafteriniter_pass_info);
	register_callback(plugin_name, PLUGIN_FINISH, rai_callback_finish,
			  NULL);

	return 0;
}

/* Static definitions */
static void die(const char *format, ...)
{
	va_list vargs;
	va_start(vargs, format);
	fprintf(stderr, "FAILURE: ");
	vfprintf(stderr, format, vargs);
	fprintf(stderr, "\n");
	va_end(vargs);
	exit(-1);
}

/*
 * rai_map_cache - Map cache files into memory.
 *
 * The following cache files are mapped into memory:
 *	- STAGE1_INT   : Cache holding struct types that are considered interesting.
 *	- STAGE1_CHK   : Cache holding struct types that have been checked for whether they are interesting
 *		         or not.
 *	- STAGE2_FINAL : Cache holding log entries corresponding to writes to instances of interesting struct
 *			 types.
 */
static void rai_map_cache(void)
{
	int ret;
	if ((ret = cache_map(&interesting, STAGE1_INT, "/int", STAGE1_PG_COUNT*0x1000) != CACHE_OP_SUCCESS))
		die("cache_map() returned %d at %d", ret, __LINE__);

	if (!stage2 &&
	    (ret = cache_map(&checked, STAGE1_CHK, "/chk", STAGE1_PG_COUNT*0x1000) != CACHE_OP_SUCCESS))
		die("cache_map() returned %d at %d", ret, __LINE__);

	if (stage2 &&
	    (ret = cache_map(&results, STAGE2_FINAL, "/final", STAGE2_PG_COUNT*0x1000) != CACHE_OP_SUCCESS))
		die("cache_map() returned %d at %d", ret, __LINE__);
}

/*
 * rai_structtype_str - Return the name of the struct type.
 *
 * @type_tree: tree node corresponding to the RECORD type or struct instance.
 *
 * Returns:
 *	const char* representing struct instance name or struct type name. If the
 *	typename is a typedef, return the typedef.
 */
static const char *rai_structtype_str(tree type_tree)
{
	tree name_tree;

	if (!type_tree)
		return NULL;

	if (!(name_tree = TYPE_NAME(type_tree)))
		return NULL;

	if (TREE_CODE(name_tree) == IDENTIFIER_NODE)
		return IDENTIFIER_POINTER(name_tree);
	else if (TREE_CODE(name_tree) == TYPE_DECL && DECL_NAME(name_tree))
		return IDENTIFIER_POINTER(DECL_NAME(name_tree));

	return NULL;
}

/*
 * rai_check_interesting_sttype - Check if a struct type is interesting.
 *
 * The following struct types will be considered not interesting given that
 * `struct A` is not interesting.
 *
 * struct B {
 *	struct A a;	// non-interesting as `struct A` is non-interesting.
 * };
 * struct C {
 *	struct A *a_ptr; // non-interesting as `struct A` is non-interesting.
 * };
 * struct D {
 *	struct B *b;	// non-interesting as `struct B` is non-interesting.
 * };
 * struct E {
 *	struct C c;	// non-interesting as `struct C` is non-interesting.
 * };
 * struct F {
 *	struct F *f;	// non-interesting as contains pointer to its own type.
 * };
 *
 * @type_tree: tree node corresponding to a struct type.
 * @type_name: string representation of the struct type name.
 */
static bool rai_check_interesting_sttype(tree type_tree, const char *type_name)
{
	tree member;
	bool has_fields = false;
	gcc_assert(TREE_CODE(type_tree) == RECORD_TYPE);

	/* (1) Iterate through each member of the struct type. Investigate each
	 * member for properties that might make this struct type non-interesting. */
	FOR_EACH_STRUCT_MEMBER(type_tree, member) {
		has_fields = true;
		gcc_assert(TREE_CODE(member) == FIELD_DECL);

		/* (1.1) Check if the member is a pointer to something. */
		tree member_tree = TREE_TYPE(member);
		if (TREE_CODE(member_tree) == POINTER_TYPE) {

			/* (1.1.1) If it is a pointer to a non-RECORD type, we cannot
			 * infer anything useful from it. So continue onto the next member. */
			tree member_type = TREE_TYPE(member_tree);
			if (TREE_CODE(member_type) != RECORD_TYPE)
				continue;

			/* (1.1.2) If it is an anonymous struct, we cannot infer anything useful
			 * from it. So continue onto the next member. */
			const char *member_typename = rai_structtype_str(member_type);
			if (!member_typename)
				continue;

			/* (1.1.3) If it is a pointer to a RECORD type, check if it is a pointer
			 * to itself. If so, this struct type is deemed as not interesting. */
			/* (1.1.4) If it is a pointer to a RECORD type, check if the RECORD type
			 * is interesting. If it is not interesting, then this struct
			 * type will also be deemed as not interesting. */
			if (!strcmp(member_typename, type_name) ||
			    !rai_interesting_struct_type(member_type))
				return false;

		/* (1.2) Check if the member is an instance of another non-interesting
		 * struct type. If so, return false. */
		} else if (TREE_CODE(member_tree) == RECORD_TYPE &&
			   !rai_interesting_struct_type(member_tree)) {
			return false;
		}
	}

	/* If we are unable to iterate through the fields of the RECORD_TYPE
	 * deem the struct type to be non-interesting. */
	if (!has_fields)
		return false;

	return true;
}

/*
 * rai_hardcoded_blacklist_typename - check if type_name is a blacklisted type.
 *
 * @type_name: string representation of a type.
 *
 * Returns:
 *	true: if type_name is present in blacklisted_typenames.
 *	false: otherwise.
 */
static bool rai_hardcoded_blacklist_typename(const char *type_name)
{
	const char **tmp;

	if (!type_name)
		return false;

	for (tmp = blacklisted_typenames; *tmp; tmp++)
		if (!strcmp(*tmp, type_name))
			return true;
	return false;
}

static bool rai_interesting_struct_type(tree type_tree)
{
	const char *type_name;
	int ret;

	if (!IS_RECORD_TYPE(type_tree))
		return false;

	type_name = rai_structtype_str(type_tree);
	if (!type_name)
		return false;

	/* If type_name is already categorized as interesting, return true */
	if (cache_contains(&interesting, type_name) == CACHE_CONTAINS_SUCCESS)
		return true;

	/* If type_name is already checked, return. Else insert and continue */
	ret = cache_notcontains_insert(&checked, type_name);
	if (ret == CACHE_CONTAINS_SUCCESS)
		return false;

	if (ret == CACHE_INSERTION_FAILED)
		die("cache_notcontains_insert() returned %d at %d", ret, __LINE__);

	if (rai_hardcoded_blacklist_typename(type_name))
		return false;

	if (rai_check_interesting_sttype(type_tree, type_name)) {
		ret = cache_notcontains_insert(&interesting, type_name);
		if (ret == CACHE_INSERTION_FAILED)
			die("cache_notcontains_insert() returned %d at %d\n", ret, __LINE__);
		return true;
	} else {
		return false;
	}

	return true;
}

/*
 * rai_stage1_execute - Entry point of plugin stage 1.
 *
 * In stage 1, the plugin iterates over each global variable in a translation
 * unit and determines if its type is interesting.
 */
static void rai_stage1_execute(void)
{
	varpool_node_ptr node;

	FOR_EACH_VARIABLE(node) {
		tree var_node = NODE_DECL(node);
		gcc_assert(TREE_CODE(var_node) == VAR_DECL);

		tree type_tree;
		type_tree = TREE_TYPE(var_node);
		rai_interesting_struct_type(type_tree);
	}
}

/*
 * is_global - Returns true if var_tree corresponds to a global variable.
 */
static bool is_global(tree var_tree)
{
	varpool_node_ptr node;

	FOR_EACH_VARIABLE(node) {
		tree var_node = NODE_DECL(node);
		gcc_assert(TREE_CODE(var_node) == VAR_DECL);
		if (var_node == var_tree) return true;
	}

	return false;
}

/*
 * is_annotated - Returns true of the declaration is annotated.
 *
 * @decl: tree node representing variable or function.
 * @sname: annotation to check on decl
 */
static bool is_annotated(tree decl, const char *sname)
{
	tree section, attr_value;

	section = lookup_attribute("section", DECL_ATTRIBUTES(decl));
	if (!section || !TREE_VALUE(section))
		return false;

	FOR_EACH_ATTR_VALUE(section, attr_value) {
		const char *str = TREE_STRING_POINTER(TREE_VALUE(attr_value));
		if (!strncmp(str, sname, strlen(sname)))
			return true;
	}

	return false;
}

/*
 * is_fn_annotated: Returns true if a function is annotated with __init.
 *
 * @var_decl: tree node representing a variable.
 */
static bool is_fn_annotated(tree var_decl)
{
	return is_annotated(var_decl, __init);
}

/*
 * is_var_annotated: Returns true if a variable declaration is annotated with
 *		     either __initdata or __ro_after_init.
 *
 * @var_decl: tree node representing a function.
 */
static bool is_var_annotated(tree var_decl)
{
	return is_annotated(var_decl, __initdata) ||
	       is_annotated(var_decl, __ro_after_init);
}

/*
 * rai_check_assign_stmt: Investigate an assignment statement.
 *
 * Given a gimple statement, write a log entry to STAGE2_FINAL iff the
 * following conditions are met.
 * - The write is to an instance of an interesting struct type.
 * - The write is to a global variable that is not already annotated.
 *
 * A single line of the log entry will have the following information.
 * - name of struct instance whose member is being written to.
 * - name of struct type corresponding to the instance.
 * - function name within which the write occurs.
 * - whether or not the function is annotated with __init.
 *
 * int a;
 * struct sometype {
 *	int b;
 * };
 * struct sometype st;
 *
 * void func1(void) {
 *	a = 10;
 *	st.b = 123;
 * }
 *
 * void __init func2(void) {
 *     st.b = 234;
 * };
 *
 * In the above example, `struct sometype` is interesting. The following log
 * records(without quotes) will be written to STAGE2_FINAL.
 * "v:st t:sometype fn:func1 status:NK"
 * "v:st t:sometype fn:func2 status:OK"
 *
 * The status fields correspond to whether or not they were written to from a
 * function annotated with __init.
 *
 * @stmt: statement to check for a write.
 */
static void rai_check_assign_stmt(gimple stmt)
{
	tree lhs, arg0, arg0_type;
	char buffer[LINELEN];
	int ret;

	lhs = gimple_assign_lhs(stmt);
	if (TREE_CODE(lhs) != COMPONENT_REF)
		return;

	arg0 = TREE_OPERAND(lhs, 0);
	if (TREE_CODE(arg0) != VAR_DECL)
		return;

	if (!is_global(arg0) || is_var_annotated(arg0))
		return;

	arg0_type = TREE_TYPE(arg0);
	if (TREE_CODE(arg0_type) != RECORD_TYPE)
		return;

	if (cache_contains(&interesting, rai_structtype_str(arg0_type)) == CACHE_CONTAINS_FAILED)
		return;

	memset(buffer, 0, LINELEN);
	snprintf(buffer, LINELEN-1, "v:%s t:%s fn:%s status:%s",
		 IDENTIFIER_POINTER(DECL_NAME(arg0)),
		 rai_structtype_str(arg0_type),
		 DECL_NAME_POINTER(current_function_decl),
		 is_fn_annotated(current_function_decl) ? "OK" : "NK");
	if ((ret = cache_notcontains_insert(&results, buffer)) == CACHE_INSERTION_FAILED) {
		die("cache_notcontains_insert() returned %d at %d\n", ret, __LINE__);
		exit(-1);
	}
}

/*
 * rai_stage2_execute: Entry point plugin stage 2.
 *
 * In stage 2 the plugin iterates over each statement of each basic block
 * of each function in a translation unit, and processes GIMPLE_ASSIGN
 * statements.
 */
static void rai_stage2_execute(void)
{
	basic_block bb;

	FOR_ALL_BB_FN(bb, cfun) {
		gimple_stmt_iterator gsi;
		for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
			gimple stmt = gsi_stmt(gsi);
			if (gimple_code(stmt) == GIMPLE_ASSIGN)
				rai_check_assign_stmt(stmt);
		}
	}
}

/* Callback definitions */
static unsigned int roafteriniter_execute(void)
{
	if (!stage2)
		rai_stage1_execute();
	else
		rai_stage2_execute();

	return 0;
}

/*
 * rai_callback_finish: Unmap the caches from memory.
 */
static void rai_callback_finish(void *event_data __unused,
				void *user_data __unused)
{
	cache_unmap(&interesting);
	if (!stage2)
		cache_unmap(&checked);
	if (stage2)
		cache_unmap(&results);
}
