public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 4/4] libctf: work on platforms without O_CLOEXEC.
  2019-06-04 15:25 [PATCH v2 0/4] More portability fixes Nick Alcock
  2019-06-04 15:24 ` [PATCH v2 3/4] libctf: look for BSD versus GNU qsort_r signatures Nick Alcock
@ 2019-06-04 15:24 ` Nick Alcock
  2019-06-04 15:24 ` [PATCH 2/4] libctf: fix use-after-free in function dumping Nick Alcock
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-04 15:24 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber, nickc

(Not tested on any such platforms, since I don't have access to any at
the moment.  Testing encouraged.)

libctf/
	* configure.ac: Check for O_CLOEXEC.
	* ctf-decls.h (O_CLOEXEC): Define (to 0), if need be.
	* config.h.in: Regenerate.
---
 libctf/ChangeLog    |  7 +++++++
 libctf/config.h.in  |  3 +++
 libctf/configure    | 37 +++++++++++++++++++++++++++++++++++++
 libctf/configure.ac | 16 ++++++++++++++++
 libctf/ctf-decls.h  |  4 ++++
 5 files changed, 67 insertions(+)

diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index c51efea8bc..52c2e1e8fc 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,10 @@
+2019-06-04  Nick Alcock  <nick.alcock@oracle.com>
+
+	* configure.ac: Check for O_CLOEXEC.
+	* ctf-decls.h (O_CLOEXEC): Define (to 0), if need be.
+	* config.h.in: Regenerate.
+	* configure: Likewise.
+
 2019-06-04  Nick Alcock  <nick.alcock@oracle.com>
 
 	* qsort_r.c: Rename to...
diff --git a/libctf/config.h.in b/libctf/config.h.in
index d81c500c5c..3f45cd6d74 100644
--- a/libctf/config.h.in
+++ b/libctf/config.h.in
@@ -24,6 +24,9 @@
 /* Define to 1 if you have a working `mmap' system call. */
 #undef HAVE_MMAP
 
+/* Whether the platform has a definition of O_CLOEXEC. */
+#undef HAVE_O_CLOEXEC
+
 /* Define to 1 if you have the `pread' function. */
 #undef HAVE_PREAD
 
diff --git a/libctf/configure b/libctf/configure
index d485b1a7ce..31f166779e 100755
--- a/libctf/configure
+++ b/libctf/configure
@@ -6462,6 +6462,43 @@ else
 fi
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for O_CLOEXEC" >&5
+$as_echo_n "checking for O_CLOEXEC... " >&6; }
+if ${ac_cv_libctf_macro_O_CLOEXEC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <fcntl.h>
+                       #ifndef O_CLOEXEC
+                         choke me;
+                       #endif
+
+int
+main ()
+{
+return O_CLOEXEC;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_libctf_macro_O_CLOEXEC=yes
+else
+  ac_cv_libctf_macro_O_CLOEXEC=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libctf_macro_O_CLOEXEC" >&5
+$as_echo "$ac_cv_libctf_macro_O_CLOEXEC" >&6; }
+
+if test $ac_cv_libctf_macro_O_CLOEXEC = yes; then
+
+$as_echo "#define HAVE_O_CLOEXEC 1" >>confdefs.h
+
+fi
+
 ac_config_files="$ac_config_files Makefile"
 
 ac_config_headers="$ac_config_headers config.h"
diff --git a/libctf/configure.ac b/libctf/configure.ac
index beb90ba75c..2a1a80b7ec 100644
--- a/libctf/configure.ac
+++ b/libctf/configure.ac
@@ -133,6 +133,22 @@ esac
 
 AM_CONDITIONAL(NEED_CTF_QSORT_R, test "${ac_cv_libctf_qsort_r_signature}" = unknown)
 
+AC_CACHE_CHECK([for O_CLOEXEC], [ac_cv_libctf_macro_O_CLOEXEC],
+  [AC_LINK_IFELSE(
+    [AC_LANG_PROGRAM([[#include <fcntl.h>
+                       #ifndef O_CLOEXEC
+                         choke me;
+                       #endif
+                     ]],
+                     [[return O_CLOEXEC;]])],
+    [ac_cv_libctf_macro_O_CLOEXEC=yes],
+    [ac_cv_libctf_macro_O_CLOEXEC=no])])
+
+if test $ac_cv_libctf_macro_O_CLOEXEC = yes; then
+  AC_DEFINE([HAVE_O_CLOEXEC], 1,
+	    [Whether the platform has a definition of O_CLOEXEC.])
+fi
+
 AC_CONFIG_FILES(Makefile)
 AC_CONFIG_HEADERS(config.h)
 AC_OUTPUT
diff --git a/libctf/ctf-decls.h b/libctf/ctf-decls.h
index d12409e4b6..c840b793c9 100644
--- a/libctf/ctf-decls.h
+++ b/libctf/ctf-decls.h
@@ -62,6 +62,10 @@ void ctf_qsort_r (void *base, size_t nmemb, size_t size,
 	      void *arg);
 #endif
 
+#ifndef HAVE_O_CLOEXEC
+# define O_CLOEXEC 0
+#endif
+
 #undef MAX
 #undef MIN
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
-- 
2.21.0.237.gd0cfaa883d

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 3/4] libctf: look for BSD versus GNU qsort_r signatures
  2019-06-04 15:25 [PATCH v2 0/4] More portability fixes Nick Alcock
