#if !defined(__Fuchsia__)
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#if defined(_WIN32)
#include "WindowsMMap.h"
#include <io.h>
#include <process.h>
#else
#include <sys/file.h>
#include <sys/mman.h>
#include <unistd.h>
#if defined(__linux__)
#include <sys/types.h>
#endif
#endif
#include "InstrProfiling.h"
#include "InstrProfilingInternal.h"
#include "InstrProfilingPort.h"
#include "InstrProfilingUtil.h"
ProfileNameSpecifier;
static const char *getPNSStr(ProfileNameSpecifier PNS) { … }
#define MAX_PID_SIZE …
lprofFilename;
static lprofFilename lprofCurFilename = …;
static int ProfileMergeRequested = …;
static int getProfileFileSizeForMerging(FILE *ProfileFile,
uint64_t *ProfileFileSize);
#if defined(__APPLE__)
static const int ContinuousModeSupported = 1;
static const int UseBiasVar = 0;
static const char *FileOpenMode = "a+b";
static void *BiasAddr = NULL;
static void *BiasDefaultAddr = NULL;
static void *BitmapBiasAddr = NULL;
static void *BitmapBiasDefaultAddr = NULL;
static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
const char *CountersBegin = __llvm_profile_begin_counters();
const char *CountersEnd = __llvm_profile_end_counters();
const char *BitmapBegin = __llvm_profile_begin_bitmap();
const char *BitmapEnd = __llvm_profile_end_bitmap();
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();
const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char);
uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd);
uint64_t CountersSize =
__llvm_profile_get_counters_size(CountersBegin, CountersEnd);
uint64_t NumBitmapBytes =
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);
unsigned PageSize = getpagesize();
if ((intptr_t)CountersBegin % PageSize != 0) {
PROF_ERR("Counters section not page-aligned (start = %p, pagesz = %u).\n",
CountersBegin, PageSize);
return 1;
}
if ((intptr_t)BitmapBegin % PageSize != 0) {
PROF_ERR("Bitmap section not page-aligned (start = %p, pagesz = %u).\n",
BitmapBegin, PageSize);
return 1;
}
if ((intptr_t)DataBegin % PageSize != 0) {
PROF_ERR("Data section not page-aligned (start = %p, pagesz = %u).\n",
DataBegin, PageSize);
return 1;
}
int Fileno = fileno(File);
uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,
PaddingBytesAfterNames, PaddingBytesAfterBitmapBytes,
PaddingBytesAfterVTable, PaddingBytesAfterVNames;
__llvm_profile_get_padding_sizes_for_counters(
DataSize, CountersSize, NumBitmapBytes, NamesSize, 0,
0, &PaddingBytesBeforeCounters, &PaddingBytesAfterCounters,
&PaddingBytesAfterBitmapBytes, &PaddingBytesAfterNames,
&PaddingBytesAfterVTable, &PaddingBytesAfterVNames);
uint64_t PageAlignedCountersLength = CountersSize + PaddingBytesAfterCounters;
uint64_t FileOffsetToCounters = CurrentFileOffset +
sizeof(__llvm_profile_header) + DataSize +
PaddingBytesBeforeCounters;
void *CounterMmap = mmap((void *)CountersBegin, PageAlignedCountersLength,
PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED,
Fileno, FileOffsetToCounters);
if (CounterMmap != CountersBegin) {
PROF_ERR(
"Continuous counter sync mode is enabled, but mmap() failed (%s).\n"
" - CountersBegin: %p\n"
" - PageAlignedCountersLength: %" PRIu64 "\n"
" - Fileno: %d\n"
" - FileOffsetToCounters: %" PRIu64 "\n",
strerror(errno), CountersBegin, PageAlignedCountersLength, Fileno,
FileOffsetToCounters);
return 1;
}
if (NumBitmapBytes == 0)
return 0;
uint64_t PageAlignedBitmapLength =
NumBitmapBytes + PaddingBytesAfterBitmapBytes;
uint64_t FileOffsetToBitmap =
FileOffsetToCounters + CountersSize + PaddingBytesAfterCounters;
void *BitmapMmap =
mmap((void *)BitmapBegin, PageAlignedBitmapLength, PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED, Fileno, FileOffsetToBitmap);
if (BitmapMmap != BitmapBegin) {
PROF_ERR(
"Continuous counter sync mode is enabled, but mmap() failed (%s).\n"
" - BitmapBegin: %p\n"
" - PageAlignedBitmapLength: %" PRIu64 "\n"
" - Fileno: %d\n"
" - FileOffsetToBitmap: %" PRIu64 "\n",
strerror(errno), BitmapBegin, PageAlignedBitmapLength, Fileno,
FileOffsetToBitmap);
return 1;
}
return 0;
}
#elif defined(__ELF__) || defined(_WIN32)
#define INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR …
COMPILER_RT_VISIBILITY intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR = …;
#define INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR …
COMPILER_RT_VISIBILITY intptr_t INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR = …;
#if defined(_MSC_VER)
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR;
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_BITMAP_BIAS_VAR;
#if defined(_M_IX86) || defined(__i386__)
#define WIN_SYM_PREFIX …
#else
#define WIN_SYM_PREFIX
#endif
#pragma comment( \
linker, "/alternatename:" WIN_SYM_PREFIX INSTR_PROF_QUOTE( \
INSTR_PROF_PROFILE_COUNTER_BIAS_VAR) "=" WIN_SYM_PREFIX \
INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_COUNTER_BIAS_DEFAULT_VAR))
#pragma comment( \
linker, "/alternatename:" WIN_SYM_PREFIX INSTR_PROF_QUOTE( \
INSTR_PROF_PROFILE_BITMAP_BIAS_VAR) "=" WIN_SYM_PREFIX \
INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_BITMAP_BIAS_DEFAULT_VAR))
#else
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_COUNTER_BIAS_VAR
__attribute__((weak …, alias …));
COMPILER_RT_VISIBILITY extern intptr_t INSTR_PROF_PROFILE_BITMAP_BIAS_VAR
__attribute__((weak …, alias …));
#endif
static const int ContinuousModeSupported = …;
static const int UseBiasVar = …;
static const char *FileOpenMode = …;
static void *BiasAddr = …;
static void *BiasDefaultAddr = …;
static void *BitmapBiasAddr = …;
static void *BitmapBiasDefaultAddr = …;
static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) { … }
#else
static const int ContinuousModeSupported = 0;
static const int UseBiasVar = 0;
static const char *FileOpenMode = "a+b";
static void *BiasAddr = NULL;
static void *BiasDefaultAddr = NULL;
static void *BitmapBiasAddr = NULL;
static void *BitmapBiasDefaultAddr = NULL;
static int mmapForContinuousMode(uint64_t CurrentFileOffset, FILE *File) {
return 0;
}
#endif
static int isProfileMergeRequested(void) { … }
static void setProfileMergeRequested(int EnableMerge) { … }
static FILE *ProfileFile = …;
static FILE *getProfileFile(void) { … }
static void setProfileFile(FILE *File) { … }
static int getCurFilenameLength(void);
static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf);
static unsigned doMerging(void) { … }
static uint32_t fileWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs,
uint32_t NumIOVecs) { … }
static uint32_t orderFileWriter(FILE *File, const uint32_t *DataStart) { … }
static void initFileWriter(ProfDataWriter *This, FILE *File) { … }
COMPILER_RT_VISIBILITY ProfBufferIO *
lprofCreateBufferIOInternal(void *File, uint32_t BufferSz) { … }
static void setupIOBuffer(void) { … }
static int getProfileFileSizeForMerging(FILE *ProfileFile,
uint64_t *ProfileFileSize) { … }
static int mmapProfileForMerging(FILE *ProfileFile, uint64_t ProfileFileSize,
char **ProfileBuffer) { … }
static int doProfileMerging(FILE *ProfileFile, int *MergeDone) { … }
static void createProfileDir(const char *Filename) { … }
static FILE *openFileForMerging(const char *ProfileFileName, int *MergeDone) { … }
static FILE *getFileObject(const char *OutputName) { … }
static int writeFile(const char *OutputName) { … }
static int writeOrderFile(const char *OutputName) { … }
#define LPROF_INIT_ONCE_ENV …
static void truncateCurrentFile(void) { … }
static int writeProfileWithFileObject(const char *Filename, FILE *File) { … }
static void initializeProfileForContinuousMode(void) { … }
static const char *DefaultProfileName = …;
static void resetFilenameToDefault(void) { … }
static unsigned getMergePoolSize(const char *FilenamePat, int *I) { … }
static int checkBounds(int Idx, int Strlen) { … }
static int parseFilenamePattern(const char *FilenamePat,
unsigned CopyFilenamePat) { … }
static void parseAndSetFilename(const char *FilenamePat,
ProfileNameSpecifier PNS,
unsigned CopyFilenamePat) { … }
#define SIGLEN …
static int getCurFilenameLength(void) { … }
static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) { … }
static const char *getFilenamePatFromEnv(void) { … }
COMPILER_RT_VISIBILITY
const char *__llvm_profile_get_path_prefix(void) { … }
COMPILER_RT_VISIBILITY
const char *__llvm_profile_get_filename(void) { … }
COMPILER_RT_VISIBILITY
void __llvm_profile_initialize_file(void) { … }
COMPILER_RT_VISIBILITY
void __llvm_profile_initialize(void) { … }
COMPILER_RT_VISIBILITY
void __llvm_profile_set_filename(const char *FilenamePat) { … }
COMPILER_RT_VISIBILITY
int __llvm_profile_write_file(void) { … }
COMPILER_RT_VISIBILITY
int __llvm_profile_dump(void) { … }
static const char *OrderFileSuffix = …;
COMPILER_RT_VISIBILITY
int __llvm_orderfile_write_file(void) { … }
COMPILER_RT_VISIBILITY
int __llvm_orderfile_dump(void) { … }
static void writeFileWithoutReturn(void) { … }
COMPILER_RT_VISIBILITY
int __llvm_profile_register_write_file_atexit(void) { … }
COMPILER_RT_VISIBILITY int __llvm_profile_set_file_object(FILE *File,
int EnableMerge) { … }
#endif