Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright 2014-2016 by Open Source Security, Inc., Brad Spengler <spender@grsecurity.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *                   and PaX Team <pageexec@freemail.hu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Licensed under the GPL v2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Note: the choice of the license means that the compilation process is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *       NOT 'eligible' as defined by gcc's library exception to the GPL v3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *       but for the kernel it doesn't matter since it doesn't link against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *       any of the gcc libraries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * $ # for 4.5/4.6/C based 4.7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * $ gcc -I`gcc -print-file-name=plugin`/include -I`gcc -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * $ # for C++ based 4.7/4.8+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * $ g++ -I`g++ -print-file-name=plugin`/include -I`g++ -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * $ gcc -fplugin=./randomize_layout_plugin.so test.c -O2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "gcc-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "randomize_layout_seed.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #if BUILDING_GCC_MAJOR < 4 || (BUILDING_GCC_MAJOR == 4 && BUILDING_GCC_MINOR < 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #error "The RANDSTRUCT plugin requires GCC 4.7 or newer."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define ORIG_TYPE_NAME(node) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	(TYPE_NAME(TYPE_MAIN_VARIANT(node)) != NULL_TREE ? ((const unsigned char *)IDENTIFIER_POINTER(TYPE_NAME(TYPE_MAIN_VARIANT(node)))) : (const unsigned char *)"anonymous")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define INFORM(loc, msg, ...)	inform(loc, "randstruct: " msg, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define MISMATCH(loc, how, ...)	INFORM(loc, "casting between randomized structure pointer types (" how "): %qT and %qT\n", __VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) __visible int plugin_is_GPL_compatible;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static int performance_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static struct plugin_info randomize_layout_plugin_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	.version	= "201402201816vanilla",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	.help		= "disable\t\t\tdo not activate plugin\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			  "performance-mode\tenable cacheline-aware layout randomization\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) struct whitelist_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	const char *pathname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	const char *lhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	const char *rhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static const struct whitelist_entry whitelist[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	/* NIU overloads mapping with page struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	{ "drivers/net/ethernet/sun/niu.c", "page", "address_space" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	/* unix_skb_parms via UNIXCB() buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	{ "net/unix/af_unix.c", "unix_skb_parms", "char" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	/* big_key payload.data struct splashing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	{ "security/keys/big_key.c", "path", "void *" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	/* walk struct security_hook_heads as an array of struct hlist_head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	{ "security/security.c", "hlist_head", "security_hook_heads" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) /* from old Linux dcache.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static inline unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) partial_name_hash(unsigned long c, unsigned long prevhash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	return (prevhash + (c << 4) + (c >> 4)) * 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) name_hash(const unsigned char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	unsigned long hash = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	unsigned int len = strlen((const char *)name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		hash = partial_name_hash(*name++, hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	return (unsigned int)hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	tree type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	*no_add_attrs = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (TREE_CODE(*node) == FUNCTION_DECL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		error("%qE attribute does not apply to functions (%qF)", name, *node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (TREE_CODE(*node) == PARM_DECL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		error("%qE attribute does not apply to function parameters (%qD)", name, *node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (TREE_CODE(*node) == VAR_DECL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		error("%qE attribute does not apply to variables (%qD)", name, *node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (TYPE_P(*node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		type = *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		gcc_assert(TREE_CODE(*node) == TYPE_DECL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		type = TREE_TYPE(*node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (TREE_CODE(type) != RECORD_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		error("%qE attribute used on %qT applies to struct types only", name, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		error("%qE attribute is already applied to the type %qT", name, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	*no_add_attrs = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* set on complete types that we don't need to inspect further at all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static tree handle_randomize_considered_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	*no_add_attrs = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * set on types that we've performed a shuffle on, to prevent re-shuffling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * this does not preclude us from inspecting its fields for potential shuffles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static tree handle_randomize_performed_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	*no_add_attrs = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	return NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * 64bit variant of Bob Jenkins' public domain PRNG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * 256 bits of internal state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) typedef unsigned long long u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) typedef struct ranctx { u64 a; u64 b; u64 c; u64 d; } ranctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define rot(x,k) (((x)<<(k))|((x)>>(64-(k))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static u64 ranval(ranctx *x) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	u64 e = x->a - rot(x->b, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	x->a = x->b ^ rot(x->c, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	x->b = x->c + rot(x->d, 37);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	x->c = x->d + e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	x->d = e + x->a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return x->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void raninit(ranctx *x, u64 *seed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	x->a = seed[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	x->b = seed[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	x->c = seed[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	x->d = seed[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	for (i=0; i < 30; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		(void)ranval(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static u64 shuffle_seed[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct partition_group {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	tree tree_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	unsigned long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	unsigned long length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void partition_struct(tree *fields, unsigned long length, struct partition_group *size_groups, unsigned long *num_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	unsigned long accum_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	unsigned long accum_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	unsigned long group_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	gcc_assert(length < INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	memset(size_groups, 0, sizeof(struct partition_group) * length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	for (i = 0; i < length; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		if (size_groups[group_idx].tree_start == NULL_TREE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			size_groups[group_idx].tree_start = fields[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			size_groups[group_idx].start = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			accum_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			accum_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		accum_size += (unsigned long)int_size_in_bytes(TREE_TYPE(fields[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		accum_length++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		if (accum_size >= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			size_groups[group_idx].length = accum_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			accum_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			group_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (size_groups[group_idx].tree_start != NULL_TREE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	    !size_groups[group_idx].length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		size_groups[group_idx].length = accum_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		group_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	*num_groups = group_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	unsigned long i, x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	struct partition_group size_group[length];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	unsigned long num_groups = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	unsigned long randnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	for (i = num_groups - 1; i > 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		struct partition_group tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		randnum = ranval(prng_state) % (i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		tmp = size_group[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		size_group[i] = size_group[randnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		size_group[randnum] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	for (x = 0; x < num_groups; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		for (i = size_group[x].start + size_group[x].length - 1; i > size_group[x].start; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			tree tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			if (DECL_BIT_FIELD_TYPE(newtree[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			randnum = ranval(prng_state) % (i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			// we could handle this case differently if desired
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			if (DECL_BIT_FIELD_TYPE(newtree[randnum]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			tmp = newtree[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			newtree[i] = newtree[randnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			newtree[randnum] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static void full_shuffle(tree *newtree, unsigned long length, ranctx *prng_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	unsigned long i, randnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	for (i = length - 1; i > 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		tree tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		randnum = ranval(prng_state) % (i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		tmp = newtree[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		newtree[i] = newtree[randnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		newtree[randnum] = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* modern in-place Fisher-Yates shuffle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static void shuffle(const_tree type, tree *newtree, unsigned long length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	u64 seed[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	ranctx prng_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	const unsigned char *structname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	if (length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	gcc_assert(TREE_CODE(type) == RECORD_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	structname = ORIG_TYPE_NAME(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #ifdef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	fprintf(stderr, "Shuffling struct %s %p\n", (const char *)structname, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #ifdef __DEBUG_VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	debug_tree((tree)type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		seed[i] = shuffle_seed[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		seed[i] ^= name_hash(structname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	raninit(&prng_state, (u64 *)&seed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (performance_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		performance_shuffle(newtree, length, &prng_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		full_shuffle(newtree, length, &prng_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static bool is_flexible_array(const_tree field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	const_tree fieldtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	const_tree typesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	const_tree elemtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	const_tree elemsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	fieldtype = TREE_TYPE(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	typesize = TYPE_SIZE(fieldtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (TREE_CODE(fieldtype) != ARRAY_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	elemtype = TREE_TYPE(fieldtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	elemsize = TYPE_SIZE(elemtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	/* size of type is represented in bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	if (typesize == NULL_TREE && TYPE_DOMAIN(fieldtype) != NULL_TREE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	    TYPE_MAX_VALUE(TYPE_DOMAIN(fieldtype)) == NULL_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	if (typesize != NULL_TREE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	    (TREE_CONSTANT(typesize) && (!tree_to_uhwi(typesize) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	     tree_to_uhwi(typesize) == tree_to_uhwi(elemsize))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int relayout_struct(tree type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	unsigned long num_fields = (unsigned long)list_length(TYPE_FIELDS(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	unsigned long shuffle_length = num_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	tree field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	tree newtree[num_fields];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	tree list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	tree variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	tree main_variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	expanded_location xloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	bool has_flexarray = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (TYPE_FIELDS(type) == NULL_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	if (num_fields < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	gcc_assert(TREE_CODE(type) == RECORD_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	gcc_assert(num_fields < INT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(type)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	    lookup_attribute("no_randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	/* Workaround for 3rd-party VirtualBox source that we can't modify ourselves */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	if (!strcmp((const char *)ORIG_TYPE_NAME(type), "INTNETTRUNKFACTORY") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	    !strcmp((const char *)ORIG_TYPE_NAME(type), "RAWPCIFACTORY"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	/* throw out any structs in uapi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	xloc = expand_location(DECL_SOURCE_LOCATION(TYPE_FIELDS(type)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (strstr(xloc.file, "/uapi/"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		error(G_("attempted to randomize userland API struct %s"), ORIG_TYPE_NAME(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	for (field = TYPE_FIELDS(type), i = 0; field; field = TREE_CHAIN(field), i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		gcc_assert(TREE_CODE(field) == FIELD_DECL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		newtree[i] = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	 * enforce that we don't randomize the layout of the last
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	 * element of a struct if it's a 0 or 1-length array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	 * or a proper flexible array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (is_flexible_array(newtree[num_fields - 1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		has_flexarray = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		shuffle_length--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	shuffle(type, (tree *)newtree, shuffle_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	 * set up a bogus anonymous struct field designed to error out on unnamed struct initializers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	 * as gcc provides no other way to detect such code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	list = make_node(FIELD_DECL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	TREE_CHAIN(list) = newtree[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	TREE_TYPE(list) = void_type_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	DECL_SIZE(list) = bitsize_zero_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	DECL_NONADDRESSABLE_P(list) = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	DECL_FIELD_BIT_OFFSET(list) = bitsize_zero_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	DECL_SIZE_UNIT(list) = size_zero_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	DECL_FIELD_OFFSET(list) = size_zero_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	DECL_CONTEXT(list) = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	// to satisfy the constify plugin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	TREE_READONLY(list) = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	for (i = 0; i < num_fields - 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		TREE_CHAIN(newtree[i]) = newtree[i+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	TREE_CHAIN(newtree[num_fields - 1]) = NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	main_variant = TYPE_MAIN_VARIANT(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	for (variant = main_variant; variant; variant = TYPE_NEXT_VARIANT(variant)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		TYPE_FIELDS(variant) = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		TYPE_ATTRIBUTES(variant) = copy_list(TYPE_ATTRIBUTES(variant));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("randomize_performed"), NULL_TREE, TYPE_ATTRIBUTES(variant));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		TYPE_ATTRIBUTES(variant) = tree_cons(get_identifier("designated_init"), NULL_TREE, TYPE_ATTRIBUTES(variant));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		if (has_flexarray)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("has_flexarray"), NULL_TREE, TYPE_ATTRIBUTES(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	 * force a re-layout of the main variant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	 * the TYPE_SIZE for all variants will be recomputed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	 * by finalize_type_size()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	TYPE_SIZE(main_variant) = NULL_TREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	layout_type(main_variant);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	gcc_assert(TYPE_SIZE(main_variant) != NULL_TREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* from constify plugin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static const_tree get_field_type(const_tree field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	return strip_array_types(TREE_TYPE(field));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* from constify plugin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static bool is_fptr(const_tree fieldtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	if (TREE_CODE(fieldtype) != POINTER_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	return TREE_CODE(TREE_TYPE(fieldtype)) == FUNCTION_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* derived from constify plugin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int is_pure_ops_struct(const_tree node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	const_tree field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		const_tree fieldtype = get_field_type(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		enum tree_code code = TREE_CODE(fieldtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		if (node == fieldtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		if (code == RECORD_TYPE || code == UNION_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 			if (!is_pure_ops_struct(fieldtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		if (!is_fptr(fieldtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static void randomize_type(tree type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	tree variant;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	gcc_assert(TREE_CODE(type) == RECORD_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	if (lookup_attribute("randomize_considered", TYPE_ATTRIBUTES(type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	if (lookup_attribute("randomize_layout", TYPE_ATTRIBUTES(TYPE_MAIN_VARIANT(type))) || is_pure_ops_struct(type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		relayout_struct(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	for (variant = TYPE_MAIN_VARIANT(type); variant; variant = TYPE_NEXT_VARIANT(variant)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("randomize_considered"), NULL_TREE, TYPE_ATTRIBUTES(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) #ifdef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	fprintf(stderr, "Marking randomize_considered on struct %s\n", ORIG_TYPE_NAME(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #ifdef __DEBUG_VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	debug_tree(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static void update_decl_size(tree decl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	tree lastval, lastidx, field, init, type, flexsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	unsigned HOST_WIDE_INT len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	type = TREE_TYPE(decl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	if (!lookup_attribute("has_flexarray", TYPE_ATTRIBUTES(type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	init = DECL_INITIAL(decl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	if (init == NULL_TREE || init == error_mark_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	if (TREE_CODE(init) != CONSTRUCTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	len = CONSTRUCTOR_NELTS(init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)         if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	lastval = CONSTRUCTOR_ELT(init, CONSTRUCTOR_NELTS(init) - 1)->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	lastidx = CONSTRUCTOR_ELT(init, CONSTRUCTOR_NELTS(init) - 1)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	for (field = TYPE_FIELDS(TREE_TYPE(decl)); TREE_CHAIN(field); field = TREE_CHAIN(field))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	if (lastidx != field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	if (TREE_CODE(lastval) != STRING_CST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		error("Only string constants are supported as initializers "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		      "for randomized structures with flexible arrays");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	flexsize = bitsize_int(TREE_STRING_LENGTH(lastval) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		tree_to_uhwi(TYPE_SIZE(TREE_TYPE(TREE_TYPE(lastval)))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	DECL_SIZE(decl) = size_binop(PLUS_EXPR, TYPE_SIZE(type), flexsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static void randomize_layout_finish_decl(void *event_data, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	tree decl = (tree)event_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	tree type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	if (decl == NULL_TREE || decl == error_mark_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	type = TREE_TYPE(decl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	if (TREE_CODE(decl) != VAR_DECL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	if (!lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	DECL_SIZE(decl) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	DECL_SIZE_UNIT(decl) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	SET_DECL_ALIGN(decl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	SET_DECL_MODE (decl, VOIDmode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	SET_DECL_RTL(decl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	update_decl_size(decl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	layout_decl(decl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static void finish_type(void *event_data, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	tree type = (tree)event_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	if (type == NULL_TREE || type == error_mark_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	if (TREE_CODE(type) != RECORD_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	if (TYPE_FIELDS(type) == NULL_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	if (lookup_attribute("randomize_considered", TYPE_ATTRIBUTES(type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) #ifdef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	fprintf(stderr, "Calling randomize_type on %s\n", ORIG_TYPE_NAME(type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #ifdef __DEBUG_VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	debug_tree(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	randomize_type(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static struct attribute_spec randomize_layout_attr = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static struct attribute_spec no_randomize_layout_attr = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static struct attribute_spec randomize_considered_attr = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static struct attribute_spec randomize_performed_attr = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static void register_attributes(void *event_data, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	randomize_layout_attr.name		= "randomize_layout";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	randomize_layout_attr.type_required	= true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	randomize_layout_attr.handler		= handle_randomize_layout_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) #if BUILDING_GCC_VERSION >= 4007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	randomize_layout_attr.affects_type_identity = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	no_randomize_layout_attr.name		= "no_randomize_layout";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	no_randomize_layout_attr.type_required	= true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	no_randomize_layout_attr.handler	= handle_randomize_layout_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) #if BUILDING_GCC_VERSION >= 4007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	no_randomize_layout_attr.affects_type_identity = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	randomize_considered_attr.name		= "randomize_considered";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	randomize_considered_attr.type_required	= true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	randomize_considered_attr.handler	= handle_randomize_considered_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	randomize_performed_attr.name		= "randomize_performed";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	randomize_performed_attr.type_required	= true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	randomize_performed_attr.handler	= handle_randomize_performed_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	register_attribute(&randomize_layout_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	register_attribute(&no_randomize_layout_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	register_attribute(&randomize_considered_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	register_attribute(&randomize_performed_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static void check_bad_casts_in_constructor(tree var, tree init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	unsigned HOST_WIDE_INT idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	tree field, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	tree field_type, val_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(init), idx, field, val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		if (TREE_CODE(val) == CONSTRUCTOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 			check_bad_casts_in_constructor(var, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		/* pipacs' plugin creates franken-arrays that differ from those produced by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		   normal code which all have valid 'field' trees. work around this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		if (field == NULL_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		field_type = TREE_TYPE(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		val_type = TREE_TYPE(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		if (TREE_CODE(field_type) != POINTER_TYPE || TREE_CODE(val_type) != POINTER_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		if (field_type == val_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 		field_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(field_type))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		val_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(val_type))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		if (field_type == void_type_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		if (field_type == val_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		if (TREE_CODE(val_type) != RECORD_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		if (!lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(val_type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		MISMATCH(DECL_SOURCE_LOCATION(var), "constructor\n", TYPE_MAIN_VARIANT(field_type), TYPE_MAIN_VARIANT(val_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /* derived from the constify plugin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static void check_global_variables(void *event_data, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	struct varpool_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	tree init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	FOR_EACH_VARIABLE(node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		tree var = NODE_DECL(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		init = DECL_INITIAL(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		if (init == NULL_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		if (TREE_CODE(init) != CONSTRUCTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		check_bad_casts_in_constructor(var, init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static bool dominated_by_is_err(const_tree rhs, basic_block bb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	basic_block dom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	gimple dom_stmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	gimple call_stmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	const_tree dom_lhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	const_tree poss_is_err_cond;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	const_tree poss_is_err_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	const_tree is_err_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	dom = get_immediate_dominator(CDI_DOMINATORS, bb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	if (!dom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	dom_stmt = last_stmt(dom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	if (!dom_stmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	if (gimple_code(dom_stmt) != GIMPLE_COND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	if (gimple_cond_code(dom_stmt) != NE_EXPR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	if (!integer_zerop(gimple_cond_rhs(dom_stmt)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	poss_is_err_cond = gimple_cond_lhs(dom_stmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	if (TREE_CODE(poss_is_err_cond) != SSA_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	call_stmt = SSA_NAME_DEF_STMT(poss_is_err_cond);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	if (gimple_code(call_stmt) != GIMPLE_CALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	dom_lhs = gimple_get_lhs(call_stmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	poss_is_err_func = gimple_call_fndecl(call_stmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	if (!poss_is_err_func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	if (dom_lhs != poss_is_err_cond)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	if (strcmp(DECL_NAME_POINTER(poss_is_err_func), "IS_ERR"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	is_err_arg = gimple_call_arg(call_stmt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	if (!is_err_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	if (is_err_arg != rhs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static void handle_local_var_initializers(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	tree var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	FOR_EACH_LOCAL_DECL(cfun, i, var) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		tree init = DECL_INITIAL(var);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		if (!init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		if (TREE_CODE(init) != CONSTRUCTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		check_bad_casts_in_constructor(var, init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) static bool type_name_eq(gimple stmt, const_tree type_tree, const char *wanted_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	const char *type_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	if (type_tree == NULL_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	switch (TREE_CODE(type_tree)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	case RECORD_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		type_name = TYPE_NAME_POINTER(type_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	case INTEGER_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 		if (TYPE_PRECISION(type_tree) == CHAR_TYPE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 			type_name = "char";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 			INFORM(gimple_location(stmt), "found non-char INTEGER_TYPE cast comparison: %qT\n", type_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 			debug_tree(type_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	case POINTER_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		if (TREE_CODE(TREE_TYPE(type_tree)) == VOID_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 			type_name = "void *";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 			INFORM(gimple_location(stmt), "found non-void POINTER_TYPE cast comparison %qT\n", type_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 			debug_tree(type_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		INFORM(gimple_location(stmt), "unhandled cast comparison: %qT\n", type_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		debug_tree(type_tree);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	return strcmp(type_name, wanted_name) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static bool whitelisted_cast(gimple stmt, const_tree lhs_tree, const_tree rhs_tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	const struct whitelist_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	expanded_location xloc = expand_location(gimple_location(stmt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	for (entry = whitelist; entry->pathname; entry++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 		if (!strstr(xloc.file, entry->pathname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 		if (type_name_eq(stmt, lhs_tree, entry->lhs) && type_name_eq(stmt, rhs_tree, entry->rhs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)  * iterate over all statements to find "bad" casts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)  * those where the address of the start of a structure is cast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)  * to a pointer of a structure of a different type, or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)  * structure pointer type is cast to a different structure pointer type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) static unsigned int find_bad_casts_execute(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	basic_block bb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	handle_local_var_initializers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	FOR_EACH_BB_FN(bb, cfun) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 		gimple_stmt_iterator gsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 		for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 			gimple stmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 			const_tree lhs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 			const_tree lhs_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 			const_tree rhs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 			const_tree rhs_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 			const_tree ptr_lhs_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 			const_tree ptr_rhs_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 			const_tree op0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 			const_tree op0_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 			enum tree_code rhs_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 			stmt = gsi_stmt(gsi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) #ifdef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) #ifdef __DEBUG_VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 			debug_gimple_stmt(stmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 			debug_tree(gimple_get_lhs(stmt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 			if (gimple_code(stmt) != GIMPLE_ASSIGN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) #ifdef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) #ifdef __DEBUG_VERBOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 			debug_tree(gimple_assign_rhs1(stmt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 			rhs_code = gimple_assign_rhs_code(stmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 			if (rhs_code != ADDR_EXPR && rhs_code != SSA_NAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 			lhs = gimple_get_lhs(stmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 			lhs_type = TREE_TYPE(lhs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 			rhs1 = gimple_assign_rhs1(stmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 			rhs_type = TREE_TYPE(rhs1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 			if (TREE_CODE(rhs_type) != POINTER_TYPE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 			    TREE_CODE(lhs_type) != POINTER_TYPE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 			ptr_lhs_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(lhs_type))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 			ptr_rhs_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(rhs_type))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 			if (ptr_rhs_type == void_type_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 			if (ptr_lhs_type == void_type_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 			if (dominated_by_is_err(rhs1, bb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 			if (TREE_CODE(ptr_rhs_type) != RECORD_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) #ifndef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 				if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_lhs_type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 				{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 					if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 						MISMATCH(gimple_location(stmt), "rhs", ptr_lhs_type, ptr_rhs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 			if (rhs_code == SSA_NAME && ptr_lhs_type == ptr_rhs_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 			if (rhs_code == ADDR_EXPR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 				op0 = TREE_OPERAND(rhs1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 				if (op0 == NULL_TREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 				if (TREE_CODE(op0) != VAR_DECL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 				op0_type = TYPE_MAIN_VARIANT(strip_array_types(TYPE_MAIN_VARIANT(TREE_TYPE(op0))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 				if (op0_type == ptr_lhs_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) #ifndef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 				if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(op0_type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 				{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 					if (!whitelisted_cast(stmt, ptr_lhs_type, op0_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 						MISMATCH(gimple_location(stmt), "op0", ptr_lhs_type, op0_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 				const_tree ssa_name_var = SSA_NAME_VAR(rhs1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 				/* skip bogus type casts introduced by container_of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 				if (ssa_name_var != NULL_TREE && DECL_NAME(ssa_name_var) && 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 				    !strcmp((const char *)DECL_NAME_POINTER(ssa_name_var), "__mptr"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) #ifndef __DEBUG_PLUGIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 				if (lookup_attribute("randomize_performed", TYPE_ATTRIBUTES(ptr_rhs_type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 				{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 					if (!whitelisted_cast(stmt, ptr_lhs_type, ptr_rhs_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 						MISMATCH(gimple_location(stmt), "ssa", ptr_lhs_type, ptr_rhs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #define PASS_NAME find_bad_casts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) #define NO_GATE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) #define TODO_FLAGS_FINISH TODO_dump_func
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) #include "gcc-generate-gimple-pass.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 	const char * const plugin_name = plugin_info->base_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 	const int argc = plugin_info->argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 	const struct plugin_argument * const argv = plugin_info->argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 	bool enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	int obtained_seed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 	struct register_pass_info find_bad_casts_pass_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	find_bad_casts_pass_info.pass			= make_find_bad_casts_pass();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 	find_bad_casts_pass_info.reference_pass_name	= "ssa";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	find_bad_casts_pass_info.ref_pass_instance_number	= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 	find_bad_casts_pass_info.pos_op			= PASS_POS_INSERT_AFTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 	if (!plugin_default_version_check(version, &gcc_version)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 		error(G_("incompatible gcc/plugin versions"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 	if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 		inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 		enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 	for (i = 0; i < argc; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 		if (!strcmp(argv[i].key, "disable")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 			enable = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 		if (!strcmp(argv[i].key, "performance-mode")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 			performance_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) 		error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) 	if (strlen(randstruct_seed) != 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) 		error(G_("invalid seed value supplied for %s plugin"), plugin_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) 	obtained_seed = sscanf(randstruct_seed, "%016llx%016llx%016llx%016llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) 		&shuffle_seed[0], &shuffle_seed[1], &shuffle_seed[2], &shuffle_seed[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) 	if (obtained_seed != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) 		error(G_("Invalid seed supplied for %s plugin"), plugin_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) 	register_callback(plugin_name, PLUGIN_INFO, NULL, &randomize_layout_plugin_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) 	if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) 		register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) 		register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &find_bad_casts_pass_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) 		register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) 		register_callback(plugin_name, PLUGIN_FINISH_DECL, randomize_layout_finish_decl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) 	register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }