Index: lib/profile/InstrProfilingMergeFile.c =================================================================== --- lib/profile/InstrProfilingMergeFile.c +++ lib/profile/InstrProfilingMergeFile.c @@ -20,6 +20,7 @@ /* Merge value profile data pointed to by SrcValueProfData into * in-memory profile counters pointed by to DstData. */ +COMPILER_RT_VISIBILITY void lprofMergeValueProfData(ValueProfData *SrcValueProfData, __llvm_profile_data *DstData) { unsigned I, S, V, DstIndex = 0; Index: test/profile/Inputs/instrprof-value-prof-visibility.c =================================================================== --- /dev/null +++ test/profile/Inputs/instrprof-value-prof-visibility.c @@ -0,0 +1,61 @@ +#include +#include +#include +#ifdef DLOPEN_FUNC_DIR +#include +#endif + +int __llvm_profile_runtime = 0; +int __llvm_profile_write_file(); +void __llvm_profile_reset_counters(void); +void __llvm_profile_initialize_file(void); +struct __llvm_profile_data; +struct ValueProfData; +void lprofMergeValueProfData(struct ValueProfData *, struct __llvm_profile_data *); +/* Force the vp merger module to be linked in. */ +void *Dummy = &lprofMergeValueProfData; + +void callee1() {} +void callee2() {} + +typedef void (*FP)(void); +FP Fps[2] = {callee1, callee2}; + +int main(int argc, char *argv[]) { + __llvm_profile_initialize_file(); + __llvm_profile_write_file(); + __llvm_profile_reset_counters(); + +#ifdef DLOPEN_FUNC_DIR + void *Handle = dlopen(DLOPEN_FUNC_DIR"/func.shared", RTLD_NOW); + if (!Handle) { + fprintf(stderr, "unable to open '" DLOPEN_FUNC_DIR "/func.shared': %s\n", + dlerror()); + return EXIT_FAILURE; + } + + // This tests that lprofMergeValueProfData is not accessed + // from outside a module + void (*SymHandle)(struct ValueProfData *, struct __llvm_profile_data *) = + (void (*)(struct ValueProfData *, struct __llvm_profile_data *))dlsym( + Handle, "lprofMergeValueProfData"); + if (SymHandle) { + fprintf(stderr, + "should not be able to lookup symbol 'lprofMergeValueProfData': %s\n", + dlerror()); + return EXIT_FAILURE; + } + + dlclose(Handle); + +#endif + + Fps[0](); + Fps[1](); + + __llvm_profile_write_file(); + __llvm_profile_reset_counters(); + + return EXIT_SUCCESS; +} + Index: test/profile/Linux/instrprof-value-prof-visibility.test =================================================================== --- /dev/null +++ test/profile/Linux/instrprof-value-prof-visibility.test @@ -0,0 +1,6 @@ +# This tests that lprofMergeValueProfData is not accessed from outside a module +RUN: mkdir -p %t.d +RUN: %clang_profgen -o %t.d/func.shared -fPIC -shared -fuse-ld=gold -mllvm --enable-value-profiling=true %S/../Inputs/instrprof-value-prof-visibility.c -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections +RUN: %clang_profgen -o %t.d/main -fuse-ld=gold -mllvm --enable-value-profiling=true -DDLOPEN_FUNC_DIR=\"%t.d\" %S/../Inputs/instrprof-value-prof-visibility.c -fdata-sections -ffunction-sections -fuse-ld=gold -Wl,--gc-sections +RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.d/main +