@ 2019-06-04 15:24 ` Nick Alcock
  2019-06-04 15:24 ` [PATCH v2 4/4] libctf: work on platforms without O_CLOEXEC Nick Alcock
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-04 15:24 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber, nickc

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 use AC_LINK_IFELSE to check for both
known variants of qsort_r(), and swap their args into a consistent order
in a suitable inline function.  (The code for this is taken almost
unchanged from gnulib.)

(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.
	(struct ctf_qsort_arg): New, transport the real ARG and COMPAR.
	(ctf_qsort_compar_thunk): Rearrange the arguments to COMPAR.
	* 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 BSD versus GNU qsort_r signature.
	* Makefile.in: Regenerate.
	* config.h.in: Likewise.
	* configure: Likewise.
---
 libctf/ChangeLog                    |  18 ++++
 libctf/Makefile.am                  |   4 +-
 libctf/Makefile.in                  |  29 ++---
 libctf/config.h.in                  |  13 ++-
 libctf/configure                    | 161 ++++++++++++++++++----------
 libctf/configure.ac                 |  44 +++++++-
 libctf/ctf-archive.c                |   9 +-
 libctf/ctf-create.c                 |   2 +-
 libctf/ctf-decls.h                  |  39 ++++++-
 libctf/{qsort_r.c => ctf-qsort_r.c} |   2 +-
 10 files changed, 236 insertions(+), 85 deletions(-)
 rename libctf/{qsort_r.c => ctf-qsort_r.c} (99%)

diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index 01b8d8da24..c51efea8bc 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,21 @@
+2019-06-04  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.
+	(struct ctf_qsort_arg): New, transport the real ARG and COMPAR.
+	(ctf_qsort_compar_thunk): Rearrange the arguments to COMPAR.
+	* 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 BSD versus GNU qsort_r signature.
+	* Makefile.in: Regenerate.
+	* config.h.in: Likewise.
+	* configure: Likewise.
+
 2019-06-03  Nick Alcock  <nick.alcock@oracle.com>
 
 	* ctf-dump.c (ctf_dump_funcs): Free in the right place.
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..d81c500c5c 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,15 @@
 /* Define to 1 if you have the `pread' function. */
 #undef HAVE_PREAD
 
+/* Define to 1 if you have the `qsort_r' function. */
+#undef HAVE_QSORT_R
+
+/* Whether a qsort_r exists with a void *arg as its last arg. */
+#undef HAVE_QSORT_R_ARG_LAST
+
+/* Whether a qsort_r exists with the compar function as its last arg. */
+#undef HAVE_QSORT_R_COMPAR_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..d485b1a7ce 100755
--- a/libctf/configure
+++ b/libctf/configure
@@ -620,10 +620,13 @@ ac_includes_default="\
 #endif"
 
 ac_header_list=
+ac_func_list=
 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 +1812,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.
@@ -2142,6 +2099,7 @@ fi
 as_fn_append ac_header_list " stdlib.h"
 as_fn_append ac_header_list " unistd.h"
 as_fn_append ac_header_list " sys/param.h"
+as_fn_append ac_func_list " qsort_r"
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
@@ -6401,23 +6359,108 @@ _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
-else
-  ac_have_decl=0
+
+
+
+
+  for ac_func in $ac_func_list
+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"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
 fi
+done
 
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_QSORT_R $ac_have_decl
+
+
+
+if test $ac_cv_func_qsort_r = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for qsort_r signature" >&5
+$as_echo_n "checking for qsort_r signature... " >&6; }
+if ${ac_cv_libctf_qsort_r_signature+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#undef qsort_r
+                          #include <stdlib.h>
+                          void qsort_r (void *, size_t, size_t,
+                                        int (*) (void const *, void const *,
+                                                 void *),
+                                        void *);
+                          void (*p) (void *, size_t, size_t,
+                                     int (*) (void const *, void const *,
+                                              void *),
+                                     void *) = qsort_r;
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_libctf_qsort_r_signature=GNU
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#undef qsort_r
+	                     #include <stdlib.h>
+                             void qsort_r (void *, size_t, size_t, void *,
+                                           int (*) (void *,
+                                                    void const *,
+                                                    void const *));
+                             void (*p) (void *, size_t, size_t, void *,
+                                        int (*) (void *, void const *,
+                                                 void const *)) = qsort_r;
 
-case " $LIBOBJS " in
-  *" qsort_r.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS qsort_r.$ac_objext"
- ;;
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_libctf_qsort_r_signature=BSD
+else
+  ac_cv_libctf_qsort_r_signature=unknown
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libctf_qsort_r_signature" >&5
+$as_echo "$ac_cv_libctf_qsort_r_signature" >&6; }
+fi
+
+case x$ac_cv_libctf_qsort_r_signature in
+  xGNU)
+$as_echo "#define HAVE_QSORT_R_ARG_LAST 1" >>confdefs.h
+;;
+  xBSD)
+$as_echo "#define HAVE_QSORT_R_COMPAR_LAST 1" >>confdefs.h
+;;
+  *) ac_cv_libctf_qsort_r_signature=unknown;;
 esac
 
