18c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/*===- GCDAProfiling.c - Support library for GCDA file emission -----------===*\ 28c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* 38c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* The LLVM Compiler Infrastructure 48c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* 58c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* This file is distributed under the University of Illinois Open Source 68c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* License. See LICENSE.TXT for details. 78c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* 88c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|*===----------------------------------------------------------------------===*| 98c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* 108c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* This file implements the call back routines for the gcov profiling 118c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* instrumentation pass. Link against this library when running code through 128c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* the -insert-gcov-profiling LLVM pass. 138c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* 148c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* We emit files in a corrupt version of GCOV's "gcda" file format. These files 158c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* are only close enough that LCOV will happily parse them. Anything that lcov 168c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* ignores is missing. 178c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* 188c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* TODO: gcov is multi-process safe by having each exit open the existing file 198c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* and append to it. We'd like to achieve that and be thread-safe too. 208c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar|* 218c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar\*===----------------------------------------------------------------------===*/ 228c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 23254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth#include <errno.h> 24d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling#include <fcntl.h> 258c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <stdio.h> 268c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <stdlib.h> 278c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <string.h> 288c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <sys/stat.h> 29d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling#include <sys/mman.h> 308c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <sys/types.h> 318c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef _WIN32 328c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <direct.h> 338c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 348c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 358c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifndef _MSC_VER 368c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#include <stdint.h> 378c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#else 388c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbartypedef unsigned int uint32_t; 398c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbartypedef unsigned int uint64_t; 408c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 418c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 428c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* #define DEBUG_GCDAPROFILING */ 438c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 448c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* 458c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * --- GCOV file format I/O primitives --- 468c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */ 478c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 48a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling/* 49254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth * The current file name we're outputting. Used primarily for error logging. 50254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth */ 51254abfa43326c2d49143529c26a86a27356e1243Chandler Carruthstatic char *filename = NULL; 52254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth 53254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth/* 54a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling * The current file we're outputting. 55a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling */ 568c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic FILE *output_file = NULL; 578c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 58a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling/* 592a46a60510948b5005d62025fbba307a0323ed8dBill Wendling * Buffer that we write things into. 602a46a60510948b5005d62025fbba307a0323ed8dBill Wendling */ 612811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling#define WRITE_BUFFER_SIZE (128 * 1024) 622811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendlingstatic char *write_buffer = NULL; 63d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendlingstatic uint64_t cur_buffer_size = 0; 64d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendlingstatic uint64_t cur_pos = 0; 65d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendlingstatic uint64_t file_size = 0; 662a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic int new_file = 0; 67d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendlingstatic int fd = -1; 682a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 692a46a60510948b5005d62025fbba307a0323ed8dBill Wendling/* 70c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling * A list of functions to write out the data. 71c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling */ 72c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendlingtypedef void (*writeout_fn)(); 73c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 74c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendlingstruct writeout_fn_node { 75c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling writeout_fn fn; 76c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling struct writeout_fn_node *next; 77c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling}; 78c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 792a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic struct writeout_fn_node *writeout_fn_head = NULL; 802a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic struct writeout_fn_node *writeout_fn_tail = NULL; 81c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 82c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling/* 83a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling * A list of flush functions that our __gcov_flush() function should call. 84a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling */ 85a539183bf29a42ae584244106e48c99c6630e8cdBill Wendlingtypedef void (*flush_fn)(); 86a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 87a539183bf29a42ae584244106e48c99c6630e8cdBill Wendlingstruct flush_fn_node { 88a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling flush_fn fn; 89a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling struct flush_fn_node *next; 90a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling}; 91a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 922a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic struct flush_fn_node *flush_fn_head = NULL; 932a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic struct flush_fn_node *flush_fn_tail = NULL; 942a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 95d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendlingstatic void resize_write_buffer(uint64_t size) { 96d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling if (!new_file) return; 97d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling size += cur_pos; 98d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling if (size <= cur_buffer_size) return; 992811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling size = (size - 1) / WRITE_BUFFER_SIZE + 1; 1002811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling size *= WRITE_BUFFER_SIZE; 1012811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling write_buffer = realloc(write_buffer, size); 102d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling cur_buffer_size = size; 1038c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 1048c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 1052a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic void write_bytes(const char *s, size_t len) { 106d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling resize_write_buffer(len); 1072811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling memcpy(&write_buffer[cur_pos], s, len); 108d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling cur_pos += len; 1092a46a60510948b5005d62025fbba307a0323ed8dBill Wendling} 1104aa08fae9b02ba9a0701fe27f58e2645d236798bBill Wendling 1112a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic void write_32bit_value(uint32_t i) { 1122a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes((char*)&i, 4); 1132a46a60510948b5005d62025fbba307a0323ed8dBill Wendling} 1142a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 1152a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic void write_64bit_value(uint64_t i) { 1162a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes((char*)&i, 8); 1178c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 1188c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 1198c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic uint32_t length_of_string(const char *s) { 1208c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar return (strlen(s) / 4) + 1; 1218c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 1228c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 1238c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic void write_string(const char *s) { 1248c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar uint32_t len = length_of_string(s); 1252a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_32bit_value(len); 1262a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes(s, strlen(s)); 1272a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes("\0\0\0\0", 4 - (strlen(s) % 4)); 1288c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 1298c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 1302a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic uint32_t read_32bit_value() { 1312a46a60510948b5005d62025fbba307a0323ed8dBill Wendling uint32_t val; 1322a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 1332a46a60510948b5005d62025fbba307a0323ed8dBill Wendling if (new_file) 134843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling return (uint32_t)-1; 135843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 1362811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling val = *(uint32_t*)&write_buffer[cur_pos]; 137d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling cur_pos += 4; 1382a46a60510948b5005d62025fbba307a0323ed8dBill Wendling return val; 139843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling} 140843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 1412a46a60510948b5005d62025fbba307a0323ed8dBill Wendlingstatic uint64_t read_64bit_value() { 1422a46a60510948b5005d62025fbba307a0323ed8dBill Wendling uint64_t val; 143843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 1442a46a60510948b5005d62025fbba307a0323ed8dBill Wendling if (new_file) 145d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling return (uint64_t)-1; 1462a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 1472811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling val = *(uint64_t*)&write_buffer[cur_pos]; 148d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling cur_pos += 8; 1492a46a60510948b5005d62025fbba307a0323ed8dBill Wendling return val; 150843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling} 151843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 1528c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarstatic char *mangle_filename(const char *orig_filename) { 1538c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar char *filename = 0; 154906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling int prefix_len = 0; 155ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling int prefix_strip = 0; 156ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling int level = 0; 157ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling const char *fname = orig_filename, *ptr = NULL; 158906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling const char *prefix = getenv("GCOV_PREFIX"); 1592a46a60510948b5005d62025fbba307a0323ed8dBill Wendling const char *prefix_strip_str = getenv("GCOV_PREFIX_STRIP"); 1608c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 161ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling if (!prefix) 1628c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar return strdup(orig_filename); 1638c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 1642a46a60510948b5005d62025fbba307a0323ed8dBill Wendling if (prefix_strip_str) { 1652a46a60510948b5005d62025fbba307a0323ed8dBill Wendling prefix_strip = atoi(prefix_strip_str); 166ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling 167ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling /* Negative GCOV_PREFIX_STRIP values are ignored */ 168ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling if (prefix_strip < 0) 169ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling prefix_strip = 0; 170ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling } 171ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling 172906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling prefix_len = strlen(prefix); 173906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling filename = malloc(prefix_len + 1 + strlen(orig_filename) + 1); 1748c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar strcpy(filename, prefix); 175ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling 176906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling if (prefix[prefix_len - 1] != '/') 177906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling strcat(filename, "/"); 178ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling 179ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling for (ptr = fname + 1; *ptr != '\0' && level < prefix_strip; ++ptr) { 180ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling if (*ptr != '/') continue; 181ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling fname = ptr; 182ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling ++level; 183ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling } 184ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling 185ec63f456de18b9ac75d7546f8a53beb6ce048e67Bill Wendling strcat(filename, fname); 1868c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 1878c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar return filename; 1888c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 1898c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 190906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendlingstatic void recursive_mkdir(char *filename) { 191906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling int i; 1928c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 193906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling for (i = 1; filename[i] != '\0'; ++i) { 1945a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling if (filename[i] != '/') continue; 195906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling filename[i] = '\0'; 1968c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef _WIN32 197906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling _mkdir(filename); 1988c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#else 199906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling mkdir(filename, 0755); /* Some of these will fail, ignore it. */ 2008c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 201906d5a5d38f2984a9b78a0786016a3d67d0798e9Bill Wendling filename[i] = '/'; 2028c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar } 2038c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 2048c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 205254abfa43326c2d49143529c26a86a27356e1243Chandler Carruthstatic int map_file() { 206d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling fseek(output_file, 0L, SEEK_END); 207d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling file_size = ftell(output_file); 208d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling 2092811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling write_buffer = mmap(0, file_size, PROT_READ | PROT_WRITE, 2102811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling MAP_FILE | MAP_SHARED, fd, 0); 211254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth if (write_buffer == (void *)-1) { 212254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth int errnum = errno; 213254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth fprintf(stderr, "profiling: %s: cannot map: %s\n", filename, 214254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth strerror(errnum)); 215254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth return -1; 216254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth } 217254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth return 0; 218d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling} 219d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling 220d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendlingstatic void unmap_file() { 221254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth if (msync(write_buffer, file_size, MS_SYNC) == -1) { 222254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth int errnum = errno; 223254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth fprintf(stderr, "profiling: %s: cannot msync: %s\n", filename, 224254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth strerror(errnum)); 225254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth } 226254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth 227254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth /* We explicitly ignore errors from unmapping because at this point the data 228254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth * is written and we don't care. 229254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth */ 230254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth (void)munmap(write_buffer, file_size); 2312811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling write_buffer = NULL; 232d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling file_size = 0; 233d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling} 234d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling 2358c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* 2368c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * --- LLVM line counter API --- 2378c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */ 2388c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 2398c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* A file in this case is a translation unit. Each .o file built with line 2408c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * profiling enabled will emit to a different file. Only one file may be 2418c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * started at a time. 2428c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */ 24342296c7b5d69e6d79390005b6e1861ca66e3a0cbNick Lewyckyvoid llvm_gcda_start_file(const char *orig_filename, const char version[4]) { 244d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling const char *mode = "r+b"; 245254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth filename = mangle_filename(orig_filename); 246843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 247843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling /* Try just opening the file. */ 248d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling new_file = 0; 249d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling fd = open(filename, O_RDWR); 2505a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling 251d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling if (fd == -1) { 252843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling /* Try opening the file, creating it if necessary. */ 2532a46a60510948b5005d62025fbba307a0323ed8dBill Wendling new_file = 1; 254d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling mode = "w+b"; 2552811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling fd = open(filename, O_RDWR | O_CREAT, 0644); 256d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling if (fd == -1) { 257843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling /* Try creating the directories first then opening the file. */ 258843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling recursive_mkdir(filename); 2592811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling fd = open(filename, O_RDWR | O_CREAT, 0644); 260254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth if (fd == -1) { 261843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling /* Bah! It's hopeless. */ 262254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth int errnum = errno; 263254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth fprintf(stderr, "profiling: %s: cannot open: %s\n", filename, 264254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth strerror(errnum)); 265843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling return; 266843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling } 2675a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling } 2685a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling } 2698c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 270d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling output_file = fdopen(fd, mode); 2712a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 2722a46a60510948b5005d62025fbba307a0323ed8dBill Wendling /* Initialize the write buffer. */ 2732811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling write_buffer = NULL; 274d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling cur_buffer_size = 0; 275d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling cur_pos = 0; 276d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling 277d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling if (new_file) { 2782811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling resize_write_buffer(WRITE_BUFFER_SIZE); 2792811a0ccbadb9f8c50fe0b6aa8e4e39193fef4e7Bill Wendling memset(write_buffer, 0, WRITE_BUFFER_SIZE); 280d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling } else { 281254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth if (map_file() == -1) { 282254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth /* mmap failed, try to recover by clobbering */ 283254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth new_file = 1; 284254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth write_buffer = NULL; 285254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth cur_buffer_size = 0; 286254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth resize_write_buffer(WRITE_BUFFER_SIZE); 287254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth memset(write_buffer, 0, WRITE_BUFFER_SIZE); 288254abfa43326c2d49143529c26a86a27356e1243Chandler Carruth } 289d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling } 2902a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 29142296c7b5d69e6d79390005b6e1861ca66e3a0cbNick Lewycky /* gcda file, version, stamp LLVM. */ 2922a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes("adcg", 4); 2932a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes(version, 4); 2942a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes("MVLL", 4); 2952a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 2968c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING 297843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling fprintf(stderr, "llvmgcda: [%s]\n", orig_filename); 2988c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 2998c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 3008c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 3018c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar/* Given an array of pointers to counters (counters), increment the n-th one, 3028c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar * where we're also given a pointer to n (predecessor). 3038c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar */ 3048c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_increment_indirect_counter(uint32_t *predecessor, 3058c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar uint64_t **counters) { 3068c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar uint64_t *counter; 3078c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar uint32_t pred; 3088c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 3098c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar pred = *predecessor; 3108c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar if (pred == 0xffffffff) 3118c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar return; 3128c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar counter = counters[pred]; 3138c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 3148c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar /* Don't crash if the pred# is out of sync. This can happen due to threads, 3158c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar or because of a TODO in GCOVProfiling.cpp buildEdgeLookupTable(). */ 3168c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar if (counter) 3178c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar ++*counter; 3188c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING 3198c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar else 320de47cb8f12474c7c528a84de0ea73c743c33f015Bill Wendling fprintf(stderr, 321843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling "llvmgcda: increment_indirect_counter counters=%08llx, pred=%u\n", 322843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling *counter, *predecessor); 3238c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 3248c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 3258c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 32607020829d181dcd352ff6f01eab4d353c37a19b6Nick Lewyckyvoid llvm_gcda_emit_function(uint32_t ident, const char *function_name, 32707020829d181dcd352ff6f01eab4d353c37a19b6Nick Lewycky uint8_t use_extra_checksum) { 32807020829d181dcd352ff6f01eab4d353c37a19b6Nick Lewycky uint32_t len = 2; 3292a46a60510948b5005d62025fbba307a0323ed8dBill Wendling 33007020829d181dcd352ff6f01eab4d353c37a19b6Nick Lewycky if (use_extra_checksum) 33107020829d181dcd352ff6f01eab4d353c37a19b6Nick Lewycky len++; 3328c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING 33358c400c58019070045e548bb5173b22af092f314Nick Lewycky fprintf(stderr, "llvmgcda: function id=0x%08x name=%s\n", ident, 33458c400c58019070045e548bb5173b22af092f314Nick Lewycky function_name ? function_name : "NULL"); 3358c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 3365a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling if (!output_file) return; 3378c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 33858c400c58019070045e548bb5173b22af092f314Nick Lewycky /* function tag */ 3392a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes("\0\0\0\1", 4); 34058c400c58019070045e548bb5173b22af092f314Nick Lewycky if (function_name) 34158c400c58019070045e548bb5173b22af092f314Nick Lewycky len += 1 + length_of_string(function_name); 3422a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_32bit_value(len); 3432a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_32bit_value(ident); 3442a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_32bit_value(0); 34507020829d181dcd352ff6f01eab4d353c37a19b6Nick Lewycky if (use_extra_checksum) 3462a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_32bit_value(0); 34758c400c58019070045e548bb5173b22af092f314Nick Lewycky if (function_name) 34858c400c58019070045e548bb5173b22af092f314Nick Lewycky write_string(function_name); 3498c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 3508c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 3518c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) { 3528c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar uint32_t i; 353843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling uint64_t *old_ctrs = NULL; 354843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling uint32_t val = 0; 355d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling uint64_t save_cur_pos = cur_pos; 3565a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling 3575a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling if (!output_file) return; 358843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 3592a46a60510948b5005d62025fbba307a0323ed8dBill Wendling val = read_32bit_value(); 360843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 361843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling if (val != (uint32_t)-1) { 362843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling /* There are counters present in the file. Merge them. */ 363843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling if (val != 0x01a10000) { 3644aa08fae9b02ba9a0701fe27f58e2645d236798bBill Wendling fprintf(stderr, "profiling:invalid magic number (0x%08x)\n", val); 365843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling return; 366843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling } 367843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 3682a46a60510948b5005d62025fbba307a0323ed8dBill Wendling val = read_32bit_value(); 369843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling if (val == (uint32_t)-1 || val / 2 != num_counters) { 3704aa08fae9b02ba9a0701fe27f58e2645d236798bBill Wendling fprintf(stderr, "profiling:invalid number of counters (%d)\n", val); 371843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling return; 372843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling } 373843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 374843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling old_ctrs = malloc(sizeof(uint64_t) * num_counters); 3752a46a60510948b5005d62025fbba307a0323ed8dBill Wendling for (i = 0; i < num_counters; ++i) 3762a46a60510948b5005d62025fbba307a0323ed8dBill Wendling old_ctrs[i] = read_64bit_value(); 3772a46a60510948b5005d62025fbba307a0323ed8dBill Wendling } 378843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 379d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling cur_pos = save_cur_pos; 380d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling 381843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling /* Counter #1 (arcs) tag */ 3822a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_bytes("\0\0\xa1\1", 4); 3832a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_32bit_value(num_counters * 2); 3842a46a60510948b5005d62025fbba307a0323ed8dBill Wendling for (i = 0; i < num_counters; ++i) { 3854aa08fae9b02ba9a0701fe27f58e2645d236798bBill Wendling counters[i] += (old_ctrs ? old_ctrs[i] : 0); 3862a46a60510948b5005d62025fbba307a0323ed8dBill Wendling write_64bit_value(counters[i]); 3874aa08fae9b02ba9a0701fe27f58e2645d236798bBill Wendling } 388843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling 389843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling free(old_ctrs); 3908c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 3918c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING 392843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling fprintf(stderr, "llvmgcda: %u arcs\n", num_counters); 3935a240c5c1746d07351fc38deb81c1794e8668d15Bill Wendling for (i = 0; i < num_counters; ++i) 394843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling fprintf(stderr, "llvmgcda: %llu\n", (unsigned long long)counters[i]); 3958c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 3968c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 3978c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 3988c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbarvoid llvm_gcda_end_file() { 3998c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar /* Write out EOF record. */ 400cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth if (output_file) { 401cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth write_bytes("\0\0\0\0\0\0\0\0", 8); 402cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth 403cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth if (new_file) { 404cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth fwrite(write_buffer, cur_pos, 1, output_file); 405cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth free(write_buffer); 406cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth } else { 407cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth unmap_file(); 408cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth } 409d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling 410cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth fclose(output_file); 411cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth output_file = NULL; 412cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth write_buffer = NULL; 413d06f2fc03087e7cccda19bd550bf6fb3bc2f5ae7Bill Wendling } 414cf5fb62c0206c6544c464fa1b414bbfa26cb3244Chandler Carruth free(filename); 4158c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar 4168c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#ifdef DEBUG_GCDAPROFILING 417843f359862fb8370eacf8aed4e749c46a92b2e38Bill Wendling fprintf(stderr, "llvmgcda: -----\n"); 4188c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar#endif 4198c88119d6334a470e3ad638c5a1f1b42c4258ac9Daniel Dunbar} 420a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 421c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendlingvoid llvm_register_writeout_function(writeout_fn fn) { 422c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling struct writeout_fn_node *new_node = malloc(sizeof(struct writeout_fn_node)); 423c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling new_node->fn = fn; 424c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling new_node->next = NULL; 425c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 426c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling if (!writeout_fn_head) { 427c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling writeout_fn_head = writeout_fn_tail = new_node; 428c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling } else { 429c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling writeout_fn_tail->next = new_node; 430c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling writeout_fn_tail = new_node; 431c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling } 432c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling} 433c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 43484b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendlingvoid llvm_writeout_files() { 435c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling struct writeout_fn_node *curr = writeout_fn_head; 436c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 437c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling while (curr) { 438c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling curr->fn(); 439c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling curr = curr->next; 440c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling } 441c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling} 442c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 443c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendlingvoid llvm_delete_writeout_function_list() { 444c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling while (writeout_fn_head) { 445c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling struct writeout_fn_node *node = writeout_fn_head; 446c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling writeout_fn_head = writeout_fn_head->next; 447c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling free(node); 448c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling } 449c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 450c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling writeout_fn_head = writeout_fn_tail = NULL; 451c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling} 452c533304a95fbed444ea02f5f9e7c6e37debd1c43Bill Wendling 453a539183bf29a42ae584244106e48c99c6630e8cdBill Wendlingvoid llvm_register_flush_function(flush_fn fn) { 454a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling struct flush_fn_node *new_node = malloc(sizeof(struct flush_fn_node)); 455a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling new_node->fn = fn; 456a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling new_node->next = NULL; 457a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 458a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling if (!flush_fn_head) { 459a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling flush_fn_head = flush_fn_tail = new_node; 460a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling } else { 461a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling flush_fn_tail->next = new_node; 462a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling flush_fn_tail = new_node; 463a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling } 464a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling} 465a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 466a539183bf29a42ae584244106e48c99c6630e8cdBill Wendlingvoid __gcov_flush() { 467a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling struct flush_fn_node *curr = flush_fn_head; 468a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 469a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling while (curr) { 470a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling curr->fn(); 471a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling curr = curr->next; 472a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling } 473a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling} 474a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 475a539183bf29a42ae584244106e48c99c6630e8cdBill Wendlingvoid llvm_delete_flush_function_list() { 476a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling while (flush_fn_head) { 477a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling struct flush_fn_node *node = flush_fn_head; 478a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling flush_fn_head = flush_fn_head->next; 479a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling free(node); 480a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling } 481a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling 482a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling flush_fn_head = flush_fn_tail = NULL; 483a539183bf29a42ae584244106e48c99c6630e8cdBill Wendling} 48484b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling 48584b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendlingvoid llvm_gcov_init(writeout_fn wfn, flush_fn ffn) { 48684b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling static int atexit_ran = 0; 48784b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling 48884b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling if (wfn) 48984b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling llvm_register_writeout_function(wfn); 49084b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling 49184b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling if (ffn) 49284b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling llvm_register_flush_function(ffn); 49384b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling 49484b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling if (atexit_ran == 0) { 49584b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling atexit_ran = 1; 49684b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling 49784b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling /* Make sure we write out the data and delete the data structures. */ 49884b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling atexit(llvm_delete_flush_function_list); 49984b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling atexit(llvm_delete_writeout_function_list); 50084b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling atexit(llvm_writeout_files); 50184b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling } 50284b46d300c7a4f1c3ea4e452791de7733ce0d143Bill Wendling} 503