Commit graph

50 commits

Author SHA1 Message Date
Nick Alcock
97a2a623d0 libctf, include: add ctf_getsymsect and ctf_getstrsect
libctf has long provided ctf_getdatasect, which hands back a pointer to
the CTF section a (read-only) dict came from.  But it has no such
functions to return pointers to the ELF symbol table or string table
it's working from, which is unfortunate because several libctf functions
(ctf_open, ctf_fdopen, and ctf_bfdopen) figure out which string and
symbol table to use themselves, and don't tell the user what they
decided, so the caller can't agree on which symtab to use with libctf
even if it wanted to.

Add a pair of functions to return the symtab and strtab in use.  Like
ctf_getdatasect, these return ctf_sect_t structures by value, filled
with all-NULL/0 content if a symtab or strtab is not being used.

include/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-api.h (ctf_getsymsect): New.
	(ctf_getstrsect): Likewise.

libctf/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-open.c (ctf_getsymsect): New.
	(ctf_getstrsect): Likewise.
	* libctf.ver: Add them.
2020-11-20 13:34:12 +00:00
Nick Alcock
2c78e92523 libctf, include: CTF-archive-wide symbol lookup
CTF archives may contain multiple dicts, each of which contain many
types and possibly a bunch of symtypetab entries relating to those
types: each symtypetab entry is going to appear in exactly one dict,
with the corresponding entries in the other dicts empty (either pads, or
indexed symtypetabs that do not mention that symbol).  But users of
libctf usually want to get back the type associated with a symbol
without having to dig around to find out which dict that type might be
in.

This adds machinery to do that -- and since you probably want to do it
repeatedly, it adds internal caching to the ctf-archive machinery so
that iteration over archives via ctf_archive_next and repeated symbol
lookups do not have to repeatedly reopen the archive.  (Iteration using
ctf_archive_iter will gain caching soon.)

Two new API functions:

ctf_dict_t *
ctf_arc_lookup_symbol (ctf_archive_t *arc, unsigned long symidx,
		       ctf_id_t *typep, int *errp);

This looks up the symbol with index SYMIDX in the archive ARC, returning
the dictionary in which it resides and optionally the type index as
well.  Errors are returned in ERRP.  The dict should be
ctf_dict_close()d when done, but is also cached inside the ctf_archive
so that the open cost is only paid once.  The result of the symbol
lookup is also cached internally, so repeated lookups of the same symbol
are nearly free.

void ctf_arc_flush_caches (ctf_archive_t *arc);

Flush all the caches. Done at close time, but also available as an API
function if users want to do it by hand.

include/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-api.h (ctf_arc_lookup_symbol): New.
	(ctf_arc_flush_caches): Likewise.
	* ctf.h: Document new auto-ctf_import behaviour.

libctf/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-impl.h (struct ctf_archive_internal) <ctfi_dicts>: New, dicts
	the archive machinery has opened and cached.
	<ctfi_symdicts>: New, cache of dicts containing symbols looked up.
	<ctfi_syms>: New, cache of types of symbols looked up.
	* ctf-archive.c (ctf_arc_close): Free them on close.
	(enosym): New, flag entry for 'symbol not present'.
	(ctf_arc_import_parent): New, automatically import the parent from
	".ctf" if this is a child in an archive and ".ctf" is present.
	(ctf_dict_open_sections): Use it.
	(ctf_archive_iter_internal): Likewise.
	(ctf_cached_dict_close): New, thunk around ctf_dict_close.
	(ctf_dict_open_cached): New, open and cache a dict.
	(ctf_arc_flush_caches): New, flush the caches.
	(ctf_arc_lookup_symbol): New, look up a symbol in (all members of)
	an archive, and cache the lookup.
	(ctf_archive_iter): Note the new caching behaviour.
	(ctf_archive_next): Use ctf_dict_open_cached.
	* libctf.ver: Add ctf_arc_lookup_symbol and ctf_arc_flush_caches.
2020-11-20 13:34:11 +00:00
Nick Alcock
1136c37971 libctf: symbol type linking support
This adds facilities to write out the function info and data object
sections, which efficiently map from entries in the symbol table to
types.  The write-side code is entirely new: the read-side code was
merely significantly changed and support for indexed tables added
(pointed to by the no-longer-unused cth_objtidxoff and cth_funcidxoff
header fields).

With this in place, you can use ctf_lookup_by_symbol to look up the
types of symbols of function and object type (and, as before, you can
use ctf_lookup_variable to look up types of file-scope variables not
present in the symbol table, as long as you know their name: but
variables that are also data objects are now found in the data object
section instead.)

(Compatible) file format change:

The CTF spec has always said that the function info section looks much
like the CTF_K_FUNCTIONs in the type section: an info word (including an
argument count) followed by a return type and N argument types. This
format is suboptimal: it means function symbols cannot be deduplicated
and it causes a lot of ugly code duplication in libctf.  But
conveniently the compiler has never emitted this!  Because it has always
emitted a rather different format that libctf has never accepted, we can
be sure that there are no instances of this function info section in the
wild, and can freely change its format without compatibility concerns or
a file format version bump.  (And since it has never been emitted in any
code that generated any older file format version, either, we need keep
no code to read the format as specified at all!)

So the function info section is now specified as an array of uint32_t,
exactly like the object data section: each entry is a type ID in the
type section which must be of kind CTF_K_FUNCTION, the prototype of
this function.

This allows function types to be deduplicated and also correctly encodes
the fact that all functions declared in C really are types available to
the program: so they should be stored in the type section like all other
types.  (In format v4, we will be able to represent the types of static
functions as well, but that really does require a file format change.)

We introduce a new header flag, CTF_F_NEWFUNCINFO, which is set if the
new function info format is in use.  A sufficiently new compiler will
always set this flag.  New libctf will always set this flag: old libctf
will refuse to open any CTF dicts that have this flag set.  If the flag
is not set on a dict being read in, new libctf will disregard the
function info section.  Format v4 will remove this flag (or, rather, the
flag has no meaning there and the bit position may be recycled for some
other purpose).

New API:

Symbol addition:
  ctf_add_func_sym: Add a symbol with a given name and type.  The
                    type must be of kind CTF_K_FUNCTION (a function
                    pointer).  Internally this adds a name -> type
                    mapping to the ctf_funchash in the ctf_dict.
  ctf_add_objt_sym: Add a symbol with a given name and type.  The type
                    kind can be anything, including function pointers.
		    This adds to ctf_objthash.

These both treat symbols as name -> type mappings: the linker associates
symbol names with symbol indexes via the ctf_link_shuffle_syms callback,
which sets up the ctf_dynsyms/ctf_dynsymidx/ctf_dynsymmax fields in the
ctf_dict.  Repeated relinks can add more symbols.

Variables that are also exposed as symbols are removed from the variable
section at serialization time.

CTF symbol type sections which have enough pads, defined by
CTF_INDEX_PAD_THRESHOLD (whether because they are in dicts with symbols
where most types are unknown, or in archive where most types are defined
in some child or parent dict, not in this specific dict) are sorted by
name rather than symidx and accompanied by an index which associates
each symbol type entry with a name: the existing ctf_lookup_by_symbol
will map symbol indexes to symbol names and look the names up in the
index automatically.  (This is currently ELF-symbol-table-dependent, but
there is almost nothing specific to ELF in here and we can add support
for other symbol table formats easily).

The compiler also uses index sections to communicate the contents of
object file symbol tables without relying on any specific ordering of
symbols: it doesn't need to sort them, and libctf will detect an
unsorted index section via the absence of the new CTF_F_IDXSORTED header
flag, and sort it if needed.

Iteration:
  ctf_symbol_next: Iterator which returns the types and names of symbols
                   one by one, either for function or data symbols.

This does not require any sorting: the ctf_link machinery uses it to
pull in all the compiler-provided symbols cheaply, but it is not
restricted to that use.

(Compatible) changes in API:
  ctf_lookup_by_symbol: can now be called for object and function
                        symbols: never returns ECTF_NOTDATA (which is
			now not thrown by anything, but is kept for
                        compatibility and because it is a plausible
                        error that we might start throwing again at some
                        later date).

Internally we also have changes to the ctf-string functionality so that
"external" strings (those where we track a string -> offset mapping, but
only write out an offset) can be consulted via the usual means
(ctf_strptr) before the strtab is written out.  This is important
because ctf_link_add_linker_symbol can now be handed symbols named via
strtab offsets, and ctf_link_shuffle_syms must figure out their actual
names by looking in the external symtab we have just been fed by the
ctf_link_add_strtab callback, long before that strtab is written out.

include/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-api.h (ctf_symbol_next): New.
	(ctf_add_objt_sym): Likewise.
	(ctf_add_func_sym): Likewise.
	* ctf.h: Document new function info section format.
	(CTF_F_NEWFUNCINFO): New.
	(CTF_F_IDXSORTED): New.
	(CTF_F_MAX): Adjust accordingly.

libctf/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-impl.h (CTF_INDEX_PAD_THRESHOLD): New.
	(_libctf_nonnull_): Likewise.
	(ctf_in_flight_dynsym_t): New.
	(ctf_dict_t) <ctf_funcidx_names>: Likewise.
	<ctf_objtidx_names>: Likewise.
	<ctf_nfuncidx>: Likewise.
	<ctf_nobjtidx>: Likewise.
	<ctf_funcidx_sxlate>: Likewise.
	<ctf_objtidx_sxlate>: Likewise.
	<ctf_objthash>: Likewise.
	<ctf_funchash>: Likewise.
	<ctf_dynsyms>: Likewise.
	<ctf_dynsymidx>: Likewise.
	<ctf_dynsymmax>: Likewise.
	<ctf_in_flight_dynsym>: Likewise.
	(struct ctf_next) <u.ctn_next>: Likewise.
	(ctf_symtab_skippable): New prototype.
	(ctf_add_funcobjt_sym): Likewise.
	(ctf_dynhash_sort_by_name): Likewise.
	(ctf_sym_to_elf64): Rename to...
	(ctf_elf32_to_link_sym): ... this, and...
	(ctf_elf64_to_link_sym): ... this.
	* ctf-open.c (init_symtab): Check for lack of CTF_F_NEWFUNCINFO
	flag, and presence of index sections.  Refactor out
	ctf_symtab_skippable and ctf_elf*_to_link_sym, and use them.  Use
	ctf_link_sym_t, not Elf64_Sym.  Skip initializing objt or func
	sxlate sections if corresponding index section is present.  Adjust
	for new func info section format.
	(ctf_bufopen_internal): Add ctf_err_warn to corrupt-file error
	handling.  Report incorrect-length index sections.  Always do an
	init_symtab, even if there is no symtab section (there may be index
	sections still).
	(flip_objts): Adjust comment: func and objt sections are actually
	identical in structure now, no need to caveat.
	(ctf_dict_close):  Free newly-added data structures.
	* ctf-create.c (ctf_create): Initialize them.
	(ctf_symtab_skippable): New, refactored out of
	init_symtab, with st_nameidx_set check added.
	(ctf_add_funcobjt_sym): New, add a function or object symbol to the
	ctf_objthash or ctf_funchash, by name.
	(ctf_add_objt_sym): Call it.
	(ctf_add_func_sym): Likewise.
	(symtypetab_delete_nonstatic_vars): New, delete vars also present as
	data objects.
	(CTF_SYMTYPETAB_EMIT_FUNCTION): New flag to symtypetab emitters:
	this is a function emission, not a data object emission.
	(CTF_SYMTYPETAB_EMIT_PAD): New flag to symtypetab emitters: emit
	pads for symbols with no type (only set for unindexed sections).
	(CTF_SYMTYPETAB_FORCE_INDEXED): New flag to symtypetab emitters:
	always emit indexed.
	(symtypetab_density): New, figure out section sizes.
	(emit_symtypetab): New, emit a symtypetab.
	(emit_symtypetab_index): New, emit a symtypetab index.
	(ctf_serialize): Call them, emitting suitably sorted symtypetab
	sections and indexes.  Set suitable header flags.  Copy over new
	fields.
	* ctf-hash.c (ctf_dynhash_sort_by_name): New, used to impose an
	order on symtypetab index sections.
	* ctf-link.c (ctf_add_type_mapping): Delete erroneous comment
	relating to code that was never committed.
	(ctf_link_one_variable): Improve variable name.
	(check_sym): New, symtypetab analogue of check_variable.
	(ctf_link_deduplicating_one_symtypetab): New.
	(ctf_link_deduplicating_syms): Likewise.
	(ctf_link_deduplicating): Call them.
	(ctf_link_deduplicating_per_cu): Note that we don't call them in
	this case (yet).
	(ctf_link_add_strtab): Set the error on the fp correctly.
	(ctf_link_add_linker_symbol): New (no longer a do-nothing stub), add
	a linker symbol to the in-flight list.
	(ctf_link_shuffle_syms): New (no longer a do-nothing stub), turn the
	in-flight list into a mapping we can use, now its names are
	resolvable in the external strtab.
	* ctf-string.c (ctf_str_rollback_atom): Don't roll back atoms with
	external strtab offsets.
	(ctf_str_rollback): Adjust comment.
	(ctf_str_write_strtab): Migrate ctf_syn_ext_strtab population from
	writeout time...
	(ctf_str_add_external): ... to string addition time.
	* ctf-lookup.c (ctf_lookup_var_key_t): Rename to...
	(ctf_lookup_idx_key_t): ... this, now we use it for syms too.
	<clik_names>: New member, a name table.
	(ctf_lookup_var): Adjust accordingly.
	(ctf_lookup_variable): Likewise.
	(ctf_lookup_by_id): Shuffle further up in the file.
	(ctf_symidx_sort_arg_cb): New, callback for...
	(sort_symidx_by_name): ... this new function to sort a symidx
	found to be unsorted (likely originating from the compiler).
	(ctf_symidx_sort): New, sort a symidx.
	(ctf_lookup_symbol_name): Support dynamic symbols with indexes
	provided by the linker.  Use ctf_link_sym_t, not Elf64_Sym.
	Check the parent if a child lookup fails.
	(ctf_lookup_by_symbol): Likewise.  Work for function symbols too.
	(ctf_symbol_next): New, iterate over symbols with types (without
	sorting).
	(ctf_lookup_idx_name): New, bsearch for symbol names in indexes.
	(ctf_try_lookup_indexed): New, attempt an indexed lookup.
	(ctf_func_info): Reimplement in terms of ctf_lookup_by_symbol.
	(ctf_func_args): Likewise.
	(ctf_get_dict): Move...
	* ctf-types.c (ctf_get_dict): ... here.
	* ctf-util.c (ctf_sym_to_elf64): Re-express as...
	(ctf_elf64_to_link_sym): ... this.  Add new st_symidx field, and
	st_nameidx_set (always 0, so st_nameidx can be ignored).  Look in
	the ELF strtab for names.
	(ctf_elf32_to_link_sym): Likewise, for Elf32_Sym.
	(ctf_next_destroy): Destroy ctf_next_t.u.ctn_next if need be.
	* libctf.ver: Add ctf_symbol_next, ctf_add_objt_sym and
	ctf_add_func_sym.
