This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Questions related to creation of libgcov.so
On 08/14/2018 03:40 PM, Michael Matz wrote:
> Hi,
>
> On Tue, 14 Aug 2018, Martin Liška wrote:
>
>> I'm sending second version of the patch candidate. I was able to create
>> a mapfile and generate versioned symbols for libgcov.so file.
>>
>> Unresolved issues:
>> 1) I still see linking with static library:
>>
>> $ find /home/marxin/bin/gcc -name libgcov*
>> /home/marxin/bin/gcc/lib64/libgcov.so.1
>> /home/marxin/bin/gcc/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/libgcov.a
>> /home/marxin/bin/gcc/lib64/libgcov.so
>
> The .so softlink needs to go into into the same directory as libgcov.a.
> See how libgcc_s is installed using the SHLIB_INSTALL macro (defined in
> libgcc/config/t-slibgcc). In fact, with the right substitutions you
> should be able to use that macro directly without writing your own (you
> need to subst @shlib_base_name@, @multilib_dir@ and @shlib_slibdir_qual@).
Hi.
Good, I'm getting more familiar with the Makefile magic. So I can image reuse
of SHLIB_LINK macro, but it uses:
SHLIB_SOVERSION = 1
SHLIB_SONAME = @shlib_base_name@.so.$(SHLIB_SOVERSION)
which would require a substitution for soversion, show I generalize even so much?
About the location of libgcov.{a,so}, I believe right place would be now:
/home/marxin/bin/gcc/lib64/libgcov.so.1
/home/marxin/bin/gcc/lib64/libgcov.so
/home/marxin/bin/gcc/lib64/libgcov.a
Because of LD_LIBRARY_PATH location I believe libgcov.so should not be in:
/home/marxin/bin/gcc/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/libgcov.so
?
Now I see it working as expected during compilation and run-time.
One another question has popped up:
libgcov.a archive consists of many one-function-per-object-file objects,
this is guarded with e.g. #ifdef L_gcov_reset macro. For shared library I need
something like:
+#if defined(L_gcov_reset) || defined(L_gcov_shared)
question is whether it worth separating the functions into separate objects? I know
during linking linker can strip the unused ones. But still.
I'm attaching WIP.
Martin
>
>> 3) I added t-libgcov t-libgcov-gld t-libgcov-elf-ver into *-linux for now. Am I right that it should be added
>> basically to all places where e.g. 't-slibgcc-elf-ver' is?
>
> I think you only need to add further makefile includes if you need new
> macros. I don't think you should need any? Also for linking you
> probably should be able to reuse the SHLIB_LINK macro (maybe a bit
> extending it is required).
>
>
> Ciao,
> Michael.
>
>From 17422b4cbdd13db48d397943ea8021b6cbe76c3d Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Fri, 3 Aug 2018 11:14:15 +0200
Subject: [PATCH] Add libgcov.so: work in progress.
---
libgcc/Makefile.in | 62 +++++++++++++++++++++++++++++++++-----
libgcc/config.host | 2 +-
libgcc/config/t-libgcov | 46 ++++++++++++++++++++++++++++
libgcc/libgcov-driver.c | 4 +--
libgcc/libgcov-interface.c | 28 ++++++++---------
libgcc/libgcov-merge.c | 14 ++++-----
libgcc/libgcov-profiler.c | 34 ++++++++++-----------
libgcc/libgcov-std.ver.in | 53 ++++++++++++++++++++++++++++++++
libgcc/libgcov.h | 31 +++++++++----------
9 files changed, 209 insertions(+), 65 deletions(-)
create mode 100644 libgcc/config/t-libgcov
create mode 100644 libgcc/libgcov-std.ver.in
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 0c5b264f717..1c50e525eaa 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -912,15 +912,25 @@ libgcov-objects = $(libgcov-merge-objects) $(libgcov-profiler-objects) \
$(libgcov-interface-objects) $(libgcov-driver-objects)
$(libgcov-merge-objects): %$(objext): $(srcdir)/libgcov-merge.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
- $(gcc_compile) -DL$* -c $(srcdir)/libgcov-merge.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-merge.c $(vis_hide)
$(libgcov-profiler-objects): %$(objext): $(srcdir)/libgcov-profiler.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
- $(gcc_compile) -DL$* -c $(srcdir)/libgcov-profiler.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-profiler.c $(vis_hide)
$(libgcov-interface-objects): %$(objext): $(srcdir)/libgcov-interface.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
- $(gcc_compile) -DL$* -c $(srcdir)/libgcov-interface.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-interface.c $(vis_hide)
$(libgcov-driver-objects): %$(objext): $(srcdir)/libgcov-driver.c \
$(srcdir)/libgcov-driver-system.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
- $(gcc_compile) -DL$* -c $(srcdir)/libgcov-driver.c
+ $(gcc_compile) -DL$* -c $(srcdir)/libgcov-driver.c $(vis_hide)
+libgcov-s-merge$(objext): $(srcdir)/libgcov-merge.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
+ $(gcc_compile) -DL_gcov_shared -c $(srcdir)/libgcov-merge.c
+libgcov-s-profiler$(objext): $(srcdir)/libgcov-profiler.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
+ $(gcc_compile) -DL_gcov_shared -c $(srcdir)/libgcov-profiler.c
+libgcov-s-interface$(objext): $(srcdir)/libgcov-interface.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
+ $(gcc_compile) -DL_gcov_shared -c $(srcdir)/libgcov-interface.c
+libgcov-s-driver$(objext): $(srcdir)/libgcov-driver.c $(srcdir)/libgcov-driver-system.c $(srcdir)/gcov.h $(srcdir)/libgcov.h
+ $(gcc_compile) -DL_gcov_shared -c $(srcdir)/libgcov-driver.c
+
+libgcov-s-objects = libgcov-s-merge${objext} libgcov-s-profiler${objext} libgcov-s-interface${objext} libgcov-s-driver${objext}
# Static libraries.
libgcc.a: $(libgcc-objects)
@@ -944,7 +954,7 @@ libgcc.a libgcov.a libunwind.a libgcc_eh.a:
all: libgcc.a
ifeq ($(enable_gcov),yes)
-all: libgcov.a
+all: libgcov.a libgcov$(SHLIB_EXT)
endif
ifneq ($(LIBUNWIND),)
@@ -1006,6 +1016,38 @@ libunwind$(SHLIB_EXT): $(libunwind-s-objects) $(extra-parts)
@shlib_base_name@,libunwind,$(subst \
@shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIBUNWIND_LINK))))))
+# Map-file generation.
+libgcov.map.in: $(SHLIBGCOV_MAPFILES)
+ { cat $(SHLIBGCOV_MAPFILES) \
+ | sed -e '/^[ ]*#/d' \
+ -e 's/^%\(if\|else\|elif\|endif\|define\)/#\1/' \
+ | $(gcc_compile_bare) -E -xassembler-with-cpp -; \
+ } > tmp-$@
+ mv tmp-$@ $@
+libgcov.map: $(SHLIB_MKMAP) libgcov.map.in $(libgcov-objects)
+ { $(NM) $(SHLIBGCOV_NM_FLAGS) $(libgcov-objects); echo %%; \
+ cat libgcov.map.in; \
+ } | $(AWK) -f $(SHLIB_MKMAP) $(SHLIB_MKMAP_OPTS) > tmp-$@
+ mv tmp-$@ $@
+libgcov$(SHLIB_EXT): libgcov.map
+libgcov_mapfile = libgcov.map
+
+libgcov-std.ver: $(srcdir)/libgcov-std.ver.in
+ cat < $< > $@
+
+libgcov$(SHLIB_EXT): $(libgcov-s-objects) libgcc_s$(SHLIB_EXT)
+ # @multilib_flags@ is still needed because this may use
+ # $(GCC_FOR_TARGET) and $(LIBGCC2_CFLAGS) directly.
+ # @multilib_dir@ is not really necessary, but sometimes it has
+ # more uses than just a directory name.
+ $(mkinstalldirs) $(MULTIDIR)
+ $(subst @multilib_flags@,$(CFLAGS) -B./,$(subst \
+ @multilib_dir@,$(MULTIDIR),$(subst \
+ @shlib_objs@,$(objects),$(subst \
+ @shlib_base_name@,libgcov,$(subst \
+ @shlib_map_file@,$(libgcov_mapfile),$(subst \
+ @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIBGCOV_LINK)))))))
+
endif
# Build the standard GCC startfiles and endfiles.
@@ -1169,9 +1211,13 @@ install-leaf: $(install-shared) $(install-libunwind)
chmod 644 $(DESTDIR)$(inst_libdir)/libgcc.a
$(RANLIB) $(DESTDIR)$(inst_libdir)/libgcc.a
ifeq ($(enable_gcov),yes)
- $(INSTALL_DATA) libgcov.a $(DESTDIR)$(inst_libdir)/
- chmod 644 $(DESTDIR)$(inst_libdir)/libgcov.a
- $(RANLIB) $(DESTDIR)$(inst_libdir)/libgcov.a
+ $(INSTALL_DATA) libgcov.a $(DESTDIR)$(inst_slibdir)/
+ chmod 644 $(DESTDIR)$(inst_slibdir)/libgcov.a
+ $(RANLIB) $(DESTDIR)$(inst_slibdir)/libgcov.a
+
+ $(subst @multilib_dir@,$(MULTIDIR),$(subst \
+ @shlib_base_name@,libgcov,$(subst \
+ @shlib_slibdir_qual@,$(MULTIOSSUBDIR),$(SHLIBGCOV_INSTALL))))
endif
parts="$(INSTALL_PARTS)"; \
diff --git a/libgcc/config.host b/libgcc/config.host
index 18cabaf24f6..553fe726fee 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -236,7 +236,7 @@ case ${host} in
extra_parts="crtbegin.o crtend.o"
;;
*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu)
- tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux"
+ tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux t-libgcov t-libgcov-elf-ver"
extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
if test x$enable_vtable_verify = xyes; then
extra_parts="$extra_parts vtv_start.o vtv_end.o vtv_start_preinit.o vtv_end_preinit.o"
diff --git a/libgcc/config/t-libgcov b/libgcc/config/t-libgcov
new file mode 100644
index 00000000000..9359b68ef3b
--- /dev/null
+++ b/libgcc/config/t-libgcov
@@ -0,0 +1,46 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Build libgcov for ELF with the GNU linker.
+
+SHLIBGCOV_SOVERSION = 1
+SHLIBGCOV_SONAME = @shlib_base_name@.so.$(SHLIBGCOV_SOVERSION)
+
+SHLIBGCOV_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared \
+ $(SHLIB_LDFLAGS) \
+ -nodefaultlibs -Wl,-h,$(SHLIBGCOV_SONAME) \
+ -Wl,-z,text -Wl,-z,defs -Wl,-z,now -o $(SHLIB_DIR)/$(SHLIBGCOV_SONAME).tmp \
+ @multilib_flags@ $(SHLIB_OBJS) -lc -lgcc && \
+ rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \
+ if [ -f $(SHLIB_DIR)/$(SHLIBGCOV_SONAME) ]; then \
+ mv -f $(SHLIB_DIR)/$(SHLIBGCOV_SONAME) \
+ $(SHLIB_DIR)/$(SHLIBGCOV_SONAME).backup; \
+ else true; fi && \
+ mv $(SHLIB_DIR)/$(SHLIBGCOV_SONAME).tmp \
+ $(SHLIB_DIR)/$(SHLIBGCOV_SONAME) && \
+ $(LN_S) $(SHLIBGCOV_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK)
+
+SHLIBGCOV_INSTALL_SOLINK = $(LN_S) $(SHLIBGCOV_SONAME) \
+ $(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
+
+SHLIBGCOV_INSTALL = \
+ $(mkinstalldirs) $(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL); \
+ $(INSTALL_SHLIB) $(SHLIB_DIR)/$(SHLIB_SONAME) \
+ $(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME); \
+ rm -f $(DESTDIR)$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \
+ $(SHLIBGCOV_INSTALL_SOLINK)
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 1f2c4a74298..f886b056aa6 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -28,7 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined(inhibit_libc)
/* If libc and its header files are not available, provide dummy functions. */
-#if defined(L_gcov)
+#if defined(L_gcov) || defined(L_gcov_shared)
void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
#endif
@@ -41,7 +41,7 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
#include <sys/stat.h>
#endif
-#ifdef L_gcov
+#if defined(L_gcov) || defined(L_gcov_shared)
/* A utility function for outputting errors. */
static int gcov_error (const char *, ...);
diff --git a/libgcc/libgcov-interface.c b/libgcc/libgcov-interface.c
index 227a5a04ccb..3f38e9ad868 100644
--- a/libgcc/libgcov-interface.c
+++ b/libgcc/libgcov-interface.c
@@ -28,15 +28,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined(inhibit_libc)
-#ifdef L_gcov_flush
+#if defined(L_gcov_flush) || defined(L_gcov_shared)
void __gcov_flush (void) {}
#endif
-#ifdef L_gcov_reset
+#if defined(L_gcov_reset) || defined(L_gcov_shared)
void __gcov_reset (void) {}
#endif
-#ifdef L_gcov_dump
+#if defined(L_gcov_dump) || defined(L_gcov_shared)
void __gcov_dump (void) {}
#endif
@@ -54,8 +54,8 @@ void __gcov_dump (void) {}
extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
-#ifdef L_gcov_flush
-#ifdef __GTHREAD_MUTEX_INIT
+#if defined(L_gcov_flush) || defined(L_gcov_shared)
+#if defined(__GTHREAD_MUTEX_INIT) || defined(L_gcov_shared)
__gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
#define init_mx_once()
#else
@@ -93,7 +93,7 @@ __gcov_flush (void)
#endif /* L_gcov_flush */
-#ifdef L_gcov_reset
+#if defined(L_gcov_reset) || defined(L_gcov_shared)
/* Reset all counters to zero. */
@@ -148,7 +148,7 @@ ALIAS_void_fn (__gcov_reset_int, __gcov_reset);
#endif /* L_gcov_reset */
-#ifdef L_gcov_dump
+#if defined(L_gcov_dump) || defined(L_gcov_shared)
/* Function that can be called from application to write profile collected
so far, in order to collect profile in region of interest. */
@@ -168,7 +168,7 @@ ALIAS_void_fn (__gcov_dump_int, __gcov_dump);
#endif /* L_gcov_dump */
-#ifdef L_gcov_fork
+#if defined(L_gcov_fork) || defined(L_gcov_shared)
/* A wrapper for the fork function. Flushes the accumulated profiling data, so
that they are not counted twice. */
@@ -184,7 +184,7 @@ __gcov_fork (void)
}
#endif
-#ifdef L_gcov_execl
+#if defined(L_gcov_execl) || defined(L_gcov_shared)
/* A wrapper for the execl function. Flushes the accumulated
profiling data, so that they are not lost. */
@@ -215,7 +215,7 @@ __gcov_execl (const char *path, char *arg, ...)
}
#endif
-#ifdef L_gcov_execlp
+#if defined(L_gcov_execlp) || defined(L_gcov_shared)
/* A wrapper for the execlp function. Flushes the accumulated
profiling data, so that they are not lost. */
@@ -246,7 +246,7 @@ __gcov_execlp (const char *path, char *arg, ...)
}
#endif
-#ifdef L_gcov_execle
+#if defined(L_gcov_execle) || defined(L_gcov_shared)
/* A wrapper for the execle function. Flushes the accumulated
profiling data, so that they are not lost. */
@@ -279,7 +279,7 @@ __gcov_execle (const char *path, char *arg, ...)
}
#endif
-#ifdef L_gcov_execv
+#if defined(L_gcov_execv) || defined(L_gcov_shared)
/* A wrapper for the execv function. Flushes the accumulated
profiling data, so that they are not lost. */
@@ -291,7 +291,7 @@ __gcov_execv (const char *path, char *const argv[])
}
#endif
-#ifdef L_gcov_execvp
+#if defined(L_gcov_execvp) || defined(L_gcov_shared)
/* A wrapper for the execvp function. Flushes the accumulated
profiling data, so that they are not lost. */
@@ -303,7 +303,7 @@ __gcov_execvp (const char *path, char *const argv[])
}
#endif
-#ifdef L_gcov_execve
+#if defined(L_gcov_execve) || defined(L_gcov_shared)
/* A wrapper for the execve function. Flushes the accumulated
profiling data, so that they are not lost. */
diff --git a/libgcc/libgcov-merge.c b/libgcc/libgcov-merge.c
index 3ab509a8d7f..412c01820cf 100644
--- a/libgcc/libgcov-merge.c
+++ b/libgcc/libgcov-merge.c
@@ -28,19 +28,19 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#if defined(inhibit_libc)
/* If libc and its header files are not available, provide dummy functions. */
-#ifdef L_gcov_merge_add
+#if defined(L_gcov_merge_add) || defined(L_gcov_shared)
void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
unsigned n_counters __attribute__ ((unused))) {}
#endif
-#ifdef L_gcov_merge_single
+#if defined(L_gcov_merge_single) || defined(L_gcov_shared)
void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
unsigned n_counters __attribute__ ((unused))) {}
#endif
#else
-#ifdef L_gcov_merge_add
+#if defined(L_gcov_merge_add) || defined(L_gcov_shared)
/* The profile merging function that just adds the counters. It is given
an array COUNTERS of N_COUNTERS old counters and it reads the same number
of counters from the gcov file. */
@@ -52,7 +52,7 @@ __gcov_merge_add (gcov_type *counters, unsigned n_counters)
}
#endif /* L_gcov_merge_add */
-#ifdef L_gcov_merge_ior
+#if defined(L_gcov_merge_ior) || defined(L_gcov_shared)
/* The profile merging function that just adds the counters. It is given
an array COUNTERS of N_COUNTERS old counters and it reads the same number
of counters from the gcov file. */
@@ -64,7 +64,7 @@ __gcov_merge_ior (gcov_type *counters, unsigned n_counters)
}
#endif
-#ifdef L_gcov_merge_time_profile
+#if defined(L_gcov_merge_time_profile) || defined(L_gcov_shared)
/* Time profiles are merged so that minimum from all valid (greater than zero)
is stored. There could be a fork that creates new counters. To have
the profile stable, we chosen to pick the smallest function visit time. */
@@ -84,7 +84,7 @@ __gcov_merge_time_profile (gcov_type *counters, unsigned n_counters)
}
#endif /* L_gcov_merge_time_profile */
-#ifdef L_gcov_merge_single
+#if defined(L_gcov_merge_single) || defined(L_gcov_shared)
/* The profile merging function for choosing the most common value.
It is given an array COUNTERS of N_COUNTERS old counters and it
reads the same number of counters from the gcov file. The counters
@@ -122,7 +122,7 @@ __gcov_merge_single (gcov_type *counters, unsigned n_counters)
}
#endif /* L_gcov_merge_single */
-#ifdef L_gcov_merge_icall_topn
+#if defined(L_gcov_merge_icall_topn) || defined(L_gcov_shared)
/* The profile merging function used for merging indirect call counts
This function is given array COUNTERS of N_COUNTERS old counters and it
reads the same number of counters from the gcov file. */
diff --git a/libgcc/libgcov-profiler.c b/libgcc/libgcov-profiler.c
index 7e208d75d86..4ee886e6184 100644
--- a/libgcc/libgcov-profiler.c
+++ b/libgcc/libgcov-profiler.c
@@ -37,7 +37,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif
#endif
-#ifdef L_gcov_interval_profiler
+#if defined(L_gcov_interval_profiler) || defined(L_gcov_shared)
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below
the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
@@ -57,7 +57,7 @@ __gcov_interval_profiler (gcov_type *counters, gcov_type value,
}
#endif
-#if defined(L_gcov_interval_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
+#if (defined(L_gcov_interval_profiler_atomic) || defined(L_gcov_shared)) && GCOV_SUPPORTS_ATOMIC
/* If VALUE is in interval <START, START + STEPS - 1>, then increases the
corresponding counter in COUNTERS. If the VALUE is above or below
the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
@@ -77,7 +77,7 @@ __gcov_interval_profiler_atomic (gcov_type *counters, gcov_type value,
}
#endif
-#ifdef L_gcov_pow2_profiler
+#if defined(L_gcov_pow2_profiler) || defined(L_gcov_shared)
/* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
COUNTERS[0] is incremented. */
@@ -91,7 +91,7 @@ __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#if defined(L_gcov_pow2_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
+#if (defined(L_gcov_pow2_profiler_atomic) || defined(L_gcov_shared)) && GCOV_SUPPORTS_ATOMIC
/* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
COUNTERS[0] is incremented. Function is thread-safe. */
@@ -137,7 +137,7 @@ __gcov_one_value_profiler_body (gcov_type *counters, gcov_type value,
counters[2]++;
}
-#ifdef L_gcov_one_value_profiler
+#if defined(L_gcov_one_value_profiler) || defined(L_gcov_shared)
void
__gcov_one_value_profiler (gcov_type *counters, gcov_type value)
{
@@ -145,7 +145,7 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#if defined(L_gcov_one_value_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
+#if (defined(L_gcov_one_value_profiler_atomic) || defined(L_gcov_shared)) && GCOV_SUPPORTS_ATOMIC
/* Update one value profilers (COUNTERS) for a given VALUE.
@@ -163,7 +163,7 @@ __gcov_one_value_profiler_atomic (gcov_type *counters, gcov_type value)
}
#endif
-#ifdef L_gcov_indirect_call_topn_profiler
+#if defined(L_gcov_indirect_call_topn_profiler) || defined(L_gcov_shared)
/* Tries to keep track the most frequent N values in the counters where
N is specified by parameter TOPN_VAL. To track top N values, 2*N counter
entries are used.
@@ -271,14 +271,14 @@ __gcov_topn_value_profiler_body (gcov_type *counters, gcov_type value)
#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
__thread
#endif
-gcov_type *__gcov_indirect_call_topn_counters ATTRIBUTE_HIDDEN;
+gcov_type *__gcov_indirect_call_topn_counters;
#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
__thread
#endif
-void *__gcov_indirect_call_topn_callee ATTRIBUTE_HIDDEN;
+void *__gcov_indirect_call_topn_callee;
-#ifdef TARGET_VTABLE_USES_DESCRIPTORS
+#if defined(TARGET_VTABLE_USES_DESCRIPTORS) || defined(L_gcov_shared)
#define VTABLE_USES_DESCRIPTORS 1
#else
#define VTABLE_USES_DESCRIPTORS 0
@@ -301,7 +301,7 @@ __gcov_indirect_call_topn_profiler (gcov_type value, void* cur_func)
}
#endif
-#ifdef L_gcov_indirect_call_profiler_v2
+#if defined(L_gcov_indirect_call_profiler_v2) || defined(L_gcov_shared)
/* These two variables are used to actually track caller and callee. Keep
them in TLS memory so races are not common (they are written to often).
@@ -341,14 +341,14 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
}
#endif
-#ifdef L_gcov_time_profiler
+#if defined(L_gcov_time_profiler) || defined(L_gcov_shared)
/* Counter for first visit of each function. */
-gcov_type __gcov_time_profiler_counter ATTRIBUTE_HIDDEN;
+gcov_type __gcov_time_profiler_counter;
#endif
-#ifdef L_gcov_average_profiler
+#if defined(L_gcov_average_profiler) || defined(L_gcov_shared)
/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
to saturate up. */
@@ -360,7 +360,7 @@ __gcov_average_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#if defined(L_gcov_average_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
+#if (defined(L_gcov_average_profiler_atomic) || defined(L_gcov_shared)) && GCOV_SUPPORTS_ATOMIC
/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
to saturate up. Function is thread-safe. */
@@ -372,7 +372,7 @@ __gcov_average_profiler_atomic (gcov_type *counters, gcov_type value)
}
#endif
-#ifdef L_gcov_ior_profiler
+#if defined(L_gcov_ior_profiler) || defined(L_gcov_shared)
/* Bitwise-OR VALUE into COUNTER. */
void
@@ -382,7 +382,7 @@ __gcov_ior_profiler (gcov_type *counters, gcov_type value)
}
#endif
-#if defined(L_gcov_ior_profiler_atomic) && GCOV_SUPPORTS_ATOMIC
+#if (defined(L_gcov_ior_profiler_atomic) || defined(L_gcov_shared)) && GCOV_SUPPORTS_ATOMIC
/* Bitwise-OR VALUE into COUNTER. Function is thread-safe. */
void
diff --git a/libgcc/libgcov-std.ver.in b/libgcc/libgcov-std.ver.in
new file mode 100644
index 00000000000..71fa43e26c9
--- /dev/null
+++ b/libgcc/libgcov-std.ver.in
@@ -0,0 +1,53 @@
+# Copyright (C) 2018 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+GCC_9.1.0 {
+ __gcov_init
+ __gcov_exit
+ __gcov_merge_add
+ __gcov_merge_time_profile
+ __gcov_merge_single
+ __gcov_merge_ior
+ __gcov_merge_icall_topn
+ __gcov_interval_profiler
+ __gcov_interval_profiler_atomic
+ __gcov_pow2_profiler
+ __gcov_pow2_profiler_atomic
+ __gcov_one_value_profiler
+ __gcov_one_value_profiler_atomic
+ __gcov_indirect_call_profiler_v2
+ __gcov_time_profiler
+ __gcov_time_profiler_atomic
+ __gcov_average_profiler
+ __gcov_average_profiler_atomic
+ __gcov_ior_profiler
+ __gcov_ior_profiler_atomic
+ __gcov_indirect_call_topn_profiler
+
+ __gcov_fork
+ __gcov_execl
+ __gcov_execlp
+ __gcov_execle
+ __gcov_execv
+ __gcov_execvp
+ __gcov_execve
+
+ __gcov_indirect_call_callee
+ __gcov_indirect_call_counters
+ __gcov_time_profiler_counter
+}
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 21422873cf2..d47e3fec703 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -234,10 +234,10 @@ extern struct gcov_master __gcov_master;
extern void __gcov_dump_one (struct gcov_root *) ATTRIBUTE_HIDDEN;
/* Register a new object file module. */
-extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;
+extern void __gcov_init (struct gcov_info *);
/* GCOV exit function registered via a static destructor. */
-extern void __gcov_exit (void) ATTRIBUTE_HIDDEN;
+extern void __gcov_exit (void);
/* Function to reset all counters to 0. Both externally visible (and
overridable) and internal version. */
@@ -247,19 +247,19 @@ extern void __gcov_reset_int (void) ATTRIBUTE_HIDDEN;
extern void __gcov_dump_int (void) ATTRIBUTE_HIDDEN;
/* The merge function that just sums the counters. */
-extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+extern void __gcov_merge_add (gcov_type *, unsigned);
/* The merge function to select the minimum valid counter value. */
-extern void __gcov_merge_time_profile (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+extern void __gcov_merge_time_profile (gcov_type *, unsigned);
/* The merge function to choose the most common value. */
-extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+extern void __gcov_merge_single (gcov_type *, unsigned);
/* The merge function that just ors the counters together. */
-extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+extern void __gcov_merge_ior (gcov_type *, unsigned);
/* The merge function is used for topn indirect call counters. */
-extern void __gcov_merge_icall_topn (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
+extern void __gcov_merge_icall_topn (gcov_type *, unsigned);
/* The profiler functions. */
extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
@@ -277,18 +277,17 @@ extern void __gcov_average_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_ior_profiler (gcov_type *, gcov_type);
extern void __gcov_ior_profiler_atomic (gcov_type *, gcov_type);
extern void __gcov_indirect_call_topn_profiler (gcov_type, void *);
-extern void gcov_sort_n_vals (gcov_type *, int);
+extern void gcov_sort_n_vals (gcov_type *, int) ATTRIBUTE_HIDDEN;
#ifndef inhibit_libc
/* The wrappers around some library functions.. */
-extern pid_t __gcov_fork (void) ATTRIBUTE_HIDDEN;
-extern int __gcov_execl (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execlp (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execle (const char *, char *, ...) ATTRIBUTE_HIDDEN;
-extern int __gcov_execv (const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execvp (const char *, char *const []) ATTRIBUTE_HIDDEN;
-extern int __gcov_execve (const char *, char *const [], char *const [])
- ATTRIBUTE_HIDDEN;
+extern pid_t __gcov_fork (void);
+extern int __gcov_execl (const char *, char *, ...);
+extern int __gcov_execlp (const char *, char *, ...);
+extern int __gcov_execle (const char *, char *, ...);
+extern int __gcov_execv (const char *, char *const []);
+extern int __gcov_execvp (const char *, char *const []);
+extern int __gcov_execve (const char *, char *const [], char *const []);
/* Functions that only available in libgcov. */
GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
--
2.18.0