[PATCH libctf] Fix a number of build problems found on Solaris and NetBSD

Nick Alcock nick.alcock@oracle.com
Mon Jun 3 19:28:00 GMT 2019


On 3 Jun 2019, John Marshall verbalised:

> * just use the system qsort() with a global
> * code ctf-archive.c etc in terms of a xqsort_r() or so, that is the system qsort_r() if it has the expected signature or qsort_r.c's otherwise
> * ...or that also calls the macOS/BSD qsort_r() with a shim around the compare function to rearrange the arguments
> * play preprocessor games in ctf-archive.c etc so that compare functions have their parameters in the order the system qsort_r() (if any) expects

I'm doing the second, using AC_RUN_IFELSE to verify the order of
parameters, not just the existence of a declaration, and pulling in a
replacement if that fails.  (Unfortunately we have to use AC_RUN_IFELSE
because we cannot rely on prototype errors of this nature being fatal to
the compilation, and there is no portable way to make them fatal. So
we also fall back to the gnulib implementation when cross-compiling.)

Verified functional with the patch below on FreeBSD, mingw, Solaris, and
x86_64-pc-linux-gnu. (Just doing some other regtests before submitting.)

I cannot test MacOS X, I'm afraid, but it should work there too, since
it seems to have the same problem as FreeBSD.

>>> Incidentally, this warning seems accurate in saying this free() should be further down:
>>> ../../../binutils-gdb/libctf/ctf-dump.c:276:13: warning: variable 'bit' is uninitialized when used here
>> 
>> Will fix, of course. (I wonder why I haven't seen this warning with any
>> of the GCCs I've compiled it with...
>
> Despite the "gcc" command name, this warning came from Clang. Sometimes you get a useful warning from one compiler, sometimes from the other one... :-)

Aha, that explains it. I'll make sure to test-compile with clang, then.