2020-11-20 13:34:08 +00:00
Nick Alcock
3d16b64e28 bfd, include, ld, binutils, libctf: CTF should use the dynstr/sym
This is embarrassing.

The whole point of CTF is that it remains intact even after a binary is
stripped, providing a compact mapping from symbols to types for
everything in the externally-visible interface of an ELF object: it has
connections to the symbol table for that purpose, and to the string
table to avoid duplicating symbol names.  So it's a shame that the hooks
I implemented last year served to hook it up to the .symtab and .strtab,
which obviously disappear on strip, leaving any accompanying the CTF
dict containing references to strings (and, soon, symbols) which don't
exist any more because their containing strtab has been vaporized.  The
original Solaris design used .dynsym and .dynstr (well, actually,
.ldynsym, which has more symbols) which do not disappear. So should we.

Thankfully the work we did before serves as guide rails, and adjusting
things to use the .dynstr and .dynsym was fast and easy.  The only
annoyance is that the dynsym is assembled inside elflink.c in a fairly
piecemeal fashion, so that the easiest way to get the symbols out was to
hook in before every call to swap_symbol_out (we also leave in a hook in
front of symbol additions to the .symtab because it seems plausible that
we might want to hook them in future too: for now that hook is unused).
We adjust things so that rather than being offered a whole hash table of
symbols at once, libctf is now given symbols one at a time, with st_name
indexes already resolved and pointing at their final .dynstr offsets:
it's now up to libctf to resolve these to names as needed using the
strtab info we pass it separately.

Some bits might be contentious.  The ctf_new_dynstr callback takes an
elf_internal_sym, and this remains an elf_internal_sym right down
through the generic emulation layers into ldelfgen.  This is no worse
than the elf_sym_strtab we used to pass down, but in the future when we
gain non-ELF CTF symtab support we might want to lower the
elf_internal_sym to some other representation (perhaps a
ctf_link_symbol) in bfd or in ldlang_ctf_new_dynsym.  We rename the
'apply_strsym' hooks to 'acquire_strings' instead, becuse they no longer
have anything to do with symbols.

There are some API changes to pieces of API which are technically public
but actually totally unused by anything and/or unused by anything but ld
so they can change freely: the ctf_link_symbol gains new fields to allow
symbol names to be given as strtab offsets as well as strings, and a
symidx so that the symbol index can be passed in.  ctf_link_shuffle_syms
loses its callback parameter: the idea now is that linkers call the new
ctf_link_add_linker_symbol for every symbol in .dynsym, feed in all the
strtab entries with ctf_link_add_strtab, and then a call to
ctf_link_shuffle_syms will apply both and arrange to use them to reorder
the CTF symtab at CTF serialization time (which is coming in the next
commit).

Inside libctf we have a new preamble flag CTF_F_DYNSTR which is always
set in v3-format CTF dicts from this commit forwards: CTF dicts without
this flag are associated with .strtab like they used to be, so that old
dicts' external strings don't turn to garbage when loaded by new libctf.
Dicts with this flag are associated with .dynstr and .dynsym instead.
(The flag is not the next in sequence because this commit was written
quite late: the missing flags will be filled in by the next commit.)

Tests forthcoming in a later commit in this series.

bfd/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* elflink.c (elf_finalize_dynstr): Call examine_strtab after
	dynstr finalization.
	(elf_link_swap_symbols_out): Don't call it here.  Call
	ctf_new_symbol before swap_symbol_out.
	(elf_link_output_extsym): Call ctf_new_dynsym before
	swap_symbol_out.
	(bfd_elf_final_link): Likewise.
	* elf.c (swap_out_syms): Pass in bfd_link_info.  Call
	ctf_new_symbol before swap_symbol_out.
	(_bfd_elf_compute_section_file_positions): Adjust.

binutils/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* readelf.c (dump_section_as_ctf): Use .dynsym and .dynstr, not
	.symtab and .strtab.

include/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* bfdlink.h (struct elf_sym_strtab): Replace with...
	(struct elf_internal_sym): ... this.
	(struct bfd_link_callbacks) <examine_strtab>: Take only a
	symstrtab argument.
	<ctf_new_symbol>: New.
	<ctf_new_dynsym>: Likewise.
	* ctf-api.h (struct ctf_link_sym) <st_symidx>: New.
	<st_nameidx>: Likewise.
	<st_nameidx_set>: Likewise.
	(ctf_link_iter_symbol_f): Removed.
	(ctf_link_shuffle_syms): Remove most parameters, just takes a
	ctf_dict_t now.
	(ctf_link_add_linker_symbol): New, split from
	ctf_link_shuffle_syms.
	* ctf.h (CTF_F_DYNSTR): New.
	(CTF_F_MAX): Adjust.

ld/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ldelfgen.c (struct ctf_strsym_iter_cb_arg): Rename to...
	(struct ctf_strtab_iter_cb_arg): ... this, changing fields:
	<syms>: Remove.
	<symcount>: Remove.
	<symstrtab>: Rename to...
	<strtab>: ... this.
	(ldelf_ctf_strtab_iter_cb): Adjust.
	(ldelf_ctf_symbols_iter_cb): Remove.
	(ldelf_new_dynsym_for_ctf): New, tell libctf about a single
	symbol.
	(ldelf_examine_strtab_for_ctf): Rename to...
	(ldelf_acquire_strings_for_ctf): ... this, only doing the strtab
	portion and not symbols.
	* ldelfgen.h: Adjust declarations accordingly.
	* ldemul.c (ldemul_examine_strtab_for_ctf): Rename to...
	(ldemul_acquire_strings_for_ctf): ... this.
	(ldemul_new_dynsym_for_ctf): New.
	* ldemul.h: Adjust declarations accordingly.
	* ldlang.c (ldlang_ctf_apply_strsym): Rename to...
	(ldlang_ctf_acquire_strings): ... this.
	(ldlang_ctf_new_dynsym): New.
	(lang_write_ctf): Call ldemul_new_dynsym_for_ctf with NULL to do
	the actual symbol shuffle.
	* ldlang.h (struct elf_strtab_hash): Adjust accordingly.
	* ldmain.c (bfd_link_callbacks): Wire up new/renamed callbacks.

libctf/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-link.c (ctf_link_shuffle_syms): Adjust.
	(ctf_link_add_linker_symbol): New, unimplemented stub.
	* libctf.ver: Add it.
	* ctf-create.c (ctf_serialize): Set CTF_F_DYNSTR on newly-serialized
	dicts.
	* ctf-open-bfd.c (ctf_bfdopen_ctfsect): Check for the flag: open the
	symtab/strtab if not present, dynsym/dynstr otherwise.
	* ctf-archive.c (ctf_arc_bufpreamble): New, get the preamble from
	some arbitrary member of a CTF archive.
	* ctf-impl.h (ctf_arc_bufpreamble): Declare it.
2020-11-20 13:34:07 +00:00
Nick Alcock
ae41200ba8 libctf, include, binutils, gdb: rename CTF-opening functions
The functions that return ctf_dict_t's given a ctf_archive_t and a name
are very clumsily named.  It sounds like they return *archives*, not
dictionaries, and the names are very long and clunky.  Why do we
have a ctf_arc_open_by_name when it opens a dictionary, not an archive,
and when there is no way to open a dictionary in any other way?  The
answer is purely internal: the function is located in ctf-archive.c,
and everything in there was called ctf_arc_*, and there is another
way to open a dict (by offset in the archive), that is internal to
ctf-archive.c and that nothing else can call.

This is clearly bad naming. The internal organization of the source tree
should not dictate public API names!

So rename things (keeping the old, bad names for compatibility), and
adjust all users.  You now open a dict using ctf_dict_open, and
open it giving ELF sections via ctf_dict_open_sections.

binutils/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* objdump.c (dump_ctf): Use ctf_dict_open, not
	ctf_arc_open_by_name.
	* readelf.c (dump_section_as_ctf): Likewise.

gdb/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctfread.c (elfctf_build_psymtabs): Use ctf_dict_open, not
	ctf_arc_open_by_name.

include/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-api.h (ctf_arc_open_by_name): Rename to...
	(ctf_dict_open): ... this, keeping compatibility function.
	(ctf_arc_open_by_name_sections): Rename to...
	(ctf_dict_open_sections): ... this, keeping compatibility function.

libctf/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-archive.c (ctf_arc_open_by_offset): Rename to...
	(ctf_dict_open_by_offset): ... this.  Adjust callers.
	(ctf_arc_open_by_name_internal): Rename to...
	(ctf_dict_open_internal): ... this.  Adjust callers.
	(ctf_arc_open_by_name_sections): Rename to...
	(ctf_dict_open_sections): ... this, keeping compatibility function.
	(ctf_arc_open_by_name): Rename to...
	(ctf_dict_open): ... this, keeping compatibility function.
	* libctf.ver: New functions added.
	* ctf-link.c (ctf_link_one_input_archive): Adjusted accordingly.
	(ctf_link_deduplicating_open_inputs): Likewise.
2020-11-20 13:34:05 +00:00
Nick Alcock
139633c307 libctf, include, binutils, gdb, ld: rename ctf_file_t to ctf_dict_t
The naming of the ctf_file_t type in libctf is a historical curiosity.
Back in the Solaris days, CTF dictionaries were originally generated as
a separate file and then (sometimes) merged into objects: hence the
datatype was named ctf_file_t, and known as a "CTF file".  Nowadays, raw
CTF is essentially never written to a file on its own, and the datatype
changed name to a "CTF dictionary" years ago.  So the term "CTF file"
refers to something that is never a file!  This is at best confusing.

The type has also historically been known as a 'CTF container", which is
even more confusing now that we have CTF archives which are *also* a
sort of container (they contain CTF dictionaries), but which are never
referred to as containers in the source code.

