Index: lib/profile/InstrProfiling.h =================================================================== --- lib/profile/InstrProfiling.h +++ lib/profile/InstrProfiling.h @@ -30,6 +30,16 @@ #include "InstrProfData.inc" } __llvm_profile_header; +typedef struct __llvm_covmap_header { +#define COVMAP_HEADER(Type, LLVMType, Name, Initializer) Type Name; +#include "InstrProfData.inc" +} __llvm_covmap_header; + +typedef struct __llvm_covmap_func_record { +#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Initializer) Type Name; +#include "InstrProfData.inc" +} __llvm_covmap_func_record; + /*! * \brief Get number of bytes necessary to pad the argument to eight * byte boundary. @@ -55,6 +65,8 @@ const char *__llvm_profile_end_names(void); uint64_t *__llvm_profile_begin_counters(void); uint64_t *__llvm_profile_end_counters(void); +const __llvm_covmap_header *__llvm_profile_begin_covmap(void); +const __llvm_covmap_header *__llvm_profile_end_covmap(void); /*! * \brief Clear profile counters to zero. Index: lib/profile/InstrProfilingFile.c =================================================================== --- lib/profile/InstrProfilingFile.c +++ lib/profile/InstrProfilingFile.c @@ -205,6 +205,7 @@ COMPILER_RT_VISIBILITY int __llvm_profile_write_file(void) { + __llvm_covmap_header *CovHeader; int rc; GetEnvHook = &getenv; @@ -227,7 +228,19 @@ rc = writeFileWithName(__llvm_profile_CurrentFilename); if (rc) PROF_ERR("LLVM Profile: Failed to write file \"%s\": %s\n", - __llvm_profile_CurrentFilename, strerror(errno)); + __llvm_profile_CurrentFilename, strerror(errno)); + + /* Force reference to coverage data. */ + for (CovHeader = __llvm_profile_begin_covmap(); + CovHeader < __llvm_profile_end_covmap();) { + uint32_t CoverageSize = CovHeader->CoverageSize; + uint32_t NR = CovHeader->NRecords; + uint32_t FilenamesSize = CovHeader->FilenamesSize; + CovHeader = + (__llvm_covmap_header *)((char *)CovHeader + + NR * sizeof(__llvm_covmap_func_record) + + CoverageSize + FilenamesSize); + } return rc; } Index: lib/profile/InstrProfilingPlatformLinux.c =================================================================== --- lib/profile/InstrProfilingPlatformLinux.c +++ lib/profile/InstrProfilingPlatformLinux.c @@ -19,6 +19,9 @@ #define PROF_CNTS_START INSTR_PROF_SECT_START(INSTR_PROF_CNTS_SECT_NAME) #define PROF_CNTS_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_CNTS_SECT_NAME) +#define COVMAP_START INSTR_PROF_SECT_START(INSTR_PROF_COVMAP_SECT_NAME) +#define COVMAP_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_COVMAP_SECT_NAME) + /* Declare section start and stop symbols for various sections * generated by compiler instrumentation. */ @@ -28,6 +31,8 @@ extern uint64_t PROF_CNTS_STOP COMPILER_RT_VISIBILITY; extern char PROF_NAME_START COMPILER_RT_VISIBILITY; extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY; +extern __llvm_covmap_header COVMAP_START COMPILER_RT_VISIBILITY; +extern __llvm_covmap_header COVMAP_STOP COMPILER_RT_VISIBILITY; /* Add dummy data to ensure the section is always created. */ __llvm_profile_data @@ -56,4 +61,15 @@ COMPILER_RT_VISIBILITY uint64_t *__llvm_profile_end_counters(void) { return &PROF_CNTS_STOP; } + +COMPILER_RT_VISIBILITY const __llvm_covmap_header * +__llvm_profile_begin_covmap(void) { + return &COVMAP_START; +} + +COMPILER_RT_VISIBILITY const __llvm_covmap_header * +__llvm_profile_end_covmap(void) { + return &COVMAP_STOP; +} + #endif