From: Sergei Trofimovich <siarh...@google.com> Before the change gcc did not stream correctly TOPN counters if counters belonged to a non-local shared object.
As a result zero-section optimization generated TOPN sections in a form not recognizable by '__gcov_merge_topn'. The problem happens because in a case of multiple shared objects '__gcov_merge_topn' function is present in address space multiple times (once per each object). The fix is to never rely on function address and predicate on TOPN counter types. libgcc/ChangeLog: PR gcov-profile/96913 * libgcov-driver.c (write_one_data): Avoid function pointer comparison in TOP streaming decision. --- libgcc/libgcov-driver.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c index 58914268d4e..86a6b5ad68a 100644 --- a/libgcc/libgcov-driver.c +++ b/libgcc/libgcov-driver.c @@ -424,10 +424,15 @@ write_one_data (const struct gcov_info *gi_ptr, n_counts = ci_ptr->num; - if (gi_ptr->merge[t_ix] == __gcov_merge_topn) + /* Do not zero-compress top counters because: + * - __gcv_merge_topn does not handle such sections + * - GCOV_COUNTER_V_INDIR contains non-zero keys + */ + if (t_ix == GCOV_COUNTER_V_TOPN || t_ix == GCOV_COUNTER_V_INDIR) write_top_counters (ci_ptr, t_ix, n_counts); else { + /* Do not stream when all counters are zero. */ int all_zeros = 1; for (unsigned i = 0; i < n_counts; i++) -- 2.28.0