Commit Graph

12 Commits

Author SHA1 Message Date
Alan Modra b3adc24a07 Update year range in copyright notice of binutils files 2020-01-01 18:42:54 +10:30
Nick Alcock 9323dd869d libctf: make ctf_dump not crash on OOM
ctf_dump calls ctf_str_append extensively but never checks to see if it
returns NULL (on OOM).  If it ever does, we truncate the string we are
appending to and leak it!

Instead, create a variant of ctf_str_append that returns the *original
string* on OOM, and use it in ctf-dump.  It is far better to omit a tiny
piece of a dump on OOM than to omit a bigger piece, and it is also
better to do this in what is after all purely debugging code than it is
to uglify ctf-dump.c with huge numbers of checks for the out-of-memory
case.  Slightly truncated debugging output is better than no debugging
output at all and an out-of-memory message.

New in v4.

libctf/
	* ctf-impl.h (ctf_str_append_noerr): Declare.
	* ctf-util.c (ctf_str_append_noerr): Define in terms of
	ctf_str_append.
	* ctf-dump.c (str_append): New, call it.
	(ctf_dump_format_type): Use str_append, not ctf_str_append.
	(ctf_dump_label): Likewise.
	(ctf_dump_objts): Likewise.
	(ctf_dump_funcs): Likewise.
	(ctf_dump_var): Likewise.
	(ctf_dump_member): Likewise.
	(ctf_dump_type): Likewise.
	(ctf_dump): Likewise.
2019-10-03 17:04:56 +01:00
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 d18f9f1629 libctf: dump: check the right error values when dumping functions
We weren't correctly detecting when there were no functions to dump in
the function info table, because we were checking for ECTF_NOTYPEDAT,
which means there are no *data objects* to dump.

Adjust accordingly.

libctf/
	* ctf-dump.c (ctf_dump_funcs): Check the right error value.
2019-10-03 17:04:55 +01:00
Nick Alcock b4f0e09cd1 libctf: dump: support non-root type dumping
Use the recently-added ctf_type_iter_all function to iterate over
non-root types, too, indicating them via {....} surrounding the type
description in the dump.

libctf/
	* ctf-dump.c (ctf_dump): Use ctf_type_iter_all to dump types, not
	ctf_type_iter.
	(ctf_dump_type): Pass down the flag from ctf_type_iter_all.
	(ctf_dump_format_type): Add non-root-type { } notation.
	Add root flag to prototype.
	(ctf_dump_label): Adjust accordingly.
	(ctf_dump_objts): Likewise.
	(ctf_dump_var): Likewise.
2019-10-03 17:04:55 +01:00
Nick Alcock 9b32cba44d libctf, binutils: dump the CTF header
The CTF header has before now been thrown away too soon to be dumped
using the ctf_dump() machinery used by objdump and readelf: instead, a
kludge involving debugging-priority dumps of the header offsets on every
open was used.

Replace this with proper first-class dumping machinery just like
everything else in the CTF file, and have objdump and readelf use it.
(The dumper already had an enum value in ctf_sect_names_t for this
purpose, waiting to be used.)

v5: fix tabdamage.

libctf/
	* ctf-impl.h (ctf_file_t): New field ctf_openflags.
	* ctf-open.c (ctf_bufopen): Set it.  No longer dump header offsets.
	* ctf-dump.c (dump_header): New function, dump the CTF header.
	(ctf_dump): Call it.
	(ctf_dump_header_strfield): New function.
	(ctf_dump_header_sectfield): Likewise.

binutils/
	* objdump.c (dump_ctf_archive_member): Dump the CTF header.
	* readelf.c (dump_section_as_ctf): Likewise.
2019-10-03 17:04:55 +01:00
Nick Alcock c550e7ba93 libctf: disambiguate hex output in dumps
We were sometimes printing hex values without prefixing them with '0x',
leading to confusion about what base the numbers were actually in.

libctf/
	* ctf-dump.c (ctf_dump_format_type): Prefix hex strings with 0x.
	(ctf_dump_funcs): Likewise.
2019-07-01 11:05:59 +01:00
Nick Alcock 595a4d439b libctf: explicitly cast more size_t types used in printf()s
Unsigned long will always be adequate (the only cases involving an
ssize_t are cases in which no error can be generated, or in which
negative output would require a seriously corrupted file: the latter has
been rewritten on a branch in any case).

Tested on x86_64-pc-linux-gnu, x86_64-unknown-freebsd12.0,
sparc-sun-solaris2.11, i686-pc-cygwin, i686-w64-mingw32.

libctf/
	* ctf-dump.c (ctf_dump_format_type): Cast size_t's used in printf()s.
	(ctf_dump_objts): Likewise.
	(ctf_dump_funcs): Likewise.
	(ctf_dump_member): Likewise.
	(ctf_dump_str): Likewise.
