// SPDX-License-Identifier: GPL-2.0
/*
 *  This code provides functions to handle gcc's profiling data format
 *  introduced with gcc 3.4. Future versions of gcc may change the gcov
 *  format (as happened before), so all format-specific information needs
 *  to be kept modular and easily exchangeable.
 *
 *  This file is based on gcc-internal definitions. Functions and data
 *  structures are defined to be compatible with gcc counterparts.
 *  For a better understanding, refer to gcc source: gcc/gcov-io.h.
 *
 *    Copyright IBM Corp. 2009
 *    Author(s): Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
 *
 *    Uses gcc-internal data definitions.
 */

#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
#include "gcov.h"

#define GCOV_COUNTERS		5

static struct gcov_info *gcov_info_head;

/**
 * struct gcov_fn_info - profiling meta data per function
 * @ident: object file-unique function identifier
 * @checksum: function checksum
 * @n_ctrs: number of values per counter type belonging to this function
 *
 * This data is generated by gcc during compilation and doesn't change
 * at run-time.
 */
struct gcov_fn_info {
	unsigned int ident;
	unsigned int checksum;
	unsigned int n_ctrs[0];
};

/**
 * struct gcov_ctr_info - profiling data per counter type
 * @num: number of counter values for this type
 * @values: array of counter values for this type
 * @merge: merge function for counter values of this type (unused)
 *
 * This data is generated by gcc during compilation and doesn't change
 * at run-time with the exception of the values array.
 */
struct gcov_ctr_info {
	unsigned int	num;
	gcov_type	*values;
	void		(*merge)(gcov_type *, unsigned int);
};

/**
 * struct gcov_info - profiling data per object file
 * @version: gcov version magic indicating the gcc version used for compilation
 * @next: list head for a singly-linked list
 * @stamp: time stamp
 * @filename: name of the associated gcov data file
 * @n_functions: number of instrumented functions
 * @functions: function data
 * @ctr_mask: mask specifying which counter types are active
 * @counts: counter data per counter type
 *
 * This data is generated by gcc during compilation and doesn't change
 * at run-time with the exception of the next pointer.
 */
struct gcov_info {
	unsigned int			version;
	struct gcov_info		*next;
	unsigned int			stamp;
	const char			*filename;
	unsigned int			n_functions;
	const struct gcov_fn_info	*functions;
	unsigned int			ctr_mask;
	struct gcov_ctr_info		counts[0];
};

/**
 * gcov_info_filename - return info filename
 * @info: profiling data set
 */
const char *gcov_info_filename(struct gcov_info *info)
{
	return info->filename;
}

/**
 * gcov_info_version - return info version
 * @info: profiling data set
 */
unsigned int gcov_info_version(struct gcov_info *info)
{
	return info->version;
}

/**
 * gcov_info_next - return next profiling data set
 * @info: profiling data set
 *
 * Returns next gcov_info following @info or first gcov_info in the chain if
 * @info is %NULL.
 */
struct gcov_info *gcov_info_next(struct gcov_info *info)
{
	if (!info)
		return gcov_info_head;

	return info->next;
}

/**
 * gcov_info_link - link/add profiling data set to the list
 * @info: profiling data set
 */
void gcov_info_link(struct gcov_info *info)
{
	info->next = gcov_info_head;
	gcov_info_head = info;
}

/**
 * gcov_info_unlink - unlink/remove profiling data set from the list
 * @prev: previous profiling data set
 * @info: profiling data set
 */
void gcov_info_unlink(struct gcov_info *prev, struct gcov_info *info)
{
	if (prev)
		prev->next = info->next;
	else
		gcov_info_head = info->next;
}

/* Symbolic links to be created for each profiling data file. */
const struct gcov_link gcov_link[] = {
	{ OBJ_TREE, "gcno" },	/* Link to .gcno file in $(objtree). */
	{ 0, NULL},
};

/*
 * Determine whether a counter is active. Based on gcc magic. Doesn't change
 * at run-time.
 */
static int counter_active(struct gcov_info *info, unsigned int type)
{
	return (1 << type) & info->ctr_mask;
}

