summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r--compiler-rt/lib/profile/InstrProfiling.c3
-rw-r--r--compiler-rt/lib/profile/InstrProfiling.h3
-rw-r--r--compiler-rt/lib/profile/InstrProfilingBuffer.c11
-rw-r--r--compiler-rt/lib/profile/InstrProfilingFile.c50
-rw-r--r--compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c12
-rw-r--r--compiler-rt/lib/profile/InstrProfilingPlatformOther.c7
-rw-r--r--compiler-rt/lib/profile/InstrProfilingRuntime.cc11
7 files changed, 84 insertions, 13 deletions
diff --git a/compiler-rt/lib/profile/InstrProfiling.c b/compiler-rt/lib/profile/InstrProfiling.c
index 123dd0d3b35..aeb3681aa34 100644
--- a/compiler-rt/lib/profile/InstrProfiling.c
+++ b/compiler-rt/lib/profile/InstrProfiling.c
@@ -10,6 +10,7 @@
#include "InstrProfiling.h"
#include <string.h>
+__attribute__((visibility("hidden")))
uint64_t __llvm_profile_get_magic(void) {
/* Magic number to detect file format and endianness.
*
@@ -32,11 +33,13 @@ uint64_t __llvm_profile_get_magic(void) {
(uint64_t)129;
}
+__attribute__((visibility("hidden")))
uint64_t __llvm_profile_get_version(void) {
/* This should be bumped any time the output format changes. */
return 1;
}
+__attribute__((visibility("hidden")))
void __llvm_profile_reset_counters(void) {
uint64_t *I = __llvm_profile_counters_begin();
uint64_t *E = __llvm_profile_counters_end();
diff --git a/compiler-rt/lib/profile/InstrProfiling.h b/compiler-rt/lib/profile/InstrProfiling.h
index 5aba69e12a2..57ebf3c3a2e 100644
--- a/compiler-rt/lib/profile/InstrProfiling.h
+++ b/compiler-rt/lib/profile/InstrProfiling.h
@@ -83,6 +83,9 @@ void __llvm_profile_set_filename(const char *Name);
/*! \brief Register to write instrumentation data to file at exit. */
int __llvm_profile_register_write_file_atexit(void);
+/*! \brief Register the write file function for this executable. */
+void __llvm_profile_register_write_file(void);
+
/*! \brief Get the magic token for the file format. */
uint64_t __llvm_profile_get_magic(void);
diff --git a/compiler-rt/lib/profile/InstrProfilingBuffer.c b/compiler-rt/lib/profile/InstrProfilingBuffer.c
index 8c6d43e7b45..b53d4f7954b 100644
--- a/compiler-rt/lib/profile/InstrProfilingBuffer.c
+++ b/compiler-rt/lib/profile/InstrProfilingBuffer.c
@@ -10,14 +10,18 @@
#include "InstrProfiling.h"
#include <string.h>
+__attribute__((visibility("hidden")))
uint64_t __llvm_profile_get_size_for_buffer(void) {
/* Match logic in __llvm_profile_write_buffer(). */
+ const uint64_t NamesSize = PROFILE_RANGE_SIZE(names) * sizeof(char);
+ const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);
return sizeof(uint64_t) * PROFILE_HEADER_SIZE +
PROFILE_RANGE_SIZE(data) * sizeof(__llvm_profile_data) +
PROFILE_RANGE_SIZE(counters) * sizeof(uint64_t) +
- PROFILE_RANGE_SIZE(names) * sizeof(char);
+ NamesSize + Padding;
}
+__attribute__((visibility("hidden")))
int __llvm_profile_write_buffer(char *Buffer) {
/* Match logic in __llvm_profile_get_size_for_buffer().
* Match logic in __llvm_profile_write_file().
@@ -33,6 +37,10 @@ int __llvm_profile_write_buffer(char *Buffer) {
const uint64_t DataSize = DataEnd - DataBegin;
const uint64_t CountersSize = CountersEnd - CountersBegin;
const uint64_t NamesSize = NamesEnd - NamesBegin;
+ const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);
+
+ /* Enough zeroes for padding. */
+ const char Zeroes[sizeof(uint64_t)] = {0};
/* Create the header. */
uint64_t Header[PROFILE_HEADER_SIZE];
@@ -54,6 +62,7 @@ int __llvm_profile_write_buffer(char *Buffer) {
UPDATE_memcpy(DataBegin, DataSize * sizeof(__llvm_profile_data));
UPDATE_memcpy(CountersBegin, CountersSize * sizeof(uint64_t));
UPDATE_memcpy(NamesBegin, NamesSize * sizeof(char));
+ UPDATE_memcpy(Zeroes, Padding * sizeof(char));
#undef UPDATE_memcpy
return 0;
diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c
index 2c40ca5af4f..5ed32d56267 100644
--- a/compiler-rt/lib/profile/InstrProfilingFile.c
+++ b/compiler-rt/lib/profile/InstrProfilingFile.c
@@ -25,6 +25,10 @@ static int writeFile(FILE *File) {
const uint64_t DataSize = DataEnd - DataBegin;
const uint64_t CountersSize = CountersEnd - CountersBegin;
const uint64_t NamesSize = NamesEnd - NamesBegin;
+ const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);
+
+ /* Enough zeroes for padding. */
+ const char Zeroes[sizeof(uint64_t)] = {0};
/* Create the header. */
uint64_t Header[PROFILE_HEADER_SIZE];
@@ -43,9 +47,30 @@ static int writeFile(FILE *File) {
CHECK_fwrite(DataBegin, sizeof(__llvm_profile_data), DataSize, File);
CHECK_fwrite(CountersBegin, sizeof(uint64_t), CountersSize, File);
CHECK_fwrite(NamesBegin, sizeof(char), NamesSize, File);
+ CHECK_fwrite(Zeroes, sizeof(char), Padding, File);
#undef CHECK_fwrite
- return 0;
+ return 0;
+}
+
+typedef struct __llvm_profile_writer {
+ struct __llvm_profile_writer *Next;
+ int (*Data)(FILE *);
+} __llvm_profile_writer;
+
+__attribute__((weak)) __llvm_profile_writer *__llvm_profile_HeadWriter = NULL;
+static __llvm_profile_writer Writer = {NULL, writeFile};
+
+__attribute__((visibility("hidden")))
+void __llvm_profile_register_write_file(void) {
+ static int HasBeenRegistered = 0;
+
+ if (HasBeenRegistered)
+ return;
+
+ HasBeenRegistered = 1;
+ Writer.Next = __llvm_profile_HeadWriter;
+ __llvm_profile_HeadWriter = &Writer;
}
static int writeFileWithName(const char *OutputName) {
@@ -57,19 +82,28 @@ static int writeFileWithName(const char *OutputName) {
if (!OutputFile)
return -1;
- RetVal = writeFile(OutputFile);
+ __llvm_profile_writer *Writer = __llvm_profile_HeadWriter;
+ if (Writer)
+ for (; Writer; Writer = Writer->Next) {
+ RetVal = Writer->Data(OutputFile);
+ if (RetVal != 0)
+ break;
+ }
+ else
+ // Default to calling this executable's writeFile.
+ RetVal = writeFile(OutputFile);
fclose(OutputFile);
return RetVal;
}
-static const char *CurrentFilename = NULL;
-void __llvm_profile_set_filename(const char *Filename) {
- CurrentFilename = Filename;
+__attribute__((weak)) const char *__llvm_profile_CurrentFilename = NULL;
+__attribute__((weak)) void __llvm_profile_set_filename(const char *Filename) {
+ __llvm_profile_CurrentFilename = Filename;
}
int getpid(void);
-int __llvm_profile_write_file(void) {
+__attribute__((weak)) int __llvm_profile_write_file(void) {
char *AllocatedFilename = NULL;
int I, J;
int RetVal;
@@ -80,7 +114,7 @@ int __llvm_profile_write_file(void) {
int NumPids = 0;
/* Get the filename. */
- const char *Filename = CurrentFilename;
+ const char *Filename = __llvm_profile_CurrentFilename;
#define UPDATE_FILENAME(NextFilename) \
if (!Filename || !Filename[0]) Filename = NextFilename
UPDATE_FILENAME(getenv("LLVM_PROFILE_FILE"));
@@ -131,7 +165,7 @@ static void writeFileWithoutReturn(void) {
__llvm_profile_write_file();
}
-int __llvm_profile_register_write_file_atexit(void) {
+__attribute__((weak)) int __llvm_profile_register_write_file_atexit(void) {
static int HasBeenRegistered = 0;
if (HasBeenRegistered)
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c b/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c
index 6e34db6121e..74019772d36 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c
@@ -11,21 +11,33 @@
#if defined(__APPLE__)
/* Use linker magic to find the bounds of the Data section. */
+__attribute__((visibility("hidden")))
extern __llvm_profile_data DataStart __asm("section$start$__DATA$__llvm_prf_data");
+__attribute__((visibility("hidden")))
extern __llvm_profile_data DataEnd __asm("section$end$__DATA$__llvm_prf_data");
+__attribute__((visibility("hidden")))
extern char NamesStart __asm("section$start$__DATA$__llvm_prf_names");
+__attribute__((visibility("hidden")))
extern char NamesEnd __asm("section$end$__DATA$__llvm_prf_names");
+__attribute__((visibility("hidden")))
extern uint64_t CountersStart __asm("section$start$__DATA$__llvm_prf_cnts");
+__attribute__((visibility("hidden")))
extern uint64_t CountersEnd __asm("section$end$__DATA$__llvm_prf_cnts");
+__attribute__((visibility("hidden")))
const __llvm_profile_data *__llvm_profile_data_begin(void) {
return &DataStart;
}
+__attribute__((visibility("hidden")))
const __llvm_profile_data *__llvm_profile_data_end(void) {
return &DataEnd;
}
+__attribute__((visibility("hidden")))
const char *__llvm_profile_names_begin(void) { return &NamesStart; }
+__attribute__((visibility("hidden")))
const char *__llvm_profile_names_end(void) { return &NamesEnd; }
+__attribute__((visibility("hidden")))
uint64_t *__llvm_profile_counters_begin(void) { return &CountersStart; }
+__attribute__((visibility("hidden")))
uint64_t *__llvm_profile_counters_end(void) { return &CountersEnd; }
#endif
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
index 407ca0a7ea9..404c1a85110 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
@@ -26,6 +26,7 @@ static uint64_t *CountersLast = NULL;
* calls are only required (and only emitted) on targets where we haven't
* implemented linker magic to find the bounds of the sections.
*/
+__attribute__((visibility("hidden")))
void __llvm_profile_register_function(void *Data_) {
/* TODO: Only emit this function if we can't use linker magic. */
const __llvm_profile_data *Data = (__llvm_profile_data*)Data_;
@@ -54,14 +55,20 @@ void __llvm_profile_register_function(void *Data_) {
#undef UPDATE_LAST
}
+__attribute__((visibility("hidden")))
const __llvm_profile_data *__llvm_profile_data_begin(void) {
return DataFirst;
}
+__attribute__((visibility("hidden")))
const __llvm_profile_data *__llvm_profile_data_end(void) {
return DataLast;
}
+__attribute__((visibility("hidden")))
const char *__llvm_profile_names_begin(void) { return NamesFirst; }
+__attribute__((visibility("hidden")))
const char *__llvm_profile_names_end(void) { return NamesLast; }
+__attribute__((visibility("hidden")))
uint64_t *__llvm_profile_counters_begin(void) { return CountersFirst; }
+__attribute__((visibility("hidden")))
uint64_t *__llvm_profile_counters_end(void) { return CountersLast; }
#endif
diff --git a/compiler-rt/lib/profile/InstrProfilingRuntime.cc b/compiler-rt/lib/profile/InstrProfilingRuntime.cc
index 79018177ef8..280de834b4b 100644
--- a/compiler-rt/lib/profile/InstrProfilingRuntime.cc
+++ b/compiler-rt/lib/profile/InstrProfilingRuntime.cc
@@ -11,17 +11,20 @@ extern "C" {
#include "InstrProfiling.h"
-int __llvm_profile_runtime;
+__attribute__((visibility("hidden"))) int __llvm_profile_runtime;
}
namespace {
-class RegisterAtExit {
+class RegisterRuntime {
public:
- RegisterAtExit() { __llvm_profile_register_write_file_atexit(); }
+ RegisterRuntime() {
+ __llvm_profile_register_write_file_atexit();
+ __llvm_profile_register_write_file();
+ }
};
-RegisterAtExit Registration;
+RegisterRuntime Registration;
}
OpenPOWER on IntegriCloud