+ if test "${ac_cv_libctf_qsort_r_signature}" = unknown; then
+  NEED_CTF_QSORT_R_TRUE=
+  NEED_CTF_QSORT_R_FALSE='#'
+else
+  NEED_CTF_QSORT_R_TRUE='#'
+  NEED_CTF_QSORT_R_FALSE=
+fi
+
 
 ac_config_files="$ac_config_files Makefile"
 
@@ -6561,6 +6604,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..beb90ba75c 100644
--- a/libctf/configure.ac
+++ b/libctf/configure.ac
@@ -90,8 +90,48 @@ fi
 AC_C_BIGENDIAN
 AC_CHECK_HEADERS(byteswap.h endian.h)
 AC_CHECK_FUNCS(pread)
-AC_CHECK_DECLS([qsort_r])
-AC_LIBOBJ([qsort_r])
+
+dnl Check for qsort_r.  (Taken from gnulib.)
+AC_CHECK_FUNCS_ONCE([qsort_r])
+if test $ac_cv_func_qsort_r = yes; then
+  AC_CACHE_CHECK([for qsort_r signature], [ac_cv_libctf_qsort_r_signature],
+    [AC_LINK_IFELSE(
+       [AC_LANG_PROGRAM([[#undef qsort_r
+                          #include <stdlib.h>
+                          void qsort_r (void *, size_t, size_t,
+                                        int (*) (void const *, void const *,
+                                                 void *),
+                                        void *);
+                          void (*p) (void *, size_t, size_t,
+                                     int (*) (void const *, void const *,
+                                              void *),
+                                     void *) = qsort_r;
+                        ]])],
+       [ac_cv_libctf_qsort_r_signature=GNU],
+       [AC_LINK_IFELSE(
+          [AC_LANG_PROGRAM([[#undef qsort_r
+	                     #include <stdlib.h>
+                             void qsort_r (void *, size_t, size_t, void *,
+                                           int (*) (void *,
+                                                    void const *,
+                                                    void const *));
+                             void (*p) (void *, size_t, size_t, void *,
+                                        int (*) (void *, void const *,
+                                                 void const *)) = qsort_r;
+                           ]])],
+          [ac_cv_libctf_qsort_r_signature=BSD],
+          [ac_cv_libctf_qsort_r_signature=unknown])])])
+fi
+
+case x$ac_cv_libctf_qsort_r_signature in
+  xGNU)     AC_DEFINE([HAVE_QSORT_R_ARG_LAST], 1,
+	     [Whether a qsort_r exists with a void *arg as its last arg.]);;
+  xBSD)     AC_DEFINE([HAVE_QSORT_R_COMPAR_LAST], 1,
+	     [Whether a qsort_r exists with the compar function as its last arg.]);;
+  *) ac_cv_libctf_qsort_r_signature=unknown;;
+esac
+
+AM_CONDITIONAL(NEED_CTF_QSORT_R, test "${ac_cv_libctf_qsort_r_signature}" = unknown)
 
 AC_CONFIG_FILES(Makefile)
 AC_CONFIG_HEADERS(config.h)
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..d12409e4b6 100644
--- a/libctf/ctf-decls.h
+++ b/libctf/ctf-decls.h
@@ -22,12 +22,45 @@
 
 #include "config.h"
 