2019-06-07 13:46:38 +01:00
Nick Alcock 941accce38 libctf: fix use-after-free in function dumping
This is actually a free-before-initializing (i.e. a free of garbage).

libctf/
	* ctf-dump.c (ctf_dump_funcs): Free in the right place.
2019-06-04 17:05:08 +01:00
Jose E. Marchesi a0486bac41 libctf: fix a number of build problems found on Solaris and NetBSD
- Use of nonportable <endian.h>
- Use of qsort_r
- Use of zlib without appropriate magic to pull in the binutils zlib
- Use of off64_t without checking (fixed by dropping the unused fields
  that need off64_t entirely)
- signedness problems due to long being too short a type on 32-bit
  platforms: ctf_id_t is now 'unsigned long', and CTF_ERR must be
  used only for functions that return ctf_id_t
- One lingering use of bzero() and of <sys/errno.h>

All fixed, using code from gnulib where possible.

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

binutils/
	* objdump.c (make_ctfsect): Drop cts_type, cts_flags, and
	cts_offset.
	* readelf.c (shdr_to_ctf_sect): Likewise.
include/
	* ctf-api.h (ctf_sect_t): Drop cts_type, cts_flags, and cts_offset.
	(ctf_id_t): This is now an unsigned type.
	(CTF_ERR): Cast it to ctf_id_t.  Note that it should only be used
	for ctf_id_t-returning functions.
libctf/
	* Makefile.am (ZLIB): New.
	(ZLIBINC): Likewise.
	(AM_CFLAGS): Use them.
	(libctf_a_LIBADD): New, for LIBOBJS.
	* configure.ac: Check for zlib, endian.h, and qsort_r.
	* ctf-endian.h: New, providing htole64 and le64toh.
	* swap.h: Code style fixes.
	(bswap_identity_64): New.
	* qsort_r.c: New, from gnulib (with one added #include).
	* ctf-decls.h: New, providing a conditional qsort_r declaration,
	and unconditional definitions of MIN and MAX.
	* ctf-impl.h: Use it.  Do not use <sys/errno.h>.
	(ctf_set_errno): Now returns unsigned long.
	* ctf-util.c (ctf_set_errno): Adjust here too.
	* ctf-archive.c: Use ctf-endian.h.
	(ctf_arc_open_by_offset): Use memset, not bzero.  Drop cts_type,
	cts_flags and cts_offset.
	(ctf_arc_write): Drop debugging dependent on the size of off_t.
	* ctf-create.c: Provide a definition of roundup if not defined.
	(ctf_create): Drop cts_type, cts_flags and cts_offset.
	(ctf_add_reftype): Do not check if type IDs are below zero.
	(ctf_add_slice): Likewise.
	(ctf_add_typedef): Likewise.
	(ctf_add_member_offset): Cast error-returning ssize_t's to size_t
	when known error-free.  Drop CTF_ERR usage for functions returning
	int.
	(ctf_add_member_encoded): Drop CTF_ERR usage for functions returning
	int.
	(ctf_add_variable): Likewise.
	(enumcmp): Likewise.
	(enumadd): Likewise.
	(membcmp): Likewise.
	(ctf_add_type): Likewise.  Cast error-returning ssize_t's to size_t
	when known error-free.
	* ctf-dump.c (ctf_is_slice): Drop CTF_ERR usage for functions
	returning int: use CTF_ERR for functions returning ctf_type_id.
	(ctf_dump_label): Likewise.
	(ctf_dump_objts): Likewise.
	* ctf-labels.c (ctf_label_topmost): Likewise.
	(ctf_label_iter): Likewise.
	(ctf_label_info): Likewise.
	* ctf-lookup.c (ctf_func_args): Likewise.
	* ctf-open.c (upgrade_types): Cast to size_t where appropriate.
	(ctf_bufopen): Likewise.  Use zlib types as needed.
	* ctf-types.c (ctf_member_iter): Drop CTF_ERR usage for functions
	returning int.
	(ctf_enum_iter): Likewise.
	(ctf_type_size): Likewise.
	(ctf_type_align): Likewise.  Cast to size_t where appropriate.
	(ctf_type_kind_unsliced): Likewise.
	(ctf_type_kind): Likewise.
	(ctf_type_encoding): Likewise.
	(ctf_member_info): Likewise.
	(ctf_array_info): Likewise.
	(ctf_enum_value): Likewise.
	(ctf_type_rvisit): Likewise.
	* ctf-open-bfd.c (ctf_bfdopen): Drop cts_type, cts_flags and
	cts_offset.
	(ctf_simple_open): Likewise.
	(ctf_bfdopen_ctfsect): Likewise.  Set cts_size properly.
	* Makefile.in: Regenerate.
	* aclocal.m4: Likewise.
	* config.h: Likewise.
	* configure: Likewise.
2019-05-31 11:10:51 +02:00
Nick Alcock 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