/* SPDX-License-Identifier: GPL-3.0-only WITH GCC-exception-3.1 */

/* File format for coverage information
   Copyright (C) 1996, 1997, 1998, 2000, 2002, 2003, 2004, 2005, 2007,
   2008  Free Software Foundation, Inc.
   Contributed by Bob Manson <manson@cygnus.com>.
   Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
*/

/* Routines declared in gcov-io.h.  This file should be #included by
   another source file, after having #included gcov-io.h.  */

#if !IN_GCOV
static void gcov_write_block(unsigned int);
static gcov_unsigned_t *gcov_write_words(unsigned int);
#endif
static const gcov_unsigned_t *gcov_read_words(unsigned int);
#if !IN_LIBGCOV
static void gcov_allocate(unsigned int);
#endif

static inline gcov_unsigned_t from_file(gcov_unsigned_t value)
{
#if !IN_LIBGCOV
	if (gcov_var.endian) {
		value = (value >> 16) | (value << 16);
		value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff);
	}
#endif
	return value;
}

/* Open a gcov file. NAME is the name of the file to open and MODE
   indicates whether a new file should be created, or an existing file
   opened. If MODE is >= 0 an existing file will be opened, if
   possible, and if MODE is <= 0, a new file will be created. Use
   MODE=0 to attempt to reopen an existing file and then fall back on
   creating a new one.  If MODE < 0, the file will be opened in
   read-only mode.  Otherwise it will be opened for modification.
   Return zero on failure, >0 on opening an existing file and <0 on
   creating a new one.  */

GCOV_LINKAGE int
#if IN_LIBGCOV
gcov_open(const char *name)
#else
gcov_open(const char *name, int mode)
#endif
{
#if IN_LIBGCOV
	const int mode = 0;
#endif
#if GCOV_LOCKED
	struct flock s_flock;
	int fd;

	s_flock.l_whence = SEEK_SET;
	s_flock.l_start = 0;
	s_flock.l_len = 0; /* Until EOF.  */
	s_flock.l_pid = getpid();
#endif

	gcc_assert(!gcov_var.file);
	gcov_var.start = 0;
	gcov_var.offset = gcov_var.length = 0;
	gcov_var.overread = -1u;
	gcov_var.error = 0;
#if !IN_LIBGCOV
	gcov_var.endian = 0;
#endif
#if GCOV_LOCKED
	if (mode > 0) {
		/* Read-only mode - acquire a read-lock.  */
		s_flock.l_type = F_RDLCK;
		fd = open(name, O_RDONLY);
	} else {
		/* Write mode - acquire a write-lock.  */
		s_flock.l_type = F_WRLCK;
		fd = open(name, O_RDWR | O_CREAT, 0666);
	}
	if (fd < 0)
		return 0;

	while (fcntl(fd, F_SETLKW, &s_flock) && errno == EINTR)
		continue;

	gcov_var.file = fdopen(fd, (mode > 0) ? "rb" : "r+b");

	if (!gcov_var.file) {
		close(fd);
		return 0;
	}

	if (mode > 0)
		gcov_var.mode = 1;
	else if (mode == 0) {
		struct stat st;

		if (fstat(fd, &st) < 0) {
			fclose(gcov_var.file);
			gcov_var.file = 0;
			return 0;
		}
		if (st.st_size != 0)
			gcov_var.mode = 1;
		else
			gcov_var.mode = mode * 2 + 1;
	} else
		gcov_var.mode = mode * 2 + 1;
#else
	if (mode >= 0)
		gcov_var.file = fopen(name, (mode > 0) ? "rb" : "r+b");

	if (gcov_var.file)
		gcov_var.mode = 1;
	else if (mode <= 0) {
		gcov_var.file = fopen(name, "w+b");
		if (gcov_var.file)
			gcov_var.mode = mode * 2 + 1;
	}
	if (!gcov_var.file)
		return 0;
#endif

	setbuf(gcov_var.file, (char *)0);

	return 1;
}