-#if !HAVE_DECL_QSORT_R
 #include <stddef.h>
-void qsort_r (void *base, size_t nmemb, size_t size,
+#include <stdlib.h>
+
+#if HAVE_QSORT_R_ARG_LAST
+static 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);
+}
+#elif HAVE_QSORT_R_COMPAR_LAST
+struct ctf_qsort_arg
+{
+  int (*compar) (const void *, const void *, void *);
+  void *arg;
+};
+
+static int
+ctf_qsort_compar_thunk (void *arg, const void *a, const void *b)
+{
+  struct ctf_qsort_arg *qsort_arg = (struct ctf_qsort_arg *) arg;
+
+  return qsort_arg->compar (a, b, arg);
+}
+
+static inline void
+ctf_qsort_r (void *base, size_t nmemb, size_t size,
+	     int (*compar)(const void *, const void *, void *),
+	     void *arg)
+{
+  struct ctf_qsort_arg thunk = { compar, arg };
+  qsort_r (base, nmemb, size, &thunk, ctf_qsort_compar_thunk);
+}
+#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
 
 #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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/4] libctf: fix use-after-free in function dumping
  2019-06-04 15:25 [PATCH v2 0/4] More portability fixes Nick Alcock
  2019-06-04 15:24 ` [PATCH v2 3/4] libctf: look for BSD versus GNU qsort_r signatures Nick Alcock
  2019-06-04 15:24 ` [PATCH v2 4/4] libctf: work on platforms without O_CLOEXEC Nick Alcock
@ 2019-06-04 15:24 ` Nick Alcock
  2019-06-04 15:27 ` [PATCH 1/4] libctf: fix the type of ctf_enum.cte_value Nick Alcock
  2019-06-04 16:15 ` [PATCH v2 0/4] More portability fixes Jose E. Marchesi
  4 siblings, 0 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-04 15:24 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber, nickc

This is actually a free-before-initializing (i.e. a free of garbage).

libctf/
	* ctf-dump.c (ctf_dump_funcs): Free in the right place.
---
 libctf/ChangeLog  | 4 ++++
 libctf/ctf-dump.c | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index d059d58d19..01b8d8da24 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,3 +1,7 @@
+2019-06-03  Nick Alcock  <nick.alcock@oracle.com>
+
+	* ctf-dump.c (ctf_dump_funcs): Free in the right place.
+
 2019-05-29  Nick Alcock  <nick.alcock@oracle.com>
 
 	* Makefile.am (ZLIB): New.
diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c
index c2ed791eea..82f63c29d0 100644
--- a/libctf/ctf-dump.c
+++ b/libctf/ctf-dump.c
@@ -273,7 +273,6 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state)
 	goto err;
 
       str = ctf_str_append (str, " ");
-      free (bit);
 
       /* Function name.  */
 
@@ -290,6 +289,7 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state)
 	}
       str = ctf_str_append (str, bit);
       str = ctf_str_append (str, " (");
+      free (bit);
 
       /* Function arguments.  */
 
-- 
2.21.0.237.gd0cfaa883d

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 0/4] More portability fixes
@ 2019-06-04 15:25 Nick Alcock
  2019-06-04 15:24 ` [PATCH v2 3/4] libctf: look for BSD versus GNU qsort_r signatures Nick Alcock
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-04 15:25 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber, nickc

This also fixes a use-after-free (well, free-before-initialization)
and a bug that leads to an accidentally different file format on
platforms where int is not 32 bits wide.

The last two patches are new or changed in this version. (Unchanged
patches are not denoted v2.)

Nick Alcock (4):
  libctf: fix the type of ctf_enum.cte_value
  libctf: fix use-after-free in function dumping
  libctf: look for BSD versus GNU qsort_r signatures
  libctf: work on platforms without O_CLOEXEC.

 include/ChangeLog                   |   4 +
 include/ctf.h                       |   2 +-
 libctf/ChangeLog                    |  29 ++++
 libctf/Makefile.am                  |   4 +-
 libctf/Makefile.in                  |  29 ++--
 libctf/config.h.in                  |  16 ++-
 libctf/configure                    | 198 ++++++++++++++++++++--------
 libctf/configure.ac                 |  60 ++++++++-
 libctf/ctf-archive.c                |   9 +-
 libctf/ctf-create.c                 |   2 +-
 libctf/ctf-decls.h                  |  43 +++++-
 libctf/ctf-dump.c                   |   2 +-
 libctf/{qsort_r.c => ctf-qsort_r.c} |   2 +-
 13 files changed, 313 insertions(+), 87 deletions(-)
 rename libctf/{qsort_r.c => ctf-qsort_r.c} (99%)

