commit 44a2f95676a50d4f9503f994064f3b52cb072a5f
parent 39cb4f0d11e97be5acc091d1ab54f82d2716b550
Author: Dimitris Papastamos <dimitris.papastamos@arm.com>
Date: Tue, 19 Feb 2019 10:50:55 +0000
Remove libgcov
Change-Id: I2a7ff5495d7e69e378d75f735d1961a4002bf5ac
Diffstat:
5 files changed, 0 insertions(+), 2482 deletions(-)
diff --git a/src/libgcov/gcov-glue.c b/src/libgcov/gcov-glue.c
@@ -1,156 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2012 Google, Inc. All rights reserved.
- *
- * This program 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; version 2 of the License.
- *
- * This program 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.
- */
-
-#include <stdint.h>
-#include <bootstate.h>
-#include <cbmem.h>
-
-typedef struct file {
- uint32_t magic;
- struct file *next;
- char *filename;
- char *data;
- int offset;
- int len;
-} FILE;
-
-#define SEEK_SET 0 /* Seek from beginning of file. */
-
-#define DIR_SEPARATOR '/'
-#define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
-#define HAS_DRIVE_SPEC(f) (0)
-
-#define COVERAGE_SIZE (32*1024)
-
-#define COVERAGE_MAGIC 0x584d4153
-
-static FILE *current_file = NULL;
-static FILE *previous_file = NULL;
-
-static FILE *fopen(const char *path, const char *mode)
-{
-#if IS_ENABLED(CONFIG_DEBUG_COVERAGE)
- printk(BIOS_DEBUG, "fopen %s with mode %s\n",
- path, mode);
-#endif
- if (!current_file) {
- current_file = cbmem_add(CBMEM_ID_COVERAGE, 32*1024);
- } else {
- previous_file = current_file;
- current_file =
- (FILE *)(ALIGN(((unsigned long)previous_file->data
- + previous_file->len), 16));
- }
-
- // TODO check if we're at the end of the CBMEM region (ENOMEM)
- if (current_file) {
- current_file->magic = COVERAGE_MAGIC;
- current_file->next = NULL;
- if (previous_file)
- previous_file->next = current_file;
- current_file->filename = (char *)¤t_file[1];
- strcpy(current_file->filename, path);
- current_file->data =
- (char *)ALIGN(((unsigned long)current_file->filename
- + strlen(path) + 1), 16);
- current_file->offset = 0;
- current_file->len = 0;
- }
-
- return current_file;
-}
-
-static int fclose(FILE *stream)
-{
-#if IS_ENABLED(CONFIG_DEBUG_COVERAGE)
- printk(BIOS_DEBUG, "fclose %s\n", stream->filename);
-#endif
- return 0;
-}
-
-static int fseek(FILE *stream, long offset, int whence)
-{
- /* fseek should only be called with offset==0 and whence==SEEK_SET
- * to a freshly opened file. */
- gcc_assert(offset == 0 && whence == SEEK_SET);
-#if IS_ENABLED(CONFIG_DEBUG_COVERAGE)
- printk(BIOS_DEBUG, "fseek %s offset=%ld whence=%d\n",
- stream->filename, offset, whence);
-#endif
- return 0;
-}
-
-static long ftell(FILE *stream)
-{
- /* ftell should currently not be called */
- gcc_assert(0);
-#if IS_ENABLED(CONFIG_DEBUG_COVERAGE)
- printk(BIOS_DEBUG, "ftell %s\n", stream->filename);
-#endif
- return 0;
-}
-
-static size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
-#if IS_ENABLED(CONFIG_DEBUG_COVERAGE)
- printk(BIOS_DEBUG, "fread: ptr=%p size=%zd nmemb=%zd FILE*=%p\n",
- ptr, size, nmemb, stream);
-#endif
- return 0;
-}
-
-static size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
-#if IS_ENABLED(CONFIG_DEBUG_COVERAGE)
- printk(BIOS_DEBUG, "fwrite: %zd * %zd bytes to file %s\n",
- nmemb, size, stream->filename);
-#endif
- // TODO check if file is last opened file and fail otherwise.
-
- memcpy(stream->data + stream->offset, ptr, size * nmemb);
- stream->len += (nmemb * size) - (stream->len - stream->offset);
- stream->offset += nmemb * size;
- return nmemb;
-}
-
-static void setbuf(FILE *stream, char *buf)
-{
- gcc_assert(buf == 0);
-}
-
-static void coverage_init(void *unused)
-{
- extern long __CTOR_LIST__;
- typedef void (*func_ptr)(void);
- func_ptr *ctor = (func_ptr *) &__CTOR_LIST__;
- if (ctor == NULL)
- return;
-
- for (; *ctor != (func_ptr) 0; ctor++)
- (*ctor)();
-}
-
-void __gcov_flush(void);
-static void coverage_exit(void *unused)
-{
-#if IS_ENABLED(CONFIG_DEBUG_COVERAGE)
- printk(BIOS_DEBUG, "Syncing coverage data.\n");
-#endif
- __gcov_flush();
-}
-
-BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, coverage_init, NULL);
-BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, coverage_exit, NULL);
-BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, coverage_exit, NULL);
diff --git a/src/libgcov/gcov-io.c b/src/libgcov/gcov-io.c
@@ -1,532 +0,0 @@
-/* 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 */
diff --git a/src/libgcov/gcov-io.h b/src/libgcov/gcov-io.h
@@ -1,633 +0,0 @@
-/* File format for coverage information
- Copyright (C) 1996, 1997, 1998, 2000, 2002,
- 2003, 2004, 2005, 2008, 2009 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.
-*/
-
-
-/* Coverage information is held in two files. A notes file, which is
- generated by the compiler, and a data file, which is generated by
- the program under test. Both files use a similar structure. We do
- not attempt to make these files backwards compatible with previous
- versions, as you only need coverage information when developing a
- program. We do hold version information, so that mismatches can be
- detected, and we use a format that allows tools to skip information
- they do not understand or are not interested in.
-
- 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. Strings are
- padded with 1 to 4 NUL bytes, to bring the length up to a multiple
- of 4. The number of 4 bytes is stored, followed by the padded
- string. Zero length and NULL strings are simply stored as a length
- of zero (they have no trailing NUL or padding).
-
- int32: byte3 byte2 byte1 byte0 | byte0 byte1 byte2 byte3
- int64: int32:low int32:high
- string: int32:0 | int32:length char* char:0 padding
- padding: | char:0 | char:0 char:0 | char:0 char:0 char:0
- item: int32 | int64 | string
-
- The basic format of the files is
-
- file : int32:magic int32:version int32:stamp record*
-
- The magic ident is different for the notes and the data files. The
- magic ident is used to determine the endianness of the file, when
- reading. The version is the same for both files and is derived
- from gcc's version number. The stamp value is used to synchronize
- note and data files and to synchronize merging within a data
- file. It need not be an absolute time stamp, merely a ticker that
- increments fast enough and cycles slow enough to distinguish
- different compile/run/compile cycles.
-
- Although the ident and version are formally 32 bit numbers, they
- are derived from 4 character ASCII strings. The version number
- consists of the single character major version number, a two
- character minor version number (leading zero for versions less than
- 10), and a single character indicating the status of the release.
- That will be 'e' experimental, 'p' prerelease and 'r' for release.
- Because, by good fortune, these are in alphabetical order, string
- collating can be used to compare version strings. Be aware that
- the 'e' designation will (naturally) be unstable and might be
- incompatible with itself. For gcc 3.4 experimental, it would be
- '304e' (0x33303465). When the major version reaches 10, the
- letters A-Z will be used. Assuming minor increments releases every
- 6 months, we have to make a major increment every 50 years.
- Assuming major increments releases every 5 years, we're ok for the
- next 155 years -- good enough for me.
-
- A record has a tag, length and variable amount of data.
-
- record: header data
- header: int32:tag int32:length
- data: item*
-
- Records are not nested, but there is a record hierarchy. Tag
- numbers reflect this hierarchy. Tags are unique across note and
- data files. Some record types have a varying amount of data. The
- LENGTH is the number of 4bytes that follow and is usually used to
- determine how much data. The tag value is split into 4 8-bit
- fields, one for each of four possible levels. The most significant
- is allocated first. Unused levels are zero. Active levels are
- odd-valued, so that the LSB of the level is one. A sub-level
- incorporates the values of its superlevels. This formatting allows
- you to determine the tag hierarchy, without understanding the tags
- themselves, and is similar to the standard section numbering used
- in technical documents. Level values [1..3f] are used for common
- tags, values [41..9f] for the notes file and [a1..ff] for the data
- file.
-
- The basic block graph file contains the following records
- note: unit function-graph*
- unit: header int32:checksum string:source
- function-graph: announce_function basic_blocks {arcs | lines}*
- announce_function: header int32:ident
- int32:lineno_checksum int32:cfg_checksum
- string:name string:source int32:lineno
- basic_block: header int32:flags*
- arcs: header int32:block_no arc*
- arc: int32:dest_block int32:flags
- lines: header int32:block_no line*
- int32:0 string:NULL
- line: int32:line_no | int32:0 string:filename
-
- The BASIC_BLOCK record holds per-bb flags. The number of blocks
- can be inferred from its data length. There is one ARCS record per
- basic block. The number of arcs from a bb is implicit from the
- data length. It enumerates the destination bb and per-arc flags.
- There is one LINES record per basic block, it enumerates the source
- lines which belong to that basic block. Source file names are
- introduced by a line number of 0, following lines are from the new
- source file. The initial source file for the function is NULL, but
- the current source file should be remembered from one LINES record
- to the next. The end of a block is indicated by an empty filename
- - this does not reset the current source file. Note there is no
- ordering of the ARCS and LINES records: they may be in any order,
- interleaved in any manner. The current filename follows the order
- the LINES records are stored in the file, *not* the ordering of the
- blocks they are for.
-
- The data file contains the following records.
- data: {unit summary:object summary:program* function-data*}*
- unit: header int32:checksum
- function-data: announce_function present counts
- announce_function: header int32:ident
- int32:lineno_checksum int32:cfg_checksum
- present: header int32:present
- counts: header int64:count*
- summary: int32:checksum {count-summary}GCOV_COUNTERS_SUMMABLE
- count-summary: int32:num int32:runs int64:sum
- int64:max int64:sum_max
-
- The ANNOUNCE_FUNCTION record is the same as that in the note file,
- but without the source location. The COUNTS gives the
- counter values for instrumented features. The about the whole
- program. The checksum is used for whole program summaries, and
- disambiguates different programs which include the same
- instrumented object file. There may be several program summaries,
- each with a unique checksum. The object summary's checksum is
- zero. Note that the data file might contain information from
- several runs concatenated, or the data might be merged.
-
- This file is included by both the compiler, gcov tools and the
- runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to
- distinguish which case is which. If IN_LIBGCOV is nonzero,
- libgcov is being built. If IN_GCOV is nonzero, the gcov tools are
- being built. Otherwise the compiler is being built. IN_GCOV may be
- positive or negative. If positive, we are compiling a tool that
- requires additional functions (see the code for knowledge of what
- those functions are). */
-
-#ifndef GCC_GCOV_IO_H
-#define GCC_GCOV_IO_H
-
-#ifdef __COREBOOT__
-#define GCOV_LINKAGE /* nothing */
-/* We need the definitions for
- BITS_PER_UNIT and
- LONG_LONG_TYPE_SIZE
- They are defined in gcc/defaults.h and gcc/config/<arch_depend_files>
- (like, gcc/config/i386/i386.h). And it can be overridden by setting
- in build scripts. Here I hardcoded the value for x86. */
-#define BITS_PER_UNIT 8
-#define LONG_LONG_TYPE_SIZE 64
-
-/* There are many gcc_assertions. Set the value to 1 if we want a warning
- message if the assertion fails. */
-#ifndef ENABLE_ASSERT_CHECKING
-#define ENABLE_ASSERT_CHECKING 1
-#endif
-#endif /* __COREBOOT__ */
-
-#if IN_LIBGCOV
-/* About the target */
-
-#if BITS_PER_UNIT == 8
-typedef unsigned int gcov_unsigned_t __attribute__((mode(SI)));
-typedef unsigned int gcov_position_t __attribute__((mode(SI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__((mode(DI)));
-#else
-typedef signed gcov_type __attribute__((mode(SI)));
-#endif
-#else
-#if BITS_PER_UNIT == 16
-typedef unsigned int gcov_unsigned_t __attribute__((mode(HI)));
-typedef unsigned int gcov_position_t __attribute__((mode(HI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__((mode(SI)));
-#else
-typedef signed gcov_type __attribute__((mode(HI)));
-#endif
-#else
-typedef unsigned int gcov_unsigned_t __attribute__((mode(QI)));
-typedef unsigned int gcov_position_t __attribute__((mode(QI)));
-#if LONG_LONG_TYPE_SIZE > 32
-typedef signed gcov_type __attribute__((mode(HI)));
-#else
-typedef signed gcov_type __attribute__((mode(QI)));
-#endif
-#endif
-#endif
-
-
-#if defined(TARGET_POSIX_IO)
-#define GCOV_LOCKED 1
-#else
-#define GCOV_LOCKED 0
-#endif
-
-#else /* !IN_LIBGCOV */
-/* About the host */
-
-typedef unsigned int gcov_unsigned_t;
-typedef unsigned int gcov_position_t;
-/* gcov_type is typedef'd elsewhere for the compiler */
-#if IN_GCOV
-#define GCOV_LINKAGE static
-typedef HOST_WIDEST_INT gcov_type;
-#if IN_GCOV > 0
-#include <sys/types.h>
-#endif
-#else /*!IN_GCOV */
-#define GCOV_TYPE_SIZE (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32)
-#endif
-
-#if defined(HOST_HAS_F_SETLKW)
-#define GCOV_LOCKED 1
-#else
-#define GCOV_LOCKED 0
-#endif
-
-#endif /* !IN_LIBGCOV */
-
-/* In gcov we want function linkage to be static. In the compiler we want
- it extern, so that they can be accessed from elsewhere. In libgcov we
- need these functions to be extern, so prefix them with __gcov. In
- libgcov they must also be hidden so that the instance in the executable
- is not also used in a DSO. */
-#if IN_LIBGCOV
-
-#ifndef __COREBOOT__
-#include "tconfig.h"
-#endif /* __COREBOOT__ */
-
-#define gcov_var __gcov_var
-#define gcov_open __gcov_open
-#define gcov_close __gcov_close
-#define gcov_write_tag_length __gcov_write_tag_length
-#define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
-#define gcov_rewrite __gcov_rewrite
-#define gcov_is_error __gcov_is_error
-#define gcov_write_unsigned __gcov_write_unsigned
-#define gcov_write_counter __gcov_write_counter
-#define gcov_write_summary __gcov_write_summary
-#define gcov_read_unsigned __gcov_read_unsigned
-#define gcov_read_counter __gcov_read_counter
-#define gcov_read_summary __gcov_read_summary
-
-/* Poison these, so they don't accidentally slip in. */
-#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
-#pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic
-
-#ifdef HAVE_GAS_HIDDEN
-#define ATTRIBUTE_HIDDEN __attribute__((__visibility__("hidden")))
-#else
-#define ATTRIBUTE_HIDDEN
-#endif
-
-#else
-
-#define ATTRIBUTE_HIDDEN
-
-#endif
-
-#ifndef GCOV_LINKAGE
-#define GCOV_LINKAGE extern
-#endif
-
-/* File suffixes. */
-#define GCOV_DATA_SUFFIX ".gcda"
-#define GCOV_NOTE_SUFFIX ".gcno"
-
-/* File magic. Must not be palindromes. */
-#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */
-#define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */
-
-/* gcov-iov.h is automatically generated by the makefile from
- version.c, it looks like
- #define GCOV_VERSION ((gcov_unsigned_t)0x89abcdef)
-*/
-#include "gcov-iov.h"
-
-/* Convert a magic or version number to a 4 character string. */
-#define GCOV_UNSIGNED2STRING(ARRAY, VALUE) \
- ((ARRAY)[0] = (char)((VALUE) >> 24), \
- (ARRAY)[1] = (char)((VALUE) >> 16), \
- (ARRAY)[2] = (char)((VALUE) >> 8), \
- (ARRAY)[3] = (char)((VALUE) >> 0))
-
-/* The record tags. Values [1..3f] are for tags which may be in either
- file. Values [41..9f] for those in the note file and [a1..ff] for
- the data file. The tag value zero is used as an explicit end of
- file marker -- it is not required to be present. */
-
-#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000)
-#define GCOV_TAG_FUNCTION_LENGTH (3)
-#define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000)
-#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM)
-#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH)
-#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000)
-#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2)
-#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2)
-#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000)
-#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000)
-#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2)
-#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2)
-#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) /* Obsolete */
-#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000)
-#define GCOV_TAG_SUMMARY_LENGTH \
- (1 + GCOV_COUNTERS_SUMMABLE * (2 + 3 * 2))
-
-/* Counters that are collected. */
-#define GCOV_COUNTER_ARCS 0 /* Arc transitions. */
-#define GCOV_COUNTERS_SUMMABLE 1 /* Counters which can be
- summed. */
-#define GCOV_FIRST_VALUE_COUNTER 1 /* The first of counters used for value
- profiling. They must form a consecutive
- interval and their order must match
- the order of HIST_TYPEs in
- value-prof.h. */
-#define GCOV_COUNTER_V_INTERVAL 1 /* Histogram of value inside an interval. */
-#define GCOV_COUNTER_V_POW2 2 /* Histogram of exact power2 logarithm
- of a value. */
-#define GCOV_COUNTER_V_SINGLE 3 /* The most common value of expression. */
-#define GCOV_COUNTER_V_DELTA 4 /* The most common difference between
- consecutive values of expression. */
-
-#define GCOV_COUNTER_V_INDIR 5 /* The most common indirect address */
-#define GCOV_COUNTER_AVERAGE 6 /* Compute average value passed to the
- counter. */
-#define GCOV_COUNTER_IOR 7 /* IOR of the all values passed to
- counter. */
-#define GCOV_LAST_VALUE_COUNTER 7 /* The last of counters used for value
- profiling. */
-#define GCOV_COUNTERS 8
-
-/* Number of counters used for value profiling. */
-#define GCOV_N_VALUE_COUNTERS \
- (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
-
- /* A list of human readable names of the counters */
-#define GCOV_COUNTER_NAMES {"arcs", "interval", "pow2", "single", \
- "delta", "indirect_call", "average", "ior"}
-
- /* Names of merge functions for counters. */
-#define GCOV_MERGE_FUNCTIONS {"__gcov_merge_add", \
- "__gcov_merge_add", \
- "__gcov_merge_add", \
- "__gcov_merge_single", \
- "__gcov_merge_delta", \
- "__gcov_merge_single", \
- "__gcov_merge_add", \
- "__gcov_merge_ior"}
-
-/* Convert a counter index to a tag. */
-#define GCOV_TAG_FOR_COUNTER(COUNT) \
- (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
-/* Convert a tag to a counter. */
-#define GCOV_COUNTER_FOR_TAG(TAG) \
- ((unsigned int)(((TAG) - GCOV_TAG_COUNTER_BASE) >> 17))
-/* Check whether a tag is a counter tag. */
-#define GCOV_TAG_IS_COUNTER(TAG) \
- (!((TAG) & 0xFFFF) && GCOV_COUNTER_FOR_TAG(TAG) < GCOV_COUNTERS)
-
-/* The tag level mask has 1's in the position of the inner levels, &
- the lsb of the current level, and zero on the current and outer
- levels. */
-#define GCOV_TAG_MASK(TAG) (((TAG) - 1) ^ (TAG))
-
-/* Return nonzero if SUB is an immediate subtag of TAG. */
-#define GCOV_TAG_IS_SUBTAG(TAG, SUB) \
- (GCOV_TAG_MASK(TAG) >> 8 == GCOV_TAG_MASK(SUB) \
- && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK(TAG)))
-
-/* Return nonzero if SUB is at a sublevel to TAG. */
-#define GCOV_TAG_IS_SUBLEVEL(TAG, SUB) \
- (GCOV_TAG_MASK(TAG) > GCOV_TAG_MASK(SUB))
-
-/* Basic block flags. */
-#define GCOV_BLOCK_UNEXPECTED (1 << 1)
-
-/* Arc flags. */
-#define GCOV_ARC_ON_TREE (1 << 0)
-#define GCOV_ARC_FAKE (1 << 1)
-#define GCOV_ARC_FALLTHROUGH (1 << 2)
-
-/* Structured records. */
-
-/* Cumulative counter data. */
-struct gcov_ctr_summary {
- gcov_unsigned_t num; /* number of counters. */
- gcov_unsigned_t runs; /* number of program runs */
- gcov_type sum_all; /* sum of all counters accumulated. */
- gcov_type run_max; /* maximum value on a single run. */
- gcov_type sum_max; /* sum of individual run max values. */
-};
-
-/* Object & program summary record. */
-struct gcov_summary {
- gcov_unsigned_t checksum; /* checksum of program */
- struct gcov_ctr_summary ctrs[GCOV_COUNTERS_SUMMABLE];
-};
-
-/* Structures embedded in coverage program. The structures generated
- by write_profile must match these. */
-
-#if IN_LIBGCOV
-/* Information about counters for a single function. */
-struct gcov_ctr_info {
- gcov_unsigned_t num; /* number of counters. */
- gcov_type *values; /* their values. */
-};
-
-/* Information about a single function. This uses the trailing array
- idiom. The number of counters is determined from the merge pointer
- array in gcov_info. The key is used to detect which of a set of
- comdat functions was selected -- it points to the gcov_info object
- of the object file containing the selected comdat function. */
-
-struct gcov_fn_info {
- const struct gcov_info *key; /* comdat key */
- gcov_unsigned_t ident; /* unique ident of function */
- gcov_unsigned_t lineno_checksum; /* function lineo_checksum */
- gcov_unsigned_t cfg_checksum; /* function cfg checksum */
- struct gcov_ctr_info ctrs[0]; /* instrumented counters */
-};
-
-/* Type of function used to merge counters. */
-typedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t);
-
-/* Information about a single object file. */
-struct gcov_info {
- gcov_unsigned_t version; /* expected version number */
- struct gcov_info *next; /* link to next, used by libgcov */
-
- gcov_unsigned_t stamp; /* uniquifying time stamp */
- const char *filename; /* output file name */
-
- gcov_merge_fn merge[GCOV_COUNTERS]; /* merge functions (null for
- unused) */
-
- unsigned int n_functions; /* number of functions */
- const struct gcov_fn_info *const *functions; /* pointer to pointers to
- function information */
-};
-
-/* Register a new object file module. */
-extern void __gcov_init(struct gcov_info *) ATTRIBUTE_HIDDEN;
-
-#ifndef __COREBOOT__
-/* Called before fork, to avoid double counting. */
-extern void __gcov_flush(void) ATTRIBUTE_HIDDEN;
-#endif
-
-/* The merge function that just sums the counters. */
-extern void __gcov_merge_add(gcov_type *, unsigned int) ATTRIBUTE_HIDDEN;
-
-/* The merge function to choose the most common value. */
-extern void __gcov_merge_single(gcov_type *, unsigned int) ATTRIBUTE_HIDDEN;
-
-/* The merge function to choose the most common difference between
- consecutive values. */
-extern void __gcov_merge_delta(gcov_type *, unsigned int) ATTRIBUTE_HIDDEN;
-
-/* The merge function that just ors the counters together. */
-extern void __gcov_merge_ior(gcov_type *, unsigned int) ATTRIBUTE_HIDDEN;
-
-/* The profiler functions. */
-extern void __gcov_interval_profiler(gcov_type *, gcov_type, int, unsigned int);
-extern void __gcov_pow2_profiler(gcov_type *, gcov_type);
-extern void __gcov_one_value_profiler(gcov_type *, gcov_type);
-extern void __gcov_indirect_call_profiler(gcov_type *, gcov_type, void *,
- void *);
-extern void __gcov_average_profiler(gcov_type *, gcov_type);
-extern void __gcov_ior_profiler(gcov_type *, gcov_type);
-
-#ifndef inhibit_libc
-/* The wrappers around some library functions.. */
-extern pid_t __gcov_fork(void) ATTRIBUTE_HIDDEN;
-extern int __gcov_execl(const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execlp(const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execle(const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execv(const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execvp(const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execve(const char *, char *const [], char *const [])
- ATTRIBUTE_HIDDEN;
-#endif
-
-#endif /* IN_LIBGCOV */
-
-#if IN_LIBGCOV >= 0
-
-/* Optimum number of gcov_unsigned_t's read from or written to disk. */
-#define GCOV_BLOCK_SIZE (1 << 10)
-
-GCOV_LINKAGE struct gcov_var
-{
- FILE *file;
- gcov_position_t start; /* Position of first byte of block */
- unsigned int offset; /* Read/write position within the block. */
- unsigned int length; /* Read limit in the block. */
- unsigned int overread; /* Number of words overread. */
- int error; /* < 0 overflow, > 0 disk error. */
- int mode; /* < 0 writing, > 0 reading */
-#if IN_LIBGCOV
- /* Holds one block plus 4 bytes, thus all coverage reads & writes
- * fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
- * to and from the disk. libgcov never backtracks and only writes 4
- * or 8 byte objects.
- */
- gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
-#else
- int endian; /* Swap endianness. */
- /* Holds a variable length block, as the compiler can write
- * strings and needs to backtrack.
- */
- size_t alloc;
- gcov_unsigned_t *buffer;
-#endif
-} gcov_var ATTRIBUTE_HIDDEN;
-
-/* Functions for reading and writing gcov files. In libgcov you can
- open the file for reading then writing. Elsewhere you can open the
- file either for reading or for writing. When reading a file you may
- use the gcov_read_* functions, gcov_sync, gcov_position, &
- gcov_error. When writing a file you may use the gcov_write
- functions, gcov_seek & gcov_error. When a file is to be rewritten
- you use the functions for reading, then gcov_rewrite then the
- functions for writing. Your file may become corrupted if you break
- these invariants. */
-#if IN_LIBGCOV
-GCOV_LINKAGE int gcov_open(const char */*name*/) ATTRIBUTE_HIDDEN;
-#else
-GCOV_LINKAGE int gcov_open(const char */*name*/, int /*direction*/);
-GCOV_LINKAGE int gcov_magic(gcov_unsigned_t, gcov_unsigned_t);
-#endif
-GCOV_LINKAGE int gcov_close(void) ATTRIBUTE_HIDDEN;
-
-/* Available everywhere. */
-static gcov_position_t gcov_position(void);
-static int gcov_is_error(void);
-
-GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned(void) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE gcov_type gcov_read_counter(void) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_read_summary(struct gcov_summary *) ATTRIBUTE_HIDDEN;
-
-#if IN_LIBGCOV
-/* Available only in libgcov */
-GCOV_LINKAGE void gcov_write_counter(gcov_type) ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_tag_length(gcov_unsigned_t, gcov_unsigned_t)
- ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_write_summary(gcov_unsigned_t /*tag*/,
- const struct gcov_summary *)
- ATTRIBUTE_HIDDEN;
-static void gcov_rewrite(void);
-GCOV_LINKAGE void gcov_seek(gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
-#else
-/* Available outside libgcov */
-GCOV_LINKAGE const char *gcov_read_string(void);
-GCOV_LINKAGE void gcov_sync(gcov_position_t /*base*/,
- gcov_unsigned_t /*length */);
-#endif
-
-#if !IN_GCOV
-/* Available outside gcov */
-GCOV_LINKAGE void gcov_write_unsigned(gcov_unsigned_t) ATTRIBUTE_HIDDEN;
-#endif
-
-#if !IN_GCOV && !IN_LIBGCOV
-/* Available only in compiler */
-GCOV_LINKAGE void gcov_write_string(const char *);
-GCOV_LINKAGE gcov_position_t gcov_write_tag(gcov_unsigned_t);
-GCOV_LINKAGE void gcov_write_length(gcov_position_t /*position*/);
-#endif
-
-#if IN_GCOV > 0
-/* Available in gcov */
-GCOV_LINKAGE time_t gcov_time(void);
-#endif
-
-/* Save the current position in the gcov file. */
-
-static inline gcov_position_t
-gcov_position(void)
-{
- gcc_assert(gcov_var.mode > 0);
- return gcov_var.start + gcov_var.offset;
-}
-
-/* Return nonzero if the error flag is set. */
-
-static inline int
-gcov_is_error(void)
-{
- return gcov_var.file ? gcov_var.error : 1;
-}
-
-#if IN_LIBGCOV
-/* Move to beginning of file and initialize for writing. */
-
-static inline void
-gcov_rewrite(void)
-{
- gcc_assert(gcov_var.mode > 0);
- gcov_var.mode = -1;
- gcov_var.start = 0;
- gcov_var.offset = 0;
- fseek(gcov_var.file, 0L, SEEK_SET);
-}
-#endif
-
-#endif /* IN_LIBGCOV >= 0 */
-
-#endif /* GCC_GCOV_IO_H */
diff --git a/src/libgcov/gcov-iov.h b/src/libgcov/gcov-iov.h
@@ -1,4 +0,0 @@
-/* Generated automatically by the program `build/gcov-iov'
- from `4.7.2 (4 7) and (*)'. */
-
-#define GCOV_VERSION ((gcov_unsigned_t)0x3430372a) /* 407* */
diff --git a/src/libgcov/libgcov.c b/src/libgcov/libgcov.c
@@ -1,1157 +0,0 @@
-/* Routines required for instrumenting a program. */
-/* Compile this one with gcc. */
-/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010, 2011
- Free Software Foundation, Inc.
-
-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.
-*/
-
-#define __COREBOOT__
-#ifdef __COREBOOT__
-#include <stdlib.h>
-#include <string.h>
-#include <console/console.h>
-#include <assert.h>
-typedef s32 pid_t;
-#define gcc_assert(x) ASSERT(x)
-#define fprintf(file, x...) printk(BIOS_ERR, x)
-#define alloca(size) __builtin_alloca(size)
-#include "gcov-glue.c"
-
-/* Define MACROs to be used by coreboot compilation. */
-# define L_gcov
-# define L_gcov_interval_profiler
-# define L_gcov_pow2_profiler
-# define L_gcov_one_value_profiler
-# define L_gcov_indirect_call_profiler
-# define L_gcov_average_profiler
-# define L_gcov_ior_profiler
-
-# define HAVE_CC_TLS 0
-# define __GCOV_KERNEL__
-
-# define IN_LIBGCOV 1
-# define IN_GCOV 0
-#else /* __COREBOOT__ */
-#include "tconfig.h"
-#include "tsystem.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "libgcc_tm.h"
-#endif /* __COREBOOT__ */
-
-#ifndef __COREBOOT__
-#if defined(inhibit_libc)
-#define IN_LIBGCOV (-1)
-#else
-#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
-#include <stdio.h>
-#define IN_LIBGCOV 1
-#if defined(L_gcov)
-#define GCOV_LINKAGE /* nothing */
-#endif
-#endif
-#endif /* __COREBOOT__ */
-#include "gcov-io.h"
-
-#if defined(inhibit_libc)
-/* If libc and its header files are not available, provide dummy functions. */
-
-#ifdef L_gcov
-void __gcov_init(struct gcov_info *p __attribute__((unused))) {}
-void __gcov_flush(void) {}
-#endif
-
-#ifdef L_gcov_merge_add
-void __gcov_merge_add(gcov_type *counters __attribute__((unused)),
- unsigned int n_counters __attribute__((unused))) {}
-#endif
-
-#ifdef L_gcov_merge_single
-void __gcov_merge_single(gcov_type *counters __attribute__((unused)),
- unsigned int n_counters __attribute__((unused))) {}
-#endif
-
-#ifdef L_gcov_merge_delta
-void __gcov_merge_delta(gcov_type *counters __attribute__((unused)),
- unsigned int n_counters __attribute__((unused))) {}
-#endif
-
-#else
-
-#ifndef __COREBOOT__
-#include <string.h>
-#if GCOV_LOCKED
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/stat.h>
-#endif
-#else
-void __gcov_merge_add(gcov_type *counters __attribute__((unused)),
- unsigned int n_counters __attribute__((unused))) {}
-#endif /* __COREBOOT__ */
-
-#ifdef L_gcov
-#include "gcov-io.c"
-
-struct gcov_fn_buffer {
- struct gcov_fn_buffer *next;
- unsigned int fn_ix;
- struct gcov_fn_info info;
- /* note gcov_fn_info ends in a trailing array. */
-};
-
-/* Chain of per-object gcov structures. */
-static struct gcov_info *gcov_list;
-
-/* Size of the longest file name. */
-static size_t gcov_max_filename = 0;
-
-/* Make sure path component of the given FILENAME exists, create
- missing directories. FILENAME must be writable.
- Returns zero on success, or -1 if an error occurred. */
-
-static int
-create_file_directory(char *filename)
-{
-#ifdef __COREBOOT__
- (void) filename;
- return 0;
-#else
-#if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
- (void) filename;
- return -1;
-#else
- char *s;
-
- s = filename;
-
- if (HAS_DRIVE_SPEC(s))
- s += 2;
- if (IS_DIR_SEPARATOR(*s))
- ++s;
- for (; *s != '\0'; s++)
- if (IS_DIR_SEPARATOR(*s)) {
- char sep = *s;
- *s = '\0';
-
- /* Try to make directory if it doesn't already exist. */
- if (access(filename, F_OK) == -1
-#ifdef TARGET_POSIX_IO
- && mkdir(filename, 0755) == -1
-#else
- && mkdir(filename) == -1
-#endif
- /* The directory might have been made by another
- * process.
- */
- && errno != EEXIST) {
- fprintf(stderr,
- "profiling:%s:Cannot create directory\n",
- filename);
- *s = sep;
- return -1;
- };
-
- *s = sep;
- };
- return 0;
-#endif
-#endif
-}
-
-static struct gcov_fn_buffer *
-free_fn_data(const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
- unsigned int limit)
-{
- struct gcov_fn_buffer *next;
- unsigned int ix, n_ctr = 0;
-
- if (!buffer)
- return 0;
- next = buffer->next;
-
- for (ix = 0; ix != limit; ix++)
- if (gi_ptr->merge[ix])
- free(buffer->info.ctrs[n_ctr++].values);
- free(buffer);
- return next;
-}
-
-static struct gcov_fn_buffer **
-buffer_fn_data(const char *filename, const struct gcov_info *gi_ptr,
- struct gcov_fn_buffer **end_ptr, unsigned int fn_ix)
-{
- unsigned int n_ctrs = 0, ix = 0;
- struct gcov_fn_buffer *fn_buffer;
- unsigned int len;
-
- for (ix = GCOV_COUNTERS; ix--;)
- if (gi_ptr->merge[ix])
- n_ctrs++;
-
- len = sizeof(*fn_buffer) + sizeof(fn_buffer->info.ctrs[0]) * n_ctrs;
- fn_buffer = (struct gcov_fn_buffer *)malloc(len);
-
- if (!fn_buffer)
- goto fail;
-
- fn_buffer->next = 0;
- fn_buffer->fn_ix = fn_ix;
- fn_buffer->info.ident = gcov_read_unsigned();
- fn_buffer->info.lineno_checksum = gcov_read_unsigned();
- fn_buffer->info.cfg_checksum = gcov_read_unsigned();
-
- for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++) {
- gcov_unsigned_t length;
- gcov_type *values;
-
- if (!gi_ptr->merge[ix])
- continue;
-
- if (gcov_read_unsigned() != GCOV_TAG_FOR_COUNTER(ix)) {
- len = 0;
- goto fail;
- }
-
- length = GCOV_TAG_COUNTER_NUM(gcov_read_unsigned());
- len = length * sizeof(gcov_type);
- values = (gcov_type *)malloc(len);
- if (!values)
- goto fail;
-
- fn_buffer->info.ctrs[n_ctrs].num = length;
- fn_buffer->info.ctrs[n_ctrs].values = values;
-
- while (length--)
- *values++ = gcov_read_counter();
- n_ctrs++;
- }
-
- *end_ptr = fn_buffer;
- return &fn_buffer->next;
-
-fail:
- fprintf(stderr, "profiling:%s:Function %u %s %u\n", filename, fn_ix,
- len ? "cannot allocate" : "counter mismatch", len ? len : ix);
-
- return (struct gcov_fn_buffer **)free_fn_data(gi_ptr, fn_buffer, ix);
-}
-
-/* Add an unsigned value to the current crc */
-
-static gcov_unsigned_t
-crc32_unsigned(gcov_unsigned_t crc32, gcov_unsigned_t value)
-{
- unsigned int ix;
-
- for (ix = 32; ix--; value <<= 1) {
- unsigned int feedback;
-
- feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
- crc32 <<= 1;
- crc32 ^= feedback;
- }
-
- return crc32;
-}
-
-/* Check if VERSION of the info block PTR matches libgcov one.
- Return 1 on success, or zero in case of versions mismatch.
- If FILENAME is not NULL, its value used for reporting purposes
- instead of value from the info block. */
-
-static int
-gcov_version(struct gcov_info *ptr, gcov_unsigned_t version,
- const char *filename)
-{
- if (version != GCOV_VERSION) {
- char v[4], e[4];
-
- GCOV_UNSIGNED2STRING(v, version);
- GCOV_UNSIGNED2STRING(e, GCOV_VERSION);
-
- fprintf(stderr,
- "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
- filename ? filename : ptr->filename, e, v);
- return 0;
- }
- return 1;
-}
-
-/* Dump the coverage counts. We merge with existing counts when
- possible, to avoid growing the .da files ad infinitum. We use this
- program's checksum to make sure we only accumulate whole program
- statistics to the correct summary. An object file might be embedded
- in two separate programs, and we must keep the two program
- summaries separate. */
-
-static void
-gcov_exit(void)
-{
- struct gcov_info *gi_ptr;
- const struct gcov_fn_info *gfi_ptr;
- struct gcov_summary this_prg; /* summary for program. */
- struct gcov_summary all_prg; /* summary for all instances of program. */
- struct gcov_ctr_summary *cs_ptr;
- const struct gcov_ctr_info *ci_ptr;
- unsigned int t_ix;
- int f_ix = 0;
- gcov_unsigned_t c_num;
- const char *gcov_prefix;
- int gcov_prefix_strip = 0;
- size_t prefix_length;
- char *gi_filename, *gi_filename_up;
- gcov_unsigned_t crc32 = 0;
-
- memset(&all_prg, 0, sizeof(all_prg));
- /* Find the totals for this execution. */
- memset(&this_prg, 0, sizeof(this_prg));
- for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) {
- crc32 = crc32_unsigned(crc32, gi_ptr->stamp);
- crc32 = crc32_unsigned(crc32, gi_ptr->n_functions);
-
- for (f_ix = 0; (unsigned int)f_ix != gi_ptr->n_functions;
- f_ix++) {
- gfi_ptr = gi_ptr->functions[f_ix];
-
- if (gfi_ptr && gfi_ptr->key != gi_ptr)
- gfi_ptr = 0;
-
- crc32 = crc32_unsigned(crc32, gfi_ptr
- ? gfi_ptr->cfg_checksum : 0);
- crc32 = crc32_unsigned(crc32,
- gfi_ptr ? gfi_ptr->lineno_checksum : 0);
- if (!gfi_ptr)
- continue;
-
- ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++) {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- cs_ptr = &this_prg.ctrs[t_ix];
- cs_ptr->num += ci_ptr->num;
- crc32 = crc32_unsigned(crc32, ci_ptr->num);
-
- for (c_num = 0; c_num < ci_ptr->num; c_num++) {
- cs_ptr->sum_all +=
- ci_ptr->values[c_num];
- if (cs_ptr->run_max
- < ci_ptr->values[c_num])
- cs_ptr->run_max =
- ci_ptr->values[c_num];
- }
- ci_ptr++;
- }
- }
- }
-
-#ifndef __COREBOOT__
- {
- /* Check if the level of dirs to strip off specified. */
- char *tmp = getenv("GCOV_PREFIX_STRIP");
- if (tmp) {
- gcov_prefix_strip = atoi(tmp);
- /* Do not consider negative values. */
- if (gcov_prefix_strip < 0)
- gcov_prefix_strip = 0;
- }
- }
-
- /* Get file name relocation prefix. Non-absolute values are ignored. */
- gcov_prefix = getenv("GCOV_PREFIX");
- if (gcov_prefix) {
- prefix_length = strlen(gcov_prefix);
-
- /* Remove an unnecessary trailing '/' */
- if (IS_DIR_SEPARATOR(gcov_prefix[prefix_length - 1]))
- prefix_length--;
- } else
-#endif
- prefix_length = 0;
-
- /* If no prefix was specified and a prefix strip, then we assume
- relative. */
- if (gcov_prefix_strip != 0 && prefix_length == 0) {
- gcov_prefix = ".";
- prefix_length = 1;
- }
- /* Allocate and initialize the filename scratch space plus one. */
- gi_filename = (char *) alloca(prefix_length + gcov_max_filename + 2);
- if (prefix_length)
- memcpy(gi_filename, gcov_prefix, prefix_length);
- gi_filename_up = gi_filename + prefix_length;
-
- /* Now merge each file. */
- for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) {
- unsigned int n_counts;
- struct gcov_summary prg; /* summary for this object over all
- program. */
- struct gcov_ctr_summary *cs_prg, *cs_tprg, *cs_all;
- int error = 0;
- gcov_unsigned_t tag, length;
- gcov_position_t summary_pos = 0;
- gcov_position_t eof_pos = 0;
- const char *fname, *s;
- struct gcov_fn_buffer *fn_buffer = NULL;
- struct gcov_fn_buffer **fn_tail = &fn_buffer;
-
- fname = gi_ptr->filename;
-
- /* Avoid to add multiple drive letters into combined path. */
- if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
- fname += 2;
-
- /* Build relocated filename, stripping off leading
- * directories from the initial filename if requested.
- */
- if (gcov_prefix_strip > 0) {
- int level = 0;
-
- s = fname;
- if (IS_DIR_SEPARATOR(*s))
- ++s;
-
- /* Skip selected directory levels. */
- for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
- if (IS_DIR_SEPARATOR(*s)) {
- fname = s;
- level++;
- }
- }
-
- /* Update complete filename with stripped original. */
- if (prefix_length != 0 && !IS_DIR_SEPARATOR(*fname)) {
- /* If prefix is given, add directory separator.
- */
- strcpy(gi_filename_up, "/");
- strcpy(gi_filename_up + 1, fname);
- } else
- strcpy(gi_filename_up, fname);
-
- if (!gcov_open(gi_filename)) {
- /* Open failed likely due to missed directory.
- * Create directory and retry to open file.
- */
- if (create_file_directory(gi_filename)) {
- fprintf(stderr, "profiling:%s:Skip\n",
- gi_filename);
- continue;
- }
- if (!gcov_open(gi_filename)) {
- fprintf(stderr,
- "profiling:%s:Cannot open\n",
- gi_filename);
- continue;
- }
- }
-
- tag = gcov_read_unsigned();
- if (tag) {
- /* Merge data from file. */
- if (tag != GCOV_DATA_MAGIC) {
- fprintf(stderr,
- "profiling:%s:Not a gcov data file\n",
- gi_filename);
- goto read_fatal;
- }
- length = gcov_read_unsigned();
- if (!gcov_version(gi_ptr, length, gi_filename))
- goto read_fatal;
-
- length = gcov_read_unsigned();
- if (length != gi_ptr->stamp)
- /* Read from a different compilation.
- * Overwrite the file.
- */
- goto rewrite;
-
- /* Look for program summary. */
- for (f_ix = 0;;) {
- struct gcov_summary tmp;
-
- eof_pos = gcov_position();
- tag = gcov_read_unsigned();
- if (tag != GCOV_TAG_PROGRAM_SUMMARY)
- break;
-
- f_ix--;
- length = gcov_read_unsigned();
- if (length != GCOV_TAG_SUMMARY_LENGTH)
- goto read_mismatch;
- gcov_read_summary(&tmp);
- error = gcov_is_error();
- if (error)
- goto read_error;
- if (summary_pos
- || tmp.checksum != crc32)
- goto next_summary;
-
- for (t_ix = 0; t_ix !=
- GCOV_COUNTERS_SUMMABLE; t_ix++)
- if (tmp.ctrs[t_ix].num !=
- this_prg.ctrs[t_ix].num)
- goto next_summary;
- prg = tmp;
- summary_pos = eof_pos;
-
- next_summary:;
- }
-
- /* Merge execution counts for each function. */
- for (f_ix = 0; (unsigned int)f_ix !=
- gi_ptr->n_functions;
- f_ix++, tag = gcov_read_unsigned()) {
- gfi_ptr = gi_ptr->functions[f_ix];
-
- if (tag != GCOV_TAG_FUNCTION)
- goto read_mismatch;
-
- length = gcov_read_unsigned();
- if (!length)
- /* This function did not appear
- * in the other program. We
- * have nothing to merge.
- */
- continue;
-
- if (length != GCOV_TAG_FUNCTION_LENGTH)
- goto read_mismatch;
-
- if (!gfi_ptr || gfi_ptr->key !=
- gi_ptr) {
- /* This function appears in the
- * other program. We need to
- * buffer the information in
- * order to write it back out --
- * we'll be inserting data
- * before this point, so cannot
- * simply keep the data in the
- * file.
- */
- fn_tail = buffer_fn_data(
- gi_filename, gi_ptr,
- fn_tail, f_ix);
- if (!fn_tail)
- goto read_mismatch;
- continue;
- }
-
- length = gcov_read_unsigned();
- if (length != gfi_ptr->ident)
- goto read_mismatch;
-
- length = gcov_read_unsigned();
- if (length != gfi_ptr->lineno_checksum)
- goto read_mismatch;
-
- length = gcov_read_unsigned();
- if (length != gfi_ptr->cfg_checksum)
- goto read_mismatch;
-
- ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix < GCOV_COUNTERS;
- t_ix++) {
- gcov_merge_fn merge =
- gi_ptr->merge[t_ix];
-
- if (!merge)
- continue;
-
- tag = gcov_read_unsigned();
- length = gcov_read_unsigned();
- if (tag != GCOV_TAG_FOR_COUNTER(
- t_ix) || length !=
- GCOV_TAG_COUNTER_LENGTH(
- ci_ptr->num))
- goto read_mismatch;
- (*merge)(ci_ptr->values,
- ci_ptr->num);
- ci_ptr++;
- }
- error = gcov_is_error();
- if (error)
- goto read_error;
- }
-
- if (tag) {
- read_mismatch:;
- fprintf(stderr,
- "profiling:%s:Merge mismatch for %s %u\n",
- gi_filename, f_ix >= 0 ?
- "function" : "summary",
- f_ix < 0 ? -1 - f_ix : f_ix);
- goto read_fatal;
- }
- }
- goto rewrite;
-
-read_error:;
- fprintf(stderr, "profiling:%s:%s merging\n", gi_filename,
- error < 0 ? "Overflow" : "Error");
-
- goto read_fatal;
-
-rewrite:;
- gcov_rewrite();
- if (!summary_pos) {
- memset(&prg, 0, sizeof(prg));
- summary_pos = eof_pos;
- }
-
- /* Merge the summaries. */
- for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++) {
- cs_prg = &prg.ctrs[t_ix];
- cs_tprg = &this_prg.ctrs[t_ix];
- cs_all = &all_prg.ctrs[t_ix];
-
- if (gi_ptr->merge[t_ix]) {
- if (!cs_prg->runs++)
- cs_prg->num = cs_tprg->num;
- cs_prg->sum_all += cs_tprg->sum_all;
- if (cs_prg->run_max < cs_tprg->run_max)
- cs_prg->run_max = cs_tprg->run_max;
- cs_prg->sum_max += cs_tprg->run_max;
- } else if (cs_prg->runs)
- goto read_mismatch;
-
- if (!cs_all->runs && cs_prg->runs)
- memcpy(cs_all, cs_prg, sizeof(*cs_all));
- else if (!all_prg.checksum
- && (!GCOV_LOCKED
- || cs_all->runs == cs_prg->runs)
- && memcmp(cs_all, cs_prg, sizeof(*cs_all))) {
- fprintf(stderr,
- "profiling:%s:Invocation mismatch - some data files may have been removed%s\n",
- gi_filename, GCOV_LOCKED ? "" :
- " or concurrently updated without locking support");
- all_prg.checksum = ~0u;
- }
- }
-
- prg.checksum = crc32;
-
- /* Write out the data. */
- if (!eof_pos) {
- gcov_write_tag_length(GCOV_DATA_MAGIC, GCOV_VERSION);
- gcov_write_unsigned(gi_ptr->stamp);
- }
-
- if (summary_pos)
- gcov_seek(summary_pos);
-
- /* Generate whole program statistics. */
- gcov_write_summary(GCOV_TAG_PROGRAM_SUMMARY, &prg);
-
- if (summary_pos < eof_pos)
- gcov_seek(eof_pos);
-
- /* Write execution counts for each function. */
- for (f_ix = 0; (unsigned int)f_ix != gi_ptr->n_functions;
- f_ix++) {
- unsigned int buffered = 0;
-
- if (fn_buffer && fn_buffer->fn_ix
- == (unsigned int)f_ix) {
- /* Buffered data from another program. */
- buffered = 1;
- gfi_ptr = &fn_buffer->info;
- length = GCOV_TAG_FUNCTION_LENGTH;
- } else {
- gfi_ptr = gi_ptr->functions[f_ix];
- if (gfi_ptr && gfi_ptr->key == gi_ptr)
- length = GCOV_TAG_FUNCTION_LENGTH;
- else
- length = 0;
- }
-
- gcov_write_tag_length(GCOV_TAG_FUNCTION, length);
- if (!length)
- continue;
-
- gcov_write_unsigned(gfi_ptr->ident);
- gcov_write_unsigned(gfi_ptr->lineno_checksum);
- gcov_write_unsigned(gfi_ptr->cfg_checksum);
-
- ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++) {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- n_counts = ci_ptr->num;
- gcov_write_tag_length(
- GCOV_TAG_FOR_COUNTER(t_ix),
- GCOV_TAG_COUNTER_LENGTH(n_counts));
- gcov_type *c_ptr = ci_ptr->values;
- while (n_counts--)
- gcov_write_counter(*c_ptr++);
- ci_ptr++;
- }
- if (buffered)
- fn_buffer = free_fn_data(gi_ptr, fn_buffer,
- GCOV_COUNTERS);
- }
-
- gcov_write_unsigned(0);
-
-read_fatal:;
- while (fn_buffer)
- fn_buffer = free_fn_data(gi_ptr, fn_buffer,
- GCOV_COUNTERS);
-
- error = gcov_close();
- if (error)
- fprintf(stderr, error < 0 ?
- "profiling:%s:Overflow writing\n" :
- "profiling:%s:Error writing\n",
- gi_filename);
- }
-}
-
-/* Add a new object file onto the bb chain. Invoked automatically
- when running an object file's global ctors. */
-
-void
-__gcov_init(struct gcov_info *info)
-{
- if (!info->version || !info->n_functions)
- return;
- if (gcov_version(info, info->version, 0)) {
- size_t filename_length = strlen(info->filename);
-
- /* Refresh the longest file name information */
- if (filename_length > gcov_max_filename)
- gcov_max_filename = filename_length;
-
-#ifndef __COREBOOT__
- if (!gcov_list)
- atexit(gcov_exit);
-#endif
-
- info->next = gcov_list;
- gcov_list = info;
- }
- info->version = 0;
-}
-
-/* Called before fork or exec - write out profile information gathered so
- far and reset it to zero. This avoids duplication or loss of the
- profile information gathered so far. */
-
-void
-__gcov_flush(void)
-{
- const struct gcov_info *gi_ptr;
-
- gcov_exit();
- for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) {
- unsigned int f_ix;
-
- for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++) {
- unsigned int t_ix;
- const struct gcov_fn_info *gfi_ptr =
- gi_ptr->functions[f_ix];
-
- if (!gfi_ptr || gfi_ptr->key != gi_ptr)
- continue;
- const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
- for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++) {
- if (!gi_ptr->merge[t_ix])
- continue;
-
- memset(ci_ptr->values, 0,
- sizeof(gcov_type) * ci_ptr->num);
- ci_ptr++;
- }
- }
- }
-}
-
-#endif /* L_gcov */
-
-#ifdef L_gcov_merge_add
-/* The profile merging function that just adds the counters. It is given
- an array COUNTERS of N_COUNTERS old counters and it reads the same number
- of counters from the gcov file. */
-void
-__gcov_merge_add(gcov_type *counters, unsigned int n_counters)
-{
- for (; n_counters; counters++, n_counters--)
- *counters += gcov_read_counter();
-}
-#endif /* L_gcov_merge_add */
-
-#ifdef L_gcov_merge_ior
-/* The profile merging function that just adds the counters. It is given
- an array COUNTERS of N_COUNTERS old counters and it reads the same number
- of counters from the gcov file. */
-void
-__gcov_merge_ior(gcov_type *counters, unsigned int n_counters)
-{
- for (; n_counters; counters++, n_counters--)
- *counters |= gcov_read_counter();
-}
-#endif
-
-#ifdef L_gcov_merge_single
-/* The profile merging function for choosing the most common value.
- * It is given an array COUNTERS of N_COUNTERS old counters and it
- * reads the same number of counters from the gcov file. The counters
- * are split into 3-tuples where the members of the tuple have
- * meanings:
- *
- * -- the stored candidate on the most common value of the measured entity
- * -- counter
- * -- total number of evaluations of the value
- */
-void
-__gcov_merge_single(gcov_type *counters, unsigned int n_counters)
-{
- unsigned int i, n_measures;
- gcov_type value, counter, all;
-
- gcc_assert(!(n_counters % 3));
- n_measures = n_counters / 3;
- for (i = 0; i < n_measures; i++, counters += 3) {
- value = gcov_read_counter();
- counter = gcov_read_counter();
- all = gcov_read_counter();
-
- if (counters[0] == value)
- counters[1] += counter;
- else if (counter > counters[1]) {
- counters[0] = value;
- counters[1] = counter - counters[1];
- } else
- counters[1] -= counter;
- counters[2] += all;
- }
-}
-#endif /* L_gcov_merge_single */
-
-#ifdef L_gcov_merge_delta
-/* The profile merging function for choosing the most common
- * difference between two consecutive evaluations of the value. It is
- * given an array COUNTERS of N_COUNTERS old counters and it reads the
- * same number of counters from the gcov file. The counters are split
- * into 4-tuples where the members of the tuple have meanings:
- *
- * -- the last value of the measured entity
- * -- the stored candidate on the most common difference
- * -- counter
- * -- total number of evaluations of the value
- */
-void
-__gcov_merge_delta(gcov_type *counters, unsigned int n_counters)
-{
- unsigned int i, n_measures;
- gcov_type value, counter, all;
-
- gcc_assert(!(n_counters % 4));
- n_measures = n_counters / 4;
- for (i = 0; i < n_measures; i++, counters += 4) {
- /* last = */
- gcov_read_counter();
- value = gcov_read_counter();
- counter = gcov_read_counter();
- all = gcov_read_counter();
-
- if (counters[1] == value)
- counters[2] += counter;
- else if (counter > counters[2]) {
- counters[1] = value;
- counters[2] = counter - counters[2];
- } else
- counters[2] -= counter;
- counters[3] += all;
- }
-}
-#endif /* L_gcov_merge_delta */
-
-#ifdef L_gcov_interval_profiler
-/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
- corresponding counter in COUNTERS. If the VALUE is above or below
- the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
- instead. */
-
-void
-__gcov_interval_profiler(gcov_type *counters, gcov_type value,
- int start, unsigned int steps)
-{
- gcov_type delta = value - start;
- if (delta < 0)
- counters[steps + 1]++;
- else if (delta >= steps)
- counters[steps]++;
- else
- counters[delta]++;
-}
-#endif
-
-#ifdef L_gcov_pow2_profiler
-/* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
- COUNTERS[0] is incremented. */
-
-void
-__gcov_pow2_profiler(gcov_type *counters, gcov_type value)
-{
- if (value & (value - 1))
- counters[0]++;
- else
- counters[1]++;
-}
-#endif
-
-/* Tries to determine the most common value among its inputs. Checks if the
- value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
- is incremented. If this is not the case and COUNTERS[1] is not zero,
- COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
- VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
- function is called more than 50% of the time with one value, this value
- will be in COUNTERS[0] in the end.
-
- In any case, COUNTERS[2] is incremented. */
-
-static inline void
-__gcov_one_value_profiler_body(gcov_type *counters, gcov_type value)
-{
- if (value == counters[0])
- counters[1]++;
- else if (counters[1] == 0) {
- counters[1] = 1;
- counters[0] = value;
- } else
- counters[1]--;
- counters[2]++;
-}
-
-#ifdef L_gcov_one_value_profiler
-void
-__gcov_one_value_profiler(gcov_type *counters, gcov_type value)
-{
- __gcov_one_value_profiler_body(counters, value);
-}
-#endif
-
-#ifdef L_gcov_indirect_call_profiler
-
-/* By default, the C++ compiler will use function addresses in the
- vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
- tells the compiler to use function descriptors instead. The value
- of this macro says how many words wide the descriptor is (normally 2),
- but it may be dependent on target flags. Since we do not have access
- to the target flags here we just check to see if it is set and use
- that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
-
- It is assumed that the address of a function descriptor may be treated
- as a pointer to a function. */
-
-#ifdef TARGET_VTABLE_USES_DESCRIPTORS
-#define VTABLE_USES_DESCRIPTORS 1
-#else
-#define VTABLE_USES_DESCRIPTORS 0
-#endif
-
-/* Tries to determine the most common value among its inputs. */
-void
-__gcov_indirect_call_profiler(gcov_type *counter, gcov_type value,
- void *cur_func, void *callee_func)
-{
- /* If the C++ virtual tables contain function descriptors then one
- * function may have multiple descriptors and we need to dereference
- * the descriptors to see if they point to the same function.
- */
- if (cur_func == callee_func
- || (VTABLE_USES_DESCRIPTORS && callee_func
- && *(void **) cur_func == *(void **) callee_func))
- __gcov_one_value_profiler_body(counter, value);
-}
-#endif
-
-
-#ifdef L_gcov_average_profiler
-/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
- to saturate up. */
-
-void
-__gcov_average_profiler(gcov_type *counters, gcov_type value)
-{
- counters[0] += value;
- counters[1]++;
-}
-#endif
-
-#ifdef L_gcov_ior_profiler
-/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
- to saturate up. */
-
-void
-__gcov_ior_profiler(gcov_type *counters, gcov_type value)
-{
- *counters |= value;
-}
-#endif
-
-#ifdef L_gcov_fork
-/* A wrapper for the fork function. Flushes the accumulated profiling data, so
- that they are not counted twice. */
-
-pid_t
-__gcov_fork(void)
-{
- __gcov_flush();
- return fork();
-}
-#endif
-
-#ifdef L_gcov_execl
-/* A wrapper for the execl function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execl(const char *path, char *arg, ...)
-{
- va_list ap, aq;
- unsigned int i, length;
- char **args;
-
- __gcov_flush();
-
- va_start(ap, arg);
- va_copy(aq, ap);
-
- length = 2;
- while (va_arg(ap, char *))
- length++;
- va_end(ap);
-
- args = (char **) alloca(length * sizeof(void *));
- args[0] = arg;
- for (i = 1; i < length; i++)
- args[i] = va_arg(aq, char *);
- va_end(aq);
-
- return execv(path, args);
-}
-#endif
-
-#ifdef L_gcov_execlp
-/* A wrapper for the execlp function. Flushes the accumulated profiling data,
- * so that they are not lost.
- */
-
-int
-__gcov_execlp(const char *path, char *arg, ...)
-{
- va_list ap, aq;
- unsigned int i, length;
- char **args;
-
- __gcov_flush();
-
- va_start(ap, arg);
- va_copy(aq, ap);
-
- length = 2;
- while (va_arg(ap, char *))
- length++;
- va_end(ap);
-
- args = (char **) alloca(length * sizeof(void *));
- args[0] = arg;
- for (i = 1; i < length; i++)
- args[i] = va_arg(aq, char *);
- va_end(aq);
-
- return execvp(path, args);
-}
-#endif
-
-#ifdef L_gcov_execle
-/* A wrapper for the execle function. Flushes the accumulated profiling data,
- * so that they are not lost.
- */
-
-int
-__gcov_execle(const char *path, char *arg, ...)
-{
- va_list ap, aq;
- unsigned int i, length;
- char **args;
- char **envp;
-
- __gcov_flush();
-
- va_start(ap, arg);
- va_copy(aq, ap);
-
- length = 2;
- while (va_arg(ap, char *))
- length++;
- va_end(ap);
-
- args = (char **) alloca(length * sizeof(void *));
- args[0] = arg;
- for (i = 1; i < length; i++)
- args[i] = va_arg(aq, char *);
- envp = va_arg(aq, char **);
- va_end(aq);
-
- return execve(path, args, envp);
-}
-#endif
-
-#ifdef L_gcov_execv
-/* A wrapper for the execv function. Flushes the accumulated profiling data, so
- that they are not lost. */
-
-int
-__gcov_execv(const char *path, char *const argv[])
-{
- __gcov_flush();
- return execv(path, argv);
-}
-#endif
-
-#ifdef L_gcov_execvp
-/* A wrapper for the execvp function. Flushes the accumulated profiling data,
- * so that they are not lost.
- */
-
-int
-__gcov_execvp(const char *path, char *const argv[])
-{
- __gcov_flush();
- return execvp(path, argv);
-}
-#endif
-
-#ifdef L_gcov_execve
-/* A wrapper for the execve function. Flushes the accumulated profiling data,
- * so that they are not lost.
- */
-
-int
-__gcov_execve(const char *path, char *const argv[], char *const envp[])
-{
- __gcov_flush();
- return execve(path, argv, envp);
-}
-#endif
-#endif /* inhibit_libc */