/* Close the current gcov file. Flushes data to disk. Returns nonzero
   on failure or error flag set.  */

GCOV_LINKAGE int
gcov_close(void)
{
	if (gcov_var.file) {
#if !IN_GCOV
	if (gcov_var.offset && gcov_var.mode < 0)
		gcov_write_block(gcov_var.offset);
#endif
		fclose(gcov_var.file);
		gcov_var.file = 0;
		gcov_var.length = 0;
	}
#if !IN_LIBGCOV
	free(gcov_var.buffer);
	gcov_var.alloc = 0;
	gcov_var.buffer = 0;
#endif
	gcov_var.mode = 0;
	return gcov_var.error;
}

#if !IN_LIBGCOV
/* Check if MAGIC is EXPECTED. Use it to determine endianness of the
   file. Returns +1 for same endian, -1 for other endian and zero for
   not EXPECTED.  */

GCOV_LINKAGE int
gcov_magic(gcov_unsigned_t magic, gcov_unsigned_t expected)
{
	if (magic == expected)
		return 1;
	magic = (magic >> 16) | (magic << 16);
	magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff);
	if (magic == expected) {
		gcov_var.endian = 1;
		return -1;
	}
	return 0;
}
#endif

#if !IN_LIBGCOV
static void
gcov_allocate(unsigned int length)
{
	size_t new_size = gcov_var.alloc;

	if (!new_size)
		new_size = GCOV_BLOCK_SIZE;
	new_size += length;
	new_size *= 2;

	gcov_var.alloc = new_size;
	gcov_var.buffer = XRESIZEVAR(gcov_unsigned_t, gcov_var.buffer,
		new_size << 2);
}
#endif

#if !IN_GCOV
/* Write out the current block, if needs be.  */

static void
gcov_write_block(unsigned int size)
{
	if (fwrite(gcov_var.buffer, size << 2, 1, gcov_var.file) != 1)
		gcov_var.error = 1;
	gcov_var.start += size;
	gcov_var.offset -= size;
}

/* Allocate space to write BYTES bytes to the gcov file. Return a
   pointer to those bytes, or NULL on failure.  */

static gcov_unsigned_t *
gcov_write_words(unsigned int words)
{
	gcov_unsigned_t *result;

	gcc_assert(gcov_var.mode < 0);
#if IN_LIBGCOV
	if (gcov_var.offset >= GCOV_BLOCK_SIZE) {
		gcov_write_block(GCOV_BLOCK_SIZE);
		if (gcov_var.offset) {
			gcc_assert(gcov_var.offset == 1);
			memcpy(gcov_var.buffer, gcov_var.buffer
				+ GCOV_BLOCK_SIZE, 4);
		}
	}
#else
	if (gcov_var.offset + words > gcov_var.alloc)
		gcov_allocate(gcov_var.offset + words);
#endif
	result = &gcov_var.buffer[gcov_var.offset];
	gcov_var.offset += words;

	return result;
}

/* Write unsigned VALUE to coverage file.  Sets error flag
   appropriately.  */

GCOV_LINKAGE void
gcov_write_unsigned(gcov_unsigned_t value)
{
	gcov_unsigned_t *buffer = gcov_write_words(1);

	buffer[0] = value;
}

/* Write counter VALUE to coverage file.  Sets error flag
   appropriately.  */

#if IN_LIBGCOV
GCOV_LINKAGE void
gcov_write_counter(gcov_type value)
{
	gcov_unsigned_t *buffer = gcov_write_words(2);

	buffer[0] = (gcov_unsigned_t) value;
	if (sizeof(value) > sizeof(gcov_unsigned_t))
		buffer[1] = (gcov_unsigned_t) (value >> 32);
	else
		buffer[1] = 0;
}
#endif /* IN_LIBGCOV */