/* Determine number of active counters. Based on gcc magic. */
static unsigned int num_counter_active(struct gcov_info *info)
{
	unsigned int i;
	unsigned int result = 0;

	for (i = 0; i < GCOV_COUNTERS; i++) {
		if (counter_active(info, i))
			result++;
	}
	return result;
}

/**
 * gcov_info_reset - reset profiling data to zero
 * @info: profiling data set
 */
void gcov_info_reset(struct gcov_info *info)
{
	unsigned int active = num_counter_active(info);
	unsigned int i;

	for (i = 0; i < active; i++) {
		memset(info->counts[i].values, 0,
		       info->counts[i].num * sizeof(gcov_type));
	}
}

/**
 * gcov_info_is_compatible - check if profiling data can be added
 * @info1: first profiling data set
 * @info2: second profiling data set
 *
 * Returns non-zero if profiling data can be added, zero otherwise.
 */
int gcov_info_is_compatible(struct gcov_info *info1, struct gcov_info *info2)
{
	return (info1->stamp == info2->stamp);
}

/**
 * gcov_info_add - add up profiling data
 * @dest: profiling data set to which data is added
 * @source: profiling data set which is added
 *
 * Adds profiling counts of @source to @dest.
 */
void gcov_info_add(struct gcov_info *dest, struct gcov_info *source)
{
	unsigned int i;
	unsigned int j;

	for (i = 0; i < num_counter_active(dest); i++) {
		for (j = 0; j < dest->counts[i].num; j++) {
			dest->counts[i].values[j] +=
				source->counts[i].values[j];
		}
	}
}

/* Get size of function info entry. Based on gcc magic. */
static size_t get_fn_size(struct gcov_info *info)
{
	size_t size;

	size = sizeof(struct gcov_fn_info) + num_counter_active(info) *
	       sizeof(unsigned int);
	if (__alignof__(struct gcov_fn_info) > sizeof(unsigned int))
		size = ALIGN(size, __alignof__(struct gcov_fn_info));
	return size;
}

/* Get address of function info entry. Based on gcc magic. */
static struct gcov_fn_info *get_fn_info(struct gcov_info *info, unsigned int fn)
{
	return (struct gcov_fn_info *)
		((char *) info->functions + fn * get_fn_size(info));
}

/**
 * gcov_info_dup - duplicate profiling data set
 * @info: profiling data set to duplicate
 *
 * Return newly allocated duplicate on success, %NULL on error.
 */
struct gcov_info *gcov_info_dup(struct gcov_info *info)
{
	struct gcov_info *dup;
	unsigned int i;
	unsigned int active;

	/* Duplicate gcov_info. */
	active = num_counter_active(info);
	dup = kzalloc(sizeof(struct gcov_info) +
		      sizeof(struct gcov_ctr_info) * active, GFP_KERNEL);
	if (!dup)
		return NULL;
	dup->version		= info->version;
	dup->stamp		= info->stamp;
	dup->n_functions	= info->n_functions;
	dup->ctr_mask		= info->ctr_mask;
	/* Duplicate filename. */
	dup->filename		= kstrdup(info->filename, GFP_KERNEL);
	if (!dup->filename)
		goto err_free;
	/* Duplicate table of functions. */
	dup->functions = kmemdup(info->functions, info->n_functions *
				 get_fn_size(info), GFP_KERNEL);
	if (!dup->functions)
		goto err_free;
	/* Duplicate counter arrays. */
	for (i = 0; i < active ; i++) {
		struct gcov_ctr_info *ctr = &info->counts[i];
		size_t size = ctr->num * sizeof(gcov_type);

		dup->counts[i].num = ctr->num;
		dup->counts[i].merge = ctr->merge;
		dup->counts[i].values = vmalloc(size);
		if (!dup->counts[i].values)
			goto err_free;
		memcpy(dup->counts[i].values, ctr->values, size);
	}
	return dup;

err_free:
	gcov_info_free(dup);
	return NULL;
}

