From patchwork Wed May 29 16:33:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Alcock X-Patchwork-Id: 32902 Received: (qmail 113968 invoked by alias); 29 May 2019 16:33:48 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 113781 invoked by uid 89); 29 May 2019 16:33:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, SPF_HELO_PASS, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 spammy=Vol, Experience X-HELO: aserp2130.oracle.com Received: from aserp2130.oracle.com (HELO aserp2130.oracle.com) (141.146.126.79) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 29 May 2019 16:33:38 +0000 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x4TGT7IT156517; Wed, 29 May 2019 16:33:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : references : date : in-reply-to : message-id : mime-version : content-type; s=corp-2018-07-02; bh=VqLhaNn4VHu7y024D7856NBBIWbR3IDvkSjYHpTQJ0A=; b=vJAj0rZ86MxuMxGpfBdmBRjOZ7UUh9fPxN734nAo8Cyx5ZeOnl8TjVHfRR62Yt5SKdCz zRGGRgoPAt2zQ3Q5OeTONDDGimDKMIWdRdoRto+B6IpZH1lER4rrBmSFX4bDj1tDBoBw NKVxmJ1KTluHDVZqFc4RXfgy5Dr+YQ0CONr5KGUK7BJa2FWDTTrWilwRLnu6W0ORQdli fzCOBD1B/2QVJKzR3XP+sZl3a9XoS2gNbLp05xWNVpQJepRZwom45gSQeetZJ1f9d9VM IN5GbbFrEy4q6KdUx06+UtwBap85irGERD/WEXK+zwPzFcA2Hh1pWcG6sR9SnbOK+rTB qg== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by aserp2130.oracle.com with ESMTP id 2spu7dkaf1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 29 May 2019 16:33:29 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x4TGWk5d125813; Wed, 29 May 2019 16:33:28 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userp3020.oracle.com with ESMTP id 2sr31vcbk7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 29 May 2019 16:33:28 +0000 Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x4TGXGav027326; Wed, 29 May 2019 16:33:16 GMT Received: from loom (/81.187.191.129) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 29 May 2019 09:33:14 -0700 From: Nick Alcock To: Rainer Orth Cc: Simon Marchi , gdb-buildbot@sergiodj.net, gdb-patches@sourceware.org, binutils@sourceware.org Subject: [PATCH] Fix a number of build problems found on Solaris and NetBSD (was Re: Oh dear. I regret to inform you that commit 0e65dfbaf3a0299e4837216a103c28625d4b4f1d might be unfortunate) References: <0e65dfbaf3a0299e4837216a103c28625d4b4f1d-master-breakage@gdb-build> <87r28h5sz0.fsf@esperi.org.uk> Date: Wed, 29 May 2019 17:33:11 +0100 In-Reply-To: (Rainer Orth's message of "Wed, 29 May 2019 15:38:44 +0200") Message-ID: <87lfyp43w8.fsf_-_@esperi.org.uk> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1.50 (gnu/linux) MIME-Version: 1.0 On 29 May 2019, Rainer Orth stated: > Nix writes: >> I stripped almost all of these out, but it looks like one single one >> survived. It is gone now. > > Thanks. If you'd like to try the entirely unreviewed patch I'm trying out (works for me on x86_64-pc-linux-gnu, i686-pc-linux-gnu, mingw, Solaris), here it is: commit ea9ad1fe21e0d42d554cb702b29cfc312cd5fd59 Author: Nick Alcock Date: Wed May 29 15:07:06 2019 +0100 Fix a number of build problems found on Solaris and NetBSD - Use of nonportable - Use of qsort_r - Use of zlib without appropriate magic to pull in the binutils zlib - Use of off64_t without checking - signedness problems due to long being too short a type on 32-bit platforms: ctf_id_t is now 'unsigned long', and CTF_ERR must be used only for functions that return ctf_id_t - One lingering use of bzero() and of All fixed, using code from gnulib where possible. include/ * ctf-api.h (HAVE_OFF64_T): Define off64_t if need be. (ctf_id_t): This is now an unsigned type. (CTF_ERR): Cast it to ctf_id_t. Note that it should only be used for ctf_id_t-returning functions. libctf/ * Makefile.am (ZLIB): New. (ZLIBINC): Likewise. (AM_CFLAGS): Use them. (libctf_a_LIBADD): New, for LIBOBJS. * configure.ac: Check for zlib, endian.h, off64_t, and qsort_r. * ctf-endian.h: New, providing htole64 and le64toh. * swap.h: Code style fixes. (bswap_identity_64): New. * qsort_r.c: New, from gnulib (with one added #include). * ctf-decls.h: New, providing a conditional qsort_r declaration, and unconditional definitions of MIN and MAX. * ctf-impl.h: Use it. Do not use . (ctf_set_errno): Now returns unsigned long. * ctf-util.c (ctf_set_errno): Adjust here too. * ctf-archive.c: Use ctf-endian.h. (ctf_arc_open_by_offset): Use memset, not bzero. (ctf_arc_write): Drop debugging dependent on the size of off_t. * ctf-create.c: Provide a definition of roundup if not defined. (ctf_add_reftype): Do not check if type IDs are below zero. (ctf_add_slice): Likewise. (ctf_add_typedef): Likewise. (ctf_add_member_offset): Cast error-returning ssize_t's to size_t when known error-free. Drop CTF_ERR usage for functions returning int. (ctf_add_member_encoded): Drop CTF_ERR usage for functions returning int. (ctf_add_variable): Likewise. (enumcmp): Likewise. (enumadd): Likewise. (membcmp): Likewise. (ctf_add_type): Likewise. Cast error-returning ssize_t's to size_t when known error-free. * ctf-dump.c (ctf_is_slice): Drop CTF_ERR usage for functions returning int: use CTF_ERR for functions returning ctf_type_id. (ctf_dump_label): Likewise. (ctf_dump_objts): Likewise. * ctf-labels.c (ctf_label_topmost): Likewise. (ctf_label_iter): Likewise. (ctf_label_info): Likewise. * ctf-lookup.c (ctf_func_args): Likewise. * ctf-open.c (upgrade_types): Cast to size_t where appropriate. (ctf_bufopen): Likewise. Use zlib types as needed. * ctf-types.c (ctf_member_iter): Drop CTF_ERR usage for functions returning int. (ctf_enum_iter): Likewise. (ctf_type_size): Likewise. (ctf_type_align): Likewise. Cast to size_t where appropriate. (ctf_type_kind_unsliced): Likewise. (ctf_type_kind): Likewise. (ctf_type_encoding): Likewise. (ctf_member_info): Likewise. (ctf_array_info): Likewise. (ctf_enum_value): Likewise. (ctf_type_rvisit): Likewise. * Makefile.in: Regenerate. * aclocal.m4: Likewise. * config.h: Likewise. * configure: Likewise. diff --git a/include/ChangeLog b/include/ChangeLog index 05083763b1..1ad53db690 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,10 @@ +2019-05-29 Nick Alcock + + * ctf-api.h (HAVE_OFF64_T): Define off64_t if need be. + (ctf_id_t): This is now an unsigned type. + (CTF_ERR): Cast it to ctf_id_t. Note that it should only be used + for ctf_id_t-returning functions. + 2019-05-28 Nick Alcock * ctf-api.h (ctf_dump_decorate_f): New. diff --git a/include/ctf-api.h b/include/ctf-api.h index 822b3bf5a9..5d9274c55d 100644 --- a/include/ctf-api.h +++ b/include/ctf-api.h @@ -29,6 +29,10 @@ #include #include +#ifndef HAVE_OFF64_T +#define off64_t off_t +#endif + #ifdef __cplusplus extern "C" { @@ -43,7 +47,7 @@ extern "C" typedef struct ctf_file ctf_file_t; typedef struct ctf_archive_internal ctf_archive_t; -typedef long ctf_id_t; +typedef unsigned long ctf_id_t; /* This opaque definition allows libctf to accept BFD data structures without importing all the BFD noise into users' namespaces. */ @@ -125,9 +129,10 @@ typedef struct ctf_snapshot_id #define CTF_FUNC_VARARG 0x1 /* Function arguments end with varargs. */ -/* Functions that return integer status or a ctf_id_t use the following value - to indicate failure. ctf_errno() can be used to obtain an error code. */ -#define CTF_ERR (-1L) +/* Functions that return a ctf_id_t use the following value to indicate failure. + ctf_errno() can be used to obtain an error code. Functions that return + a straight integral -1 also use ctf_errno(). */ +#define CTF_ERR ((ctf_id_t) -1L) #define ECTF_BASE 1000 /* Base value for libctf errnos. */ diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 879aeed38f..d4e760f576 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,64 @@ +2019-05-29 Nick Alcock + + * Makefile.am (ZLIB): New. + (ZLIBINC): Likewise. + (AM_CFLAGS): Use them. + (libctf_a_LIBADD): New, for LIBOBJS. + * configure.ac: Check for zlib, endian.h, off64_t, and qsort_r. + * ctf-endian.h: New, providing htole64 and le64toh. + * swap.h: Code style fixes. + (bswap_identity_64): New. + * qsort_r.c: New, from gnulib (with one added #include). + * ctf-decls.h: New, providing a conditional qsort_r declaration, + and unconditional definitions of MIN and MAX. + * ctf-impl.h: Use it. Do not use . + (ctf_set_errno): Now returns unsigned long. + * ctf-util.c (ctf_set_errno): Adjust here too. + * ctf-archive.c: Use ctf-endian.h. + (ctf_arc_open_by_offset): Use memset, not bzero. + (ctf_arc_write): Drop debugging dependent on the size of off_t. + * ctf-create.c: Provide a definition of roundup if not defined. + (ctf_add_reftype): Do not check if type IDs are below zero. + (ctf_add_slice): Likewise. + (ctf_add_typedef): Likewise. + (ctf_add_member_offset): Cast error-returning ssize_t's to size_t + when known error-free. Drop CTF_ERR usage for functions returning + int. + (ctf_add_member_encoded): Drop CTF_ERR usage for functions returning + int. + (ctf_add_variable): Likewise. + (enumcmp): Likewise. + (enumadd): Likewise. + (membcmp): Likewise. + (ctf_add_type): Likewise. Cast error-returning ssize_t's to size_t + when known error-free. + * ctf-dump.c (ctf_is_slice): Drop CTF_ERR usage for functions + returning int: use CTF_ERR for functions returning ctf_type_id. + (ctf_dump_label): Likewise. + (ctf_dump_objts): Likewise. + * ctf-labels.c (ctf_label_topmost): Likewise. + (ctf_label_iter): Likewise. + (ctf_label_info): Likewise. + * ctf-lookup.c (ctf_func_args): Likewise. + * ctf-open.c (upgrade_types): Cast to size_t where appropriate. + (ctf_bufopen): Likewise. Use zlib types as needed. + * ctf-types.c (ctf_member_iter): Drop CTF_ERR usage for functions + returning int. + (ctf_enum_iter): Likewise. + (ctf_type_size): Likewise. + (ctf_type_align): Likewise. Cast to size_t where appropriate. + (ctf_type_kind_unsliced): Likewise. + (ctf_type_kind): Likewise. + (ctf_type_encoding): Likewise. + (ctf_member_info): Likewise. + (ctf_array_info): Likewise. + (ctf_enum_value): Likewise. + (ctf_type_rvisit): Likewise. + * Makefile.in: Regenerate. + * aclocal.m4: Likewise. + * config.h: Likewise. + * configure: Likewise. + 2019-05-28 Nick Alcock * configure.in: Check for bfd_section_from_elf_index. diff --git a/libctf/Makefile.am b/libctf/Makefile.am index 5fe2c95901..49c9f5280a 100644 --- a/libctf/Makefile.am +++ b/libctf/Makefile.am @@ -21,11 +21,18 @@ ACLOCAL_AMFLAGS = -I .. -I ../config AUTOMAKE_OPTIONS = foreign no-texinfo.tex +# This is where we get zlib from. zlibdir is -L../zlib and zlibinc is +# -I../zlib, unless we were configured with --with-system-zlib, in which +# case both are empty. +ZLIB = @zlibdir@ -lz +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@ +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) diff --git a/libctf/Makefile.in b/libctf/Makefile.in index b0afa5b80d..c2cada6616 100644 --- a/libctf/Makefile.in +++ b/libctf/Makefile.in @@ -109,7 +109,8 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \ $(top_srcdir)/../config/lead-dot.m4 \ $(top_srcdir)/../config/override.m4 \ - $(top_srcdir)/../config/warnings.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/../config/warnings.m4 \ + $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ @@ -127,7 +128,7 @@ 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_LIBADD = +libctf_a_DEPENDENCIES = $(LIBOBJS) 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) \ @@ -194,7 +195,8 @@ AM_RECURSIVE_TARGETS = cscope 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 + $(top_srcdir)/../missing $(top_srcdir)/../mkinstalldirs \ + ChangeLog qsort_r.c DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -308,15 +310,24 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ warn = @warn@ +zlibdir = @zlibdir@ +zlibinc = @zlibinc@ ACLOCAL_AMFLAGS = -I .. -I ../config AUTOMAKE_OPTIONS = foreign no-texinfo.tex + +# This is where we get zlib from. zlibdir is -L../zlib and zlibinc is +# -I../zlib, unless we were configured with --with-system-zlib, in which +# case both are empty. +ZLIB = @zlibdir@ -lz +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@ +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) all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am @@ -385,6 +396,7 @@ 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@ @@ -675,7 +687,7 @@ clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) + -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags @@ -723,7 +735,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) + -rm -rf $(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/libctf/aclocal.m4 b/libctf/aclocal.m4 index d792e62dfb..074f03638f 100644 --- a/libctf/aclocal.m4 +++ b/libctf/aclocal.m4 @@ -1231,3 +1231,4 @@ m4_include([../config/depstand.m4]) m4_include([../config/lead-dot.m4]) m4_include([../config/override.m4]) m4_include([../config/warnings.m4]) +m4_include([../config/zlib.m4]) diff --git a/libctf/config.h.in b/libctf/config.h.in index 829201033e..afdfeecd3a 100644 --- a/libctf/config.h.in +++ b/libctf/config.h.in @@ -1,11 +1,21 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + /* Whether libbfd was configured for an ELF target. */ #undef HAVE_BFD_ELF /* Define to 1 if you have the 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 header file. */ +#undef HAVE_ENDIAN_H + /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE @@ -18,6 +28,9 @@ /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP +/* Define to 1 if the system has the type `off64_t'. */ +#undef HAVE_OFF64_T + /* Define to 1 if you have the `pread' function. */ #undef HAVE_PREAD @@ -94,6 +107,18 @@ /* Version number of package */ #undef VERSION +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE # define _DARWIN_USE_64_BIT_INODE 1 diff --git a/libctf/configure b/libctf/configure index 1c0340125a..4a8ca2708f 100755 --- a/libctf/configure +++ b/libctf/configure @@ -624,6 +624,8 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +zlibinc +zlibdir ac_libctf_warn_cflags MAINT MAINTAINER_MODE_FALSE @@ -728,6 +730,7 @@ enable_silent_rules enable_largefile enable_werror_always enable_maintainer_mode +with_system_zlib ' ac_precious_vars='build_alias host_alias @@ -1364,6 +1367,11 @@ Optional Features: enable make rules and dependencies not useful (and sometimes confusing) to the casual installer +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-system-zlib use installed libz + Some influential environment variables: CC C compiler command CFLAGS C compiler flags @@ -1801,6 +1809,106 @@ $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +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_type + +# 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. @@ -6031,6 +6139,23 @@ if test "$ac_res" != no; then : fi + # Use the system's zlib library. + zlibdir="-L\$(top_builddir)/../zlib" + zlibinc="-I\$(top_srcdir)/../zlib" + +# Check whether --with-system-zlib was given. +if test "${with_system_zlib+set}" = set; then : + withval=$with_system_zlib; if test x$with_system_zlib = xyes ; then + zlibdir= + zlibinc= + fi + +fi + + + + + # Similar to GDB_AC_CHECK_BFD. OLD_CFLAGS=$CFLAGS OLD_LDFLAGS=$LDFLAGS @@ -6082,18 +6207,253 @@ $as_echo "#define HAVE_BFD_ELF 1" >>confdefs.h fi -for ac_header in byteswap.h + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main () +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_c_bigendian=no +else + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + +for ac_header in byteswap.h endian.h do : - ac_fn_c_check_header_mongrel "$LINENO" "byteswap.h" "ac_cv_header_byteswap_h" "$ac_includes_default" -if test "x$ac_cv_header_byteswap_h" = xyes; then : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define HAVE_BYTESWAP_H 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done +ac_fn_c_check_type "$LINENO" "off64_t" "ac_cv_type_off64_t" "$ac_includes_default" +if test "x$ac_cv_type_off64_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_OFF64_T 1 +_ACEOF + + +fi + for ac_func in pread do : ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread" @@ -6105,6 +6465,23 @@ _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 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_QSORT_R $ac_have_decl +_ACEOF + +case " $LIBOBJS " in + *" qsort_r.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS qsort_r.$ac_objext" + ;; +esac + ac_config_files="$ac_config_files Makefile" @@ -6248,6 +6625,7 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi + : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files diff --git a/libctf/configure.ac b/libctf/configure.ac index 2df10935c0..6a2eb500ee 100644 --- a/libctf/configure.ac +++ b/libctf/configure.ac @@ -56,6 +56,7 @@ ACX_PROG_CC_WARNING_OPTS([-Wall], [ac_libctf_warn_cflags]) AC_FUNC_MMAP AC_SEARCH_LIBS(dlopen, dl) +AM_ZLIB # Similar to GDB_AC_CHECK_BFD. OLD_CFLAGS=$CFLAGS @@ -86,8 +87,12 @@ if test $ac_cv_libctf_bfd_elf = yes; then [Whether libbfd was configured for an ELF target.]) fi -AC_CHECK_HEADERS(byteswap.h) +AC_C_BIGENDIAN +AC_CHECK_HEADERS(byteswap.h endian.h) +AC_CHECK_TYPES(off64_t) AC_CHECK_FUNCS(pread) +AC_CHECK_DECLS([qsort_r]) +AC_LIBOBJ([qsort_r]) AC_CONFIG_FILES(Makefile) AC_CONFIG_HEADERS(config.h) diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c index ab658fd351..f68bc13e60 100644 --- a/libctf/ctf-archive.c +++ b/libctf/ctf-archive.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include "ctf-endian.h" #include #include #include @@ -150,7 +150,6 @@ ctf_arc_write (const char *file, ctf_file_t ** ctf_files, size_t ctf_file_cnt, strcpy (&nametbl[namesz], names[i]); off = arc_write_one_ctf (ctf_files[i], fd, threshold); - ctf_dprintf ("Written %s, offset now %zi\n", names[i], off); if ((off < 0) && (off > -ECTF_BASE)) { errmsg = "ctf_arc_write(): Cannot determine file " @@ -512,7 +511,7 @@ ctf_arc_open_by_offset (const struct ctf_archive *arc, ctf_dprintf ("ctf_arc_open_by_offset(%zi): opening\n", offset); - bzero (&ctfsect, sizeof (ctf_sect_t)); + memset (&ctfsect, 0, sizeof (ctf_sect_t)); offset += le64toh (arc->ctfa_ctfs); diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index 5409ca4bb4..35d525927e 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -23,6 +23,10 @@ #include #include +#ifndef roundup +#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) +#endif + /* To create an empty CTF container, we just declare a zeroed header and call ctf_bufopen() on it. If ctf_bufopen succeeds, we mark the new container r/w and initialize the dynamic members. We set dtvstrlen to 1 to reserve the @@ -812,7 +816,7 @@ ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind) ctf_id_t type; ctf_file_t *tmp = fp; - if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) + if (ref == CTF_ERR || ref > CTF_MAX_TYPE) return (ctf_set_errno (fp, EINVAL)); if (ctf_lookup_by_id (&tmp, ref) == NULL) @@ -843,7 +847,7 @@ ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, if ((ep->cte_bits > 255) || (ep->cte_offset > 255)) return (ctf_set_errno (fp, ECTF_SLICEOVERFLOW)); - if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) + if (ref == CTF_ERR || ref > CTF_MAX_TYPE) return (ctf_set_errno (fp, EINVAL)); if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL) @@ -1175,7 +1179,7 @@ ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name, ctf_id_t type; ctf_file_t *tmp = fp; - if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE) + if (ref == CTF_ERR || ref > CTF_MAX_TYPE) return (ctf_set_errno (fp, EINVAL)); if (ctf_lookup_by_id (&tmp, ref) == NULL) @@ -1304,9 +1308,9 @@ ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name, } } - if ((msize = ctf_type_size (fp, type)) == CTF_ERR || - (malign = ctf_type_align (fp, type)) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + if ((msize = ctf_type_size (fp, type)) < 0 || + (malign = ctf_type_align (fp, type)) < 0) + return -1; /* errno is set for us. */ if ((dmd = ctf_alloc (sizeof (ctf_dmdef_t))) == NULL) return (ctf_set_errno (fp, EAGAIN)); @@ -1334,9 +1338,9 @@ ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_encoding_t linfo; ssize_t lsize; - if (ctf_type_encoding (fp, ltype, &linfo) != CTF_ERR) + if (ctf_type_encoding (fp, ltype, &linfo) == 0) off += linfo.cte_bits; - else if ((lsize = ctf_type_size (fp, ltype)) != CTF_ERR) + else if ((lsize = ctf_type_size (fp, ltype)) > 0) off += lsize * NBBY; /* Round up the offset of the end of the last member to @@ -1359,7 +1363,7 @@ ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name, dmd->dmd_offset = bit_offset; ssize = ctf_get_ctt_size (fp, &dtd->dtd_data, NULL, NULL); - ssize = MAX (ssize, (bit_offset / NBBY) + msize); + ssize = MAX (ssize, ((signed) bit_offset / NBBY) + msize); } } else @@ -1369,7 +1373,7 @@ ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name, ssize = MAX (ssize, msize); } - if (ssize > CTF_MAX_SIZE) + if ((size_t) ssize > CTF_MAX_SIZE) { dtd->dtd_data.ctt_size = CTF_LSIZE_SENT; dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (ssize); @@ -1401,7 +1405,7 @@ ctf_add_member_encoded (ctf_file_t *fp, ctf_id_t souid, const char *name, return (ctf_set_errno (fp, ECTF_NOTINTFP)); if ((type = ctf_add_slice (fp, CTF_ADD_NONROOT, otype, &encoding)) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ return ctf_add_member_offset (fp, souid, name, type, bit_offset); } @@ -1426,7 +1430,7 @@ ctf_add_variable (ctf_file_t *fp, const char *name, ctf_id_t ref) return (ctf_set_errno (fp, ECTF_DUPLICATE)); if (ctf_lookup_by_id (&tmp, ref) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((dvd = ctf_alloc (sizeof (ctf_dvdef_t))) == NULL) return (ctf_set_errno (fp, EAGAIN)); @@ -1452,7 +1456,7 @@ enumcmp (const char *name, int value, void *arg) ctf_bundle_t *ctb = arg; int bvalue; - if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) == CTF_ERR) + if (ctf_enum_value (ctb->ctb_file, ctb->ctb_type, name, &bvalue) < 0) { ctf_dprintf ("Conflict due to member %s iteration error.\n", name); return 1; @@ -1472,7 +1476,7 @@ enumadd (const char *name, int value, void *arg) ctf_bundle_t *ctb = arg; return (ctf_add_enumerator (ctb->ctb_file, ctb->ctb_type, - name, value) == CTF_ERR); + name, value) < 0); } static int @@ -1482,7 +1486,7 @@ membcmp (const char *name, ctf_id_t type _libctf_unused_, unsigned long offset, ctf_bundle_t *ctb = arg; ctf_membinfo_t ctm; - if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) == CTF_ERR) + if (ctf_member_info (ctb->ctb_file, ctb->ctb_type, name, &ctm) < 0) { ctf_dprintf ("Conflict due to member %s iteration error.\n", name); return 1; @@ -1550,7 +1554,6 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) ctf_dtdef_t *dtd; ctf_funcinfo_t ctc; - ssize_t size; ctf_hash_t *hp; @@ -1756,7 +1759,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) break; case CTF_K_ARRAY: - if (ctf_array_info (src_fp, src_type, &src_ar) == CTF_ERR) + if (ctf_array_info (src_fp, src_type, &src_ar) != 0) return (ctf_set_errno (dst_fp, ctf_errno (src_fp))); src_ar.ctr_contents = @@ -1803,6 +1806,8 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) { ctf_dmdef_t *dmd; int errs = 0; + size_t size; + ssize_t ssize; /* Technically to match a struct or union we need to check both ways (src members vs. dst, dst members vs. src) but we make @@ -1818,7 +1823,7 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) ctf_type_size (dst_fp, dst_type)) { ctf_dprintf ("Conflict for type %s against ID %lx: " - "union size differs, old %li, new %li\n", + "union size differs, old %zi, new %zi\n", name, dst_type, ctf_type_size (src_fp, src_type), ctf_type_size (dst_fp, dst_type)); return (ctf_set_errno (dst_fp, ECTF_CONFLICT)); @@ -1848,7 +1853,11 @@ ctf_add_type (ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type) if (ctf_member_iter (src_fp, src_type, membadd, &dst) != 0) errs++; /* Increment errs and fail at bottom of case. */ - if ((size = ctf_type_size (src_fp, src_type)) > CTF_MAX_SIZE) + if ((ssize = ctf_type_size (src_fp, src_type)) < 0) + return CTF_ERR; /* errno is set for us. */ + + size = (size_t) ssize; + if (size > CTF_MAX_SIZE) { dtd->dtd_data.ctt_size = CTF_LSIZE_SENT; dtd->dtd_data.ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI (size); diff --git a/libctf/ctf-decls.h b/libctf/ctf-decls.h new file mode 100644 index 0000000000..5e9ede4809 --- /dev/null +++ b/libctf/ctf-decls.h @@ -0,0 +1,37 @@ +/* Declarations for missing functions. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of libctf. + + libctf 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. + + This program 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 this program; see the file COPYING. If not see + . */ + +#ifndef _CTF_DECLS_H +#define _CTF_DECLS_H + +#include "config.h" + +#if !HAVE_DECL_QSORT_R +#include +void qsort_r (void *base, size_t nmemb, size_t size, + int (*compar)(const void *, const void *, void *), + void *arg); +#endif /* !HAVE_DECL_QSORT_R */ + +#undef MAX +#undef MIN +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#endif /* _CTF_DECLS_H */ diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c index 28f31e4872..c2ed791eea 100644 --- a/libctf/ctf-dump.c +++ b/libctf/ctf-dump.c @@ -88,7 +88,7 @@ ctf_is_slice (ctf_file_t *fp, ctf_id_t id, ctf_encoding_t *enc) return (((kind == CTF_K_INTEGER) || (kind == CTF_K_ENUM) || (kind == CTF_K_FLOAT)) && ctf_type_reference (fp, id) != CTF_ERR - && ctf_type_encoding (fp, id, enc) != CTF_ERR); + && ctf_type_encoding (fp, id, enc) == 0); } /* Return a dump for a single type, without member info: but do show the @@ -168,7 +168,7 @@ ctf_dump_label (const char *name, const ctf_lblinfo_t *info, if ((typestr = ctf_dump_format_type (state->cds_fp, info->ctb_type)) == NULL) { free (str); - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ } str = ctf_str_append (str, typestr); @@ -194,14 +194,14 @@ ctf_dump_objts (ctf_file_t *fp, ctf_dump_state_t *state) const char *sym_name; ctf_id_t type; - if ((type = ctf_lookup_by_symbol (state->cds_fp, i)) < 0) + if ((type = ctf_lookup_by_symbol (state->cds_fp, i)) == CTF_ERR) switch (ctf_errno (state->cds_fp)) { /* Most errors are just an indication that this symbol is not a data symbol, but this one indicates that we were called wrong, on a CTF file with no associated symbol table. */ case ECTF_NOSYMTAB: - return CTF_ERR; + return -1; case ECTF_NOTDATA: case ECTF_NOTYPEDAT: continue; @@ -224,7 +224,7 @@ ctf_dump_objts (ctf_file_t *fp, ctf_dump_state_t *state) if ((typestr = ctf_dump_format_type (state->cds_fp, type)) == NULL) { free (str); - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ } str = ctf_str_append (str, typestr); @@ -253,14 +253,14 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state) size_t j; ctf_id_t *args; - if ((type = ctf_func_info (state->cds_fp, i, &fi)) < 0) + if ((type = ctf_func_info (state->cds_fp, i, &fi)) == CTF_ERR) switch (ctf_errno (state->cds_fp)) { /* Most errors are just an indication that this symbol is not a data symbol, but this one indicates that we were called wrong, on a CTF file with no associated symbol table. */ case ECTF_NOSYMTAB: - return CTF_ERR; + return -1; case ECTF_NOTDATA: case ECTF_NOTYPEDAT: continue; @@ -321,7 +321,7 @@ ctf_dump_funcs (ctf_file_t *fp, ctf_dump_state_t *state) err: free (args); free (str); - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ } return 0; } @@ -340,7 +340,7 @@ ctf_dump_var (const char *name, ctf_id_t type, void *arg) if ((typestr = ctf_dump_format_type (state->cds_fp, type)) == NULL) { free (str); - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ } str = ctf_str_append (str, typestr); @@ -426,7 +426,7 @@ ctf_dump_type (ctf_id_t id, void *arg) err: free (str); - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ } /* Dump the string table into the cds_items. */ diff --git a/libctf/ctf-endian.h b/libctf/ctf-endian.h new file mode 100644 index 0000000000..ec177d1bdd --- /dev/null +++ b/libctf/ctf-endian.h @@ -0,0 +1,37 @@ +/* Interface to endianness-neutrality functions. + Copyright (C) 2019 Free Software Foundation, Inc. + + This file is part of libctf. + + libctf 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. + + This program 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 this program; see the file COPYING. If not see + . */ + +#ifndef _CTF_ENDIAN_H +#define _CTF_ENDIAN_H + +#include "config.h" +#include +#include "swap.h" + +#ifndef HAVE_ENDIAN_H +#ifndef WORDS_BIGENDIAN +# define htole64(x) bswap_identity_64 ((x)) +# define le64toh(x) bswap_identity_64 ((x)) +#else +# define htole64(x) bswap_64 ((x)) +# define le64toh(x) bswap_64 ((x)) +#endif /* WORDS_BIGENDIAN */ +#endif /* !defined(HAVE_ENDIAN_H) */ + +#endif /* !defined(_CTF_ENDIAN_H) */ diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 363b62de7d..fa9c574941 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -21,7 +21,8 @@ #define _CTF_IMPL_H #include "config.h" -#include +#include +#include "ctf-decls.h" #include #include #include @@ -339,7 +340,7 @@ extern struct ctf_archive *ctf_arc_open_internal (const char *, int *); extern struct ctf_archive *ctf_arc_bufopen (const void *, size_t, int *); extern void ctf_arc_close_internal (struct ctf_archive *); extern void *ctf_set_open_errno (int *, int); -extern long ctf_set_errno (ctf_file_t *, int); +extern unsigned long ctf_set_errno (ctf_file_t *, int); _libctf_malloc_ extern void *ctf_data_alloc (size_t); diff --git a/libctf/ctf-labels.c b/libctf/ctf-labels.c index 9b9fffea4e..1755b9720a 100644 --- a/libctf/ctf-labels.c +++ b/libctf/ctf-labels.c @@ -43,7 +43,7 @@ ctf_label_topmost (ctf_file_t *fp) const char *s; uint32_t num_labels = 0; - if (extract_label_info (fp, &ctlp, &num_labels) == CTF_ERR) + if (extract_label_info (fp, &ctlp, &num_labels) < 0) return NULL; /* errno is set for us. */ if (num_labels == 0) @@ -70,8 +70,8 @@ ctf_label_iter (ctf_file_t *fp, ctf_label_f *func, void *arg) const char *lname; int rc; - if (extract_label_info (fp, &ctlp, &num_labels) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + if (extract_label_info (fp, &ctlp, &num_labels) < 0) + return -1; /* errno is set for us. */ if (num_labels == 0) return (ctf_set_errno (fp, ECTF_NOLABELDATA)); @@ -128,7 +128,7 @@ ctf_label_info (ctf_file_t *fp, const char *lname, ctf_lblinfo_t *linfo) cb_arg.lca_name = lname; cb_arg.lca_info = linfo; - if ((rc = ctf_label_iter (fp, label_info_cb, &cb_arg)) == CTF_ERR) + if ((rc = ctf_label_iter (fp, label_info_cb, &cb_arg)) < 0) return rc; if (rc != 1) diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c index 7ea46a7295..ab12715f4b 100644 --- a/libctf/ctf-lookup.c +++ b/libctf/ctf-lookup.c @@ -412,8 +412,8 @@ ctf_func_args (ctf_file_t * fp, unsigned long symidx, uint32_t argc, const uint32_t *dp; ctf_funcinfo_t f; - if (ctf_func_info (fp, symidx, &f) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + if (ctf_func_info (fp, symidx, &f) < 0) + return -1; /* errno is set for us. */ /* The argument data is two uint32_t's past the translation table offset: one for the function info, and one for the return type. */ diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 5230d09a97..77cefc820b 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -503,7 +503,7 @@ upgrade_types (ctf_file_t *fp, ctf_header_t *cth) case CTF_K_UNION: case CTF_K_ENUM: case CTF_K_UNKNOWN: - if (size <= CTF_MAX_SIZE) + if ((size_t) size <= CTF_MAX_SIZE) t2p->ctt_size = size; else { @@ -1317,7 +1317,8 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (hp.cth_flags & CTF_F_COMPRESS) { - size_t srclen, dstlen; + size_t srclen; + uLongf dstlen; const void *src; int rc = Z_OK; @@ -1339,7 +1340,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, return (ctf_set_open_errno (errp, ECTF_DECOMPRESS)); } - if (dstlen != size) + if ((size_t) dstlen != size) { ctf_dprintf ("zlib inflate short -- got %lu of %lu " "bytes\n", (unsigned long) dstlen, (unsigned long) size); @@ -1678,12 +1679,15 @@ ctf_getmodel (ctf_file_t *fp) return fp->ctf_dmodel->ctd_code; } +/* The caller can hang an arbitrary pointer off each ctf_file_t using this + function. */ void ctf_setspecific (ctf_file_t *fp, void *data) { fp->ctf_specific = data; } +/* Retrieve the arbitrary pointer again. */ void * ctf_getspecific (ctf_file_t *fp) { diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index a7fe5d0b18..dc158e2f52 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -47,10 +47,10 @@ ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) int rc; if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ (void) ctf_get_ctt_size (fp, tp, &size, &increment); kind = LCTF_INFO_KIND (fp, tp->ctt_info); @@ -102,10 +102,10 @@ ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg) int rc; if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM) return (ctf_set_errno (ofp, ECTF_NOTENUM)); @@ -406,8 +406,8 @@ ctf_type_size (ctf_file_t *fp, ctf_id_t type) if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0) return size; - if (ctf_array_info (fp, type, &ar) == CTF_ERR - || (size = ctf_type_size (fp, ar.ctr_contents)) == CTF_ERR) + if (ctf_array_info (fp, type, &ar) < 0 + || (size = ctf_type_size (fp, ar.ctr_contents)) < 0) return -1; /* errno is set for us. */ return size * ar.ctr_nelems; @@ -445,7 +445,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type) case CTF_K_ARRAY: { ctf_arinfo_t r; - if (ctf_array_info (fp, type, &r) == CTF_ERR) + if (ctf_array_info (fp, type, &r) < 0) return -1; /* errno is set for us. */ return (ctf_type_align (fp, r.ctr_contents)); } @@ -474,7 +474,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type) for (; n != 0; n--, mp++) { ssize_t am = ctf_type_align (fp, mp->ctm_type); - align = MAX (align, am); + align = MAX (align, (size_t) am); } } else @@ -483,7 +483,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type) for (; n != 0; n--, lmp++) { ssize_t am = ctf_type_align (fp, lmp->ctlm_type); - align = MAX (align, am); + align = MAX (align, (size_t) am); } } } @@ -495,7 +495,7 @@ ctf_type_align (ctf_file_t *fp, ctf_id_t type) dmd != NULL; dmd = ctf_list_next (dmd)) { ssize_t am = ctf_type_align (fp, dmd->dmd_type); - align = MAX (align, am); + align = MAX (align, (size_t) am); if (kind == CTF_K_STRUCT) break; } @@ -520,7 +520,7 @@ ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type) const ctf_type_t *tp; if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ return (LCTF_INFO_KIND (fp, tp->ctt_info)); } @@ -533,13 +533,13 @@ ctf_type_kind (ctf_file_t *fp, ctf_id_t type) { int kind; - if ((kind = ctf_type_kind_unsliced (fp, type)) == CTF_ERR) - return CTF_ERR; + if ((kind = ctf_type_kind_unsliced (fp, type)) < 0) + return -1; if (kind == CTF_K_SLICE) { if ((type = ctf_type_reference (fp, type)) == CTF_ERR) - return CTF_ERR; + return -1; kind = ctf_type_kind_unsliced (fp, type); } @@ -624,7 +624,7 @@ ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep) uint32_t data; if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((dtd = ctf_dynamic_type (ofp, type)) != NULL) { @@ -790,10 +790,10 @@ ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name, uint32_t kind, n; if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ (void) ctf_get_ctt_size (fp, tp, &size, &increment); kind = LCTF_INFO_KIND (fp, tp->ctt_info); @@ -847,7 +847,7 @@ ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp) ssize_t increment; if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY) return (ctf_set_errno (ofp, ECTF_NOTARRAY)); @@ -919,15 +919,15 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp) uint32_t n; if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM) { (void) ctf_set_errno (ofp, ECTF_NOTENUM); - return CTF_ERR; + return -1; } (void) ctf_get_ctt_size (fp, tp, NULL, &increment); @@ -945,7 +945,7 @@ ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp) } (void) ctf_set_errno (ofp, ECTF_NOENUMNAM); - return CTF_ERR; + return -1; } /* Recursively visit the members of any type. This function is used as the @@ -965,10 +965,10 @@ ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, int rc; if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) - return CTF_ERR; /* errno is set for us. */ + return -1; /* errno is set for us. */ if ((rc = func (name, otype, offset, depth, arg)) != 0) return rc; diff --git a/libctf/ctf-util.c b/libctf/ctf-util.c index 44600467a7..730f358a93 100644 --- a/libctf/ctf-util.c +++ b/libctf/ctf-util.c @@ -166,9 +166,9 @@ ctf_set_open_errno (int *errp, int error) } /* Store the specified error code into the CTF container, and then return - CTF_ERR for the benefit of the caller. */ + CTF_ERR / -1 for the benefit of the caller. */ -long +unsigned long ctf_set_errno (ctf_file_t * fp, int err) { fp->ctf_errno = err; diff --git a/libctf/qsort_r.c b/libctf/qsort_r.c new file mode 100644 index 0000000000..6c334fdaf3 --- /dev/null +++ b/libctf/qsort_r.c @@ -0,0 +1,259 @@ +/* Copyright (C) 1991-2019 Free Software Foundation, Inc. + This file is part of libctf (imported from Gnulib). + Written by Douglas C. Schmidt (schmidt@ics.uci.edu). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* If you consider tuning this algorithm, you should consult first: + Engineering a sort function; Jon Bentley and M. Douglas McIlroy; + Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ + +#ifndef _LIBC +# include +#endif + +#include +#include +#include +#include "ctf-decls.h" + +#ifndef _LIBC +# define _quicksort qsort_r +# define __compar_d_fn_t compar_d_fn_t +typedef int (*compar_d_fn_t) (const void *, const void *, void *); +#endif + +/* Byte-wise swap two items of size SIZE. */ +#define SWAP(a, b, size) \ + do \ + { \ + size_t __size = (size); \ + char *__a = (a), *__b = (b); \ + do \ + { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (--__size > 0); \ + } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 4 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct + { + char *lo; + char *hi; + } stack_node; + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +/* The stack needs log (total_elements) entries (we could even subtract + log(MAX_THRESH)). Since total_elements has type size_t, we get as + upper bound for log (total_elements): + bits per byte (CHAR_BIT) * sizeof(size_t). */ +#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +/* Order size using quicksort. This implementation incorporates + four optimizations discussed in Sedgewick: + + 1. Non-recursive, using an explicit stack of pointer that store the + next array partition to sort. To save time, this maximum amount + of space required to store an array of SIZE_MAX is allocated on the + stack. Assuming a 32-bit (64 bit) integer for size_t, this needs + only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). + Pretty cheap, actually. + + 2. Chose the pivot element using a median-of-three decision tree. + This reduces the probability of selecting a bad pivot value and + eliminates certain extraneous comparisons. + + 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving + insertion sort to order the MAX_THRESH items within each partition. + This is a big win, since insertion sort is faster for small, mostly + sorted array segments. + + 4. The larger of the two sub-partitions is always pushed onto the + stack first, with the algorithm then concentrating on the + smaller partition. This *guarantees* no more than log (total_elems) + stack size is needed (actually O(1) in this case)! */ + +void +_quicksort (void *const pbase, size_t total_elems, size_t size, + __compar_d_fn_t cmp, void *arg) +{ + char *base_ptr = (char *) pbase; + + const size_t max_thresh = MAX_THRESH * size; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) + { + char *lo = base_ptr; + char *hi = &lo[size * (total_elems - 1)]; + stack_node stack[STACK_SIZE]; + stack_node *top = stack; + + PUSH (NULL, NULL); + + while (STACK_NOT_EMPTY) + { + char *left_ptr; + char *right_ptr; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR in + the while loops. */ + + char *mid = lo + size * ((hi - lo) / size >> 1); + + if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) + SWAP (mid, lo, size); + if ((*cmp) ((void *) hi, (void *) mid, arg) < 0) + SWAP (mid, hi, size); + else + goto jump_over; + if ((*cmp) ((void *) mid, (void *) lo, arg) < 0) + SWAP (mid, lo, size); + jump_over:; + + left_ptr = lo + size; + right_ptr = hi - size; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do + { + while ((*cmp) ((void *) left_ptr, (void *) mid, arg) < 0) + left_ptr += size; + + while ((*cmp) ((void *) mid, (void *) right_ptr, arg) < 0) + right_ptr -= size; + + if (left_ptr < right_ptr) + { + SWAP (left_ptr, right_ptr, size); + if (mid == left_ptr) + mid = right_ptr; + else if (mid == right_ptr) + mid = left_ptr; + left_ptr += size; + right_ptr -= size; + } + else if (left_ptr == right_ptr) + { + left_ptr += size; + right_ptr -= size; + break; + } + } + while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= max_thresh) + { + if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= max_thresh) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) + { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else + { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + +#define min(x, y) ((x) < (y) ? (x) : (y)) + + { + char *const end_ptr = &base_ptr[size * (total_elems - 1)]; + char *tmp_ptr = base_ptr; + char *thresh = min(end_ptr, base_ptr + max_thresh); + char *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) + if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) + tmp_ptr = run_ptr; + + if (tmp_ptr != base_ptr) + SWAP (tmp_ptr, base_ptr, size); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + + run_ptr = base_ptr + size; + while ((run_ptr += size) <= end_ptr) + { + tmp_ptr = run_ptr - size; + while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0) + tmp_ptr -= size; + + tmp_ptr += size; + if (tmp_ptr != run_ptr) + { + char *trav; + + trav = run_ptr + size; + while (--trav >= run_ptr) + { + char c = *trav; + char *hi, *lo; + + for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) + *hi = *lo; + *hi = c; + } + } + } + } +} diff --git a/libctf/swap.h b/libctf/swap.h index 06a9330181..e75e8d408a 100644 --- a/libctf/swap.h +++ b/libctf/swap.h @@ -29,13 +29,13 @@ /* Provide our own versions of the byteswap functions. */ inline uint16_t -bswap_16(uint16_t v) +bswap_16 (uint16_t v) { return ((v >> 8) & 0xff) | ((v & 0xff) << 8); } inline uint32_t -bswap_32(uint32_t v) +bswap_32 (uint32_t v) { return ( ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) @@ -44,7 +44,13 @@ bswap_32(uint32_t v) } inline uint64_t -bswap_64(uint64_t v) +bswap_identity_64 (uint64_t v) +{ + return v; +} + +inline uint64_t +bswap_64 (uint64_t v) { return ( ((v & 0xff00000000000000ULL) >> 56) | ((v & 0x00ff000000000000ULL) >> 40)