So fix this by completing the renaming, renaming ctf_file_t to
ctf_dict_t throughout, and renaming those few functions that refer to
CTF files by name (keeping compatibility aliases) to refer to dicts
instead.  Old users who still refer to ctf_file_t will see (harmless)
pointer-compatibility warnings at compile time, but the ABI is unchanged
(since C doesn't mangle names, and ctf_file_t was always an opaque type)
and things will still compile fine as long as -Werror is not specified.
All references to CTF containers and CTF files in the source code are
fixed to refer to CTF dicts instead.

Further (smaller) renamings of annoyingly-named functions to come, as
part of the process of souping up queries across whole archives at once
(needed for the function info and data object sections).

binutils/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* objdump.c (dump_ctf_errs): Rename ctf_file_t to ctf_dict_t.
	(dump_ctf_archive_member): Likewise.
	(dump_ctf): Likewise. Use ctf_dict_close, not ctf_file_close.
	* readelf.c (dump_ctf_errs): Rename ctf_file_t to ctf_dict_t.
	(dump_ctf_archive_member): Likewise.
	(dump_section_as_ctf): Likewise.  Use ctf_dict_close, not
	ctf_file_close.

gdb/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctfread.c: Change uses of ctf_file_t to ctf_dict_t.
	(ctf_fp_info::~ctf_fp_info): Call ctf_dict_close, not ctf_file_close.

include/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-api.h (ctf_file_t): Rename to...
	(ctf_dict_t): ... this.  Keep ctf_file_t around for compatibility.
	(struct ctf_file): Likewise rename to...
	(struct ctf_dict): ... this.
	(ctf_file_close): Rename to...
	(ctf_dict_close): ... this, keeping compatibility function.
	(ctf_parent_file): Rename to...
	(ctf_parent_dict): ... this, keeping compatibility function.
	All callers adjusted.
	* ctf.h: Rename references to ctf_file_t to ctf_dict_t.
	(struct ctf_archive) <ctfa_nfiles>: Rename to...
	<ctfa_ndicts>: ... this.

ld/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ldlang.c (ctf_output): This is a ctf_dict_t now.
	(lang_ctf_errs_warnings): Rename ctf_file_t to ctf_dict_t.
	(ldlang_open_ctf): Adjust comment.
	(lang_merge_ctf): Use ctf_dict_close, not ctf_file_close.
	* ldelfgen.h (ldelf_examine_strtab_for_ctf): Rename ctf_file_t to
	ctf_dict_t.  Change opaque declaration accordingly.
	* ldelfgen.c (ldelf_examine_strtab_for_ctf): Adjust.
	* ldemul.h (examine_strtab_for_ctf): Likewise.
	(ldemul_examine_strtab_for_ctf): Likewise.
	* ldeuml.c (ldemul_examine_strtab_for_ctf): Likewise.

libctf/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-impl.h: Rename ctf_file_t to ctf_dict_t: all declarations
	adjusted.
	(ctf_fileops): Rename to...
	(ctf_dictops): ... this.
	(ctf_dedup_t) <cd_id_to_file_t>: Rename to...
	<cd_id_to_dict_t>: ... this.
	(ctf_file_t): Fix outdated comment.
	<ctf_fileops>: Rename to...
	<ctf_dictops>: ... this.
	(struct ctf_archive_internal) <ctfi_file>: Rename to...
	<ctfi_dict>: ... this.
	* ctf-archive.c: Rename ctf_file_t to ctf_dict_t.
	Rename ctf_archive.ctfa_nfiles to ctfa_ndicts.
	Rename ctf_file_close to ctf_dict_close.  All users adjusted.
	* ctf-create.c: Likewise.  Refer to CTF dicts, not CTF containers.
	(ctf_bundle_t) <ctb_file>: Rename to...
	<ctb_dict): ... this.
	* ctf-decl.c: Rename ctf_file_t to ctf_dict_t.
	* ctf-dedup.c: Likewise.  Rename ctf_file_close to
	ctf_dict_close. Refer to CTF dicts, not CTF containers.
	* ctf-dump.c: Likewise.
	* ctf-error.c: Likewise.
	* ctf-hash.c: Likewise.
	* ctf-inlines.h: Likewise.
	* ctf-labels.c: Likewise.
	* ctf-link.c: Likewise.
	* ctf-lookup.c: Likewise.
	* ctf-open-bfd.c: Likewise.
	* ctf-string.c: Likewise.
	* ctf-subr.c: Likewise.
	* ctf-types.c: Likewise.
	* ctf-util.c: Likewise.
	* ctf-open.c: Likewise.
	(ctf_file_close): Rename to...
	(ctf_dict_close): ...this.
	(ctf_file_close): New trivial wrapper around ctf_dict_close, for
	compatibility.
	(ctf_parent_file): Rename to...
	(ctf_parent_dict): ... this.
	(ctf_parent_file): New trivial wrapper around ctf_parent_dict, for
	compatibility.
	* libctf.ver: Add ctf_dict_close and ctf_parent_dict.
2020-11-20 13:34:04 +00:00
Tom Tromey
0d01fbe64f Remove libctf/mkerrors.sed
This patch removes libctf/mkerrors.sed, replacing it with a macro in
ctf-api.h.  This simplifies the build and avoids possible unportable
code in the sed script.

2020-10-21  Tom Tromey  <tromey@adacore.com>

	* ctf-api.h (_CTF_ERRORS): New macro.

libctf/ChangeLog
2020-10-21  Tom Tromey  <tromey@adacore.com>

	* mkerrors.sed: Remove.
	* ctf-error.c (_CTF_FIRST): New define.
	(_CTF_ITEM): Define this, not _CTF_STR.
	(_ctf_errlist, _ctf_erridx): Use _CTF_ERRORS.
	(ERRSTRFIELD): Rewrite.
	(ERRSTRFIELD1): Remove.
	* Makefile.in: Rebuild.
	* Makefile.am (BUILT_SOURCES): Remove.
	(ctf-error.h): Remove.
2020-10-21 11:52:17 -06:00
Nick Alcock
926c9e7665 libctf, binutils, include, ld: gettextize and improve error handling
This commit follows on from the earlier commit "libctf, ld, binutils:
add textual error/warning reporting for libctf" and converts every error
in libctf that was reported using ctf_dprintf to use ctf_err_warn
instead, gettextizing them in the process, using N_() where necessary to
avoid doing gettext calls unless an error message is actually generated,
and rephrasing some error messages for ease of translation.

This requires a slight change in the ctf_errwarning_next API: this API
is public but has not been in a release yet, so can still change freely.
The problem is that many errors are emitted at open time (whether
opening of a CTF dict, or opening of a CTF archive): the former of these
throws away its incompletely-initialized ctf_file_t rather than return
it, and the latter has no ctf_file_t at all. So errors and warnings
emitted at open time cannot be stored in the ctf_file_t, and have to go
elsewhere.

We put them in a static local in ctf-subr.c (which is not very
thread-safe: a later commit will improve things here): ctf_err_warn with
a NULL fp adds to this list, and the public interface
ctf_errwarning_next with a NULL fp retrieves from it.

We need a slight exception from the usual iterator rules in this case:
with a NULL fp, there is nowhere to store the ECTF_NEXT_END "error"
which signifies the end of iteration, so we add a new err parameter to
ctf_errwarning_next which is used to report such iteration-related
errors.  (If an fp is provided -- i.e., if not reporting open errors --
this is optional, but even if it's optional it's still an API change.
This is actually useful from a usability POV as well, since
ctf_errwarning_next is usually called when there's been an error, so
overwriting the error code with ECTF_NEXT_END is not very helpful!
So, unusually, ctf_errwarning_next now uses the passed fp for its
error code *only* if no errp pointer is passed in, and leaves it
untouched otherwise.)

ld, objdump and readelf are adapted to call ctf_errwarning_next with a
NULL fp to report open errors where appropriate.

The ctf_err_warn API also has to change, gaining a new error-number
parameter which is used to add the error message corresponding to that
error number into the debug stream when LIBCTF_DEBUG is enabled:
changing this API is easy at this point since we are already touching
all existing calls to gettextize them.  We need this because the debug
stream should contain the errno's message, but the error reported in the
error/warning stream should *not*, because the caller will probably
report it themselves at failure time regardless, and reporting it in
every error message that leads up to it leads to a ridiculous chattering
on failure, which is likely to end up as ridiculous chattering on stderr
(trimmed a bit):

CTF error: `ld/testsuite/ld-ctf/A.c (0): lookup failure for type 3: flags 1: The parent CTF dictionary is unavailable'
CTF error: `ld/testsuite/ld-ctf/A.c (0): struct/union member type hashing error during type hashing for type 80000001, kind 6: The parent CTF dictionary is unavailable'
CTF error: `deduplicating link variable emission failed for ld/testsuite/ld-ctf/A.c: The parent CTF dictionary is unavailable'
ld/.libs/lt-ld-new: warning: CTF linking failed; output will have no CTF section: `The parent CTF dictionary is unavailable'

We only need to be told that the parent CTF dictionary is unavailable
*once*, not over and over again!

errmsgs are still emitted on warning generation, because warnings do not
usually lead to a failure propagated up to the caller and reported
there.

Debug-stream messages are not translated.  If translation is turned on,
there will be a mixture of English and translated messages in the debug
stream, but rather that than burden the translators with debug-only
output.

binutils/ChangeLog
2020-08-27  Nick Alcock  <nick.alcock@oracle.com>

	* objdump.c (dump_ctf_archive_member): Move error-
	reporting...
	(dump_ctf_errs): ... into this separate function.
	(dump_ctf): Call it on open errors.
	* readelf.c (dump_ctf_archive_member): Move error-
	reporting...
	(dump_ctf_errs): ... into this separate function.  Support
	calls with NULL fp. Adjust for new err parameter to
	ctf_errwarning_next.
	(dump_section_as_ctf): Call it on open errors.

include/ChangeLog
2020-08-27  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-api.h (ctf_errwarning_next): New err parameter.

ld/ChangeLog
2020-08-27  Nick Alcock  <nick.alcock@oracle.com>

	* ldlang.c (lang_ctf_errs_warnings): Support calls with NULL fp.
	Adjust for new err parameter to ctf_errwarning_next.  Only
	check for assertion failures when fp is non-NULL.
	(ldlang_open_ctf): Call it on open errors.
	* testsuite/ld-ctf/ctf.exp: Always use the C locale to avoid
	breaking the diags tests.

libctf/ChangeLog
2020-08-27  Nick Alcock  <nick.alcock@oracle.com>

	* ctf-subr.c (open_errors): New list.
	(ctf_err_warn): Calls with NULL fp append to open_errors.  Add err
	parameter, and use it to decorate the debug stream with errmsgs.
	(ctf_err_warn_to_open): Splice errors from a CTF dict into the
	open_errors.
	(ctf_errwarning_next): Calls with NULL fp report from open_errors.
	New err param to report iteration errors (including end-of-iteration)
	when fp is NULL.
	(ctf_assert_fail_internal): Adjust ctf_err_warn call for new err
	parameter: gettextize.
	* ctf-impl.h (ctfo_get_vbytes): Add ctf_file_t parameter.
	(LCTF_VBYTES): Adjust.
	(ctf_err_warn_to_open): New.
	(ctf_err_warn): Adjust.
	(ctf_bundle): Used in only one place: move...
	* ctf-create.c: ... here.
	(enumcmp): Use ctf_err_warn, not ctf_dprintf, passing the err number
	down as needed.  Don't emit the errmsg.  Gettextize.
	(membcmp): Likewise.
	(ctf_add_type_internal): Likewise.
	(ctf_write_mem): Likewise.
	(ctf_compress_write): Likewise.  Report errors writing the header or
	body.
	(ctf_write): Likewise.
	* ctf-archive.c (ctf_arc_write_fd): Use ctf_err_warn, not
	ctf_dprintf, and gettextize, as above.
	(ctf_arc_write): Likewise.
	(ctf_arc_bufopen): Likewise.
	(ctf_arc_open_internal): Likewise.
	* ctf-labels.c (ctf_label_iter): Likewise.
	* ctf-open-bfd.c (ctf_bfdclose): Likewise.
	(ctf_bfdopen): Likewise.
	(ctf_bfdopen_ctfsect): Likewise.
	(ctf_fdopen): Likewise.
	* ctf-string.c (ctf_str_write_strtab): Likewise.
	* ctf-types.c (ctf_type_resolve): Likewise.
	* ctf-open.c (get_vbytes_common): Likewise. Pass down the ctf dict.
	(get_vbytes_v1): Pass down the ctf dict.
	(get_vbytes_v2): Likewise.
	(flip_ctf): Likewise.
	(flip_types): Likewise. Use ctf_err_warn, not ctf_dprintf, and
	gettextize, as above.
	(upgrade_types_v1): Adjust calls.
	(init_types): Use ctf_err_warn, not ctf_dprintf, as above.
	(ctf_bufopen_internal): Likewise. Adjust calls. Transplant errors
	emitted into individual dicts into the open errors if this turns
	out to be a failed open in the end.
	* ctf-dump.c (ctf_dump_format_type): Adjust ctf_err_warn for new err
	argument.  Gettextize.  Don't emit the errmsg.
	(ctf_dump_funcs): Likewise.  Collapse err label into its only case.
	(ctf_dump_type): Likewise.
	* ctf-link.c (ctf_create_per_cu): Adjust ctf_err_warn for new err
	argument.  Gettextize.  Don't emit the errmsg.
	(ctf_link_one_type): Likewise.
	(ctf_link_lazy_open): Likewise.
	(ctf_link_one_input_archive): Likewise.
	(ctf_link_deduplicating_count_inputs): Likewise.
	(ctf_link_deduplicating_open_inputs): Likewise.
	(ctf_link_deduplicating_close_inputs): Likewise.
	(ctf_link_deduplicating): Likewise.
	(ctf_link): Likewise.
	(ctf_link_deduplicating_per_cu): Likewise. Add some missed
	ctf_set_errnos to obscure error cases.
	* ctf-dedup.c (ctf_dedup_rhash_type): Adjust ctf_err_warn for new
	err argument.  Gettextize.  Don't emit the errmsg.
	(ctf_dedup_populate_mappings): Likewise.
	(ctf_dedup_detect_name_ambiguity): Likewise.
	(ctf_dedup_init): Likewise.
	(ctf_dedup_multiple_input_dicts): Likewise.
	(ctf_dedup_conflictify_unshared): Likewise.
	(ctf_dedup): Likewise.
	(ctf_dedup_rwalk_one_output_mapping): Likewise.
	(ctf_dedup_id_to_target): Likewise.
	(ctf_dedup_emit_type): Likewise.
	(ctf_dedup_emit_struct_members): Likewise.
	(ctf_dedup_populate_type_mapping): Likewise.
	(ctf_dedup_populate_type_mappings): Likewise.
	(ctf_dedup_emit): Likewise.
	(ctf_dedup_hash_type): Likewise. Fix a bit of messed-up error
	status setting.
	(ctf_dedup_rwalk_one_output_mapping): Likewise. Don't hide
	unknown-type-kind messages (which signify file corruption).
