Age | Commit message (Collapse) | Author | Files | Lines |
|
This matters for the case of unnamed bitfields, whose names are the null
string. These are special in that they are the only members whose
"names" are allowed to be duplicated in a single struct, but we were
only handling this for the case where name == NULL. Translate "" to
NULL to help callers.
libctf/
* ctf-create.c (ctf_add_member_offset): Support names of ""
as if they were the null pointer.
|
|
When opening, we consider a forward with a kind above the maximum
allowable set of kinds and a forward of kind CTF_K_UNKNOWN to be a
forward to a struct. Whatever CTF version it was that produced
forwards with no associated kind, it predates anything we can read:
remove this wart.
libctf/
* ctf-open.c (init_types): Remove typeless CTF_K_FORWARD
special-casing.
|
|
One spot was missed when we rejigged ctf_update into ctf_serialize and
allowed all operations on dynamic containers: ctf_type_reference of
slices. A dynamic slice's vlen state is stored in the dtu_slice member,
so fetch it from there.
libctf/
* ctf-types.c (ctf_type_reference): Add support for dynamic slices.
|
|
This is technically unnecessary -- the compiler is quite capable of
doing the range reduction for us -- but it does mean that all
assignments of a ctf_id_t to its final uint32_t representation now have
appropriate explicit casts.
libctf/
* ctf-create.c (ctf_serialize): Add cast.
(ctf_add_slice): Likewise.
|
|
ctf_add_function assumes that function types' arglists are of type
ctf_id_t. Since they are CTF IDs, they are 32 bits wide, a uint32_t:
unfortunately ctf_id_t is a forward-compatible user-facing 64 bits wide,
and should never ever reach the CTF storage level.
All the CTF code other than ctf_add_function correctly assumes that
function arglists outside dynamic containers are 32 bits wide, so the
serialization machinery ends up cutting off half the arglist, corrupting
all args but the first (a good sign is a bunch of args of ID 0, the
unimplemented type, popping up).
Fix this by copying the arglist into place item by item, casting it
properly, at the same time as we validate the arg types. Fix the type
of the dtu_argv in the dynamic container and drop the now-unnecessary
cast in the serializer.
libctf/
* ctf-impl.h (ctf_dtdef_t) <dtu_argv>: Fix type.
* ctf-create.c (ctf_add_function): Check for unimplemented type
and populate at the same time. Populate one-by-one, not via
memcpy.
(ctf_serialize): Remove unnecessary cast.
* ctf-types.c (ctf_func_type_info): Likewise.
(ctf_func_type_args): Likewise. Fix comment typo.
|
|
The deduplicating linker adds types from the linker inputs to the output
via the same API everyone else does, so it's important that we can emit
everything that the compiler wants us to. Unfortunately, the compiler
may represent the unimplemented type (used for compiler constructs that
CTF cannot currently encode) as type zero or as a type of kind
CTF_K_UNKNOWN, and we don't allow the addition of types that cite the
former.
Adding this support adds a tiny bit of extra complexity: additions of
structure members immediately following a member of the unimplemented
type must be via ctf_add_member_offset or ctf_add_member_encoded, since
we have no idea how big members of the unimplemented type are.
(Attempts to do otherwise return -ECTF_NONREPRESENTABLE, like other
attempts to do forbidden things with the unimplemented type.)
Even slices of the unimplemented type are permitted: this is the only
case in which you can slice a type that terminates in a non-integral
type, on the grounds that it was likely integral in the source code,
it's just that we can't represent that sort of integral type properly
yet.
libctf/
* ctf-create.c (ctf_add_reftype): Support refs to type zero.
(ctf_add_array): Support array contents of type zero.
(ctf_add_function): Support arguments and return types of
type zero.
(ctf_add_typedef): Support typedefs to type zero.
(ctf_add_member_offset): Support members of type zero,
unless added at unspecified (naturally-aligned) offset.
|
|
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.
|
|
include/
* ctf-api.h: Fix typos in comments.
libctf/
* ctf-impl.h: Fix typos in comments.
|
|
readelf * readelf.c (parse_args): Silence potential warnings about a
memory resource leak when allocating space for ctf option values.
(dump_section_as_ctf): Fix typo checking dump_ctf_strtab_name
variable.
libctf * ctf-archive.c (ctf_arc_write): Avoid calling close twice on the
same file descriptor.
|
|
|
|
We were not using the right configure machinery to spot libintl on
platforms where it was required, leading to the spurious failure of
various configure tests (e.g. for things like ELF support in BFD).
libctf/
* aclocal.m4: Add config/gettext-sister.m4: Shuffle into
alphabetical order.
* configure.ac: Add ZW_GNU_GETTEXT_SISTER_DIR.
* config.h.in: Regenerated.
* Makefile.in: Likewise.
* configure: Likewise.
|
|
Causes warnings on (at least) recent FreeBSD.
libctf/
* ctf-create.c: Include <unistd.h>.
* ctf-open-bfd.c: Likewise.
|
|
At least one C library (uclibc-ng) defines some of these only when
the compiler is GCC. We might as well test for all three cases and
handle any of them being missing.
Very similar code exists in libctf and split between elfcpp and gold:
fix both.
(Also sync up elfcpp with a change made to libctf swap.h a few months
ago: since there is no out-of-line definition of the bswap replacements,
they should be declared static inline, not just inline, to prevent the
linker generating out-of-line references to them.)
PR libctf/25120
libctf/
* configure.ac: Check for bswap_16, bswap_32, and bswap_64 decls.
* swap.h (bswap_16): Do not assume that presence of <byteswap.h>
means this is declared.
(bswap_32): Likewise.
(bswap_64): Likewise.
(bswap_identity_64): Remove, unused.
* configure: Regenerated.
* config.h.in: Likewise.
gold/
* configure.ac: Check for bswap_16, bswap_32, and bswap_64 decls.
* configure: Regenerated.
* config.h.in: Likewise.
elfcpp/
* elfcpp_swap.h (bswap_16): Do not assume that presence of
<byteswap.h> means this is declared. Make static inline, matching
recent change to libctf, since there is no non-inline definition
of these functions.
(bswap_32): Likewise.
(bswap_64): Likewise.
|
|
The obvious fallback __attribute__ stanza was missing.
Thanks to Harald van Dijk.
PR 25120
libctf/
* ctf-impl.h (_libctf_printflike_): Add non-GNU-C fallback.
(_libctf_unlikely_): Likewise.
(_libctf_unused): Likewise.
(_libctf_malloc_): Likewise.
|
|
This keeps archive searching threadsafe using the new bsearch_r that was
just added to libiberty.
PR25120
libctf/
* ctf-archive.c (search_nametbl): No longer global: declare...
(ctf_arc_open_by_name_internal): ... here. Use bsearch_r.
(search_modent_by_name): Take and use ARG for the nametbl.
|
|
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.
|
|
The C namespace a forward is located in is always the same as the
namespace of the corresponding complete type: 'struct foo' is in the
struct namespace and does not collide with, say, 'union foo'.
libctf allowed for this in many places, but inconsistently: in
particular, forward *addition* never allowed for this, and was interning
forwards in the default namespace, which is always wrong, since you can
only forward structs, unions and enums, all of which are in their own
namespaces in C.
Forward removal needs corresponding adjustment to remove the names form
the right namespace, as does ctf_rollback.
libctf/
* ctf-create.c (ctf_add_forward): Intern in the right namespace.
(ctf_dtd_delete): Remove correspondingly.
(ctf_rollback): Likewise.
|
|
When we add a type from a dictionary and then try to add it again, we
should hand it back unchanged unless it is a structure, union or enum
with a different number of members. That's what the comment says we do.
Instead, we hand it back unchanged *only* if it is a structure, union or
enum with the same number of members: non-structs, unions and enums are
unconditionally added. This causes extreme type bloating and (in
conjunction with the bug fixed by the next commit) can easily lead to
the same type being mistakenly added to a dictionary more than once
(which, for forwards, was not banned and led to dictionary corruption).
libctf/
* ctf-create.c (ctf_add_type_internal): Hand back existing types
unchanged.
|
|
This is what ctf_add_forward is documented to do, but it's not what it
actually does: the code is quite happy to add forwards that duplicate
existing structs, etc.
This is obviously wrong and breaks both the nondeduplicating linker
and the upcoming deduplicator, as well as allowing ordinary callers of
ctf_add_type to corrupt the dictionary by just adding the same root-
visible forward more than once.
libctf/
* ctf-create.c (ctf_add_forward): Don't add forwards to
types that already exist.
|
|
We were accidentally interning newly-added and newly-opened
non-root-visible types into name tables, and removing names from name
tables when such types were removed. This is very wrong: the whole
point of non-root-visible types is they do not go in name tables and
cannot be looked up by name. This bug made non-root-visible types
basically identical to root-visible types, right back to the earliest
days of libctf in the Solaris era.
libctf/
* ctf-open.c (init_types): Only intern root-visible types.
* ctf-create.c (ctf_dtd_insert): Likewise.
(ctf_dtd_delete): Only remove root-visible types.
(ctf_rollback): Likewise.
(ctf_add_generic): Adjust.
(ctf_add_struct_sized): Adjust comment.
(ctf_add_union_sized): Likewise.
(ctf_add_enum): Likewise.
* ctf-impl.h (ctf_dtd_insert): Adjust prototype.
|
|
This is similar to cbbbc402e059ee345cb781d3ceb757ae1cc679ee and fixes
a link error with duplicately defined symbols on FreeBSD.
libctf/ChangeLog:
* swap.h (bswap_identity_64): Make static.
|
|
|
|
|
|
This commit fixes a compilation warning when compiling libctf
on MinGW:
libctf/ctf-dump.c:118:8: warning: implicit declaration of function
'asprintf'; did you mean 'vasprintf'? [-Wimplicit-function-declaration]
if (asprintf (&bit, " %lx: [slice 0x%x:0x%x]",
^~~~~~~~
vasprintf
MinGW doesn't provide that function, so we depend on the one provided
by libiberty. However, the declaration is guarded by HAVE_DECL_ASPRINTF,
which we do not have in libctf's config.h.
libctf/ChangeLog:
PR binutils/25155:
* configure.ac: Add AC_CHECK_DECLS([asprintf]).
* configure, config.h.in: Regenerate.
|
|
Add the ChangeLog entry.
|
|
|
|
When building binutils with mingw-w64, I get the following errors:
make[4]: Entering directory '/home/simark/build/binutils-gdb-mingw/binutils'
/bin/sh ./libtool --tag=CC --mode=link ccache x86_64-w64-mingw32-gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Wno-format -Werror -I/home/simark/src/binutils-gdb/binutils/../zlib -g3 -O0 -D__USE_MINGW_ACCESS -Wl,--stack,12582912 -o objdump.exe objdump.o dwarf.o prdbg.o rddbg.o debug.o stabs.o rdcoff.o bucomm.o version.o filemode.o elfcomm.o ../opcodes/libopcodes.la ../libctf/libctf.la ../bfd/libbfd.la ../libiberty/libiberty.a -lintl
libtool: link: ccache x86_64-w64-mingw32-gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Wno-format -Werror -I/home/simark/src/binutils-gdb/binutils/../zlib -g3 -O0 -D__USE_MINGW_ACCESS -Wl,--stack -Wl,12582912 -o .libs/objdump.exe objdump.o dwarf.o prdbg.o rddbg.o debug.o stabs.o rdcoff.o bucomm.o version.o filemode.o elfcomm.o ../opcodes/.libs/libopcodes.a ../libctf/.libs/libctf.a -L/home/simark/build/binutils-gdb-mingw/zlib ../bfd/.libs/libbfd.a -lz ../libiberty/libiberty.a -lintl
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: ../libctf/.libs/libctf.a(ctf-open.o): in function `flip_header':
/home/simark/src/binutils-gdb/libctf/ctf-open.c:964: undefined reference to `bswap_16'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:967: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:968: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:969: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:970: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:971: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: ../libctf/.libs/libctf.a(ctf-open.o):/home/simark/src/binutils-gdb/libctf/ctf-open.c:972: more undefined references to `bswap_32' follow
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: ../libctf/.libs/libctf.a(ctf-open.o): in function `flip_types':
/home/simark/src/binutils-gdb/libctf/ctf-open.c:1112: undefined reference to `bswap_16'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:1113: undefined reference to `bswap_16'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:1132: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:1133: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:1134: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:1135: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: /home/simark/src/binutils-gdb/libctf/ctf-open.c:1144: undefined reference to `bswap_32'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: ../libctf/.libs/libctf.a(ctf-open.o):/home/simark/src/binutils-gdb/libctf/ctf-open.c:1145: more undefined references to `bswap_32' follow
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: ../libctf/.libs/libctf.a(ctf-open.o): in function `ctf_bufopen_internal':
/home/simark/src/binutils-gdb/libctf/ctf-open.c:1342: undefined reference to `bswap_16'
/usr/lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld: ../libctf/.libs/libctf.a(ctf-open-bfd.o): in function `ctf_fdopen':
/home/simark/src/binutils-gdb/libctf/ctf-open-bfd.c:268: undefined reference to `bswap_16'
Apparently [1], if we have a function with `inline` but not `static`,
there should be a compilation unit defining the symbol too.
Alternatively, making those functions `static` fixes that.
[1] https://stackoverflow.com/questions/16245521/c99-inline-function-in-c-file/16254679#16254679
libctf/ChangeLog:
* swap.h (bswap_16, bswap_32, bswap_64): Make static.
Change-Id: I8fd12aedf6c90f9b7418af948e5e0bae0c32eead
|
|
A little tabdamage predating the linker patch series has crept in.
New in v5.
libctf/
* ctf-open.c (ctf_bufopen_internal): Fix tabdamage.
* ctf-types.c (ctf_type_lname): Likewise.
|
|
Calling ctf_import (fp, NULL) to cancel out a pre-existing import leaked
the refcnt increment on the parent, so it could never be freed.
New in v4.
libctf/
* ctf-open.c (ctf_import): Do not leak a ctf_file_t ref on every
ctf_import after the first for a given file.
|
|
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.
|
|
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.
|
|
If you call ctf_type_encoding() on a slice, you are meant to get the
encoding of the slice with the format of the underlying type. If
you call it on a non-int, non-fp, non-slice, you're meant to get the
error ECTF_INTNOTFP.
None of this was implemented for types in the dynamic space (which, now,
is *all* types in writable containers). Instead, we were always
returning the encoding as if it were a float, which for all other types
consulted the wrong part of a discriminated union and returned garbage.
(Curiously, existing users were more disturbed by the lack of an error
in the non-int/fp/slice case than they were about getting garbage back.)
libctf/
* ctf-types.c (ctf_type_encoding): Fix the dynamic case to
work right for non-int/fps.
|
|
The code was meant to handle this, but accidentally dereferenced the
null pointer before checking it for nullity.
v5: fix tabdamage.
libctf/
* ctf-types.c (ctf_type_name): Don't strlen a potentially-
null pointer.
|
|
The code to handle structures (and unions) that refer to themselves in
ctf_add_type is extremely dodgy. It works by looking through the list
of not-yet-committed types for a structure with the same name as the
structure in question and assuming, if it finds it, that this must be a
reference to the same type. This is a linear search that gets ever
slower as the dictionary grows, requiring you to call ctf_update at
intervals to keep performance tolerable: but if you do that, you run
into the problem that if a forward declared before the ctf_update is
changed to a structure afterwards, ctf_update explodes.
The last commit fixed most of this: this commit can use it, adding a new
ctf_add_processing hash that tracks source type IDs that are currently
being processed and uses it to avoid infinite recursion rather than the
dynamic type list: we split ctf_add_type into a ctf_add_type_internal,
so that ctf_add_type itself can become a wrapper that empties out this
being-processed hash once the entire recursive type addition is over.
Structure additions themselves avoid adding their dependent types
quite so much by checking the type mapping and avoiding re-adding types
we already know we have added.
We also add support for adding forwards to dictionaries that already
contain the thing they are a forward to: we just silently return the
original type.
v4: return existing struct/union/enum types properly, rather than using
an uninitialized variable: shrinks sizes of CTF sections back down
to roughly where they were in v1/v2 of this patch series.
v5: fix tabdamage.
libctf/
* ctf-impl.h (ctf_file_t) <ctf_add_processing>: New.
* ctf-open.c (ctf_file_close): Free it.
* ctf-create.c (ctf_serialize): Adjust.
(membcmp): When reporting a conflict due to an error, report the
error.
(ctf_add_type): Turn into a ctf_add_processing wrapper. Rename to...
(ctf_add_type_internal): ... this. Hand back types we are already
in the middle of adding immediately. Hand back structs/unions with
the same number of members immediately. Do not walk the dynamic
list. Call ctf_add_type_internal, not ctf_add_type. Handle
forwards promoted to other types and the inverse case identically.
Add structs to the mapping as soon as we intern them, before they
gain any members.
|
|
The method of operation of libctf when the dictionary is writable has
before now been that types that are added land in the dynamic type
section, which is a linked list and hash of IDs -> dynamic type
definitions (and, recently a hash of names): the DTDs are a bit of CTF
representing the ctf_type_t and ad hoc C structures representing the
vlen. Historically, libctf was unable to do anything with these types,
not even look them up by ID, let alone by name: if you wanted to do that
say if you were adding a type that depended on one you just added) you
called ctf_update, which serializes all the DTDs into a CTF file and
reopens it, copying its guts over the fp it's called with. The
ctf_updated types are then frozen in amber and unchangeable: all lookups
will return the types in the static portion in preference to the dynamic
portion, and we will refuse to re-add things that already exist in the
static portion (and, of late, in the dynamic portion too). The libctf
machinery remembers the boundary between static and dynamic types and
looks in the right portion for each type. Lots of things still don't
quite work with dynamic types (e.g. getting their size), but enough
works to do a bunch of additions and then a ctf_update, most of the
time.
Except it doesn't, because ctf_add_type finds it necessary to walk the
full dynamic type definition list looking for types with matching names,
so it gets slower and slower with every type you add: fixing this
requires calling ctf_update periodically for no other reason than to
avoid massively slowing things down.
This is all clunky and very slow but kind of works, until you consider
that it is in fact possible and indeed necessary to modify one sort of
type after it has been added: forwards. These are necessarily promoted
to structs, unions or enums, and when they do so *their type ID does not
change*. So all of a sudden we are changing types that already exist in
the static portion. ctf_update gets massively confused by this and
allocates space enough for the forward (with no members), but then emits
the new dynamic type (with all the members) into it. You get an
assertion failure after that, if you're lucky, or a coredump.
So this commit rejigs things a bit and arranges to exclusively use the
dynamic type definitions in writable dictionaries, and the static type
definitions in readable dictionaries: we don't at any time have a mixture
of static and dynamic types, and you don't need to call ctf_update to
make things "appear". The ctf_dtbyname hash I introduced a few months
ago, which maps things like "struct foo" to DTDs, is removed, replaced
instead by a change of type of the four dictionaries which track names.
Rather than just being (unresizable) ctf_hash_t's populated only at
ctf_bufopen time, they are now a ctf_names_t structure, which is a pair
of ctf_hash_t and ctf_dynhash_t, with the ctf_hash_t portion being used
in readonly dictionaries, and the ctf_dynhash_t being used in writable
ones. The decision as to which to use is centralized in the new
functions ctf_lookup_by_rawname (which takes a type kind) and
ctf_lookup_by_rawhash, which it calls (which takes a ctf_names_t *.)
This change lets us switch from using static to dynamic name hashes on
the fly across the entirety of libctf without complexifying anything: in
fact, because we now centralize the knowledge about how to map from type
kind to name hash, it actually simplifies things and lets us throw out
quite a lot of now-unnecessary complexity, from ctf_dtnyname (replaced
by the dynamic half of the name tables), through to ctf_dtnextid (now
that a dictionary's static portion is never referenced if the dictionary
is writable, we can just use ctf_typemax to indicate the maximum type:
dynamic or non-dynamic does not matter, and we no longer need to track
the boundary between the types). You can now ctf_rollback() as far as
you like, even past a ctf_update or for that matter a full writeout; all
the iteration functions work just as well on writable as on read-only
dictionaries; ctf_add_type no longer needs expensive duplicated code to
run over the dynamic types hunting for ones it might be interested in;
and the linker no longer needs a hack to call ctf_update so that calling
ctf_add_type is not impossibly expensive.
There is still a bit more complexity: some new code paths in ctf-types.c
need to know how to extract information from dynamic types. This
complexity will go away again in a few months when libctf acquires a
proper intermediate representation.
You can still call ctf_update if you like (it's public API, after all),
but its only effect now is to set the point to which ctf_discard rolls
back.
Obviously *something* still needs to serialize the CTF file before
writeout, and this job is done by ctf_serialize, which does everything
ctf_update used to except set the counter used by ctf_discard. It is
automatically called by the various functions that do CTF writeout:
nobody else ever needs to call it.
With this in place, forwards that are promoted to non-forwards no longer
crash the link, even if it happens tens of thousands of types later.
v5: fix tabdamage.
libctf/
* ctf-impl.h (ctf_names_t): New.
(ctf_lookup_t) <ctf_hash>: Now a ctf_names_t, not a ctf_hash_t.
(ctf_file_t) <ctf_structs>: Likewise.
<ctf_unions>: Likewise.
<ctf_enums>: Likewise.
<ctf_names>: Likewise.
<ctf_lookups>: Improve comment.
<ctf_ptrtab_len>: New.
<ctf_prov_strtab>: New.
<ctf_str_prov_offset>: New.
<ctf_dtbyname>: Remove, redundant to the names hashes.
<ctf_dtnextid>: Remove, redundant to ctf_typemax.
(ctf_dtdef_t) <dtd_name>: Remove.
<dtd_data>: Note that the ctt_name is now populated.
(ctf_str_atom_t) <csa_offset>: This is now the strtab
offset for internal strings too.
<csa_external_offset>: New, the external strtab offset.
(CTF_INDEX_TO_TYPEPTR): Handle the LCTF_RDWR case.
(ctf_name_table): New declaration.
(ctf_lookup_by_rawname): Likewise.
(ctf_lookup_by_rawhash): Likewise.
(ctf_set_ctl_hashes): Likewise.
(ctf_serialize): Likewise.
(ctf_dtd_insert): Adjust.
(ctf_simple_open_internal): Likewise.
(ctf_bufopen_internal): Likewise.
(ctf_list_empty_p): Likewise.
(ctf_str_remove_ref): Likewise.
(ctf_str_add): Returns uint32_t now.
(ctf_str_add_ref): Likewise.
(ctf_str_add_external): Now returns a boolean (int).
* ctf-string.c (ctf_strraw_explicit): Check the ctf_prov_strtab
for strings in the appropriate range.
(ctf_str_create_atoms): Create the ctf_prov_strtab. Detect OOM
when adding the null string to the new strtab.
(ctf_str_free_atoms): Destroy the ctf_prov_strtab.
(ctf_str_add_ref_internal): Add make_provisional argument. If
make_provisional, populate the offset and fill in the
ctf_prov_strtab accordingly.
(ctf_str_add): Return the offset, not the string.
(ctf_str_add_ref): Likewise.
(ctf_str_add_external): Return a success integer.
(ctf_str_remove_ref): New, remove a single ref.
(ctf_str_count_strtab): Do not count the initial null string's
length or the existence or length of any unreferenced internal
atoms.
(ctf_str_populate_sorttab): Skip atoms with no refs.
(ctf_str_write_strtab): Populate the nullstr earlier. Add one
to the cts_len for the null string, since it is no longer done
in ctf_str_count_strtab. Adjust for csa_external_offset rename.
Populate the csa_offset for both internal and external cases.
Flush the ctf_prov_strtab afterwards, and reset the
ctf_str_prov_offset.
* ctf-create.c (ctf_grow_ptrtab): New.
(ctf_create): Call it. Initialize new fields rather than old
ones. Tell ctf_bufopen_internal that this is a writable dictionary.
Set the ctl hashes and data model.
(ctf_update): Rename to...
(ctf_serialize): ... this. Leave a compatibility function behind.
Tell ctf_simple_open_internal that this is a writable dictionary.
Pass the new fields along from the old dictionary. Drop
ctf_dtnextid and ctf_dtbyname. Use ctf_strraw, not dtd_name.
Do not zero out the DTD's ctt_name.
(ctf_prefixed_name): Rename to...
(ctf_name_table): ... this. No longer return a prefixed name: return
the applicable name table instead.
(ctf_dtd_insert): Use it, and use the right name table. Pass in the
kind we're adding. Migrate away from dtd_name.
(ctf_dtd_delete): Adjust similarly. Remove the ref to the
deleted ctt_name.
(ctf_dtd_lookup_type_by_name): Remove.
(ctf_dynamic_type): Always return NULL on read-only dictionaries.
No longer check ctf_dtnextid: check ctf_typemax instead.
(ctf_snapshot): No longer use ctf_dtnextid: use ctf_typemax instead.
(ctf_rollback): Likewise. No longer fail with ECTF_OVERROLLBACK. Use
ctf_name_table and the right name table, and migrate away from
dtd_name as in ctf_dtd_delete.
(ctf_add_generic): Pass in the kind explicitly and pass it to
ctf_dtd_insert. Use ctf_typemax, not ctf_dtnextid. Migrate away
from dtd_name to using ctf_str_add_ref to populate the ctt_name.
Grow the ptrtab if needed.
(ctf_add_encoded): Pass in the kind.
(ctf_add_slice): Likewise.
(ctf_add_array): Likewise.
(ctf_add_function): Likewise.
(ctf_add_typedef): Likewise.
(ctf_add_reftype): Likewise. Initialize the ctf_ptrtab, checking
ctt_name rather than dtd_name.
(ctf_add_struct_sized): Pass in the kind. Use
ctf_lookup_by_rawname, not ctf_hash_lookup_type /
ctf_dtd_lookup_type_by_name.
(ctf_add_union_sized): Likewise.
(ctf_add_enum): Likewise.
(ctf_add_enum_encoded): Likewise.
(ctf_add_forward): Likewise.
(ctf_add_type): Likewise.
(ctf_compress_write): Call ctf_serialize: adjust for ctf_size not
being initialized until after the call.
(ctf_write_mem): Likewise.
(ctf_write): Likewise.
* ctf-archive.c (arc_write_one_ctf): Likewise.
* ctf-lookup.c (ctf_lookup_by_name): Use ctf_lookuup_by_rawhash, not
ctf_hash_lookup_type.
(ctf_lookup_by_id): No longer check the readonly types if the
dictionary is writable.
* ctf-open.c (init_types): Assert that this dictionary is not
writable. Adjust to use the new name hashes, ctf_name_table,
and ctf_ptrtab_len. GNU style fix for the final ptrtab scan.
(ctf_bufopen_internal): New 'writable' parameter. Flip on LCTF_RDWR
if set. Drop out early when dictionary is writable. Split the
ctf_lookups initialization into...
(ctf_set_cth_hashes): ... this new function.
(ctf_simple_open_internal): Adjust. New 'writable' parameter.
(ctf_simple_open): Adjust accordingly.
(ctf_bufopen): Likewise.
(ctf_file_close): Destroy the appropriate name hashes. No longer
destroy ctf_dtbyname, which is gone.
(ctf_getdatasect): Remove spurious "extern".
* ctf-types.c (ctf_lookup_by_rawname): New, look up types in the
specified name table, given a kind.
(ctf_lookup_by_rawhash): Likewise, given a ctf_names_t *.
(ctf_member_iter): Add support for iterating over the
dynamic type list.
(ctf_enum_iter): Likewise.
(ctf_variable_iter): Likewise.
(ctf_type_rvisit): Likewise.
(ctf_member_info): Add support for types in the dynamic type list.
(ctf_enum_name): Likewise.
(ctf_enum_value): Likewise.
(ctf_func_type_info): Likewise.
(ctf_func_type_args): Likewise.
* ctf-link.c (ctf_accumulate_archive_names): No longer call
ctf_update.
(ctf_link_write): Likewise.
(ctf_link_intern_extern_string): Adjust for new
ctf_str_add_external return value.
(ctf_link_add_strtab): Likewise.
* ctf-util.c (ctf_list_empty_p): New.
|
|
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.
|
|
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.
|
|
When we do a ctf_fdopen, we open things via bfd_fdopenr and set up a
hook to close the bfd again... but then we never actually call that hook
from anywhere, so we eventually leak every bfd we open.
Fix this by calling the hook (if set) in ctf_arc_close.
New in v3.
libctf/
* ctf-archive.c (ctf_arc_close): Call ctfi_bfd_close if set.
* ctf-open-bfd.c (ctf_bfdclose): Fix comment.
|
|
Without this, the FD is only closed when the CTF file is, leading to
running out of fds on (e.g.) very large links.
New in v3.
libctf/
* ctf-open-bfd.c (ctf_fdopen): Call bfd_set_cacheable.
|
|
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.
|
|
We shouldn't use these, since binutils doesn't require a C99-capable
compiler yet.
New in v3.
v5: fix tabdamage.
libctf/
* ctf-open.c (flip_lbls): Eschew for-loop initial declarations.
(flip_objts): Likewise.
(flip_vars): Likewise.
(flip_types): Likewise.
|
|
When a ctf_dynhash_insert() finds a slot already existing, it should
call the key and value free functions on the existing key and value and
move the passed-in key into place, so that the lifetime rules for hash
keys are always the same no matter whether the key existed or not but
neither are the keys or values leaked.
New in v3.
v5: fix tabdamage.
libctf/
* ctf-hash.c (ctf_hashtab_insert): Pass in the key and value
freeing functions: if set, free the key and value if the slot
already exists. Always reassign the key.
(ctf_dynhash_insert): Adjust call appropriately.
(ctf_hash_insert_type): Likewise.
|
|
This machinery has been broken for as long as Solaris has existed.
Forwards are meant to encode "struct foo;", "enum foo;" or "union
foo;". Obviously these all exist in distinct namespaces, so forwards
store the type kind they forward to in their ctt_type member
(which makes conceptual sense if you squint at it). The addition
machinery uses this to promote forwards to the appropriate type as
needed.
Unfortunately ctf_add_type does not: it checks the global namespace
(which is always wrong), and so fails with a spurious conflict if you
have, say, a typedef and then a forward comes along with the same name,
even if it's a forward to something like a struct. (This was observed
with <libio.h>, which has "struct _IO_FILE;" and also
"typedef struct _IO_FILE _IO_FILE"). We should look at the recorded
type kind and look in the appropriate namespace. We should also,
when creating the forward in the new container, use that type kind,
rather than just defaulting to CTF_K_STRUCT and hoping that what
eventually comes along is a struct.
This bug is as old as the first implementation of ctf_add_type in
Solaris. But we also want a new feature for the linker, closely-related
and touching the same code so we add it here: not only do we want a
forward followed by a struct/union/enum to promote the forward, but
we want want a struct/union/enum followed by a forward to act as a NOP
and return the existing type, because when we're adding many files
in succession to a target link, there will often be already-promoted
forwards (in the shape of a struct/union/enum) that want to unify
with duplicate forwards coming from other object files.
v5: fix tabdamage.
libctf/
* ctf-create.c (ctf_add_type): Look up and use the forwarded-to
type kind. Allow forwards to unify with pre-existing structs/
unions/enums.
|
|
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.
|
|
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.
|
|
This lets you call ctf_type_mapping (dest_fp, src_fp, src_type_id)
and get told what type ID the corresponding type has in the target
ctf_file_t. This works even if it was added by a recursive call, and
because it is stored in the target ctf_file_t it works even if we
had to add one type to multiple ctf_file_t's as part of conflicting
type handling.
We empty out this mapping after every archive is linked: because it maps
input to output fps, and we only visit each input fp once, its contents
are rendered entirely useless every time the source fp changes.
v3: add several missing mapping additions. Add ctf_dynhash_empty, and
empty after every input archive.
v5: fix tabdamage.
libctf/
* ctf-impl.h (ctf_file_t): New field ctf_link_type_mapping.
(struct ctf_link_type_mapping_key): New.
(ctf_hash_type_mapping_key): Likewise.
(ctf_hash_eq_type_mapping_key): Likewise.
(ctf_add_type_mapping): Likewise.
(ctf_type_mapping): Likewise.
(ctf_dynhash_empty): Likewise.
* ctf-open.c (ctf_file_close): Update accordingly.
* ctf-create.c (ctf_update): Likewise.
(ctf_add_type): Populate the mapping.
* ctf-hash.c (ctf_hash_type_mapping_key): Hash a type mapping key.
(ctf_hash_eq_type_mapping_key): Check the key for equality.
(ctf_dynhash_insert): Fix comment typo.
(ctf_dynhash_empty): New.
* ctf-link.c (ctf_add_type_mapping): New.
(ctf_type_mapping): Likewise.
(empty_link_type_mapping): New.
(ctf_link_one_input_archive): Call it.
|
|
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.
|
|
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.
|
|
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.
|
|
We were freeing the compressed data buffer twice if compression failed.
v4: Fix commit message.
v5: fix tabdamage.
libctf/
* ctf-create.c (ctf_compress_write): Fix double-free.
|