#if !IN_LIBGCOV
/* Write STRING to coverage file.  Sets error flag on file
   error, overflow flag on overflow */

GCOV_LINKAGE void
gcov_write_string(const char *string)
{
	unsigned int length = 0;
	unsigned int alloc = 0;
	gcov_unsigned_t *buffer;

	if (string) {
		length = strlen(string);
		alloc = (length + 4) >> 2;
	}

	buffer = gcov_write_words(1 + alloc);

	buffer[0] = alloc;
	buffer[alloc] = 0;
	memcpy(&buffer[1], string, length);
}
#endif

#if !IN_LIBGCOV
/* Write a tag TAG and reserve space for the record length. Return a
   value to be used for gcov_write_length.  */

GCOV_LINKAGE gcov_position_t
gcov_write_tag(gcov_unsigned_t tag)
{
	gcov_position_t result = gcov_var.start + gcov_var.offset;
	gcov_unsigned_t *buffer = gcov_write_words(2);

	buffer[0] = tag;
	buffer[1] = 0;

	return result;
}

/* Write a record length using POSITION, which was returned by
   gcov_write_tag.  The current file position is the end of the
   record, and is restored before returning.  Returns nonzero on
   overflow.  */

GCOV_LINKAGE void
gcov_write_length(gcov_position_t position)
{
	unsigned int offset;
	gcov_unsigned_t length;
	gcov_unsigned_t *buffer;

	gcc_assert(gcov_var.mode < 0);
	gcc_assert(position + 2 <= gcov_var.start + gcov_var.offset);
	gcc_assert(position >= gcov_var.start);
	offset = position - gcov_var.start;
	length = gcov_var.offset - offset - 2;
	buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset];
	buffer[1] = length;
	if (gcov_var.offset >= GCOV_BLOCK_SIZE)
		gcov_write_block(gcov_var.offset);
}

#else /* IN_LIBGCOV */

/* Write a tag TAG and length LENGTH.  */

GCOV_LINKAGE void
gcov_write_tag_length(gcov_unsigned_t tag, gcov_unsigned_t length)
{
	gcov_unsigned_t *buffer = gcov_write_words(2);

	buffer[0] = tag;
	buffer[1] = length;
}

/* Write a summary structure to the gcov file.  Return nonzero on
   overflow.  */

GCOV_LINKAGE void
gcov_write_summary(gcov_unsigned_t tag, const struct gcov_summary *summary)
{
	unsigned int ix;
	const struct gcov_ctr_summary *csum;

	gcov_write_tag_length(tag, GCOV_TAG_SUMMARY_LENGTH);
	gcov_write_unsigned(summary->checksum);
	for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) {
		gcov_write_unsigned(csum->num);
		gcov_write_unsigned(csum->runs);
		gcov_write_counter(csum->sum_all);
		gcov_write_counter(csum->run_max);
		gcov_write_counter(csum->sum_max);
	}
}
#endif /* IN_LIBGCOV */

#endif /*!IN_GCOV */

/* Return a pointer to read BYTES bytes from the gcov file. Returns
   NULL on failure (read past EOF).  */

static const gcov_unsigned_t *
gcov_read_words(unsigned int words)
{
	const gcov_unsigned_t *result;
	unsigned int excess = gcov_var.length - gcov_var.offset;

	gcc_assert(gcov_var.mode > 0);
	if (excess < words) {
		gcov_var.start += gcov_var.offset;
#if IN_LIBGCOV
		if (excess) {
			gcc_assert(excess == 1);
			memcpy(gcov_var.buffer, gcov_var.buffer
				+ gcov_var.offset, 4);
		}
#else
		memmove(gcov_var.buffer, gcov_var.buffer
			+ gcov_var.offset, excess * 4);
#endif
		gcov_var.offset = 0;
		gcov_var.length = excess;
#if IN_LIBGCOV
		gcc_assert(!gcov_var.length || gcov_var.length == 1);
		excess = GCOV_BLOCK_SIZE;
#else
		if (gcov_var.length + words > gcov_var.alloc)
			gcov_allocate(gcov_var.length + words);
		excess = gcov_var.alloc - gcov_var.length;
#endif
		excess = fread(gcov_var.buffer + gcov_var.length,
			1, excess << 2, gcov_var.file) >> 2;
		gcov_var.length += excess;
		if (gcov_var.length < words) {
			gcov_var.overread += words - gcov_var.length;
			gcov_var.length = 0;
			return 0;
		}
	}
	result = &gcov_var.buffer[gcov_var.offset];
	gcov_var.offset += words;
	return result;
}

