This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR59063


This patch is supposed to fix PR59063 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59063).

The original bug results from libasan providing clock_gettime wrapper and then trying to call the "real" clock_gettime. The "real" symbol is supposed to come from librt.so which was not necessarily linked to executable. The net result is a NULL call.

Patch is based on Evgeniy Stepanov's and Jakub's suggestions in bugzilla discussion. It instructs frontend to add -lrt on static Asan compilation and also links dynamic libasan.so against librt.so.

This was tested against gcc asan testsuite on x86_64.

-Y

diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index 6f69158..d13c21c 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -129,7 +129,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 /* Additional libraries needed by -static-libasan.  */
 #undef STATIC_LIBASAN_LIBS
-#define STATIC_LIBASAN_LIBS "-ldl -lpthread"
+#define STATIC_LIBASAN_LIBS "-ldl -lpthread -lrt"
 
 /* Additional libraries needed by -static-libtsan.  */
 #undef STATIC_LIBTSAN_LIBS
diff --git a/gcc/testsuite/c-c++-common/asan/pr59063-1.c b/gcc/testsuite/c-c++-common/asan/pr59063-1.c
new file mode 100644
index 0000000..a4e01f7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr59063-1.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+
+#include <time.h>
+static int weak_gettime (clockid_t clk_id, struct timespec *tp)
+  __attribute__((__weakref__("clock_gettime")));
+int main() {
+  if (!clock_gettime)
+    return 0;
+  struct timespec ts;
+  return weak_gettime(CLOCK_MONOTONIC, &ts);
+}
diff --git a/gcc/testsuite/c-c++-common/asan/pr59063-2.c b/gcc/testsuite/c-c++-common/asan/pr59063-2.c
new file mode 100644
index 0000000..c94ffef
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr59063-2.c
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+/* { dg-options "-static-libasan -lstdc++" } */
+
+#include <time.h>
+static int weak_gettime (clockid_t clk_id, struct timespec *tp)
+  __attribute__((__weakref__("clock_gettime")));
+int main() {
+  if (!clock_gettime)
+    return 0;
+  struct timespec ts;
+  return weak_gettime(CLOCK_MONOTONIC, &ts);
+}
diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in
index 47a8771..f342094 100644
--- a/libsanitizer/Makefile.in
+++ b/libsanitizer/Makefile.in
@@ -80,6 +80,7 @@ DIST_SUBDIRS = interception sanitizer_common lsan asan ubsan tsan
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
+ASAN_LIBS = @ASAN_LIBS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am
index 8764007..25cfd3a 100644
--- a/libsanitizer/asan/Makefile.am
+++ b/libsanitizer/asan/Makefile.am
@@ -43,7 +43,7 @@ libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(to
 endif
 libasan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
 
-libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl $(ASAN_LIBS)
 
 libasan_preinit.o: asan_preinit.o
 	cp $< $@
diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in
index be8b879..d52711e 100644
--- a/libsanitizer/asan/Makefile.in
+++ b/libsanitizer/asan/Makefile.in
@@ -118,6 +118,7 @@ CTAGS = ctags
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
+ASAN_LIBS = @ASAN_LIBS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
@@ -289,7 +290,7 @@ libasan_la_SOURCES = $(asan_files)
 @USING_MAC_INTERPOSE_TRUE@libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la \
 @USING_MAC_INTERPOSE_TRUE@	$(top_builddir)/lsan/libsanitizer_lsan.la \
 @USING_MAC_INTERPOSE_TRUE@	$(LIBSTDCXX_RAW_CXX_LDFLAGS)
-libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl $(ASAN_LIBS)
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
 # values defined in terms of make variables, as is the case for CC and
diff --git a/libsanitizer/configure b/libsanitizer/configure
index 5e425d1..41a84a3 100755
--- a/libsanitizer/configure
+++ b/libsanitizer/configure
@@ -604,6 +604,7 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+ASAN_LIBS
 USING_MAC_INTERPOSE_FALSE
 USING_MAC_INTERPOSE_TRUE
 TSAN_SUPPORTED_FALSE
@@ -11117,7 +11118,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11120 "configure"
+#line 11121 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11223,7 +11224,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11226 "configure"
+#line 11227 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14546,6 +14547,69 @@ else
 fi
 
 
+# Check for functions needed.
+for ac_func in clock_getres clock_gettime clock_settime
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+# At least for glibc, clock_gettime is in librt.  But don't pull that
+# in if it still doesn't give us the function we want.  This
+# test is copied from libgomp.
+if test $ac_cv_func_clock_gettime = no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5
+$as_echo_n "checking for clock_gettime in -lrt... " >&6; }
+if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_rt_clock_gettime=yes
+else
+  ac_cv_lib_rt_clock_gettime=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5
+$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; }
+if test "x$ac_cv_lib_rt_clock_gettime" = x""yes; then :
+  ASAN_LIBS="-lrt $ASAN_LIBS"
+fi
+
+fi
+
 ac_config_files="$ac_config_files Makefile"
 
 
diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac
index 0b2d813..61976cd 100644
--- a/libsanitizer/configure.ac
+++ b/libsanitizer/configure.ac
@@ -87,6 +87,19 @@ case "$host" in
 esac
 AM_CONDITIONAL(USING_MAC_INTERPOSE, $MAC_INTERPOSE)
 
+# Check for functions needed.
+AC_CHECK_FUNCS(clock_getres clock_gettime clock_settime)
+
+AC_SUBST(ASAN_LIBS)
+
+# At least for glibc, clock_gettime is in librt.  But don't pull that
+# in if it still doesn't give us the function we want.  This
+# test is copied from libgomp.
+if test $ac_cv_func_clock_gettime = no; then
+  AC_CHECK_LIB(rt, clock_gettime,
+    [ASAN_LIBS="-lrt $ASAN_LIBS"])
+fi
+
 AC_CONFIG_FILES([Makefile])
 
 AC_CONFIG_FILES(AC_FOREACH([DIR], [interception sanitizer_common lsan asan ubsan], [DIR/Makefile ]),
diff --git a/libsanitizer/interception/Makefile.in b/libsanitizer/interception/Makefile.in
index 59b9a9a..f3da716 100644
--- a/libsanitizer/interception/Makefile.in
+++ b/libsanitizer/interception/Makefile.in
@@ -78,6 +78,7 @@ CTAGS = ctags
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
+ASAN_LIBS = @ASAN_LIBS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in
index e01f65b..48cf3d9 100644
--- a/libsanitizer/lsan/Makefile.in
+++ b/libsanitizer/lsan/Makefile.in
@@ -77,6 +77,7 @@ CTAGS = ctags
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
+ASAN_LIBS = @ASAN_LIBS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in
index 68c9849..f6f532f 100644
--- a/libsanitizer/sanitizer_common/Makefile.in
+++ b/libsanitizer/sanitizer_common/Makefile.in
@@ -89,6 +89,7 @@ CTAGS = ctags
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
+ASAN_LIBS = @ASAN_LIBS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in
index 95a88b2..9ebb97a 100644
--- a/libsanitizer/tsan/Makefile.in
+++ b/libsanitizer/tsan/Makefile.in
@@ -128,6 +128,7 @@ CTAGS = ctags
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
+ASAN_LIBS = @ASAN_LIBS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in
index 6812538..81a81e2 100644
--- a/libsanitizer/ubsan/Makefile.in
+++ b/libsanitizer/ubsan/Makefile.in
@@ -107,6 +107,7 @@ CTAGS = ctags
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AR = @AR@
+ASAN_LIBS = @ASAN_LIBS@
 AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@


Attachment: gcc_Changelog.add.txt
Description: Text document

Attachment: gcc_testsuite_Changelog.add.txt
Description: Text document

Attachment: libsanitizer_Changelog.add.txt
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]