/**
 * gcov_info_free - release memory for profiling data set duplicate
 * @info: profiling data set duplicate to free
 */
void gcov_info_free(struct gcov_info *info)
{
	unsigned int active = num_counter_active(info);
	unsigned int i;

	for (i = 0; i < active ; i++)
		vfree(info->counts[i].values);
	kfree(info->functions);
	kfree(info->filename);
	kfree(info);
}

/**
 * struct type_info - iterator helper array
 * @ctr_type: counter type
 * @offset: index of the first value of the current function for this type
 *
 * This array is needed to convert the in-memory data format into the in-file
 * data format:
 *
 * In-memory:
 *   for each counter type
 *     for each function
 *       values
 *
 * In-file:
 *   for each function
 *     for each counter type
 *       values
 *
 * See gcc source gcc/gcov-io.h for more information on data organization.
 */
struct type_info {
	int ctr_type;
	unsigned int offset;
};

/**
 * struct gcov_iterator - specifies current file position in logical records
 * @info: associated profiling data
 * @record: record type
 * @function: function number
 * @type: counter type
 * @count: index into values array
 * @num_types: number of counter types
 * @type_info: helper array to get values-array offset for current function
 */
struct gcov_iterator {
	struct gcov_info *info;

	int record;
	unsigned int function;
	unsigned int type;
	unsigned int count;

	int num_types;
	struct type_info type_info[0];
};

static struct gcov_fn_info *get_func(struct gcov_iterator *iter)
{
	return get_fn_info(iter->info, iter->function);
}

static struct type_info *get_type(struct gcov_iterator *iter)
{
	return &iter->type_info[iter->type];
}

/**
 * gcov_iter_new - allocate and initialize profiling data iterator
 * @info: profiling data set to be iterated
 *
 * Return file iterator on success, %NULL otherwise.
 */
struct gcov_iterator *gcov_iter_new(struct gcov_info *info)
{
	struct gcov_iterator *iter;

	iter = kzalloc(sizeof(struct gcov_iterator) +
		       num_counter_active(info) * sizeof(struct type_info),
		       GFP_KERNEL);
	if (iter)
		iter->info = info;

	return iter;
}

/**
 * gcov_iter_free - release memory for iterator
 * @iter: file iterator to free
 */
void gcov_iter_free(struct gcov_iterator *iter)
{
	kfree(iter);
}

/**
 * gcov_iter_get_info - return profiling data set for given file iterator
 * @iter: file iterator
 */
struct gcov_info *gcov_iter_get_info(struct gcov_iterator *iter)
{
	return iter->info;
}

/**
 * gcov_iter_start - reset file iterator to starting position
 * @iter: file iterator
 */
void gcov_iter_start(struct gcov_iterator *iter)
{
	int i;

	iter->record = 0;
	iter->function = 0;
	iter->type = 0;
	iter->count = 0;
	iter->num_types = 0;
	for (i = 0; i < GCOV_COUNTERS; i++) {
		if (counter_active(iter->info, i)) {
			iter->type_info[iter->num_types].ctr_type = i;
			iter->type_info[iter->num_types++].offset = 0;
		}
	}
}

/* Mapping of logical record number to actual file content. */
#define RECORD_FILE_MAGIC	0
#define RECORD_GCOV_VERSION	1
#define RECORD_TIME_STAMP	2
#define RECORD_FUNCTION_TAG	3
#define RECORD_FUNCTON_TAG_LEN	4
#define RECORD_FUNCTION_IDENT	5
#define RECORD_FUNCTION_CHECK	6
#define RECORD_COUNT_TAG	7
#define RECORD_COUNT_LEN	8
#define RECORD_COUNT		9

/**
 * gcov_iter_next - advance file iterator to next logical record
 * @iter: file iterator
 *
 * Return zero if new position is valid, non-zero if iterator has reached end.
 */