-- 
2.21.0.237.gd0cfaa883d

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] libctf: fix the type of ctf_enum.cte_value
  2019-06-04 15:25 [PATCH v2 0/4] More portability fixes Nick Alcock
                   ` (2 preceding siblings ...)
  2019-06-04 15:24 ` [PATCH 2/4] libctf: fix use-after-free in function dumping Nick Alcock
@ 2019-06-04 15:27 ` Nick Alcock
  2019-06-04 16:15 ` [PATCH v2 0/4] More portability fixes Jose E. Marchesi
  4 siblings, 0 replies; 7+ messages in thread
From: Nick Alcock @ 2019-06-04 15:27 UTC (permalink / raw)
  To: binutils; +Cc: jose.marchesi, John.W.Marshall, sebastian.huber, nickc

This stops the file format from depending on the size of the host int.
(It does mean that we cannot encode enums with a value > 2^32 on
platforms with an int > 2^32: this will be fixed in the next format
revision.)

include/
	* ctf.h (ctf_enum.cte_value): Fix type to int32_t.
---
 include/ChangeLog | 4 ++++
 include/ctf.h     | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/ChangeLog b/include/ChangeLog
index 1f216b3821..f84498b590 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2019-06-03  Nick Alcock  <nick.alcock@oracle.com>
+
+	* ctf.h (ctf_enum.cte_value): Fix type to int32_t.
+
 2019-05-29  Nick Alcock  <nick.alcock@oracle.com>
 
 	* ctf-api.h (ctf_sect_t): Drop cts_type, cts_flags, and cts_offset.
diff --git a/include/ctf.h b/include/ctf.h
index 2c3384fe84..e99a673109 100644
--- a/include/ctf.h
+++ b/include/ctf.h
@@ -507,7 +507,7 @@ typedef struct ctf_lmember_v2
 typedef struct ctf_enum
 {
   uint32_t cte_name;		/* Reference to name in string table.  */
-  int cte_value;		/* Value associated with this name.  */
+  int32_t cte_value;		/* Value associated with this name.  */
 } ctf_enum_t;
 
 /* The ctf_archive is a collection of ctf_file_t's stored together. The format
-- 
2.21.0.237.gd0cfaa883d

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/4] More portability fixes
  2019-06-04 15:25 [PATCH v2 0/4] More portability fixes Nick Alcock
                   ` (3 preceding siblings ...)
  2019-06-04 15:27 ` [PATCH 1/4] libctf: fix the type of ctf_enum.cte_value Nick Alcock
@ 2019-06-04 16:15 ` Jose E. Marchesi
  2019-06-05 10:28   ` Sebastian Huber
  4 siblings, 1 reply; 7+ messages in thread
From: Jose E. Marchesi @ 2019-06-04 16:15 UTC (permalink / raw)
  To: Nick Alcock; +Cc: binutils, John.W.Marshall, sebastian.huber, nickc


Hi Nick.

    This also fixes a use-after-free (well, free-before-initialization)
    and a bug that leads to an accidentally different file format on
    platforms where int is not 32 bits wide.
    
    The last two patches are new or changed in this version. (Unchanged
    patches are not denoted v2.)

I just pushed these fixes on your behalf.
Salud!

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 0/4] More portability fixes
  2019-06-04 16:15 ` [PATCH v2 0/4] More portability fixes Jose E. Marchesi
@ 2019-06-05 10:28   ` Sebastian Huber
  0 siblings, 0 replies; 7+ messages in thread
From: Sebastian Huber @ 2019-06-05 10:28 UTC (permalink / raw)
  To: Jose E. Marchesi, Nick Alcock; +Cc: binutils, John.W.Marshall, nickc

Hello,

thanks for the fixes. I can now build cross Binutils again on FreeBSD 12 
for several *-rtems5 targets.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-06-05 10:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-04 15:25 [PATCH v2 0/4] More portability fixes Nick Alcock
2019-06-04 15:24 ` [PATCH v2 3/4] libctf: look for BSD versus GNU qsort_r signatures Nick Alcock
2019-06-04 15:24 ` [PATCH v2 4/4] libctf: work on platforms without O_CLOEXEC Nick Alcock
2019-06-04 15:24 ` [PATCH 2/4] libctf: fix use-after-free in function dumping Nick Alcock
2019-06-04 15:27 ` [PATCH 1/4] libctf: fix the type of ctf_enum.cte_value Nick Alcock
2019-06-04 16:15 ` [PATCH v2 0/4] More portability fixes Jose E. Marchesi
2019-06-05 10:28   ` Sebastian Huber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).