Commit Graph

7 Commits

Author SHA1 Message Date
Alan Modra b3adc24a07 Update year range in copyright notice of binutils files 2020-01-01 18:42:54 +10:30
Nick Alcock 87279e3cef libctf: installable libctf as a shared library
This lets other programs read and write CTF-format data.

Two versioned shared libraries are created: libctf.so and
libctf-nobfd.so.  They contain identical content except that
libctf-nobfd.so contains no references to libbfd and does not implement
ctf_open, ctf_fdopen, ctf_bfdopen or ctf_bfdopen_ctfsect, so it can be
used by programs that cannot use BFD, like readelf.

The soname major version is presently .0 until the linker API
stabilizes, when it will flip to .1 and hopefully never change again.

New in v3.
v4: libtoolize and turn into a pair of shared libraries.  Drop
    --enable-install-ctf: now controlled by --enable-shared and
    --enable-install-libbfd, like everything else.
v5: Add ../bfd to ACLOCAL_AMFLAGS and AC_CONFIG_MACRO_DIR.  Fix tabdamage.

	* Makefile.def (host_modules): libctf is no longer no_install.
	* Makefile.in: Regenerated.
libctf/
	* configure.ac (AC_DISABLE_SHARED): New, like opcodes/.
	(LT_INIT): Likewise.
	(AM_INSTALL_LIBBFD): Likewise.
	(dlopen): Note why this is necessary in a comment.
	(SHARED_LIBADD): Initialize for possibly-PIC libiberty: derived from
	opcodes/.
	(SHARED_LDFLAGS): Likewise.
	(BFD_LIBADD): Likewise, for libbfd.
	(BFD_DEPENDENCIES): Likewise.
	(VERSION_FLAGS): Initialize, using a version script if ld supports
	one, or libtool -export-symbols-regex otherwise.
	(AC_CONFIG_MACRO_DIR): Add ../BFD.
	* Makefile.am (ACLOCAL_AMFLAGS): Likewise.
	(INCDIR): New.
	(AM_CPPFLAGS): Use $(srcdir), not $(top_srcdir).
	(noinst_LIBRARIES): Replace with...
	[INSTALL_LIBBFD] (lib_LTLIBRARIES): This, or...
	[!INSTALL_LIBBFD] (noinst_LTLIBRARIES): ... this, mentioning new
	libctf-nobfd.la as well.
	[INSTALL_LIBCTF] (include_HEADERS): Add the CTF headers.
	[!INSTALL_LIBCTF] (include_HEADERS): New, empty.
	(libctf_a_SOURCES): Rename to...
	(libctf_nobfd_la_SOURCES): ... this, all of libctf other than
	ctf-open-bfd.c.
	(libctf_la_SOURCES): Now derived from libctf_nobfd_la_SOURCES,
	with ctf-open-bfd.c added.
	(libctf_nobfd_la_LIBADD): New, using @SHARED_LIBADD@.
	(libctf_la_LIBADD): New, using @BFD_LIBADD@ as well.
	(libctf_la_DEPENDENCIES): New, using @BFD_DEPENDENCIES@.
	* Makefile.am [INSTALL_LIBCTF]: Use it.
	* aclocal.m4: Add ../bfd/acinclude.m4, ../config/acx.m4, and the
	libtool macros.
	* libctf.ver: New, everything is version LIBCTF_1.0 currently (even
	the unstable components).
	* Makefile.in: Regenerated.
	* config.h.in: Likewise.
	* configure: Likewise.
binutils/
	* Makefile.am (LIBCTF): Mention the .la file.
	(LIBCTF_NOBFD): New.
	(readelf_DEPENDENCIES): Use it.
	(readelf_LDADD): Likewise.
	* Makefile.in: Regenerated.
ld/
	* configure.ac (TESTCTFLIB): Set to the .so or .a, like TESTBFDLIB.
	* Makefile.am (TESTCTFLIB): Use it.
	(LIBCTF): Use the .la file.
	(check-DEJAGNU): Use it.
	* Makefile.in: Regenerated.
	* configure: Likewise.