Thanks for the heads-up. (And sorry for the delay: reviving my FreeBSD
installation took longer than I'd hoped.)

(Note: the patch below contains a file rename: use 'git apply' or 'git
am' to apply it, not patch(1).)


>From 0af8b01cb3c50f80b1d7a638c96316d33dac3530 Mon Sep 17 00:00:00 2001
From: Nick Alcock <nick.alcock@oracle.com>
Date: Mon, 3 Jun 2019 14:02:09 +0100
Subject: [PATCH] libctf: look for a qsort_r that functions properly

We cannot just look for any declaration of qsort_r, because some
operating systems have a qsort_r that has a different prototype
but which still has a pair of pointers in the right places (the last two
args are interchanged), so we cannot rely on compilation errors to flag
up a problem.

So, instead, use AC_RUN_IFELSE to check for the function of qsort_r(),
passing function pointers in to both args and making sure that we never
actually dereference the arg pointer.

This may still be problematic on systems with different representations
for function pointers and integer pointers, but even then we should get
the right result from configure (there just might be an ugly coredump
too).

(Now we are not using AC_LIBOBJ any more, we can use a better name for
the qsort_r replacement as well.)

libctf/
	* qsort_r.c: Rename to...
	* ctf-qsort_r.c: ... this.
	(_quicksort): Define to ctf_qsort_r.
	* ctf-decls.h (qsort_r): Remove.
	(ctf_qsort_r): Add.
	* Makefile.am (libctf_a_LIBADD): Remove.
	(libctf_a_SOURCES): New, add ctf-qsort_r.c.
	* ctf-archive.c (ctf_arc_write): Call ctf_qsort_r, not qsort_r.
	* ctf-create.c (ctf_update): Likewise.
	* configure.ac: Check for specific qsort_r that functions properly,
	not just for any declaration of it.
	* Makefile.in: Regenerate.
	* config.h.in: Likewise.
	* configure: Likewise.
---
 libctf/ChangeLog                    |  17 ++++
 libctf/Makefile.am                  |   4 +-
 libctf/Makefile.in                  |  29 ++++---
 libctf/config.h.in                  |   7 +-
 libctf/configure                    | 115 +++++++++++++++-------------
 libctf/configure.ac                 |  30 +++++++-
 libctf/ctf-archive.c                |   9 ++-
 libctf/ctf-create.c                 |   2 +-
 libctf/ctf-decls.h                  |  16 +++-
 libctf/{qsort_r.c => ctf-qsort_r.c} |   2 +-
 11 files changed, 152 insertions(+), 81 deletions(-)
 rename libctf/{qsort_r.c => ctf-qsort_r.c} (99%)

diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index d059d58d19..25ce9b3e61 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,20 @@
+2019-06-03  Nick Alcock  <nick.alcock@oracle.com>
+
+	* qsort_r.c: Rename to...
+	* ctf-qsort_r.c: ... this.
+	(_quicksort): Define to ctf_qsort_r.
+	* ctf-decls.h (qsort_r): Remove.
+	(ctf_qsort_r): Add.
+	* Makefile.am (libctf_a_LIBADD): Remove.
+	(libctf_a_SOURCES): New, add ctf-qsort_r.c.
+	* ctf-archive.c (ctf_arc_write): Call ctf_qsort_r, not qsort_r.
+	* ctf-create.c (ctf_update): Likewise.
+	* configure.ac: Check for specific qsort_r that functions properly,
+	not just for any declaration of it.
+	* Makefile.in: Regenerate.
+	* config.h.in: Likewise.
+	* configure: Likewise.
+
 2019-05-29  Nick Alcock  <nick.alcock@oracle.com>
 
 	* Makefile.am (ZLIB): New.
diff --git a/libctf/Makefile.am b/libctf/Makefile.am
index 49c9f5280a..926c9919c5 100644
--- a/libctf/Makefile.am
+++ b/libctf/Makefile.am
@@ -35,4 +35,6 @@ noinst_LIBRARIES = libctf.a
 libctf_a_SOURCES = ctf-archive.c ctf-dump.c ctf-create.c ctf-decl.c ctf-error.c \
 		   ctf-hash.c ctf-labels.c ctf-lookup.c ctf-open.c ctf-open-bfd.c \
 		   ctf-subr.c ctf-types.c ctf-util.c
-libctf_a_LIBADD = $(LIBOBJS)
+if NEED_CTF_QSORT_R
+libctf_a_SOURCES += ctf-qsort_r.c
+endif
diff --git a/libctf/Makefile.in b/libctf/Makefile.in
index c2cada6616..4fea156c44 100644
--- a/libctf/Makefile.in
+++ b/libctf/Makefile.in
@@ -104,6 +104,7 @@ POST_INSTALL = :
 NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
+@NEED_CTF_QSORT_R_TRUE@am__append_1 = ctf-qsort_r.c
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
@@ -128,12 +129,17 @@ am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
 am__v_AR_0 = @echo "  AR      " $@;
 am__v_AR_1 = 
 libctf_a_AR = $(AR) $(ARFLAGS)
-libctf_a_DEPENDENCIES = $(LIBOBJS)
+libctf_a_LIBADD =
+am__libctf_a_SOURCES_DIST = ctf-archive.c ctf-dump.c ctf-create.c \
+	ctf-decl.c ctf-error.c ctf-hash.c ctf-labels.c ctf-lookup.c \
+	ctf-open.c ctf-open-bfd.c ctf-subr.c ctf-types.c ctf-util.c \
+	ctf-qsort_r.c
+@NEED_CTF_QSORT_R_TRUE@am__objects_1 = ctf-qsort_r.$(OBJEXT)
 am_libctf_a_OBJECTS = ctf-archive.$(OBJEXT) ctf-dump.$(OBJEXT) \
 	ctf-create.$(OBJEXT) ctf-decl.$(OBJEXT) ctf-error.$(OBJEXT) \
 	ctf-hash.$(OBJEXT) ctf-labels.$(OBJEXT) ctf-lookup.$(OBJEXT) \
 	ctf-open.$(OBJEXT) ctf-open-bfd.$(OBJEXT) ctf-subr.$(OBJEXT) \
-	ctf-types.$(OBJEXT) ctf-util.$(OBJEXT)
+	ctf-types.$(OBJEXT) ctf-util.$(OBJEXT) $(am__objects_1)
 libctf_a_OBJECTS = $(am_libctf_a_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -164,7 +170,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(libctf_a_SOURCES)
-DIST_SOURCES = $(libctf_a_SOURCES)
+DIST_SOURCES = $(am__libctf_a_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -196,7 +202,7 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
 	$(top_srcdir)/../ar-lib $(top_srcdir)/../compile \
 	$(top_srcdir)/../depcomp $(top_srcdir)/../install-sh \
 	$(top_srcdir)/../missing $(top_srcdir)/../mkinstalldirs \
-	ChangeLog qsort_r.c
+	ChangeLog
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -323,11 +329,10 @@ ZLIBINC = @zlibinc@
 AM_CPPFLAGS = -D_GNU_SOURCE -I$(top_srcdir) -I$(top_srcdir)/../include -I$(top_srcdir)/../bfd -I../bfd
 AM_CFLAGS = -std=gnu99 @ac_libctf_warn_cflags@ @warn@ @c_warn@ @WARN_PEDANTIC@ @WERROR@ $(ZLIBINC)
 noinst_LIBRARIES = libctf.a
-libctf_a_SOURCES = ctf-archive.c ctf-dump.c ctf-create.c ctf-decl.c ctf-error.c \
-		   ctf-hash.c ctf-labels.c ctf-lookup.c ctf-open.c ctf-open-bfd.c \
-		   ctf-subr.c ctf-types.c ctf-util.c
-
-libctf_a_LIBADD = $(LIBOBJS)
+libctf_a_SOURCES = ctf-archive.c ctf-dump.c ctf-create.c ctf-decl.c \
+	ctf-error.c ctf-hash.c ctf-labels.c ctf-lookup.c ctf-open.c \
+	ctf-open-bfd.c ctf-subr.c ctf-types.c ctf-util.c \
+	$(am__append_1)
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -396,7 +401,6 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/qsort_r.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-archive.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-create.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-decl.Po@am__quote@
@@ -407,6 +411,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-lookup.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-open-bfd.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-open.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-qsort_r.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-subr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-types.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctf-util.Po@am__quote@
@@ -687,7 +692,7 @@ clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-	-rm -rf $(DEPDIR) ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
 	distclean-hdr distclean-tags
@@ -735,7 +740,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
 	-rm -rf $(top_srcdir)/autom4te.cache
-	-rm -rf $(DEPDIR) ./$(DEPDIR)
+	-rm -rf ./$(DEPDIR)
 	-rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-generic
 
diff --git a/libctf/config.h.in b/libctf/config.h.in
index 0ecb5bb721..dff5501609 100644
--- a/libctf/config.h.in
+++ b/libctf/config.h.in
@@ -9,10 +9,6 @@
 /* Define to 1 if you have the <byteswap.h> header file. */
 #undef HAVE_BYTESWAP_H
 
-/* Define to 1 if you have the declaration of `qsort_r', and to 0 if you
-   don't. */
-#undef HAVE_DECL_QSORT_R
-
 /* Define to 1 if you have the <endian.h> header file. */
 #undef HAVE_ENDIAN_H
 
@@ -31,6 +27,9 @@
 /* Define to 1 if you have the `pread' function. */
 #undef HAVE_PREAD
 
+/* Whether a qsort_r exists with a void *arg as its last arg. */
+#undef HAVE_QSORT_R_ARG_LAST
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
diff --git a/libctf/configure b/libctf/configure
index 4fb44eb2cc..c59e4c6abc 100755
--- a/libctf/configure
+++ b/libctf/configure
@@ -624,6 +624,8 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+NEED_CTF_QSORT_R_FALSE
+NEED_CTF_QSORT_R_TRUE
 zlibinc
 zlibdir
 ac_libctf_warn_cflags
@@ -1809,52 +1811,6 @@ $as_echo "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_func
-
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
-ac_fn_c_check_decl ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  as_decl_name=`echo $2|sed 's/ *(.*//'`
-  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-#ifndef $as_decl_name
-#ifdef __cplusplus
-  (void) $as_decl_use;
-#else
-  (void) $as_decl_name;
-#endif
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_decl
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -6401,16 +6357,65 @@ _ACEOF
 fi
 done
 
-ac_fn_c_check_decl "$LINENO" "qsort_r" "ac_cv_have_decl_qsort_r" "$ac_includes_default"
-if test "x$ac_cv_have_decl_qsort_r" = xyes; then :
-  ac_have_decl=1
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for qsort_r with arg last" >&5
+$as_echo_n "checking for qsort_r with arg last... " >&6; }
+if ${ac_cv_libctf_qsort_r_arg_last+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_libctf_qsort_r_arg_last=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+  int do_not_call (const void *a, const void *b, void *arg)
+  {
+    return (a < b);
+  }
+  static int works = 0;
+  int conftest_compar (const void *a, const void *b, void *arg)
+  {
+    if (arg == do_not_call)
+      works = 1;
+    return (a < b);
+  }
+  int foo[2] = { 0, 1 };
+int
+main ()
+{
+qsort_r (foo, 2, sizeof (int), conftest_compar, do_not_call);
+   return (works == 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_libctf_qsort_r_arg_last=yes
 else
-  ac_have_decl=0
+  ac_cv_libctf_qsort_r_arg_last=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libctf_qsort_r_arg_last" >&5
+$as_echo "$ac_cv_libctf_qsort_r_arg_last" >&6; }
+
+if test $ac_cv_libctf_qsort_r_arg_last = yes; then
+
+$as_echo "#define HAVE_QSORT_R_ARG_LAST 1" >>confdefs.h
+
+fi
+ if test "${ac_cv_libctf_qsort_r_arg_last}" != yes; then
+  NEED_CTF_QSORT_R_TRUE=
+  NEED_CTF_QSORT_R_FALSE='#'
+else
+  NEED_CTF_QSORT_R_TRUE='#'
+  NEED_CTF_QSORT_R_FALSE=
 fi
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_QSORT_R $ac_have_decl
-_ACEOF
 
 case " $LIBOBJS " in
   *" qsort_r.$ac_objext "* ) ;;
@@ -6561,6 +6566,10 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
+if test -z "${NEED_CTF_QSORT_R_TRUE}" && test -z "${NEED_CTF_QSORT_R_FALSE}"; then
+  as_fn_error $? "conditional \"NEED_CTF_QSORT_R\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 : "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
diff --git a/libctf/configure.ac b/libctf/configure.ac
index 8fd5388d2a..185aa94378 100644
--- a/libctf/configure.ac
+++ b/libctf/configure.ac
@@ -90,7 +90,35 @@ fi
 AC_C_BIGENDIAN
 AC_CHECK_HEADERS(byteswap.h endian.h)
 AC_CHECK_FUNCS(pread)
-AC_CHECK_DECLS([qsort_r])
+
+AC_CACHE_CHECK([for qsort_r with arg last], ac_cv_libctf_qsort_r_arg_last,
+[AC_RUN_IFELSE(
+  [AC_LANG_PROGRAM(
+  [#include <stdlib.h>
+  int do_not_call (const void *a, const void *b, void *arg)
+  {
+    return (a < b);
+  }
+  static int works = 0;
+  int conftest_compar (const void *a, const void *b, void *arg)
+  {
+    if (arg == do_not_call)
+      works = 1;
+    return (a < b);
+  }
+  int foo[[2]] = { 0, 1 };],
+  [qsort_r (foo, 2, sizeof (int), conftest_compar, do_not_call);
+   return (works == 0);])],
+  [ac_cv_libctf_qsort_r_arg_last=yes],
+  [ac_cv_libctf_qsort_r_arg_last=no],
+  [ac_cv_libctf_qsort_r_arg_last=no])])
+
+if test $ac_cv_libctf_qsort_r_arg_last = yes; then
+  AC_DEFINE([HAVE_QSORT_R_ARG_LAST], 1,
+	    [Whether a qsort_r exists with a void *arg as its last arg.])
+fi
+AM_CONDITIONAL(NEED_CTF_QSORT_R, test "${ac_cv_libctf_qsort_r_arg_last}" != yes)
+
 AC_LIBOBJ([qsort_r])
 
 AC_CONFIG_FILES(Makefile)
diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c
index a238edb66b..90cd020b78 100644
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -169,10 +169,11 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt,
       modent++;
     }
 
-  qsort_r ((ctf_archive_modent_t *) ((char *) archdr
-				     + sizeof (struct ctf_archive)),
-	   le64toh (archdr->ctfa_nfiles),
-	   sizeof (struct ctf_archive_modent), sort_modent_by_name, nametbl);
+  ctf_qsort_r ((ctf_archive_modent_t *) ((char *) archdr
+					 + sizeof (struct ctf_archive)),
+	       le64toh (archdr->ctfa_nfiles),
+	       sizeof (struct ctf_archive_modent), sort_modent_by_name,
+	       nametbl);
 
    /* Now the name table.  */
 
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c
index 227f62d8fd..3beed88712 100644
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -344,7 +344,7 @@ ctf_update (ctf_file_t *fp)
     }
   assert (i == nvars);
 
-  qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var, s0);
+  ctf_qsort_r (dvarents, nvars, sizeof (ctf_varent_t), ctf_sort_var, s0);
   t += sizeof (ctf_varent_t) * nvars;
 
   assert (t == (unsigned char *) buf + sizeof (ctf_header_t) + hdr.cth_typeoff);
diff --git a/libctf/ctf-decls.h b/libctf/ctf-decls.h
index 5e9ede4809..1f8aab11e4 100644
--- a/libctf/ctf-decls.h
+++ b/libctf/ctf-decls.h
@@ -22,12 +22,22 @@
 
 #include "config.h"
 
-#if !HAVE_DECL_QSORT_R
 #include <stddef.h>
-void qsort_r (void *base, size_t nmemb, size_t size,
+#if HAVE_QSORT_R_ARG_LAST
+#include <stdlib.h>
+
+inline void
+ctf_qsort_r (void *base, size_t nmemb, size_t size,
+	     int (*compar)(const void *, const void *, void *),
+	     void *arg)
+{
+  qsort_r (base, nmemb, size, compar, arg);
+}
+#else
+void ctf_qsort_r (void *base, size_t nmemb, size_t size,
 	      int (*compar)(const void *, const void *, void *),
 	      void *arg);
-#endif /* !HAVE_DECL_QSORT_R */
+#endif /* !HAVE_QSORT_R_ARG_LAST */
 
 #undef MAX
 #undef MIN
diff --git a/libctf/qsort_r.c b/libctf/ctf-qsort_r.c
similarity index 99%
rename from libctf/qsort_r.c
rename to libctf/ctf-qsort_r.c
index 6c334fdaf3..6cb221d6f5 100644
--- a/libctf/qsort_r.c
+++ b/libctf/ctf-qsort_r.c
@@ -30,7 +30,7 @@
 #include "ctf-decls.h"
 
 #ifndef _LIBC
-# define _quicksort qsort_r
+# define _quicksort ctf_qsort_r
 # define __compar_d_fn_t compar_d_fn_t
 typedef int (*compar_d_fn_t) (const void *, const void *, void *);
 #endif
-- 
2.21.0.237.gd0cfaa883d



More information about the Binutils mailing list