int gcov_iter_next(struct gcov_iterator *iter)
{
	switch (iter->record) {
	case RECORD_FILE_MAGIC:
	case RECORD_GCOV_VERSION:
	case RECORD_FUNCTION_TAG:
	case RECORD_FUNCTON_TAG_LEN:
	case RECORD_FUNCTION_IDENT:
	case RECORD_COUNT_TAG:
		/* Advance to next record */
		iter->record++;
		break;
	case RECORD_COUNT:
		/* Advance to next count */
		iter->count++;
		/* fall through */
	case RECORD_COUNT_LEN:
		if (iter->count < get_func(iter)->n_ctrs[iter->type]) {
			iter->record = 9;
			break;
		}
		/* Advance to next counter type */
		get_type(iter)->offset += iter->count;
		iter->count = 0;
		iter->type++;
		/* fall through */
	case RECORD_FUNCTION_CHECK:
		if (iter->type < iter->num_types) {
			iter->record = 7;
			break;
		}
		/* Advance to next function */
		iter->type = 0;
		iter->function++;
		/* fall through */
	case RECORD_TIME_STAMP:
		if (iter->function < iter->info->n_functions)
			iter->record = 3;
		else
			iter->record = -1;
		break;
	}
	/* Check for EOF. */
	if (iter->record == -1)
		return -EINVAL;
	else
		return 0;
}

/**
 * seq_write_gcov_u32 - write 32 bit number in gcov format to seq_file
 * @seq: seq_file handle
 * @v: value to be stored
 *
 * Number format defined by gcc: numbers are recorded in the 32 bit
 * unsigned binary form of the endianness of the machine generating the
 * file.
 */
static int seq_write_gcov_u32(struct seq_file *seq, u32 v)
{
	return seq_write(seq, &v, sizeof(v));
}

/**
 * seq_write_gcov_u64 - write 64 bit number in gcov format to seq_file
 * @seq: seq_file handle
 * @v: value to be stored
 *
 * Number format defined by gcc: numbers are recorded in the 32 bit
 * unsigned binary form of the endianness of the machine generating the
 * file. 64 bit numbers are stored as two 32 bit numbers, the low part
 * first.
 */
static int seq_write_gcov_u64(struct seq_file *seq, u64 v)
{
	u32 data[2];

	data[0] = (v & 0xffffffffUL);
	data[1] = (v >> 32);
	return seq_write(seq, data, sizeof(data));
}

/**
 * gcov_iter_write - write data for current pos to seq_file
 * @iter: file iterator
 * @seq: seq_file handle
 *
 * Return zero on success, non-zero otherwise.
 */
int gcov_iter_write(struct gcov_iterator *iter, struct seq_file *seq)
{
	int rc = -EINVAL;

	switch (iter->record) {
	case RECORD_FILE_MAGIC:
		rc = seq_write_gcov_u32(seq, GCOV_DATA_MAGIC);
		break;
	case RECORD_GCOV_VERSION:
		rc = seq_write_gcov_u32(seq, iter->info->version);
		break;
	case RECORD_TIME_STAMP:
		rc = seq_write_gcov_u32(seq, iter->info->stamp);
		break;
	case RECORD_FUNCTION_TAG:
		rc = seq_write_gcov_u32(seq, GCOV_TAG_FUNCTION);
		break;
	case RECORD_FUNCTON_TAG_LEN:
		rc = seq_write_gcov_u32(seq, 2);
		break;
	case RECORD_FUNCTION_IDENT:
		rc = seq_write_gcov_u32(seq, get_func(iter)->ident);
		break;
	case RECORD_FUNCTION_CHECK:
		rc = seq_write_gcov_u32(seq, get_func(iter)->checksum);
		break;
	case RECORD_COUNT_TAG:
		rc = seq_write_gcov_u32(seq,
			GCOV_TAG_FOR_COUNTER(get_type(iter)->ctr_type));
		break;
	case RECORD_COUNT_LEN:
		rc = seq_write_gcov_u32(seq,
				get_func(iter)->n_ctrs[iter->type] * 2);
		break;
	case RECORD_COUNT:
		rc = seq_write_gcov_u64(seq,
			iter->info->counts[iter->type].
				values[iter->count + get_type(iter)->offset]);
		break;
	}
	return rc;
}