2020-08-27 13:15:43 +01:00
Nick Alcock
662df3c3f1 libctf, link: tie in the deduplicating linker
This fairly intricate commit connects up the CTF linker machinery (which
operates in terms of ctf_archive_t's on ctf_link_inputs ->
ctf_link_outputs) to the deduplicator (which operates in terms of arrays
of ctf_file_t's, all the archives exploded).

The nondeduplicating linker is retained, but is not called unless the
CTF_LINK_NONDEDUP flag is passed in (which ld never does), or the
environment variable LD_NO_CTF_DEDUP is set.  Eventually, once we have
confidence in the much-more-complex deduplicating linker, I hope the
nondeduplicating linker can be removed.

In brief, what this does is traverses each input archive in
ctf_link_inputs, opening every member (if not already open) and tying
child dicts to their parents, shoving them into an array and
constructing a corresponding parents array that tells the deduplicator
which dict is the parent of which child.  We then call ctf_dedup and
ctf_dedup_emit with that array of inputs, taking the outputs that result
and putting them into ctf_link_outputs where the rest of the CTF linker
expects to find them, then linking in the variables just as is done by
the nondeduplicating linker.

It also implements much of the CU-mapping side of things.  The problem
CU-mapping introduces is that if you map many input CUs into one output,
this is saying that you want many translation units to produce at most
one child dict if conflicting types are found in any of them.  This
means you can suddenly have multiple distinct types with the same name
in the same dict, which libctf cannot really represent because it's not
something you can do with C translation units.

The deduplicator machinery already committed does as best it can with
these, hiding types with conflicting names rather than making child
dicts out of them: but we still need to call it.  This is done similarly
to the main link, taking the inputs (one CU output at a time),
deduplicating them, taking the output and making it an input to the
final link.  Two (significant) optimizations are done: we share atoms
tables between all these links and the final link (so e.g. all type hash
values are shared, all decorated type names, etc); and any CU-mapped
links with only one input (and no child dicts) doesn't need to do
anything other than renaming the CU: the CU-mapped link phase can be
skipped for it.  Put together, large CU-mapped links can save 50% of
their memory usage and about as much time (and the memory usage for
CU-mapped links is significant, because all those output CUs have to
have all their types stored in memory all at once).

include/
	* ctf-api.h (CTF_LINK_NONDEDUP): New, turn off the
	deduplicator.
libctf/
	* ctf-impl.h (ctf_list_splice): New.
	* ctf-util.h (ctf_list_splice): Likewise.
	* ctf-link.c (link_sort_inputs_cb_arg_t): Likewise.
	(ctf_link_sort_inputs): Likewise.
	(ctf_link_deduplicating_count_inputs): Likewise.
	(ctf_link_deduplicating_open_inputs): Likewise.
	(ctf_link_deduplicating_close_inputs): Likewise.
	(ctf_link_deduplicating_variables): Likewise.
	(ctf_link_deduplicating_per_cu): Likewise.
	(ctf_link_deduplicating): Likewise.
	(ctf_link): Call it.
2020-07-22 18:02:19 +01:00
Nick Alcock
e3e8411bec libctf, link: add CTF_LINK_OMIT_VARIABLES_SECTION
This flag (not used anywhere yet) causes the variables section to be
omitted from the output CTF dict.

include/
	* ctf-api.h (CTF_LINK_OMIT_VARIABLES_SECTION): New.
libctf/
	* ctf-link.c (ctf_link_one_input_archive_member): Check
	CTF_LINK_OMIT_VARIABLES_SECTION.
2020-07-22 18:02:19 +01:00
Nick Alcock
0f0c11f7fc libctf, dedup: add deduplicator
This adds the core deduplicator that the ctf_link machinery calls
(possibly repeatedly) to link the CTF sections: it takes an array
of input ctf_file_t's and another array that indicates which entries in
the input array are parents of which other entries, and returns an array
of outputs.  The first output is always the ctf_file_t on which
ctf_link/ctf_dedup/etc was called: the other outputs are child dicts
that have the first output as their parent.

include/
	* ctf-api.h (CTF_LINK_SHARE_DUPLICATED): No longer unimplemented.
libctf/
	* ctf-impl.h (ctf_type_id_key): New, the key in the
	cd_id_to_file_t.
	(ctf_dedup): New, core deduplicator state.
	(ctf_file_t) <ctf_dedup>: New.
	<ctf_dedup_atoms>: New.
	<ctf_dedup_atoms_alloc>: New.
	(ctf_hash_type_id_key): New prototype.
	(ctf_hash_eq_type_id_key): Likewise.
	(ctf_dedup_atoms_init): Likewise.
	* ctf-hash.c (ctf_hash_eq_type_id_key): New.
	(ctf_dedup_atoms_init): Likewise.
	* ctf-create.c (ctf_serialize): Adjusted.
	(ctf_add_encoded): No longer static.
	(ctf_add_reftype): Likewise.
	* ctf-open.c (ctf_file_close): Destroy the
	ctf_dedup_atoms_alloc.
	* ctf-dedup.c: New file.
        * ctf-decls.h [!HAVE_DECL_STPCPY]: Add prototype.
	* configure.ac: Check for stpcpy.
	* Makefile.am: Add it.
	* Makefile.in: Regenerate.
        * config.h.in: Regenerate.
        * configure: Regenerate.
2020-07-22 18:02:19 +01:00
Nick Alcock
6dd2819ffc libctf, link: add the ability to filter out variables from the link
The CTF variables section (containing variables that have no
corresponding symtab entries) can cause the string table to get very
voluminous if the names of variables are long.  Some callers want to
filter out particular variables they know they won't need.

So add a "variable filter" callback that does that: it's passed the name
of the variable and a corresponding ctf_file_t / ctf_id_t pair, and
should return 1 to filter it out.

ld doesn't use this machinery yet, but we could easily add it later if
desired.  (But see later for a commit that turns off CTF variable-
section linking in ld entirely by default.)

include/
	* ctf-api.h (ctf_link_variable_filter_t): New.
	(ctf_link_set_variable_filter): Likewise.

libctf/
	* libctf.ver (ctf_link_set_variable_filter): Add.
	* ctf-impl.h (ctf_file_t) <ctf_link_variable_filter>: New.
	<ctf_link_variable_filter_arg>: Likewise.
	* ctf-create.c (ctf_serialize): Adjust.
	* ctf-link.c (ctf_link_set_variable_filter): New, set it.
	(ctf_link_one_variable): Call it if set.
2020-07-22 18:02:18 +01:00
Nick Alcock
5f54462c6a libctf, link: redo cu-mapping handling
Now a bunch of stuff that doesn't apply to ld or any normal use of
libctf, piled into one commit so that it's easier to ignore.

The cu-mapping machinery associates incoming compilation unit names with
outgoing names of CTF dictionaries that should correspond to them, for
non-gdb CTF consumers that would like to group multiple TUs into a
single child dict if conflicting types are found in it (the existing use
case is one kernel module, one child CTF dict, even if the kernel module
is composed of multiple CUs).

The upcoming deduplicator needs to track not only the mapping from
incoming CU name to outgoing dict name, but the inverse mapping from
outgoing dict name to incoming CU name, so it can work over every CTF
dict we might see in the output and link into it.

So rejig the ctf-link machinery to do that.  Simultaneously (because
they are closely associated and were written at the same time), we add a
new CTF_LINK_EMPTY_CU_MAPPINGS flag to ctf_link, which tells the
ctf_link machinery to create empty child dicts for each outgoing CU
mapping even if no CUs that correspond to it exist in the link.  This is
a bit (OK, quite a lot) of a waste of space, but some existing consumers
require it.  (Nobody else should use it.)

Its value is not consecutive with existing CTF_LINK flag values because
we're about to add more flags that are conceptually closer to the
existing ones than this one is.

include/
	* ctf-api.h (CTF_LINK_EMPTY_CU_MAPPINGS): New.

libctf/
	* ctf-impl.h (ctf_file_t): Improve comments.
	<ctf_link_cu_mapping>: Split into...
	<ctf_link_in_cu_mapping>: ... this...
	<ctf_link_out_cu_mapping>: ... and this.
	* ctf-create.c (ctf_serialize): Adjust.
	* ctf-open.c (ctf_file_close): Likewise.
	* ctf-link.c (ctf_create_per_cu): Look things up in the
	in_cu_mapping instead of the cu_mapping.
	(ctf_link_add_cu_mapping): The deduplicating link will define
	what happens if many FROMs share a TO.
	(ctf_link_add_cu_mapping): Create in_cu_mapping and
	out_cu_mapping. Do not create ctf_link_outputs here any more, or
	create per-CU dicts here: they are already created when needed.
	(ctf_link_one_variable): Log a debug message if we skip a
	variable due to its type being concealed in a CU-mapped link.
	(This is probably too common a case to make into a warning.)
	(ctf_link): Create empty per-CU dicts if requested.
2020-07-22 18:02:18 +01:00
Nick Alcock
8d2229ad1e libctf, link: add lazy linking: clean up input members: err/warn cleanup
This rather large and intertwined pile of changes does three things:

First, it transitions from dprintf to ctf_err_warn for things the user might
care about: this one file is the major impetus for the ctf_err_warn
infrastructure, because things like file names are crucial in linker
error messages, and errno values are utterly incapable of
communicating them

Second, it stabilizes the ctf_link APIs: you can now call
ctf_link_add_ctf without a CTF argument (only a NAME), to lazily
ctf_open the file with the given NAME when needed, and close it as soon
as possible, to save memory.  This is not an API change because a null
CTF argument was prohibited before now.

Since getting CTF directly from files uses ctf_open, passing in only a
NAME requires use of libctf, not libctf-nobfd.  The linker's behaviour
is unchanged, as it still passes in a ctf_archive_t as before.

This also let us fix a leak: we were opening ctf_archives and their
containing ctf_files, then only closing the files and leaving the
archives open.

Third, this commit restructures the ctf_link_in_member argument used by
the CTF linking machinery and adjusts its users accordingly.

We drop two members:

- arcname, which is difficult to construct and then only used in error
  messages (that were only dprintf()ed, so never seen!)
- share_mode, since we store the flags passed to ctf_link (including the
  share mode) in a new ctf_file_t.ctf_link_flags to help dedup get hold
  of it

We rename others whose existing names were fairly dreadful:

- done_main_member -> done_parent, using consistent terminology for .ctf
  as the parent of all archive members
- main_input_fp -> in_fp_parent, likewise
- file_name -> in_file_name, likewise

We add one new member, cu_mapped.

Finally, we move the various frees of things like mapping table data to
the top-level ctf_link, since deduplicating links will want to do that
too.

include/
	* ctf-api.h (ECTF_NEEDSBFD): New.
	(ECTF_NERR): Adjust.
	(ctf_link): Rename share_mode arg to flags.
libctf/
	* Makefile.am: Set -DNOBFD=1 in libctf-nobfd, and =0 elsewhere.
	* Makefile.in: Regenerated.
	* ctf-impl.h (ctf_link_input_name): New.
	(ctf_file_t) <ctf_link_flags>: New.
	* ctf-create.c (ctf_serialize): Adjust accordingly.
	* ctf-link.c: Define ctf_open as weak when PIC.
	(ctf_arc_close_thunk): Remove unnecessary thunk.
	(ctf_file_close_thunk): Likewise.
	(ctf_link_input_name): New.
	(ctf_link_input_t): New value of the ctf_file_t.ctf_link_input.
	(ctf_link_input_close): Adjust accordingly.
	(ctf_link_add_ctf_internal): New, split from...
	(ctf_link_add_ctf): ... here.  Return error if lazy loading of
	CTF is not possible.  Change to just call...
	(ctf_link_add): ... this new function.
	(ctf_link_add_cu_mapping): Transition to ctf_err_warn.  Drop the
	ctf_file_close_thunk.
	(ctf_link_in_member_cb_arg_t) <file_name> Rename to...
	<in_file_name>: ... this.
	<arcname>: Drop.
	<share_mode>: Likewise (migrated to ctf_link_flags).
	<done_main_member>: Rename to...
	<done_parent>: ... this.
	<main_input_fp>: Rename to...
	<in_fp_parent>: ... this.
	<cu_mapped>: New.
	(ctf_link_one_type): Adjuwt accordingly.  Transition to
	ctf_err_warn, removing a TODO.
	(ctf_link_one_variable): Note a case too common to warn about.
	Report in the debug stream if a cu-mapped link prevents addition
	of a conflicting variable.
	(ctf_link_one_input_archive_member): Adjust.
	(ctf_link_lazy_open): New, open a CTF archive for linking when
	needed.
	(ctf_link_close_one_input_archive): New, close it again.
	(ctf_link_one_input_archive): Adjust for lazy opening, member
	renames, and ctf_err_warn transition.  Move the
	empty_link_type_mapping call to...
	(ctf_link): ... here.  Adjut for renamings and thunk removal.
	Don't spuriously fail if some input contains no CTF data.
	(ctf_link_write): ctf_err_warn transition.
	* libctf.ver: Remove not-yet-stable comment.
2020-07-22 18:02:18 +01:00
Nick Alcock
8b37e7b63e libctf, ld, binutils: add textual error/warning reporting for libctf
This commit adds a long-missing piece of infrastructure to libctf: the
ability to report errors and warnings using all the power of printf,
rather than being restricted to one errno value.  Internally, libctf
calls ctf_err_warn() to add errors and warnings to a list: a new
iterator ctf_errwarning_next() then consumes this list one by one and
hands it to the caller, which can free it.  New errors and warnings are
added until the list is consumed by the caller or the ctf_file_t is
closed, so you can dump them at intervals.  The caller can of course
choose to print only those warnings it wants.  (I am not sure whether we
want objdump, readelf or ld to print warnings or not: right now I'm
printing them, but maybe we only want to print errors?  This entirely
depends on whether warnings are voluminous things describing e.g. the
inability to emit single types because of name clashes or something.
There are no users of this infrastructure yet, so it's hard to say.)

There is no internationalization here yet, but this at least adds a
place where internationalization can be added, to one of
ctf_errwarning_next or ctf_err_warn.

We also provide a new ctf_assert() function which uses this
infrastructure to provide non-fatal assertion failures while emitting an
assert-like string to the caller: to save space and avoid needlessly
duplicating unchanging strings, the assertion test is inlined but the
print-things-out failure case is not.  All assertions in libctf will be
converted to use this machinery in future commits and propagate
assertion-failure errors up, so that the linker in particular cannot be
killed by libctf assertion failures when it could perfectly well just
print warnings and drop the CTF section.

include/
	* ctf-api.h (ECTF_INTERNAL): Adjust error text.
	(ctf_errwarning_next): New.
libctf/
	* ctf-impl.h (ctf_assert): New.
	(ctf_err_warning_t): Likewise.
	(ctf_file_t) <ctf_errs_warnings>: Likewise.
	(ctf_err_warn): New prototype.
	(ctf_assert_fail_internal): Likewise.
	* ctf-inlines.h (ctf_assert_internal): Likewise.
	* ctf-open.c (ctf_file_close): Free ctf_errs_warnings.
	* ctf-create.c (ctf_serialize): Copy it on serialization.
	* ctf-subr.c (ctf_err_warn): New, add an error/warning.
	(ctf_errwarning_next): New iterator, free and pass back
	errors/warnings in succession.
	* libctf.ver (ctf_errwarning_next): Add.
ld/
	* ldlang.c (lang_ctf_errs_warnings): New, print CTF errors
	and warnings.  Assert when libctf asserts.
	(lang_merge_ctf): Call it.
	(land_write_ctf): Likewise.
binutils/
	* objdump.c (ctf_archive_member): Print CTF errors and warnings.
	* readelf.c (dump_ctf_archive_member): Likewise.
2020-07-22 18:02:17 +01:00
Nick Alcock
ec388c16cd libctf: error out on corrupt CTF with invalid header flags
If corrupt CTF with invalid header flags is passed in, return the new
error ECTF_FLAGS.

include/
	* ctf-api.h (ECTF_FLAGS): New.
	(ECTF_NERR): Adjust.
	* ctf.h (CTF_F_MAX): New.
libctf/
	* ctf-open.c (ctf_bufopen_internal): Diagnose invalid flags.
2020-07-22 17:57:54 +01:00
Nick Alcock
688d28f621 libctf, next: introduce new class of easier-to-use iterators
The libctf machinery currently only provides one way to iterate over its
data structures: ctf_*_iter functions that take a callback and an arg
and repeatedly call it.

This *works*, but if you are doing a lot of iteration it is really quite
inconvenient: you have to package up your local variables into
structures over and over again and spawn lots of little functions even
if it would be clearer in a single run of code.  Look at ctf-string.c
for an extreme example of how unreadable this can get, with
three-line-long functions proliferating wildly.

The deduplicator takes this to the Nth level. It iterates over a whole
bunch of things: if we'd had to use _iter-class iterators for all of
them there would be twenty additional functions in the deduplicator
alone, for no other reason than that the iterator API requires it.

Let's do something better. strtok_r gives us half the design: generators
in a number of other languages give us the other half.

The *_next API allows you to iterate over CTF-like entities in a single
function using a normal while loop. e.g. here we are iterating over all
the types in a dict:

ctf_next_t *i = NULL;
int *hidden;
ctf_id_t id;

while ((id = ctf_type_next (fp, &i, &hidden, 1)) != CTF_ERR)
  {
    /* do something with 'hidden' and 'id' */
  }
if (ctf_errno (fp) != ECTF_NEXT_END)
    /* iteration error */

Here we are walking through the members of a struct with CTF ID
'struct_type':

ctf_next_t *i = NULL;
ssize_t offset;
const char *name;
ctf_id_t membtype;

while ((offset = ctf_member_next (fp, struct_type, &i, &name,
                                  &membtype)) >= 0
  {
    /* do something with offset, name, and membtype */
  }
if (ctf_errno (fp) != ECTF_NEXT_END)
    /* iteration error */

Like every other while loop, this means you have access to all the local
variables outside the loop while inside it, with no need to tiresomely
package things up in structures, move the body of the loop into a
separate function, etc, as you would with an iterator taking a callback.

ctf_*_next allocates 'i' for you on first entry (when it must be NULL),
and frees and NULLs it and returns a _next-dependent flag value when the
iteration is over: the fp errno is set to ECTF_NEXT_END when the
iteartion ends normally.  If you want to exit early, call
ctf_next_destroy on the iterator.  You can copy iterators using
ctf_next_copy, which copies their current iteration position so you can
remember loop positions and go back to them later (or ctf_next_destroy
them if you don't need them after all).

Each _next function returns an always-likely-to-be-useful property of
the thing being iterated over, and takes pointers to parameters for the
others: with very few exceptions all those parameters can be NULLs if
you're not interested in them, so e.g. you can iterate over only the
offsets of members of a structure this way:

while ((offset = ctf_member_next (fp, struct_id, &i, NULL, NULL)) >= 0)

If you pass an iterator in use by one iteration function to another one,
you get the new error ECTF_NEXT_WRONGFUN back; if you try to change
ctf_file_t in mid-iteration, you get ECTF_NEXT_WRONGFP back.

Internally the ctf_next_t remembers the iteration function in use,
various sizes and increments useful for almost all iterations, then
uses unions to overlap the actual entities being iterated over to keep
ctf_next_t size down.

Iterators available in the public API so far (all tested in actual use
in the deduplicator):

/* Iterate over the members of a STRUCT or UNION, returning each member's
   offset and optionally name and member type in turn.  On end-of-iteration,
   returns -1.  */
ssize_t
ctf_member_next (ctf_file_t *fp, ctf_id_t type, ctf_next_t **it,
                 const char **name, ctf_id_t *membtype);

/* Iterate over the members of an enum TYPE, returning each enumerand's
   NAME or NULL at end of iteration or error, and optionally passing
   back the enumerand's integer VALue.  */
const char *
ctf_enum_next (ctf_file_t *fp, ctf_id_t type, ctf_next_t **it,
              int *val);

/* Iterate over every type in the given CTF container (not including
   parents), optionally including non-user-visible types, returning
   each type ID and optionally the hidden flag in turn. Returns CTF_ERR
   on end of iteration or error.  */
ctf_id_t
ctf_type_next (ctf_file_t *fp, ctf_next_t **it, int *flag,
               int want_hidden);

/* Iterate over every variable in the given CTF container, in arbitrary
   order, returning the name and type of each variable in turn.  The
   NAME argument is not optional.  Returns CTF_ERR on end of iteration
   or error.  */
ctf_id_t
ctf_variable_next (ctf_file_t *fp, ctf_next_t **it, const char **name);

/* Iterate over all CTF files in an archive, returning each dict in turn as a
   ctf_file_t, and NULL on error or end of iteration.  It is the caller's
   responsibility to close it.  Parent dicts may be skipped.  Regardless of
   whether they are skipped or not, the caller must ctf_import the parent if
   need be.  */
ctf_file_t *
ctf_archive_next (const ctf_archive_t *wrapper, ctf_next_t **it,
                  const char **name, int skip_parent, int *errp);

ctf_label_next is prototyped but not implemented yet.

include/
	* ctf-api.h (ECTF_NEXT_END): New error.
	(ECTF_NEXT_WRONGFUN): Likewise.
	(ECTF_NEXT_WRONGFP): Likewise.
	(ECTF_NERR): Adjust.
	(ctf_next_t): New.
	(ctf_next_create): New prototype.
	(ctf_next_destroy): Likewise.
	(ctf_next_copy): Likewise.
	(ctf_member_next): Likewise.
	(ctf_enum_next): Likewise.
	(ctf_type_next): Likewise.
	(ctf_label_next): Likewise.
	(ctf_variable_next): Likewise.

libctf/
	* ctf-impl.h (ctf_next): New.
	(ctf_get_dict): New prototype.
	* ctf-lookup.c (ctf_get_dict): New, split out of...
	(ctf_lookup_by_id): ... here.
	* ctf-util.c (ctf_next_create): New.
	(ctf_next_destroy): New.
	(ctf_next_copy): New.
	* ctf-types.c (includes): Add <assert.h>.
	(ctf_member_next): New.
	(ctf_enum_next): New.
	(ctf_type_iter): Document the lack of iteration over parent
	types.
	(ctf_type_next): New.
	(ctf_variable_next): New.
	* ctf-archive.c (ctf_archive_next): New.
	* libctf.ver: Add new public functions.
2020-07-22 17:57:50 +01:00
Nick Alcock
2399827bfa libctf: add ctf_ref
This allows you to bump the refcount on a ctf_file_t, so that you can
smuggle it out of iterators which open and close the ctf_file_t for you
around the loop body (like ctf_archive_iter).

You still can't use this to preserve a ctf_file_t for longer than the
lifetime of its containing entity (e.g. ctf_archive).

include/
	* ctf-api.h (ctf_ref): New.
libctf/
	* libctf.ver (ctf_ref): New.
	* ctf-open.c (ctf_ref): Implement it.
2020-07-22 17:57:49 +01:00
Nick Alcock
9c23dfa5aa libctf: add ctf_archive_count
Another count that was otherwise unavailable without doing expensive
operations.

include/
	* ctf-api.h (ctf_archive_count): New.

libctf/
	* ctf-archive.c (ctf_archive_count): New.
	* libctf.ver: New public function.
2020-07-22 17:57:39 +01:00
Nick Alcock
e0325e2ced libctf: add ctf_member_count
This returns the number of members in a struct or union, or the number
of enumerations in an enum.  (This was only available before now by
iterating across every member, but it can be returned much faster than
that.)

include/
	* ctf-api.h (ctf_member_count): New.

libctf/
	* ctf-types.c (ctf_member_count): New.
	* libctf.ver: New public function.
2020-07-22 17:57:38 +01:00
Nick Alcock
9b15cbb789 libctf: add ctf_type_kind_forwarded
This is just like ctf_type_kind, except that forwards get the
type of the thing being pointed to rather than CTF_K_FORWARD.

include/
	* ctf-api.h (ctf_type_kind_forwarded): New.
libctf/
	* ctf-types.c (ctf_type_kind_forwarded): New.
2020-07-22 17:57:37 +01:00
Nick Alcock
01d9317436 libctf: add ctf_type_name_raw
We already have a function ctf_type_aname_raw, which returns the raw
name of a type with no decoration for structures or arrays or anything
like that: just the underlying name of whatever it is that's being
ultimately pointed at.

But this can be inconvenient to use, becauswe it always allocates new
storage for the string and copies it in, so it can potentially fail.
Add ctf_type_name_raw, which just returns the string directly out of
libctf's guts: it will live until the ctf_file_t is closed (if we later
gain the ability to remove types from writable dicts, it will live as
long as the type lives).

Reimplement ctf_type_aname_raw in terms of it.

include/
	* ctf-api.c (ctf_type_name_raw): New.

libctf/
	* ctf-types.c (ctf_type_name_raw): New.
	(ctf_type_aname_raw): Reimplement accordingly.
2020-07-22 17:57:36 +01:00
Nick Alcock
7eea9d3bdb libctf: restructure error handling to reduce relocations
Jose Marchesi noted that the traditional-Unix error array in ctf-error.c
introduces one reloc per error to initialize the array: 58 so far.  We
can reduce this to zero using an array of carefully-sized individual
members which is used to construct a string table, that is then
referenced by the lookup functions: but doing this automatically is a
pain.

Bruno Haible wrote suitable code years ago: I got permission to reuse it
(Bruno says "... which I hereby put in the public domain"); I modified
it a tiny bit (similarly to what Ulrich Drepper did in the dsohowto
text, but I redid it from scratch), commented it up a bit, and shifted
the error table into that form, migrating it into the new file
ctf-error.h.

This has the advantage that it spotted both typos in the text of the
errors in the comments in ctf-api.h and typos in the error defines in
the comments in ctf-error.c, and places where the two were simply not
in sync.  All are now fixed.

One new constant exists in ctf-api.h: CTF_NERR, since the old method of
working out the number of errors in ctf-error.c was no longer usable,
and it seems that the number of CTF errors is something users might
reasonably want as well.  It should be pretty easy to keep up to date as
new errors are introduced.

include/
	* ctf-api.h (ECTF_*): Improve comments.
	(ECTF_NERR): New.

libctf/
	* ctf-error.c: Include <stddef.h>, for offsetof.
	(_ctf_errlist): Migrate to...
	(_ctf_errlist_t): ... this.
	(_ctf_erridx): New, indexes into _ctf_errlist_t.
	(_ctf_nerr): Remove.
	(ctf_errmsg): Adjust accordingly.
	* Makefile.am (BUILT_SOURCES): Note...
	(ctf-error.h): ... this new rule.
	* Makefile.in: Regenerate.
	* mkerrors.sed: New, process ctf-api.h to generate ctf-error.h.
	* .gitignore: New, ignore ctf-error.h.
2020-07-22 17:57:20 +01:00
Nick Alcock
b64751cf0b include, libctf: typo fixes
include/
	* ctf-api.h: Fix typos in comments.
libctf/
	* ctf-impl.h: Fix typos in comments.
2020-07-22 17:57:19 +01:00
Nick Alcock
2f6ecaed66 libctf, binutils: support CTF archives like objdump
objdump and readelf have one major CTF-related behavioural difference:
objdump can read .ctf sections that contain CTF archives and extract and
dump their members, while readelf cannot.  Since the linker often emits
CTF archives, this means that readelf intermittently and (from the
user's perspective) randomly fails to read CTF in files that ld emits,
with a confusing error message wrongly claiming that the CTF content is
corrupt.  This is purely because the archive-opening code in libctf was
needlessly tangled up with the BFD code, so readelf couldn't use it.

Here, we disentangle it, moving ctf_new_archive_internal from
ctf-open-bfd.c into ctf-archive.c and merging it with the helper
function in ctf-archive.c it was already using.  We add a new public API
function ctf_arc_bufopen, that looks very like ctf_bufopen but returns
an archive given suitable section data rather than a ctf_file_t: the
archive is a ctf_archive_t, so it can be called on raw CTF dictionaries
(with no archive present) and will return a single-member synthetic
"archive".

There is a tiny lifetime tweak here: before now, the archive code could
assume that the symbol section in the ctf_archive_internal wrapper
structure was always owned by BFD if it was present and should always be
freed: now, the caller can pass one in via ctf_arc_bufopen, wihch has
the usual lifetime rules for such sections (caller frees): so we add an
extra field to track whether this is an internal call from ctf-open-bfd,
in which case we still free the symbol section.

include/
	* ctf-api.h (ctf_arc_bufopen): New.
libctf/
	* ctf-impl.h (ctf_new_archive_internal): Declare.
	(ctf_arc_bufopen): Remove.
	(ctf_archive_internal) <ctfi_free_symsect>: New.
	* ctf-archive.c (ctf_arc_close): Use it.
	(ctf_arc_bufopen): Fuse into...
	(ctf_new_archive_internal): ... this, moved across from...
	* ctf-open-bfd.c: ... here.
	(ctf_bfdopen_ctfsect): Use ctf_arc_bufopen.
	* libctf.ver: Add it.
binutils/
	* readelf.c (dump_section_as_ctf): Support .ctf archives using
	ctf_arc_bufopen.  Automatically load the .ctf member of such
	archives as the parent of all other members, unless specifically
	overridden via --ctf-parent.  Split out dumping code into...
	(dump_ctf_archive_member): ... here, as in objdump, and call
	it once per archive member.
	(dump_ctf_indent_lines): Code style fix.
2020-06-26 15:56:39 +01:00
Alan Modra
b3adc24a07 Update year range in copyright notice of binutils files 2020-01-01 18:42:54 +10:30
Nick Alcock
de07e349be libctf: remove ctf_malloc, ctf_free and ctf_strdup
These just get in the way of auditing for erroneous usage of strdup and
add a huge irregular surface of "ctf_malloc or malloc? ctf_free or free?
ctf_strdup or strdup?"

ctf_malloc and ctf_free usage has not reliably matched up for many
years, if ever, making the whole game pointless.

Go back to malloc, free, and strdup like everyone else: while we're at
it, fix a bunch of places where we weren't properly checking for OOM.
This changes the interface of ctf_cuname_set and ctf_parent_name_set,
which could strdup but could not return errors (like ENOMEM).

New in v4.

include/
	* ctf-api.h (ctf_cuname_set): Can now fail, returning int.
	(ctf_parent_name_set): Likewise.
libctf/
	* ctf-impl.h (ctf_alloc): Remove.
	(ctf_free): Likewise.
	(ctf_strdup): Likewise.
	* ctf-subr.c (ctf_alloc): Remove.
	(ctf_free): Likewise.
	* ctf-util.c (ctf_strdup): Remove.

	* ctf-create.c (ctf_serialize): Use malloc, not ctf_alloc; free, not
	ctf_free; strdup, not ctf_strdup.
	(ctf_dtd_delete): Likewise.
	(ctf_dvd_delete): Likewise.
	(ctf_add_generic): Likewise.
	(ctf_add_function): Likewise.
	(ctf_add_enumerator): Likewise.
	(ctf_add_member_offset): Likewise.
	(ctf_add_variable): Likewise.
	(membadd): Likewise.
	(ctf_compress_write): Likewise.
	(ctf_write_mem): Likewise.
	* ctf-decl.c (ctf_decl_push): Likewise.
	(ctf_decl_fini): Likewise.
	(ctf_decl_sprintf): Likewise.  Check for OOM.
	* ctf-dump.c (ctf_dump_append): Use malloc, not ctf_alloc; free, not
	ctf_free; strdup, not ctf_strdup.
	(ctf_dump_free): Likewise.
	(ctf_dump): Likewise.
	* ctf-open.c (upgrade_types_v1): Likewise.
	(init_types): Likewise.
	(ctf_file_close): Likewise.
	(ctf_bufopen_internal): Likewise.  Check for OOM.
	(ctf_parent_name_set): Likewise: report the OOM to the caller.
	(ctf_cuname_set): Likewise.
	(ctf_import): Likewise.
	* ctf-string.c (ctf_str_purge_atom_refs): Use malloc, not ctf_alloc;
	free, not ctf_free; strdup, not ctf_strdup.
	(ctf_str_free_atom): Likewise.
	(ctf_str_create_atoms): Likewise.
	(ctf_str_add_ref_internal): Likewise.
	(ctf_str_remove_ref): Likewise.
	(ctf_str_write_strtab): Likewise.
2019-10-03 17:04:56 +01:00
Nick Alcock
791915db42 libctf: handle nonrepresentable types at link time
GCC can emit references to type 0 to indicate that this type is one that
is not representable in the version of CTF it emits (for instance,
version 3 cannot encode vector types).  Type 0 is already used in the
function section to indicate padding inserted to skip functions we do
not want to encode the type of, so using zero in this way is a good
extension of the format: but libctf reports such types as ECTF_BADID,
which is indistinguishable from file corruption via links to truly
nonexistent types with IDs like 0xDEADBEEF etc, which we really do want
to stop for.

In particular, this stops all traversals of types dead at this point,
preventing us from even dumping CTF files containing unrepresentable
types to see what's going on!

So add a new error, ECTF_NONREPRESENTABLE, which is returned by
recursive type resolution when a reference to a zero type is found.  (No
zero type is ever emitted into the CTF file by GCC, only references to
one).  We can't do much with types that are ultimately nonrepresentable,
but we can do enough to keep functioning.

Adjust ctf_add_type to ensure that top-level types of type zero and
structure and union members of ultimate type zero are simply skipped
without reporting an error, so we can copy structures and unions that
contain nonrepresentable members (skipping them and leaving a hole where
they would be, so no consumers downstream of the linker need to worry
about this): adjust the dumper so that we dump members of
nonrepresentable types in a simple form that indicates
nonrepresentability rather than terminating the dump, and do not falsely
assume all errors to be -ENOMEM: adjust the linker so that types that
fail to get added are simply skipped, so that both nonrepresentable
types and outright errors do not terminate the type addition, which
could skip many valid types and cause further errors when variables of
those types are added.

In future, when we gain the ability to call back to the linker to report
link-time type resolution errors, we should report failures to add all
but nonrepresentable types.  But we can't do that yet.

v5: Fix tabdamage.

include/
	* ctf-api.h (ECTF_NONREPRESENTABLE): New.
libctf/
	* ctf-types.c (ctf_type_resolve): Return ECTF_NONREPRESENTABLE on
	type zero.
	* ctf-create.c (ctf_add_type): Detect and skip nonrepresentable
	members and types.
	(ctf_add_variable): Likewise for variables pointing to them.
	* ctf-link.c (ctf_link_one_type): Do not warn for nonrepresentable
	type link failure, but do warn for others.
	* ctf-dump.c (ctf_dump_format_type): Likewise.  Do not assume all
	errors to be ENOMEM.
	(ctf_dump_member): Likewise.
	(ctf_dump_type): Likewise.
	(ctf_dump_header_strfield): Do not assume all errors to be ENOMEM.
	(ctf_dump_header_sectfield): Do not assume all errors to be ENOMEM.
	(ctf_dump_header): Likewise.
	(ctf_dump_label): likewise.
	(ctf_dump_objts): likewise.
	(ctf_dump_funcs): likewise.
	(ctf_dump_var): likewise.
	(ctf_dump_str): Likewise.
2019-10-03 17:04:56 +01:00
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
7e97445a5a libctf: get rid of a disruptive public include of <sys/param.h>
This hoary old header defines things like MAX that users of libctf might
perfectly reasonably define themselves.

The CTF headers do not need it: move it into libctf/ctf-impl.h instead.

include/
	* ctf-api.h (includes): No longer include <sys/param.h>.
libctf/
	* ctf-impl.h (includes): Include <sys/param.h> here.
2019-10-03 17:04:55 +01:00
Nick Alcock
49ea9b450b libctf: add CU-mapping machinery
Once the deduplicator is capable of actually detecting conflicting types
with the same name (i.e., not yet) we will place such conflicting types,
and types that depend on them, into CTF dictionaries that are the child
of the main dictionary we usually emit: currently, this will lead to the
.ctf section becoming a CTF archive rather than a single dictionary,
with the default-named archive member (_CTF_SECTION, or NULL) being the
main shared dictionary with most of the types in it.

By default, the sections are named after the compilation unit they come
from (complete path and all), with the cuname field in the CTF header
providing further evidence of the name without requiring the caller to
engage in tiresome parsing.  But some callers may not wish the mapping
from input CU to output sub-dictionary to be purely CU-based.

The machinery here allows this to be freely changed, in two ways:

 - callers can call ctf_link_add_cu_mapping to specify that a single
   input compilation unit should have its types placed in some other CU
   if they conflict: the CU will always be created, even if empty, so
   the consuming program can depend on its existence.  You can map
   multiple input CUs to one output CU to force all their types to be
   merged together: if some of *those* types conflict, the behaviour is
   currently unspecified (the new deduplicator will specify it).

 - callers can call ctf_link_set_memb_name_changer to provide a function
   which is passed every CTF sub-dictionary name in turn (including
   _CTF_SECTION) and can return a new name, or NULL if no change is
   desired.  The mapping from input to output names should not map two
   input names to the same output name: if this happens, the two are not
   merged but will result in an archive with two members with the same
   name (technically valid, but it's hard to access the second
   same-named member: you have to do an iteration over archive members).

This is used by the kernel's ctfarchive machinery (not yet upstream) to
encode CTF under member names like {module name}.ctf rather than
.ctf.CU, but it is anticipated that other large projects may wish to
have their own storage for CTF outside of .ctf sections and may wish to
have new naming schemes that suit their special-purpose consumers.

New in v3.
v4: check for strdup failure.
v5: fix tabdamage.

include/
	* ctf-api.h (ctf_link_add_cu_mapping): New.
	(ctf_link_memb_name_changer_f): New.
	(ctf_link_set_memb_name_changer): New.

libctf/
	* ctf-impl.h (ctf_file_t) <ctf_link_cu_mappping>: New.
	<ctf_link_memb_name_changer>: Likewise.
	<ctf_link_memb_name_changer_arg>: Likewise.
	* ctf-create.c (ctf_update): Update accordingly.
	* ctf-open.c (ctf_file_close): Likewise.
	* ctf-link.c (ctf_create_per_cu): Apply the cu mapping.
	(ctf_link_add_cu_mapping): New.
	(ctf_link_set_memb_name_changer): Likewise.
	(ctf_change_parent_name): New.
	(ctf_name_list_accum_cb_arg_t) <dynames>: New, storage for names
	allocated by the caller's ctf_link_memb_name_changer.
	<ndynames>: Likewise.
	(ctf_accumulate_archive_names): Call the ctf_link_memb_name_changer.
	(ctf_link_write): Likewise (for _CTF_SECTION only): also call
	ctf_change_parent_name.  Free any resulting names.
2019-10-03 17:04:55 +01:00
Nick Alcock
eabb7154df libctf: add linking of the variable section
The compiler describes the name and type of all file-scope variables in
this section.  Merging it at link time requires using the type mapping
added in the previous commit to determine the appropriate type for the
variable in the output, given its type in the input: we check the shared
container first, and if the type doesn't exist there, it must be a
conflicted type in the per-CU child, and the variable should go there
too.  We also put the variable in the per-CU child if a variable with
the same name but a different type already exists in the parent: we
ignore any such conflict in the child because CTF cannot represent such
things, nor can they happen unless a third-party linking program has
overridden the mapping of CU to CTF archive member name (using machinery
added in a later commit).

v3: rewritten using an algorithm that actually works in the case of
    conflicting names.  Some code motion from the next commit.  Set
    the per-CU parent name.
v4: check for strdup failure.
v5: fix tabdamage.

include/
	* ctf-api.h (ECTF_INTERNAL): New.

libctf/
	* ctf-link.c (ctf_create_per_cu): New, refactored out of...
	(ctf_link_one_type): ... here, with parent-name setting added.
	(check_variable): New.
	(ctf_link_one_variable): Likewise.
	(ctf_link_one_input_archive_member): Call it.
	* ctf-error.c (_ctf_errlist): Updated with new errors.
2019-10-03 17:04:55 +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
5537f9b9a3 libctf: write CTF files to memory, and CTF archives to fds
Before now, we've been able to write CTF files to gzFile descriptors or
fds, and CTF archives to named files only.

Make this a bit less irregular by allowing CTF archives to be written
to fds with the new function ctf_arc_write_fd: also allow CTF
files to be written to a new memory buffer via ctf_write_mem.

(It would be nice to complete things by adding a new function to write
CTF archives to memory, but this is too difficult to do given the short
time the linker is expected to be writing them out: we will transition
to a better format in format v4, though we will always support reading
CTF archives that are stored in .ctf sections.)

include/
	* ctf-api.h (ctf_arc_write_fd): New.
	(ctf_write_mem): Likewise.
	(ctf_gzwrite): Spacing fix.

libctf/
	* ctf-archive.c (ctf_arc_write): Split off, and reimplement in terms
	of...
	(ctf_arc_write_fd): ... this new function.
	* ctf-create.c (ctf_write_mem): New.
2019-10-03 17:04:55 +01:00
Nick Alcock
0ac6231298 libctf: Add iteration over non-root types
The existing function ctf_type_iter lets you iterate over root-visible
types (types you can look up by name).  There is no way to iterate over
non-root-visible types, which is troublesome because both the linker
and dumper want to do that.

So add a new function that can do it: the callback it takes accepts
an extra parameter which indicates whether the type is root-visible
or not.

include/
	* ctf-api.h (ctf_type_all_f): New.
	(ctf_type_iter_all): New.

libctf/
	* ctf_types.c (ctf_type_iter_all): New.
2019-10-03 17:04:55 +01:00
Nick Alcock
fd55eae84d libctf: allow the header to change between versions
libctf supports dynamic upgrading of the type table as file format
versions change, but before now has not supported changes to the CTF
header.  Doing this is complicated by the baroque storage method used:
the CTF header is kept prepended to the rest of the CTF data, just as
when read from the file, and written out from there, and is
endian-flipped in place.

This makes accessing it needlessly hard and makes it almost impossible
to make the header larger if we add fields.  The general storage
machinery around the malloced ctf pointer (the 'ctf_base') is also
overcomplicated: the pointer is sometimes malloced locally and sometimes
assigned from a parameter, so freeing it requires checking to see if
that parameter was used, needlessly coupling ctf_bufopen and
ctf_file_close together.

So split the header out into a new ctf_file_t.ctf_header, which is
written out explicitly: squeeze it out of the CTF buffer whenever we
reallocate it, and use ctf_file_t.ctf_buf to skip past the header when
we do not need to reallocate (when no upgrading or endian-flipping is
required).  We now track whether the CTF base can be freed explicitly
via a new ctf_dynbase pointer which is non-NULL only when freeing is
possible.

With all this done, we can upgrade the header on the fly and add new
fields as desired, via a new upgrade_header function in ctf-open.
As with other forms of upgrading, libctf upgrades older headers
automatically to the latest supported version at open time.

For a first use of this field, we add a new string field cth_cuname, and
a corresponding setter/getter pair ctf_cuname_set and ctf_cuname: this
is used by debuggers to determine whether a CTF section's types relate
to a single compilation unit, or to all compilation units in the
program.  (Types with ambiguous definitions in different CUs have only
one of these types placed in the top-level shared .ctf container: the
rest are placed in much smaller per-CU containers, which have the shared
container as their parent.  Since CTF must be useful in the absence of
DWARF, we store the names of the relevant CUs ourselves, so the debugger
can look them up.)

v5: fix tabdamage.

include/
	* ctf-api.h (ctf_cuname): New function.
	(ctf_cuname_set): Likewise.
	* ctf.h: Improve comment around upgrading, no longer
	implying that v2 is the target of upgrades (it is v3 now).
	(ctf_header_v2_t): New, old-format header for backward
	compatibility.
	(ctf_header_t): Add cth_cuname: this is the first of several
	header changes in format v3.
libctf/
	* ctf-impl.h (ctf_file_t): New fields ctf_header, ctf_dynbase,
	ctf_cuname, ctf_dyncuname: ctf_base and ctf_buf are no longer const.
	* ctf-open.c (ctf_set_base): Preserve the gap between ctf_buf and
	ctf_base: do not assume that it is always sizeof (ctf_header_t).
	Print out ctf_cuname: only print out ctf_parname if set.
	(ctf_free_base): Removed, ctf_base is no longer freed: free
	ctf_dynbase instead.
	(ctf_set_version): Fix spacing.
	(upgrade_header): New, in-place header upgrading.
	(upgrade_types): Rename to...
	(upgrade_types_v1): ... this.  Free ctf_dynbase, not ctf_base.  No
	longer track old and new headers separately.  No longer allow for
	header sizes explicitly: squeeze the headers out on upgrade (they
	are preserved in fp->ctf_header).  Set ctf_dynbase, ctf_base and
	ctf_buf explicitly.  Use ctf_free, not ctf_free_base.
	(upgrade_types): New, also handle ctf_parmax updating.
	(flip_header): Flip ctf_cuname.
	(flip_types): Flip BUF explicitly rather than deriving BUF from
	BASE.
	(ctf_bufopen): Store the header in fp->ctf_header.  Correct minimum
	required alignment of objtoff and funcoff.  No longer store it in
	the ctf_buf unless that buf is derived unmodified from the input.
	Set ctf_dynbase where ctf_base is dynamically allocated. Drop locals
	that duplicate fields in ctf_file: move allocation of ctf_file
	further up instead.  Call upgrade_header as needed.  Move
	version-specific ctf_parmax initialization into upgrade_types.  More
	concise error handling.
	(ctf_file_close): No longer test for null pointers before freeing.
	Free ctf_dyncuname, ctf_dynbase, and ctf_header.  Do not call
	ctf_free_base.
	(ctf_cuname): New.
	(ctf_cuname_set): New.
	* ctf-create.c (ctf_update): Populate ctf_cuname.
	(ctf_gzwrite): Write out the header explicitly.  Remove obsolescent
	comment.
	(ctf_write): Likewise.
	(ctf_compress_write): Get the header from ctf_header, not ctf_base.
	Fix the compression length: fp->ctf_size never counted the CTF
	header.  Simplify the compress call accordingly.
2019-10-03 17:04:55 +01:00
Nick Alcock
12a0b67d28 libctf: introduce ctf_func_type_{info,args}, ctf_type_aname_raw
The first two of these allow you to get function type info and args out
of the types section give a type ID: astonishingly, this was missing
from libctf before now: so even though types of kind CTF_K_FUNCTION were
supported, you couldn't find out anything about them.  (The existing
ctf_func_info and ctf_func_args only allow you to get info about
functions in the function section, i.e. given symbol table indexes, not
type IDs.)

The second of these allows you to get the raw undecorated name out of
the CTF section (strdupped for safety) without traversing subtypes to
build a full C identifier out of it.  It's useful for things that are
already tracking the type kind etc and just need an unadorned name.

include/
	* ctf-api.h (ECTF_NOTFUNC): Fix description.
	(ctf_func_type_info): New.
	(ctf_func_type_args): Likewise.
libctf/
	* ctf-types.c (ctf_type_aname_raw): New.
	(ctf_func_type_info): Likewise.
	(ctf_func_type_args): Likewise.
	* ctf-error.c (_ctf_errlist): Fix description.
2019-07-18 20:53:57 +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
a30b3e182a libctf: debug dumping
This introduces ctf_dump(), an iterator which returns a series of
strings, each representing a debugging dump of one item from a given
section in the CTF file.  The items may be multiline: a callback is
provided to allow the caller to decorate each line as they desire before
the line is returned.

libctf/
	* ctf-dump.c: New.

include/
	* ctf-api.h (ctf_dump_decorate_f): New.
	(ctf_dump_state_t): new.
	(ctf_dump): New.
2019-05-28 17:09:37 +01:00
Nick Alcock
6dbf2b7340 libctf: labels
This facility allows you to associate regions of type IDs with *labels*,
a labelled tiling of the type ID space. You can use these to define
CTF containers with distinct parents for distinct ranges of the ID
space, or to assist with parallelization of CTF processing, or for any
other purpose you can think of.

Notably absent from here (though declared in the API header) is any way
to define new labels: this will probably be introduced soon, as part of
the linker deduplication work.  (One existed in the past, but was deeply
tied to the Solaris CTF file generator and had to be torn out.)

libctf/
	* ctf-labels.c: New.
include/
	* ctf-api.h (ctf_label_f): New.
	(ctf_label_set): New.
	(ctf_label_get): New.
	(ctf_label_topmost): New.
	(ctf_label_info): New.
	(ctf_label_iter): New.
2019-05-28 17:09:30 +01:00
Nick Alcock
6c33b742ce libctf: library version enforcement
This old Solaris standard allows callers to specify that they are
expecting one particular API and/or CTF file format from the library.

libctf/
	* ctf-impl.h (_libctf_version): New declaration.
	* ctf-subr.c (_libctf_version): Define it.
	(ctf_version): New.

include/
	* ctf-api.h (ctf_version): New.
2019-05-28 17:08:29 +01:00
Nick Alcock
b437bfe0f4 libctf: lookups by name and symbol
These functions allow you to look up types given a name in a simple
subset of C declarator syntax (no function pointers), to look up the
types of variables given a name, and to look up the types of data
objects and the type signatures of functions given symbol table offsets.

(Despite its name, one function in this commit, ctf_lookup_symbol_name(),
is for the internal use of libctf only, and does not appear in any
public header files.)

libctf/
	* ctf-lookup.c (isqualifier): New.
	(ctf_lookup_by_name): Likewise.
	(struct ctf_lookup_var_key): Likewise.
	(ctf_lookup_var): Likewise.
	(ctf_lookup_variable): Likewise.
	(ctf_lookup_symbol_name): Likewise.
	(ctf_lookup_by_symbol): Likewise.
	(ctf_func_info): Likewise.
	(ctf_func_args): Likewise.

include/
	* ctf-api.h (ctf_func_info): New.
	(ctf_func_args): Likewise.
	(ctf_lookup_by_symbol): Likewise.
	(ctf_lookup_by_symbol): Likewise.
	(ctf_lookup_variable): Likewise.
2019-05-28 17:08:19 +01:00
Nick Alcock
316afdb130 libctf: core type lookup
Finally we get to the functions used to actually look up and enumerate
properties of types in a container (names, sizes, members, what type a
pointer or cv-qual references, determination of whether two types are
assignment-compatible, etc).

With a very few exceptions these do not work for types newly added via
ctf_add_*(): they only work on types in read-only containers, or types
added before the most recent call to ctf_update().

This also adds support for lookup of "variables" (string -> type ID
mappings) and for generation of C type names corresponding to a type ID.

libctf/
	* ctf-decl.c: New file.
	* ctf-types.c: Likewise.
	* ctf-impl.h: New declarations.

include/
	* ctf-api.h (ctf_visit_f): New definition.
	(ctf_member_f): Likewise.
	(ctf_enum_f): Likewise.
	(ctf_variable_f): Likewise.
	(ctf_type_f): Likewise.
	(ctf_type_isparent): Likewise.
	(ctf_type_ischild): Likewise.
	(ctf_type_resolve): Likewise.
	(ctf_type_aname): Likewise.
	(ctf_type_lname): Likewise.
	(ctf_type_name): Likewise.
	(ctf_type_sizee): Likewise.
	(ctf_type_align): Likewise.
	(ctf_type_kind): Likewise.
	(ctf_type_reference): Likewise.
	(ctf_type_pointer): Likewise.
	(ctf_type_encoding): Likewise.
	(ctf_type_visit): Likewise.
	(ctf_type_cmp): Likewise.
	(ctf_type_compat): Likewise.
	(ctf_member_info): Likewise.
	(ctf_array_info): Likewise.
	(ctf_enum_name): Likewise.
	(ctf_enum_value): Likewise.
	(ctf_member_iter): Likewise.
	(ctf_enum_iter): Likewise.
	(ctf_type_iter): Likewise.
	(ctf_variable_iter): Likewise.
2019-05-28 17:08:14 +01:00
Nick Alcock
143dce8481 libctf: ELF file opening via BFD
These functions let you open an ELF file with a customarily-named CTF
section in it, automatically opening the CTF file or archive and
associating the symbol and string tables in the ELF file with the CTF
container, so that you can look up the types of symbols in the ELF file
via ctf_lookup_by_symbol(), and so that strings can be shared between
the ELF file and CTF container, to save space.

It uses BFD machinery to do so.  This has now been lightly tested and
seems to work.  In particular, if you already have a bfd you can pass
it in to ctf_bfdopen(), and if you want a bfd made for you you can
call ctf_open() or ctf_fdopen(), optionally specifying a target (or
try once without a target and then again with one if you get
ECTF_BFD_AMBIGUOUS back).

We use a forward declaration for the struct bfd in ctf-api.h, so that
ctf-api.h users are not required to pull in <bfd.h>.  (This is mostly
for the sake of readelf.)

libctf/
	* ctf-open-bfd.c: New file.
	* ctf-open.c (ctf_close): New.
	* ctf-impl.h: Include bfd.h.
	(ctf_file): New members ctf_data_mmapped, ctf_data_mmapped_len.
	(ctf_archive_internal): New members ctfi_abfd, ctfi_data,
	ctfi_bfd_close.
	(ctf_bfdopen_ctfsect): New declaration.
	(_CTF_SECTION): likewise.

include/
	* ctf-api.h (struct bfd): New forward.
	(ctf_fdopen): New.
	(ctf_bfdopen): Likewise.
	(ctf_open): Likewise.
	(ctf_arc_open): Likewise.
2019-05-28 17:08:08 +01:00
Nick Alcock
9402cc593f libctf: mmappable archives
If you need to store a large number of CTF containers somewhere, this
provides a dedicated facility for doing so: an mmappable archive format
like a very simple tar or ar without all the system-dependent format
horrors or need for heavy file copying, with built-in compression of
files above a particular size threshold.

libctf automatically mmap()s uncompressed elements of these archives, or
uncompresses them, as needed.  (If the platform does not support mmap(),
copying into dynamically-allocated buffers is used.)

Archive iteration operations are partitioned into raw and non-raw
forms. Raw operations pass thhe raw archive contents to the callback:
non-raw forms open each member with ctf_bufopen() and pass the resulting
ctf_file_t to the iterator instead.  This lets you manipulate the raw
data in the archive, or the contents interpreted as a CTF file, as
needed.

It is not yet known whether we will store CTF archives in a linked ELF
object in one of these (akin to debugdata) or whether they'll get one
section per TU plus one parent container for types shared between them.
(In the case of ELF objects with very large numbers of TUs, an archive
of all of them would seem preferable, so we might just use an archive,
and add lzma support so you can assume that .gnu_debugdata and .ctf are
compressed using the same algorithm if both are present.)

To make usage easier, the ctf_archive_t is not the on-disk
representation but an abstraction over both ctf_file_t's and archives of
many ctf_file_t's: users see both CTF archives and raw CTF files as
ctf_archive_t's upon opening, the only difference being that a raw CTF
file has only a single "archive member", named ".ctf" (the default if a
null pointer is passed in as the name).  The next commit will make use
of this facility, in addition to providing the public interface to
actually open archives.  (In the future, it should be possible to have
all CTF sections in an ELF file appear as an "archive" in the same
fashion.)

This machinery is also used to allow library-internal creators of
ctf_archive_t's (such as the next commit) to stash away an ELF string
and symbol table, so that all opens of members in a given archive will
use them.  This lets CTF archives exploit the ELF string and symbol
table just like raw CTF files can.

(All this leads to somewhat confusing type naming.  The ctf_archive_t is
a typedef for the opaque internal type, struct ctf_archive_internal: the
non-internal "struct ctf_archive" is the on-disk structure meant for
other libraries manipulating CTF files.  It is probably clearest to use
the struct name for struct ctf_archive_internal inside the program, and
the typedef names outside.)

libctf/
	* ctf-archive.c: New.
	* ctf-impl.h (ctf_archive_internal): New type.
	(ctf_arc_open_internal): New declaration.
	(ctf_arc_bufopen): Likewise.
	(ctf_arc_close_internal): Likewise.
include/
	* ctf.h (CTFA_MAGIC): New.
	(struct ctf_archive): New.
	(struct ctf_archive_modent): Likewise.
	* ctf-api.h (ctf_archive_member_f): New.
	(ctf_archive_raw_member_f): Likewise.
	(ctf_arc_write): Likewise.
	(ctf_arc_close): Likewise.
	(ctf_arc_open_by_name): Likewise.
	(ctf_archive_iter): Likewise.
	(ctf_archive_raw_iter): Likewise.
	(ctf_get_arc): Likewise.
2019-05-28 17:07:55 +01:00
Nick Alcock
72f3392127 libctf: opening
This fills in the other half of the opening/creation puzzle: opening of
already-existing CTF files.  Such files are always read-only: if you
want to add to a CTF file opened with one of the opening functions in
this file, use ctf_add_type(), in a later commit, to copy appropriate
types into a newly ctf_create()d, writable container.

The lowest-level opening functions are in here: ctf_bufopen(), which
takes ctf_sect_t structures akin to ELF section headers, and
ctf_simple_open(), which can be used if you don't have an entire ELF
section header to work from.  Both will malloc() new space for the
buffers only if necessary, will mmap() directly from the file if
requested, and will mprotect() it afterwards to prevent accidental
corruption of the types. These functions are also used by ctf_update()
when converting types in a writable container into read-only types that
can be looked up using the lookup functions (in later commits).

The files are always of the native endianness of the system that created
them: at read time, the endianness of the header magic number is used to
determine whether or not the file needs byte-swapping, and the entire
thing is aggressively byte-swapped.

The agggressive nature of this swapping avoids complicating the rest of
the code with endianness conversions, while the native endianness
introduces no byte-swapping overhead in the common case. (The
endianness-independence code is also much newer than everything else in
this file, and deserves closer scrutiny.)

The accessors at the top of the file are there to transparently support
older versions of the CTF file format, allowing translation from older
formats that have different sizes for the structures in ctf.h:
currently, these older formats are intermingled with the newer ones in
ctf.h: they will probably migrate to a compatibility header in time, to
ease readability.  The ctf_set_base() function is split out for the same
reason: when conversion code to a newer format is written, it would need
to malloc() new storage for the entire ctf_file_t if a file format
change causes it to grow, and for that we need ctf_set_base() to be a
separate function.

One pair of linked data structures supported by this file has no
creation code in libctf yet: the data and function object sections read
by init_symtab(). These will probably arrive soon, when the linker comes
to need them. (init_symtab() has hardly been changed since 2009, but if
any code in libctf has rotted over time, this will.)

A few simple accessors are also present that can even be called on
read-only containers because they don't actually modify them, since the
relevant things are not stored in the container but merely change its
operation: ctf_setmodel(), which lets you specify whether a container is
LP64 or not (used to statically determine the sizes of a few types),
ctf_import(), which is the only way to associate a parent container with
a child container, and ctf_setspecific(), which lets the caller
associate an arbitrary pointer with the CTF container for any use. If
the user doesn't call these functions correctly, libctf will misbehave:
this is particularly important for ctf_import(), since a container built
against a given parent container will not be able to resolve types that
depend on types in the parent unless it is ctf_import()ed with a parent
container with the same set of types at the same IDs, or a superset.

Possible future extensions (also noted in the ctf-hash.c file) include
storing a count of things so that we don't need to do one pass over the
CTF file counting everything, and computing a perfect hash at CTF
creation time in some compact form, storing it in the CTF file, and
using it to hash things so we don't need to do a second pass over the
entire CTF file to set up the hashes used to go from names to type IDs.
(There are multiple such hashes, one for each C type namespace: types,
enums, structs, and unions.)

libctf/
	* ctf-open.c: New file.
	* swap.h: Likewise.
include/
	* ctf-api.h (ctf_file_close): New declaration.
	(ctf_getdatasect): Likewise.
	(ctf_parent_file): Likewise.
	(ctf_parent_name): Likewise.
	(ctf_parent_name_set): Likewise.
	(ctf_import): Likewise.
	(ctf_setmodel): Likewise.
	(ctf_getmodel): Likewise.
	(ctf_setspecific): Likewise.
	(ctf_getspecific): Likewise.
2019-05-28 17:07:46 +01:00
Nick Alcock
47d546f427 libctf: creation functions
The CTF creation process looks roughly like (error handling elided):

int err;
ctf_file_t *foo = ctf_create (&err);

ctf_id_t type = ctf_add_THING (foo, ...);
ctf_update (foo);
ctf_*write (...);

Some ctf_add_THING functions accept other type IDs as arguments,
depending on the type: cv-quals, pointers, and structure and union
members all take other types as arguments.  So do 'slices', which
let you take an existing integral type and recast it as a type
with a different bitness or offset within a byte, for bitfields.
One class of THING is not a type: "variables", which are mappings
of names (in the internal string table) to types.  These are mostly
useful when encoding variables that do not appear in a symbol table
but which some external user has some other way to figure out the
address of at runtime (dynamic symbol lookup or querying a VM
interpreter or something).

You can snapshot the creation process at any point: rolling back to a
snapshot deletes all types and variables added since that point.

You can make arbitrary type queries on the CTF container during the
creation process, but you must call ctf_update() first, which
translates the growing dynamic container into a static one (this uses
the CTF opening machinery, added in a later commit), which is quite
expensive.  This function must also be called after adding types
and before writing the container out.

Because addition of types involves looking up existing types, we add a
little of the type lookup machinery here, as well: only enough to
look up types in dynamic containers under construction.

libctf/
	* ctf-create.c: New file.
	* ctf-lookup.c: New file.

include/
	* ctf-api.h (zlib.h): New include.
	(ctf_sect_t): New.
	(ctf_sect_names_t): Likewise.
	(ctf_encoding_t): Likewise.
	(ctf_membinfo_t): Likewise.
	(ctf_arinfo_t): Likewise.
	(ctf_funcinfo_t): Likewise.
	(ctf_lblinfo_t): Likewise.
	(ctf_snapshot_id_t): Likewise.
	(CTF_FUNC_VARARG): Likewise.
	(ctf_simple_open): Likewise.
	(ctf_bufopen): Likewise.
	(ctf_create): Likewise.
	(ctf_add_array): Likewise.
	(ctf_add_const): Likewise.
	(ctf_add_enum_encoded): Likewise.
	(ctf_add_enum): Likewise.
	(ctf_add_float): Likewise.
	(ctf_add_forward): Likewise.
	(ctf_add_function): Likewise.
	(ctf_add_integer): Likewise.
	(ctf_add_slice): Likewise.
	(ctf_add_pointer): Likewise.
	(ctf_add_type): Likewise.
	(ctf_add_typedef): Likewise.
	(ctf_add_restrict): Likewise.
	(ctf_add_struct): Likewise.
	(ctf_add_union): Likewise.
	(ctf_add_struct_sized): Likewise.
	(ctf_add_union_sized): Likewise.
	(ctf_add_volatile): Likewise.
	(ctf_add_enumerator): Likewise.
	(ctf_add_member): Likewise.
	(ctf_add_member_offset): Likewise.
	(ctf_add_member_encoded): Likewise.
	(ctf_add_variable): Likewise.
	(ctf_set_array): Likewise.
	(ctf_update): Likewise.
	(ctf_snapshot): Likewise.
	(ctf_rollback): Likewise.
	(ctf_discard): Likewise.
	(ctf_write): Likewise.
	(ctf_gzwrite): Likewise.
	(ctf_compress_write): Likewise.
2019-05-28 17:07:40 +01:00
Nick Alcock
479604f44f libctf: error handling
CTF functions return zero on success or an extended errno value which
can be translated into a string via the functions in this commit.

The errno numbers start at -CTF_BASE.

libctf/
	* ctf-error.c: New file.

include/
	* ctf-api.h (ctf_errno): New declaration.
	(ctf_errmsg): Likewise.
2019-05-28 17:07:24 +01:00
Nick Alcock
60da9d9559 libctf: lowest-level memory allocation and debug-dumping wrappers
The memory-allocation wrappers are simple things to allow malloc
interposition: they are only used inconsistently at present, usually
where malloc debugging was required in the past.

These provide a default implementation that is environment-variable
triggered (initialized on the first call to the libctf creation and
file-opening functions, the first functions people will use), and
a ctf_setdebug()/ctf_getdebug() pair that allows the caller to
explicitly turn debugging off and on.  If ctf_setdebug() is called,
the automatic setting from an environment variable is skipped.

libctf/
	* ctf-impl.h: New file.
	* ctf-subr.c: New file.

include/
	* ctf-api.h (ctf_setdebug): New.
	(ctf_getdebug): Likewise.
2019-05-28 17:07:15 +01:00
Nick Alcock
2e94b05630 include: new header ctf-api.h
This non-installed header is the means by which libctf consumers
communicate with libctf.

This header will be extended in subsequent commits.

include/
	* ctf-api.h: New file.
2019-05-28 17:07:11 +01:00