scripts/gcc-plugins/randomize_layout_plugin.c

Source file repositories/reference/linux-study-clean/scripts/gcc-plugins/randomize_layout_plugin.c

File Facts

System
Linux kernel
Corpus path
scripts/gcc-plugins/randomize_layout_plugin.c
Extension
.c
Size
23470 bytes
Lines
882
Domain
Support Tooling And Documentation
Bucket
scripts
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct partition_group {
	tree tree_start;
	unsigned long start;
	unsigned long length;
};

static void partition_struct(tree *fields, unsigned long length, struct partition_group *size_groups, unsigned long *num_groups)
{
	unsigned long i;
	unsigned long accum_size = 0;
	unsigned long accum_length = 0;
	unsigned long group_idx = 0;

	gcc_assert(length < INT_MAX);

	memset(size_groups, 0, sizeof(struct partition_group) * length);

	for (i = 0; i < length; i++) {
		if (size_groups[group_idx].tree_start == NULL_TREE) {
			size_groups[group_idx].tree_start = fields[i];
			size_groups[group_idx].start = i;
			accum_length = 0;
			accum_size = 0;
		}
		accum_size += (unsigned long)int_size_in_bytes(TREE_TYPE(fields[i]));
		accum_length++;
		if (accum_size >= 64) {
			size_groups[group_idx].length = accum_length;
			accum_length = 0;
			group_idx++;
		}
	}

	if (size_groups[group_idx].tree_start != NULL_TREE &&
	    !size_groups[group_idx].length) {
		size_groups[group_idx].length = accum_length;
		group_idx++;
	}

	*num_groups = group_idx;
}

static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state)
{
	unsigned long i, x, index;
	struct partition_group size_group[length];
	unsigned long num_groups = 0;
	unsigned long randnum;

	partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups);

	/* FIXME: this group shuffle is currently a no-op. */
	for (i = num_groups - 1; i > 0; i--) {
		struct partition_group tmp;
		randnum = ranval(prng_state) % (i + 1);
		tmp = size_group[i];
		size_group[i] = size_group[randnum];
		size_group[randnum] = tmp;
	}

	for (x = 0; x < num_groups; x++) {
		for (index = size_group[x].length - 1; index > 0; index--) {
			tree tmp;

			i = size_group[x].start + index;
			if (DECL_BIT_FIELD_TYPE(newtree[i]))
				continue;
			randnum = ranval(prng_state) % (index + 1);
			randnum += size_group[x].start;
			// we could handle this case differently if desired
			if (DECL_BIT_FIELD_TYPE(newtree[randnum]))
				continue;
			tmp = newtree[i];
			newtree[i] = newtree[randnum];
			newtree[randnum] = tmp;
		}
	}
}

static void full_shuffle(tree *newtree, unsigned long length, ranctx *prng_state)
{
	unsigned long i, randnum;

	for (i = length - 1; i > 0; i--) {
		tree tmp;
		randnum = ranval(prng_state) % (i + 1);
		tmp = newtree[i];
		newtree[i] = newtree[randnum];
		newtree[randnum] = tmp;
	}

Annotation

Implementation Notes