include/
	* ctf-api.h: Note the instability of the ctf_link interfaces.
2019-10-03 17:04:56 +01:00
Nick Alcock 72c83edd92 libctf: add the ctf_link machinery
This is the start of work on the core of the linking mechanism for CTF
sections.  This commit handles the type and string sections.

The linker calls these functions in sequence:

ctf_link_add_ctf: to add each CTF section in the input in turn to a
  newly-created ctf_file_t (which will appear in the output, and which
  itself will become the shared parent that contains types that all
  TUs have in common (in all link modes) and all types that do not
  have conflicting definitions between types (by default).  Input files
  that are themselves products of ld -r are supported, though this is
  not heavily tested yet.

ctf_link: called once all input files are added to merge the types in
  all the input containers into the output container, eliminating
  duplicates.

ctf_link_add_strtab: called once the ELF string table is finalized and
  all its offsets are known, this calls a callback provided by the
  linker which returns the string content and offset of every string in
  the ELF strtab in turn: all these strings which appear in the input
  CTF strtab are eliminated from it in favour of the ELF strtab:
  equally, any strings that only appear in the input strtab will
  reappear in the internal CTF strtab of the output.

ctf_link_shuffle_syms (not yet implemented): called once the ELF symtab
  is finalized, this calls a callback provided by the linker which
  returns information on every symbol in turn as a ctf_link_sym_t.  This
  is then used to shuffle the function info and data object sections in
  the CTF section into symbol table order, eliminating the index
  sections which map those sections to symbol names before that point.
  Currently just returns ECTF_NOTYET.

ctf_link_write: Returns a buffer containing either a serialized
  ctf_file_t (if there are no types with conflicting definitions in the
  object files in the link) or a ctf_archive_t containing a large
  ctf_file_t (the common types) and a bunch of small ones named after
  individual CUs in which conflicting types are found (containing the
  conflicting types, and all types that reference them).  A threshold
  size above which compression takes place is passed as one parameter.
  (Currently, only gzip compression is supported, but I hope to add lzma
  as well.)

Lifetime rules for this are simple: don't close the input CTF files
until you've called ctf_link for the last time.  We do not assume
that symbols or strings passed in by the callback outlast the
call to ctf_link_add_strtab or ctf_link_shuffle_syms.

Right now, the duplicate elimination mechanism is the one already
present as part of the ctf_add_type function, and is not particularly
good: it misses numerous actual duplicates, and the conflicting-types
detection hardly ever reports that types conflict, even when they do
(one of them just tends to get silently dropped): it is also very slow.
This will all be fixed in the next few weeks, but the fix hardly touches
any of this code, and the linker does work without it, just not as
well as it otherwise might.  (And when no CTF section is present,
there is no effect on performance, of course.  So only people using
a trunk GCC with not-yet-committed patches will even notice.  By the
time it gets upstream, things should be better.)

v3: Fix error handling.
v4: check for strdup failure.
v5: fix tabdamage.

include/
	* ctf-api.h (struct ctf_link_sym): New, a symbol in flight to the
	libctf linking machinery.
	(CTF_LINK_SHARE_UNCONFLICTED): New.
	(CTF_LINK_SHARE_DUPLICATED): New.
	(ECTF_LINKADDEDLATE): New, replacing ECTF_UNUSED.
	(ECTF_NOTYET): New, a 'not yet implemented' message.
	(ctf_link_add_ctf): New, add an input file's CTF to the link.
	(ctf_link): New, merge the type and string sections.
	(ctf_link_strtab_string_f): New, callback for feeding strtab info.
	(ctf_link_iter_symbol_f): New, callback for feeding symtab info.
	(ctf_link_add_strtab): New, tell the CTF linker about the ELF
	strtab's strings.
	(ctf_link_shuffle_syms): New, ask the CTF linker to shuffle its
	symbols into symtab order.
	(ctf_link_write): New, ask the CTF linker to write the CTF out.

libctf/
	* ctf-link.c: New file, linking of the string and type sections.
	* Makefile.am (libctf_a_SOURCES): Add it.
	* Makefile.in: Regenerate.

	* ctf-impl.h (ctf_file_t): New fields ctf_link_inputs,
	ctf_link_outputs.
	* ctf-create.c (ctf_update): Update accordingly.
	* ctf-open.c (ctf_file_close): Likewise.
	* ctf-error.c (_ctf_errlist): Updated with new errors.
2019-10-03 17:04:55 +01:00
Nick Alcock f5e9c9bde0 libctf: deduplicate and sort the string table
ctf.h states:

> [...] the CTF string table does not contain any duplicated strings.

Unfortunately this is entirely untrue: libctf has before now made no
attempt whatsoever to deduplicate the string table. It computes the
string table's length on the fly as it adds new strings to the dynamic
CTF file, and ctf_update() just writes each string to the table and
notes the current write position as it traverses the dynamic CTF file's
data structures and builds the final CTF buffer.  There is no global
view of the strings and no deduplication.

Fix this by erasing the ctf_dtvstrlen dead-reckoning length, and adding
a new dynhash table ctf_str_atoms that maps unique strings to a list
of references to those strings: a reference is a simple uint32_t * to
some value somewhere in the under-construction CTF buffer that needs
updating to note the string offset when the strtab is laid out.

Adding a string is now a simple matter of calling ctf_str_add_ref(),
which adds a new atom to the atoms table, if one doesn't already exist,
and adding the location of the reference to this atom to the refs list
attached to the atom: this works reliably as long as one takes care to
only call ctf_str_add_ref() once the final location of the offset is
known (so you can't call it on a temporary structure and then memcpy()
that structure into place in the CTF buffer, because the ref will still
point to the old location: ctf_update() changes accordingly).

Generating the CTF string table is a matter of calling
ctf_str_write_strtab(), which counts the length and number of elements
in the atoms table using the ctf_dynhash_iter() function we just added,
populating an array of pointers into the atoms table and sorting it into
order (to help compressors), then traversing this table and emitting it,
updating the refs to each atom as we go.  The only complexity here is
arranging to keep the null string at offset zero, since a lot of code in
libctf depends on being able to leave strtab references at 0 to indicate
'no name'.  Once the table is constructed and the refs updated, we know
how long it is, so we can realloc() the partial CTF buffer we allocated
earlier and can copy the table on to the end of it (and purge the refs
because they're not needed any more and have been invalidated by the
realloc() call in any case).

The net effect of all this is a reduction in uncompressed strtab sizes
of about 30% (perhaps a quarter to a half of all strings across the
Linux kernel are eliminated as duplicates). Of course, duplicated
strings are highly redundant, so the space saving after compression is
only about 20%: when the other non-strtab sections are factored in, CTF
sizes shrink by about 10%.

No change in externally-visible API or file format (other than the
reduction in pointless redundancy).

libctf/
	* ctf-impl.h: (struct ctf_strs_writable): New, non-const version of
	struct ctf_strs.
	(struct ctf_dtdef): Note that dtd_data.ctt_name is unpopulated.
	(struct ctf_str_atom): New, disambiguated single string.
	(struct ctf_str_atom_ref): New, points to some other location that
	references this string's offset.
	(struct ctf_file): New members ctf_str_atoms and ctf_str_num_refs.
	Remove member ctf_dtvstrlen: we no longer track the total strlen
	as we add strings.
	(ctf_str_create_atoms): Declare new function in ctf-string.c.
	(ctf_str_free_atoms): Likewise.
	(ctf_str_add): Likewise.
	(ctf_str_add_ref): Likewise.
	(ctf_str_purge_refs): Likewise.
	(ctf_str_write_strtab): Likewise.
	(ctf_realloc): Declare new function in ctf-util.c.

	* ctf-open.c (ctf_bufopen): Create the atoms table.
	(ctf_file_close): Destroy it.
	* ctf-create.c (ctf_update): Copy-and-free it on update.  No longer
	special-case the position of the parname string.  Construct the
	strtab by calling ctf_str_add_ref and ctf_str_write_strtab after the
	rest of each buffer element is constructed, not via open-coding:
	realloc the CTF buffer and append the strtab to it.  No longer
	maintain ctf_dtvstrlen.  Sort the variable entry table later, after
	strtab construction.
	(ctf_copy_membnames): Remove: integrated into ctf_copy_{s,l,e}members.
	(ctf_copy_smembers): Drop the string offset: call ctf_str_add_ref
	after buffer element construction instead.
	(ctf_copy_lmembers): Likewise.
	(ctf_copy_emembers): Likewise.
	(ctf_create): No longer maintain the ctf_dtvstrlen.
	(ctf_dtd_delete): Likewise.
	(ctf_dvd_delete): Likewise.
	(ctf_add_generic): Likewise.
	(ctf_add_enumerator): Likewise.
	(ctf_add_member_offset): Likewise.
	(ctf_add_variable): Likewise.
	(membadd): Likewise.
	* ctf-util.c (ctf_realloc): New, wrapper around realloc that aborts
	if there are active ctf_str_num_refs.
	(ctf_strraw): Move to ctf-string.c.
	(ctf_strptr): Likewise.
	* ctf-string.c: New file, strtab manipulation.

	* Makefile.am (libctf_a_SOURCES): Add it.
	* Makefile.in: Regenerate.
2019-07-01 11:05:59 +01:00
Nick Alcock 6b22174ff1 libctf: look for BSD versus GNU qsort_r signatures
We cannot just look for any declaration of qsort_r, because some
operating systems have a qsort_r that has a different prototype
but which still has a pair of pointers in the right places (the last two
args are interchanged): so use AC_LINK_IFELSE to check for both
known variants of qsort_r(), and swap their args into a consistent order
in a suitable inline function.  (The code for this is taken almost
unchanged from gnulib.)

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

libctf/
	* qsort_r.c: Rename to...
	* ctf-qsort_r.c: ... this.
	(_quicksort): Define to ctf_qsort_r.
	* ctf-decls.h (qsort_r): Remove.
	(ctf_qsort_r): Add.
	(struct ctf_qsort_arg): New, transport the real ARG and COMPAR.
	(ctf_qsort_compar_thunk): Rearrange the arguments to COMPAR.
	* Makefile.am (libctf_a_LIBADD): Remove.
	(libctf_a_SOURCES): New, add ctf-qsort_r.c.
	* ctf-archive.c (ctf_arc_write): Call ctf_qsort_r, not qsort_r.
	* ctf-create.c (ctf_update): Likewise.
	* configure.ac: Check for BSD versus GNU qsort_r signature.
	* Makefile.in: Regenerate.
	* config.h.in: Likewise.
	* configure: Likewise.
2019-06-04 17:05:08 +01:00
Jose E. Marchesi a0486bac41 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.
2019-05-31 11:10:51 +02:00
Nick Alcock 0e65dfbaf3 libctf: build system
This ties libctf into the build system, and makes binutils depend on it
(used by the next commits).

	* Makefile.def (host_modules): Add libctf.
	* Makefile.def (dependencies): Likewise.
	libctf depends on zlib, libiberty, and bfd.
	* Makefile.in: Regenerated.
	* configure.ac (host_libs): Add libctf.
	* configure: Regenerated.

libctf/
	* Makefile.am: New.
	* Makefile.in: Regenerated.
	* config.h.in: Likewise.
	* aclocal.m4: Likewise.
	* configure: Likewise.
2019-05-28 17:09:41 +01:00