/* Read unsigned value from a coverage file. Sets error flag on file
   error, overflow flag on overflow */

GCOV_LINKAGE gcov_unsigned_t
gcov_read_unsigned(void)
{
	gcov_unsigned_t value;
	const gcov_unsigned_t *buffer = gcov_read_words(1);

	if (!buffer)
		return 0;
	value = from_file(buffer[0]);
	return value;
}

/* Read counter value from a coverage file. Sets error flag on file
   error, overflow flag on overflow */

GCOV_LINKAGE gcov_type
gcov_read_counter(void)
{
	gcov_type value;
	const gcov_unsigned_t *buffer = gcov_read_words(2);

	if (!buffer)
		return 0;
	value = from_file(buffer[0]);
	if (sizeof(value) > sizeof(gcov_unsigned_t))
		value |= ((gcov_type) from_file(buffer[1])) << 32;
	else if (buffer[1])
		gcov_var.error = -1;

	return value;
}

/* Read string from coverage file. Returns a pointer to a static
   buffer, or NULL on empty string. You must copy the string before
   calling another gcov function.  */

#if !IN_LIBGCOV
GCOV_LINKAGE const char *
gcov_read_string(void)
{
	unsigned int length = gcov_read_unsigned();

	if (!length)
		return 0;

	return (const char *) gcov_read_words(length);
}
#endif

GCOV_LINKAGE void
gcov_read_summary(struct gcov_summary *summary)
{
	unsigned int ix;
	struct gcov_ctr_summary *csum;

	summary->checksum = gcov_read_unsigned();
	for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) {
		csum->num = gcov_read_unsigned();
		csum->runs = gcov_read_unsigned();
		csum->sum_all = gcov_read_counter();
		csum->run_max = gcov_read_counter();
		csum->sum_max = gcov_read_counter();
	}
}

#if !IN_LIBGCOV
/* Reset to a known position.  BASE should have been obtained from
   gcov_position, LENGTH should be a record length.  */

GCOV_LINKAGE void
gcov_sync(gcov_position_t base, gcov_unsigned_t length)
{
	gcc_assert(gcov_var.mode > 0);
	base += length;
	if (base - gcov_var.start <= gcov_var.length)
		gcov_var.offset = base - gcov_var.start;
	else {
		gcov_var.offset = gcov_var.length = 0;
		fseek(gcov_var.file, base << 2, SEEK_SET);
		gcov_var.start = ftell(gcov_var.file) >> 2;
	}
}
#endif

#if IN_LIBGCOV
/* Move to a given position in a gcov file.  */

GCOV_LINKAGE void
gcov_seek(gcov_position_t base)
{
	gcc_assert(gcov_var.mode < 0);
	if (gcov_var.offset)
		gcov_write_block(gcov_var.offset);
	fseek(gcov_var.file, base << 2, SEEK_SET);
	gcov_var.start = ftell(gcov_var.file) >> 2;
}
#endif

#if IN_GCOV > 0
/* Return the modification time of the current gcov file.  */

GCOV_LINKAGE time_t
gcov_time(void)
{
	struct stat status;

	if (fstat(fileno(gcov_var.file), &status))
		return 0;
	else
		return status.st_mtime;
}
#endif /* IN_GCOV */
