[compiler-rt/profile] Reland mark __llvm_profile_raw_version as hidden

Since libclang_rt.profile is added later in the command line, a
definition of __llvm_profile_raw_version is not included if it is
provided from an earlier object, e.g.  from a shared dependency.

This causes an extra dependence edge where if libA.so depends on libB.so
and both are coverage-instrumented, libA.so uses libB.so's definition of
__llvm_profile_raw_version.  This leads to a runtime link failure if the
libB.so available at runtime does not provide this symbol (but provides
the other dependent symbols).  Such a scenario can occur in Android's
mainline modules.
E.g.:
  ld -o libB.so libclang_rt.profile-x86_64.a
  ld -o libA.so -l B libclang_rt.profile-x86_64.a

libB.so has a global definition of __llvm_profile_raw_version.  libA.so
uses libB.so's definition of __llvm_profile_raw_version.  At runtime,
libB.so may not be coverage-instrumented (i.e. not export
__llvm_profile_raw_version) so runtime linking of libA.so will fail.

Marking this symbol as hidden forces each binary to use the definition
of __llvm_profile_raw_version from libclang_rt.profile.  The visiblity
is unchanged for Apple platforms where its presence is checked by the
TAPI tool.

Reviewed By: MaskRay, phosek, davidxl

Differential Revision: https://reviews.llvm.org/D111759

GitOrigin-RevId: 078279ff017f799d9cb8fe515808fcc518fe0c41
diff --git a/lib/profile/InstrProfiling.h b/lib/profile/InstrProfiling.h
index 3fbee92..5b88d71 100644
--- a/lib/profile/InstrProfiling.h
+++ b/lib/profile/InstrProfiling.h
@@ -301,14 +301,12 @@
 COMPILER_RT_VISIBILITY extern int INSTR_PROF_PROFILE_RUNTIME_VAR;
 
 /*!
- * This variable is defined in InstrProfiling.c. Its main purpose is to
- * encode the raw profile version value and other format related information
- * such as whether the profile is from IR based instrumentation. The variable
- * is defined as weak so that compiler can emit an overriding definition
- * depending on user option.  Since we don't support mixing FE and IR based
- * data in the same raw profile data file (in other words, shared libs and
- * main program are expected to be instrumented in the same way), there is
- * no need for this variable to be hidden.
+ * This variable is defined in InstrProfilingVersionVar.c as a hidden symbol
+ * (except on Apple platforms where this symbol is checked by TAPI).  Its main
+ * purpose is to encode the raw profile version value and other format related
+ * information such as whether the profile is from IR based instrumentation. The
+ * variable is defined as weak so that compiler can emit an overriding
+ * definition depending on user option.
  */
 extern uint64_t INSTR_PROF_RAW_VERSION_VAR; /* __llvm_profile_raw_version */
 
diff --git a/lib/profile/InstrProfilingVersionVar.c b/lib/profile/InstrProfilingVersionVar.c
index a6f2221..e49d171 100644
--- a/lib/profile/InstrProfilingVersionVar.c
+++ b/lib/profile/InstrProfilingVersionVar.c
@@ -13,5 +13,14 @@
  * The runtime should only provide its own definition of this symbol when the
  * user has not specified one. Set this up by moving the runtime's copy of this
  * symbol to an object file within the archive.
+ *
+ * Hide this symbol everywhere except Apple platforms, where its presence is
+ * checked by the TAPI tool.
  */
-COMPILER_RT_WEAK uint64_t INSTR_PROF_RAW_VERSION_VAR = INSTR_PROF_RAW_VERSION;
+#if !defined(__APPLE__)
+#define VERSION_VAR_VISIBILITY COMPILER_RT_VISIBILITY
+#else
+#define VERSION_VAR_VISIBILITY
+#endif
+VERSION_VAR_VISIBILITY COMPILER_RT_WEAK uint64_t INSTR_PROF_RAW_VERSION_VAR =
+    INSTR_PROF_RAW_VERSION;