libctf: fix a number of build problems found on Solaris and NetBSD

- Use of nonportable <endian.h>
- Use of qsort_r
- Use of zlib without appropriate magic to pull in the binutils zlib
- Use of off64_t without checking (fixed by dropping the unused fields
  that need off64_t entirely)
- 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 <sys/errno.h>

All fixed, using code from gnulib where possible.

Relatedly, set cts_size in a couple of places it was missed
(string table and symbol table loading upon ctf_bfdopen()).

binutils/
	* objdump.c (make_ctfsect): Drop cts_type, cts_flags, and
	cts_offset.
	* readelf.c (shdr_to_ctf_sect): Likewise.
include/
	* ctf-api.h (ctf_sect_t): Drop cts_type, cts_flags, and cts_offset.
	(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, 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 <sys/errno.h>.
	(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.  Drop cts_type,
	cts_flags and cts_offset.
	(ctf_arc_write): Drop debugging dependent on the size of off_t.
	* ctf-create.c: Provide a definition of roundup if not defined.
	(ctf_create): Drop cts_type, cts_flags and cts_offset.
	(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.
	* ctf-open-bfd.c (ctf_bfdopen): Drop cts_type, cts_flags and
	cts_offset.
	(ctf_simple_open): Likewise.
	(ctf_bfdopen_ctfsect): Likewise.  Set cts_size properly.
	* Makefile.in: Regenerate.
	* aclocal.m4: Likewise.
	* config.h: Likewise.
	* configure: Likewise.
This commit is contained in:
Jose E. Marchesi 2019-05-31 11:10:51 +02:00
parent ff4a4474eb
commit a0486bac41
26 changed files with 883 additions and 115 deletions

View File

@ -1,3 +1,9 @@
2019-05-30 Nick Alcock <nick.alcock@oracle.com>
* objdump.c (make_ctfsect): Drop cts_type, cts_flags, and
cts_offset.
* readelf.c (shdr_to_ctf_sect): Likewise.
2019-05-30 Nick Clifton <nickc@redhat.com>
PR 24627

View File

@ -3240,10 +3240,7 @@ make_ctfsect (const char *name, bfd_byte *data,
ctf_sect_t ctfsect;
ctfsect.cts_name = name;
ctfsect.cts_type = SHT_PROGBITS;
ctfsect.cts_flags = 0;
ctfsect.cts_entsize = 1;
ctfsect.cts_offset = 0;
ctfsect.cts_size = size;
ctfsect.cts_data = data;

View File

@ -13829,11 +13829,8 @@ static ctf_sect_t *
shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
{
buf->cts_name = SECTION_NAME (shdr);
buf->cts_type = shdr->sh_type;
buf->cts_flags = shdr->sh_flags;
buf->cts_size = shdr->sh_size;
buf->cts_entsize = shdr->sh_entsize;
buf->cts_offset = (off64_t) shdr->sh_offset;
return buf;
}

View File

@ -1,3 +1,10 @@
2019-05-29 Nick Alcock <nick.alcock@oracle.com>
* ctf-api.h (ctf_sect_t): Drop cts_type, cts_flags, and cts_offset.
(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 <nick.alcock@oracle.com>
* ctf-api.h (ctf_dump_decorate_f): New.

View File

@ -43,7 +43,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. */
@ -60,12 +60,9 @@ struct bfd;
typedef struct ctf_sect
{
const char *cts_name; /* Section name (if any). */
unsigned long cts_type; /* Section type (ELF SHT_... value). */
unsigned long cts_flags; /* Section flags (ELF SHF_... value). */
const void *cts_data; /* Pointer to section data. */
size_t cts_size; /* Size of data in bytes. */
size_t cts_entsize; /* Size of each section entry (symtab only). */
off64_t cts_offset; /* File offset of this section (if any). */
} ctf_sect_t;
/* Symbolic names for CTF sections. */
@ -125,9 +122,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. */

View File

@ -1,3 +1,70 @@
2019-05-29 Nick Alcock <nick.alcock@oracle.com>
* Makefile.am (ZLIB): New.
(ZLIBINC): Likewise.
(AM_CFLAGS): Use them.
(libctf_a_LIBADD): New, for LIBOBJS.
* configure.ac: Check for zlib, endian.h, 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 <sys/errno.h>.
(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. Drop cts_type,
cts_flags and cts_offset.
(ctf_arc_write): Drop debugging dependent on the size of off_t.
* ctf-create.c: Provide a definition of roundup if not defined.
(ctf_create): Drop cts_type, cts_flags and cts_offset.
(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.
* ctf-open-bfd.c (ctf_bfdopen): Drop cts_type, cts_flags and
cts_offset.
(ctf_simple_open): Likewise.
(ctf_bfdopen_ctfsect): Likewise. Set cts_size properly.
* Makefile.in: Regenerate.
* aclocal.m4: Likewise.
* config.h: Likewise.
* configure: Likewise.
2019-05-28 Nick Alcock <nick.alcock@oracle.com>
* configure.in: Check for bfd_section_from_elf_index.

View File

@ -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)

View File

@ -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

1
libctf/aclocal.m4 vendored
View File

@ -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])

View File

@ -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 <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
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
@ -94,6 +104,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

322
libctf/configure vendored
View File

@ -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,52 @@ $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.
@ -6031,6 +6085,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,12 +6153,237 @@ $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 <sys/types.h>
#include <sys/param.h>
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 <sys/types.h>
#include <sys/param.h>
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 <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <limits.h>
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 <limits.h>
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
@ -6105,6 +6401,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 +6561,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

View File

@ -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,11 @@ 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_FUNCS(pread)
AC_CHECK_DECLS([qsort_r])
AC_LIBOBJ([qsort_r])
AC_CONFIG_FILES(Makefile)
AC_CONFIG_HEADERS(config.h)

View File

@ -21,7 +21,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <elf.h>
#include <endian.h>
#include "ctf-endian.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@ -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,16 +511,13 @@ 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);
ctfsect.cts_name = _CTF_SECTION;
ctfsect.cts_type = SHT_PROGBITS;
ctfsect.cts_flags = SHF_ALLOC;
ctfsect.cts_size = le64toh (*((uint64_t *) ((char *) arc + offset)));
ctfsect.cts_entsize = 1;
ctfsect.cts_offset = 0;
ctfsect.cts_data = (void *) ((char *) arc + offset + sizeof (uint64_t));
fp = ctf_bufopen (&ctfsect, symsect, strsect, errp);
if (fp)

View File

@ -23,6 +23,10 @@
#include <string.h>
#include <zlib.h>
#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
@ -67,12 +71,9 @@ ctf_create (int *errp)
}
cts.cts_name = _CTF_SECTION;
cts.cts_type = SHT_PROGBITS;
cts.cts_flags = 0;
cts.cts_data = &hdr;
cts.cts_size = sizeof (hdr);
cts.cts_entsize = 1;
cts.cts_offset = 0;
if ((fp = ctf_bufopen (&cts, NULL, NULL, errp)) == NULL)
goto err_dtbyname;
@ -812,7 +813,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 +844,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 +1176,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 +1305,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 +1335,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 +1360,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 +1370,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 +1402,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 +1427,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 +1453,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 +1473,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 +1483,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 +1551,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 +1756,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 +1803,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 +1820,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 +1850,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);

37
libctf/ctf-decls.h Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
#ifndef _CTF_DECLS_H
#define _CTF_DECLS_H
#include "config.h"
#if !HAVE_DECL_QSORT_R
#include <stddef.h>
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 */

View File

@ -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. */

37
libctf/ctf-endian.h Normal file
View File

@ -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
<http://www.gnu.org/licenses/>. */
#ifndef _CTF_ENDIAN_H
#define _CTF_ENDIAN_H
#include "config.h"
#include <stdint.h>
#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) */

View File

@ -21,7 +21,8 @@
#define _CTF_IMPL_H
#include "config.h"
#include <sys/errno.h>
#include <errno.h>
#include "ctf-decls.h"
#include <ctf-api.h>
#include <sys/types.h>
#include <stdlib.h>
@ -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);

View File

@ -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)

View File

@ -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. */

View File

@ -97,10 +97,7 @@ ctf_bfdopen (struct bfd *abfd, int *errp)
}
ctfsect.cts_name = _CTF_SECTION;
ctfsect.cts_type = SHT_PROGBITS;
ctfsect.cts_flags = 0;
ctfsect.cts_entsize = 1;
ctfsect.cts_offset = 0;
ctfsect.cts_size = bfd_section_size (abfd, ctf_asect);
ctfsect.cts_data = contents;
@ -158,10 +155,8 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
}
strsect.cts_data = contents;
strsect.cts_name = (char *) strsect.cts_data + strhdr->sh_name;
strsect.cts_type = strhdr->sh_type;
strsect.cts_flags = strhdr->sh_flags;
strsect.cts_size = bfd_section_size (abfd, str_asect);
strsect.cts_entsize = strhdr->sh_size;
strsect.cts_offset = strhdr->sh_offset;
strsectp = &strsect;
if (!bfd_malloc_and_get_section (abfd, sym_asect, &contents))
@ -172,11 +167,9 @@ ctf_bfdopen_ctfsect (struct bfd *abfd _libctf_unused_,
}
symsect.cts_name = (char *) strsect.cts_data + symhdr->sh_name;
symsect.cts_type = symhdr->sh_type;
symsect.cts_flags = symhdr->sh_flags;
symsect.cts_entsize = symhdr->sh_size;
symsect.cts_size = bfd_section_size (abfd, sym_asect);
symsect.cts_data = contents;
symsect.cts_offset = symhdr->sh_offset;
symsectp = &symsect;
}
}

View File

@ -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
{
@ -1170,10 +1170,7 @@ ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
ctf_sect_t *strsectp = NULL;
skeleton.cts_name = _CTF_SECTION;
skeleton.cts_type = SHT_PROGBITS;
skeleton.cts_flags = 0;
skeleton.cts_entsize = 1;
skeleton.cts_offset = 0;
if (ctfsect)
{
@ -1317,7 +1314,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 +1337,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 +1676,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)
{

View File

@ -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;

View File

@ -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;

259
libctf/qsort_r.c Normal file
View File

@ -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
<https://www.gnu.org/licenses/>. */
/* 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 <config.h>
#endif
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#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;
}
}
}
}
}

View File

@ -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)