aboutsummaryrefslogtreecommitdiff
path: root/libctf
AgeCommit message (Collapse)AuthorFilesLines
2021-03-18libctf: eliminate dtd_u, part 1: int/float/sliceNick Alcock6-78/+92
This series eliminates a lot of special-case code to handle dynamic types (types added to writable dicts and not yet serialized). Historically, when such types have variable-length data in their final CTF representations, libctf has always worked by adding such types to a special union (ctf_dtdef_t.dtd_u) in the dynamic type definition structure, then picking the members out of this structure at serialization time and packing them into their final form. This has the advantage that the ctf_add_* code doesn't need to know anything about the final CTF representation, but the significant disadvantage that all code that looks up types in any way needs two code paths, one for dynamic types, one for all others. Historically libctf "handled" this by not supporting most type lookups on dynamic types at all until ctf_update was called to do a complete reserialization of the entire dict (it didn't emit an error, it just emitted wrong results). Since commit 676c3ecbad6e9c4, which eliminated ctf_update in favour of the internal-only ctf_serialize function, all the type-lookup paths grew an extra branch to handle dynamic types. We can eliminate this branch again by dropping the dtd_u stuff and simply writing out the vlen in (close to) its final form at ctf_add_* time: type lookup for types using this approach is then identical for types in writable dicts and types that are in read-only ones, and serialization is also simplified (we just need to write out the vlen we already created). The only complexity lies in type kinds for which multiple vlen representations are valid depending on properties of the type, e.g. structures. But we can start simple, adjusting ints, floats, and slices to work this way, and leaving everything else as is. libctf/ChangeLog 2021-03-18 Nick Alcock <nick.alcock@oracle.com> * ctf-impl.h (ctf_dtdef_t) <dtd_u.dtu_enc>: Remove. <dtd_u.dtu_slice>: Likewise. <dtd_vlen>: New. * ctf-create.c (ctf_add_generic): Perhaps allocate it. All callers adjusted. (ctf_dtd_delete): Free it. (ctf_add_slice): Use the dtd_vlen, not dtu_enc. (ctf_add_encoded): Likewise. Assert that this must be an int or float. * ctf-serialize.c (ctf_emit_type_sect): Just copy the dtd_vlen. * ctf-dedup.c (ctf_dedup_rhash_type): Use the dtd_vlen, not dtu_slice. * ctf-types.c (ctf_type_reference): Likewise. (ctf_type_encoding): Remove most dynamic-type-specific code: just get the vlen from the right place. Report failure to look up the underlying type's encoding.
2021-03-18libctf: fix GNU style for do {} whileNick Alcock6-46/+63
It's formatted like this: do { ... } while (...); Not like this: do { ... } while (...); or this: do { ... } while (...); We used both in various places in libctf. Fixing it necessitated some light reindentation. libctf/ChangeLog 2021-03-18 Nick Alcock <nick.alcock@oracle.com> * ctf-archive.c (ctf_archive_next): GNU style fix for do {} while. * ctf-dedup.c (ctf_dedup_rhash_type): Likewise. (ctf_dedup_rwalk_one_output_mapping): Likewise. * ctf-dump.c (ctf_dump_format_type): Likewise. * ctf-lookup.c (ctf_symbol_next): Likewise. * swap.h (swap_thing): Likewise.
2021-03-18libctf: split up ctf_serializeNick Alcock2-317/+424
ctf_serialize and its various pieces may be split out into a separate file now, but ctf_serialize is still far too long and disordered, mixing header initialization, sizing of multiple CTF sections, sorting and emission of multiple CTF sections, strtab construction and ctf_dict_t copying into a single ugly organically-grown mess. Fix the worst of this by migrating all section sizing and emission into separate functions, two per section (or class of section in the case of the symtypetabs). Only the variable section is now sized and emitted directly in ctf_serialize (because it only takes about three lines to do so). The section sizes themselves are still maintained by ctf_serialize so that it can work out the header offsets, but ctf_symtypetab_sect_sizes and ctf_emit_symtypetab_sects share a lot of extra state: migrate that into a shared structure, emit_symtypetab_state_t. (Test results unchanged.) libctf/ChangeLog 2021-03-18 Nick Alcock <nick.alcock@oracle.com> * ctf-serialize.c: General reshuffling, and... (emit_symtypetab_state_t): New, migrated from local variables in ctf_serialize. (ctf_serialize): Split out most section sizing and emission. (ctf_symtypetab_sect_sizes): New (split out). (ctf_emit_symtypetab_sects): Likewise. (ctf_type_sect_size): Likewise. (ctf_emit_type_sect): Likewise.
2021-03-18libctf: fix comment above ctf_dict_tNick Alcock2-5/+10
It is perfectly possible to have dynamically allocated data owned by a specific dict: you just have to teach ctf_serialize about it. libctf/ChangeLog 2021-03-18 Nick Alcock <nick.alcock@oracle.com> * ctf-impl.h (ctf_dict_t): Fix comment.
2021-03-18libctf: split serialization and file writeout into its own fileNick Alcock5-1324/+1391
The code to serialize CTF dicts just gets bigger and bigger as the dictionary's complexity grows: adding symtypetabs almost doubled it on its own. It's long past time to split this out into its own source file, accompanied by the functions that do the actual writeout. This leaves ctf-create.c populated exclusively by functions related to actual writable dict creation (ctf_add_*, ctf_create etc), and leaves both files a much more reasonable size. libctf/ChangeLog 2021-03-18 Nick Alcock <nick.alcock@oracle.com> * ctf-create.c (symtypetab_delete_nonstatic_vars): Move into ctf-serialize.c. (ctf_symtab_skippable): Likewise. (CTF_SYMTYPETAB_EMIT_FUNCTION): Likewise. (CTF_SYMTYPETAB_EMIT_PAD): Likewise. (CTF_SYMTYPETAB_FORCE_INDEXED): Likewise. (symtypetab_density): Likewise. (emit_symtypetab): Likewise. (emit_symtypetab_index): Likewise. (ctf_copy_smembers): Likewise. (ctf_copy_lmembers): Likewise. (ctf_copy_emembers): Likewise. (ctf_sort_var): Likewise. (ctf_serialize): Likewise. (ctf_gzwrite): Likewise. (ctf_compress_write): Likewise. (ctf_write_mem): Likewise. (ctf_write): Likewise. * ctf-serialize.c: New file. * Makefile.am (libctf_nobfd_la_SOURCES): Add it. * Makefile.in: Regenerate.
2021-03-18libctf: fix some tabdamage and move some code aroundNick Alcock5-56/+65
ctf-link.c is unnecessarily confusing because ctf_link_lazy_open is positioned near functions that have nothing to do with opening files. Move it around, and fix some tabdamage that's crept in lately. libctf/ChangeLog 2021-03-18 Nick Alcock <nick.alcock@oracle.com> * ctf-link.c (ctf_link_lazy_open): Move up in the file, to near ctf_link_add_ctf. * ctf-lookup.c (ctf_lookup_symbol_idx): Repair tabdamage. (ctf_lookup_by_sym_or_name): Likewise. * testsuite/libctf-lookup/struct-iteration.c: Likewise. * testsuite/libctf-regression/type-add-unnamed-struct.c: Likewise.
2021-03-02bfd, ld, libctf: skip zero-refcount strings in CTF string reportingNick Alcock3-7/+20
This is a tricky one. BFD, on the linker's behalf, reports symbols to libctf via the ctf_new_symbol and ctf_new_dynsym callbacks, which ultimately call ctf_link_add_linker_symbol. But while this happens after strtab offsets are finalized, it happens before the .dynstr is actually laid out, so we can't iterate over it at this stage and it is not clear what the reported symbols are actually called. So a second callback, examine_strtab, is called after the .dynstr is finalized, which calls ctf_link_add_strtab and ultimately leads to ldelf_ctf_strtab_iter_cb being called back repeatedly until the offsets of every string in the .dynstr is passed to libctf. libctf can then use this to get symbol names out of the input (which usually stores symbol types in the form of a name -> type mapping at this stage) and extract the types of those symbols, feeding them back into their final form as a 1:1 association with the real symtab's STT_OBJ and STT_FUNC symbols (with a few skipped, see ctf_symtab_skippable). This representation is compact, but has one problem: if libctf somehow gets confused about the st_type of a symbol, it'll stick an entry into the function symtypetab when it should put it into the object symtypetab, or vice versa, and *every symbol from that one on* will have the wrong CTF type because it's actually looking up the type for a different symbol. And we have just such a bug. ctf_link_add_strtab was not taking the refcounts of strings into consideration, so even strings that had been eliminated from the strtab by virtue of being in objects eliminated via --as-needed etc were being reported. This is harmful because it can lead to multiple strings with the same apparent offset, and if the last duplicate to be reported relates to an eliminated symbol, we look up the wrong symbol from the input and gets its type wrong: if it's unlucky and the eliminated symbol is also of the wrong st_type, we will end up with a corrupted symtypetab. Thankfully the wrong-st_type case is already diagnosed by a this-can-never-happen paranoid warning: CTF warning: Symbol 61a added to CTF as a function but is of type 1 or the converse * CTF warning: Symbol a3 added to CTF as a data object but is of type 2 so at least we can tell when the corruption has spread to more than one symbol's type. Skipping zero-refcounted strings is easy: teach _bfd_elf_strtab_str to skip them, and ldelf_ctf_strtab_iter_cb to loop over skipped strings until it falls off the end or finds one that isn't skipped. bfd/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * elf-strtab.c (_bfd_elf_strtab_str): Skip strings with zero refcount. ld/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ldelfgen.c (ldelf_ctf_strtab_iter_cb): Skip zero-refcount strings. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-create.c (symtypetab_density): Report the symbol name as well as index in the name != object error; note the likely consequences. * ctf-link.c (ctf_link_shuffle_syms): Report the symbol index as well as name.
2021-03-02libctf: free ctf_dynsyms properlyNick Alcock2-1/+5
In the "no symbols" case (commonplace for executables), we were freeing the ctf_dynsyms using free(), instead of ctf_dynhash_destroy(), leaking a little memory. (This is harmless in the common case of ld usage, but libctf might be used by persistent processes too.) libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-link.c (ctf_link_shuffle_syms): Free ctf_dynsyms properly.
2021-03-02libctf: fix signed/unsigned comparison confusionNick Alcock2-2/+6
Comparing an encoding's cte_bits to a ctf_type_size needs a cast: one is a uint32_t and the other is an ssize_t. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-dump.c (ctf_dump_format_type): Fix signed/unsigned confusion.
2021-03-02libctf: minor error-handling fixesNick Alcock3-8/+32
A transient bug in the preceding change (fixed before commit) exposed a new failure, of ld/testsuite/ld-ctf/diag-parname.d. This attempts to ensure that if we link a dict with child type IDs but no attached parent, we get a suitable ECTF_NOPARENT error. This was happening before this commit, but only by chance, because ctf_variable_iter and ctf_variable_next check to see if the dict they're passed is a child dict without an associated parent. We forgot error-checking on the ctf_variable_next call, and as a result this was concealed -- and looking for the problem exposed a new bug. If any of the lookups beneath ctf_dedup_hash_type fail, the CTF link does *not* fail, but acts quite bizarrely, skipping the type but emitting an error to the CTF error/warning log -- so the linker will report an error, emit a partial CTF dict missing some types, and exit with exitcode 0 as if nothing went wrong. Since ctf_dedup_hash_type is never expected to fail in normal operation, this is surely wrong: failures at emission time do not emit partial CTF dicts, so failures at hashing time should not either. So propagate the error back up. Also fix a couple of smaller bugs where we fail to properly free things and/or propagate error codes on various rare link-time errors and out-of-memory conditions. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-dedup.c (ctf_dedup): Pass on errors from ctf_dedup_hash_type. Call ctf_dedup_fini properly on other errors. (ctf_dedup_emit_type): Set the errno on dynhash insertion failure. * ctf-link.c (ctf_link_deduplicating_per_cu): Close outputs beyond output 0 when asserting because >1 output is found. (ctf_link_deduplicating): Likewise, when asserting because the shared output is not the same as the passed-in fp.
2021-03-02libctf: add a deduplicator-specific type mapping tableNick Alcock5-328/+344
When CTF linking is done, the linker has to track the association between types in the inputs and types in the outputs. The deduplicator does this via the cd_output_emission_hashes, which maps from hashes of types (valid in both the input and output) to the IDs of types in the specific dict in which the cd_emission_hashes is held. However, the nondeduplicating linker and ctf_add_type used a different mechanism, a dedicated hashtab stored in the ctf_link_type_mapping, populated via ctf_add_type_mapping and queried via the ctf_type_mapping function. To allow the same functions to be used for variable and symbol population in both the deduplicating and nondeduplicating linker, the deduplicator carefully transferred all its input->output mappings into this hashtab before returning. This is *expensive*. The number of entries in this hashtab scales as the number of input types, and unlike the hashing machinery the type mapping machinery (the only other thing which scales that way) has not been much optimized. Now the nondeduplicating linker is gone, we can throw this out, move the existing type mapping machinery to ctf-create.c and dedicate it to ctf_add_type alone, and add a new function ctf_dedup_type_mapping which uses the deduplicator's built-in knowledge of type mappings directly, without requiring an expensive repopulation phase. This speeds up a test link of nouveau.ko (a good worst-case candidate with a lot of types in each of a lot of input files) from 9.11s to 7.15s in my testing, a speedup of over 20%. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-impl.h (ctf_dict_t) <ctf_link_type_mapping>: No longer used by the nondeduplicating linker. (ctf_add_type_mapping): Removed, now static. (ctf_type_mapping): Likewise. (ctf_dedup_type_mapping): New. (ctf_dedup_t) <cd_input_nums>: New. * ctf-dedup.c (ctf_dedup_init): Populate it. (ctf_dedup_fini): Free it again. Emphasise that this has to be the last thing called. (ctf_dedup): Populate it. (ctf_dedup_populate_type_mapping): Removed. (ctf_dedup_populate_type_mappings): Likewise. (ctf_dedup_emit): No longer call it. No longer call ctf_dedup_fini either. (ctf_dedup_type_mapping): New. * ctf-link.c (ctf_unnamed_cuname): New. (ctf_create_per_cu): Arguments must be non-null now. (ctf_in_member_cb_arg): Removed. (ctf_link): No longer populate it. No longer discard the mapping table. (ctf_link_deduplicating_one_symtypetab): Use ctf_dedup_type_mapping, not ctf_type_mapping. Use ctf_unnamed_cuname. (ctf_link_one_variable): Likewise. Pass in args individually: no longer a ctf_variable_iter callback. (empty_link_type_mapping): Removed. (ctf_link_deduplicating_variables): Use ctf_variable_next, not ctf_variable_iter. No longer pack arguments to ctf_link_one_variable into a struct. (ctf_link_deduplicating_per_cu): Call ctf_dedup_fini once all link phases are done. (ctf_link_deduplicating): Likewise. (ctf_link_intern_extern_string): Improve comment. (ctf_add_type_mapping): Migrate... (ctf_type_mapping): ... these functions... * ctf-create.c (ctf_add_type_mapping): ... here... (ctf_type_mapping): ... and make static, for the sole use of ctf_add_type.
2021-03-02libctf: remove reference to "unconflicted link mode".Nick Alcock2-3/+8
There is no such thing, and the comment makes no sense, and doesn't match what the code is doing. We always want to put variables in the same dicts as the types they relate to if at all possible. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-link.c (ctf_link_one_variable): Remove reference to "unconflicted link mode".
2021-03-02libctf, include: remove the nondeduplicating CTF linkerNick Alcock2-230/+39
The nondeduplicating CTF linker was kept around when the deduplicating one was added so that people had something to fall back to in case the deduplicating linker turned out to be buggy. It's now much more stable than the nondeduplicating linker, in addition to much faster, using much less memory and producing much better output. In addition, while libctf has a linker flag to invoke the nondeduplicating linker, ld does not expose it: the only way to turn it on within ld is an intentionally- undocumented environment variable. So we can remove it without any ABI or user-visibility concerns (the only thing we leave around is the CTF_LINK_NONDEDUP flag, which can easily be interpreted as "deduplicate less", though right now it does nothing). This lets us remove a lot of complexity associated with tracking filenames and CU names separately (something the deduplcating linker never bothered with, since the cunames are always reliable and ld never hands us useful filenames anyway) The biggest lacuna left behind is the ctf_type_mapping machinery, which slows down deduplicating links quite a lot. We can't just ditch it because ctf_add_type uses it: removing the slowdown from the deduplicating linker is a job for another commit. include/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-api.h (CTF_LINK_SHARE_DUPLICATED): Note that this might merely change how much deduplication is done. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-link.c (ctf_create_per_cu): Drop FILENAME now that it is always identical to CUNAME. (ctf_link_deduplicating_one_symtypetab): Adjust. (ctf_link_one_type): Remove. (ctf_link_one_input_archive_member): Likewise. (ctf_link_close_one_input_archive): Likewise. (ctf_link_one_input_archive): Likewise. (ctf_link): No longer call it. Drop CTF_LINK_NONDEDUP path. Improve header comment a bit (dicts, not files). Adjust ctf_create_per_cu call. (ctf_link_deduplicating_variables): Simplify. (ctf_link_in_member_cb_arg_t) <cu_name>: Remove. <in_input_cu_file>: Likewise. <in_fp_parent>: Likewise. <done_parent>: Likewise. (ctf_link_one_variable): Turn uses of in_file_name to in_cuname.
2021-03-02libctf: fix ChangeLog dateNick Alcock1-1/+1
I pushed this change without fixing up the date by mistake.
2021-03-02libctf: reimplement many _iter iterators in terms of _nextNick Alcock3-124/+69
Ever since the generator-style _next iterators were introduced, there have been separate implementations of the functional-style _iter iterators that do the same thing as _next. This is annoying and adds more dependencies on the internal guts of the file format. Rip them all out and replace them with the corresponding _next iterators. Only ctf_archive_raw_iter and ctf_label_iter survive, the former because there is no access to the raw binary data of archives via any _next iterator, and the latter because ctf_label_next hasn't been implemented (because labels are currently not used for anything). Tested by reverting the change (already applied) that reimplemented ctf_member_iter in terms of ctf_member_next, then verifying that the _iter and _next iterators produced the same results for every iterable entity within a large type archive. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-types.c (ctf_member_iter): Move 'rc' to an inner scope. (ctf_enum_iter): Reimplement in terms of ctf_enum_next. (ctf_type_iter): Reimplement in terms of ctf_type_next. (ctf_type_iter_all): Likewise. (ctf_variable_iter): Reimplement in terms of ctf_variable_next. * ctf-archive.c (ctf_archive_iter_internal): Remove. (ctf_archive_iter): Reimplement in terms of ctf_archive_next.
2021-03-02libctf: ctf_archive_next should set the parent name consistentlyNick Alcock2-0/+7
The top level of CTF containers is a "CTF archive", which contains a collection of named members (each a CTF dictionary). In the serialized file format, this is optional and skipped if the archive would have only one member, as when no ambiguous types are present: so it is commonplace to have a simple ctf_dict_t written out, with no archive container wrapped around it. But, unlike ctf_archive_iter, ctf_archive_next didn't quite handle this case right. It should set the name of this fake "member" to _CTF_SECTION, i.e. ".ctf", but it was failing to do so, so callers got an unintialized variable back instead and were understandably confused. So set the name properly. libctf/ChangeLog 2021-03-02 Nick Alcock <nick.alcock@oracle.com> * ctf-archive.c (ctf_archive_next): Set the name of parents in single-member archives.
2021-02-26libctf regen for NEWSAlan Modra2-1/+5
The previous regen was done on a tree without the new NEWS file. * Makefile.in: Regenerate.
2021-02-21libctf AC_CANONICAL_TARGETAlan Modra4-81/+142
AC_CANONICAL_TARGET is needed for @target@ substitution in the makefile. AC_CANONICAL_HOST and AC_CANONICAL_BUILD are alread invoked indirectly, make them explicit. * configure.ac: Invoke AC_CANONICAL_TARGET, AC_CANONICAL_HOST and AC_CANONICAL_BUILD. * configure: Regenerate. * Makefile.in: Regenerate.
2021-02-20libctf: add a NEWSNick Alcock1-0/+26
I'm dividing this into three groups for now: new features, bugfixes, and bugfixes also present on a stable branch. Only user-visible bugfixes, not build-system fixes, are listed.
2021-02-20libctf, include: find types of symbols by nameNick Alcock13-179/+567
The existing ctf_lookup_by_symbol and ctf_arc_lookup_symbol functions suffice to look up the types of symbols if the caller already has a symbol number. But the caller often doesn't have one of those and only knows the name of the symbol: also, in object files, the caller might not have a useful symbol number in any sense (and neither does libctf: the 'symbol number' we use in that case literally starts at 0 for the lexicographically first-sorted symbol in the symtypetab and counts those symbols, so it corresponds to nothing useful). This means that even though object files have a symtypetab (generated by the compiler or by ld -r), the only way we can look up anything in it is to iterate over all symbols in turn with ctf_symbol_next until we find the one we want. This is unhelpful and pointlessly inefficient. So add a pair of functions to look up symbols by name in a dict and in a whole archive: ctf_lookup_by_symbol_name and ctf_arc_lookup_symbol_name. These are identical to the existing functions except that they take symbol names rather than symbol numbers. To avoid insane repetition, we do some refactoring in the process, so that both ctf_lookup_by_symbol and ctf_arc_lookup_symbol turn into thin wrappers around internal functions that do both lookup by symbol index and lookup by name. This massively reduces code duplication because even the existing lookup-by-index stuff wants to use a name sometimes (when looking up in indexed sections), and the new lookup-by-name stuff has to turn it into an index sometimes (when looking up in non-indexed sections): doing it this way lets us share most of that. The actual name->index lookup is done by ctf_lookup_symbol_idx. We do not anticipate this lookup to be as heavily used as ld.so symbol lookup by many orders of magnitude, so using the ELF symbol hashes would probably take more time to read them than is saved by using the hashes, and it adds a lot of complexity. Instead, do a linear search for the symbol name, caching all the name -> index mappings as we go, so that future searches are likely to hit in the cache. To avoid having to repeat this search over and over in a CTF archive when ctf_arc_lookup_symbol_name is used, have cached archive lookups (the sort done by ctf_arc_lookup_symbol* and the ctf_archive_next iterator) pick out the first dict they cache in a given archive and store it in a new ctf_archive field, ctfi_crossdict_cache. This can be used to store cross-dictionary cached state that depends on things like the ELF symbol table rather than the contents of any one dict. ctf_lookup_symbol_idx then caches its name->index mappings in the dictionary named in the crossdict cache, if any, so that ctf_lookup_symbol_idx in other dicts in the same archive benefit from the previous linear search, and the symtab only needs to be scanned at most once. (Note that if you call ctf_lookup_by_symbol_name in one specific dict, and then follow it with a ctf_arc_lookup_symbol_name, the former will not use the crossdict cache because it's only populated by the dict opens in ctf_arc_lookup_symbol_name. This is harmless except for a small one-off waste of memory and time: it's only a cache, after all. We can fix this later by using the archive caching machinery more aggressively.) In ctf-archive, we do similar things, turning ctf_arc_lookup_symbol into a wrapper around a new function that does both index -> ID and name -> ID lookups across all dicts in an archive. We add a new ctfi_symnamedicts cache that maps symbol names to the ctf_dict_t * that it was found in (so that linear searches for symbols don't need to be repeated): but we also *remove* a cache, the ctfi_syms cache that was memoizing the actual ctf_id_t returned from every call to ctf_arc_lookup_symbol. This is pointless: all it saves is one call to ctf_lookup_by_symbol, and that's basically an array lookup and nothing more so isn't worth caching. (Equally, given that symbol -> index mappings are cached by ctf_lookup_by_symbol_name, those calls are nearly free after the first call, so there's no point caching the ctf_id_t in that case either.) We fix up one test that was doing manual symbol lookup to use ctf_arc_lookup_symbol instead, and enhance it to check that the caching layer is not totally broken: we also add a new test to do lookups in a .o file, and another to do lookups in an archive with conflicted types and make sure that sort of multi-dict lookup is actually working. include/ChangeLog 2021-02-17 Nick Alcock <nick.alcock@oracle.com> * ctf-api.h (ctf_arc_lookup_symbol_name): New. (ctf_lookup_by_symbol_name): Likewise. libctf/ChangeLog 2021-02-17 Nick Alcock <nick.alcock@oracle.com> * ctf-impl.h (ctf_dict_t) <ctf_symhash>: New. <ctf_symhash_latest>: Likewise. (struct ctf_archive_internal) <ctfi_crossdict_cache>: New. <ctfi_symnamedicts>: New. <ctfi_syms>: Remove. (ctf_lookup_symbol_name): Remove. * ctf-lookup.c (ctf_lookup_symbol_name): Propagate errors from parent properly. Make static. (ctf_lookup_symbol_idx): New, linear search for the symbol name, cached in the crossdict cache's ctf_symhash (if available), or this dict's (otherwise). (ctf_try_lookup_indexed): Allow the symname to be passed in. (ctf_lookup_by_symbol): Turn into a wrapper around... (ctf_lookup_by_sym_or_name): ... this, supporting name lookup too, using ctf_lookup_symbol_idx in non-writable dicts. Special-case name lookup in dynamic dicts without reported symbols, which have no symtab or dynsymidx but where name lookup should still work. (ctf_lookup_by_symbol_name): New, another wrapper. * ctf-archive.c (enosym): Note that this is present in ctfi_symnamedicts too. (ctf_arc_close): Adjust for removal of ctfi_syms. Free the ctfi_symnamedicts. (ctf_arc_flush_caches): Likewise. (ctf_dict_open_cached): Memoize the first cached dict in the crossdict cache. (ctf_arc_lookup_symbol): Turn into a wrapper around... (ctf_arc_lookup_sym_or_name): ... this. No longer cache ctf_id_t lookups: just call ctf_lookup_by_symbol as needed (but still cache the dicts those lookups succeed in). Add lookup-by-name support, with dicts of successful lookups cached in ctfi_symnamedicts. Refactor the caching code a bit. (ctf_arc_lookup_symbol_name): New, another wrapper. * ctf-open.c (ctf_dict_close): Free the ctf_symhash. * libctf.ver (LIBCTF_1.2): New version. Add ctf_lookup_by_symbol_name, ctf_arc_lookup_symbol_name. * testsuite/libctf-lookup/enum-symbol.c (main): Use ctf_arc_lookup_symbol rather than looking up the name ourselves. Fish it out repeatedly, to make sure that symbol caching isn't broken. (symidx_64): Remove. (symidx_32): Remove. * testsuite/libctf-lookup/enum-symbol-obj.lk: Test symbol lookup in an unlinked object file (indexed symtypetab sections only). * testsuite/libctf-writable/symtypetab-nonlinker-writeout.c (try_maybe_reporting): Check symbol types via ctf_lookup_by_symbol_name as well as ctf_symbol_next. * testsuite/libctf-lookup/conflicting-type-syms.*: New test of lookups in a multi-dict archive.
2021-02-20Include ld-lib.exp from ctf-lib.expAlan Modra3-172/+11
* testsuite/config/default.exp (ld_L_opt): Define. * testsuite/lib/ctf-lib.exp (load_common_lib): Delete. Instead load ld-lib.exp. (run_host_cmd, run_host_cmd_yesno, check_compiler_available): Delete. (compile_one_cc, check_ctf_available): Delete.
2021-02-10libctf: add missing header in BFD ELF checkNick Alcock3-0/+7
Without this, GCC warns: In file included from conftest.c:36: ../../libctf/../bfd/elf-bfd.h: In function 'bfd_section_is_ctf': ../../libctf/../bfd/elf-bfd.h:3089:10: warning: implicit declaration of function 'strncmp' [-Wimplicit-function-declaration] 3089 | return strncmp (name, ".ctf", 4) == 0 && (name[4] == 0 || name[4] == '.'); | ^~~~~~~ ../../libctf/../bfd/elf-bfd.h:3089:33: warning: 'strncmp' argument 3 type is 'int' where 'long unsigned int' is expected in a call to built-in function declared without prototype [-Wbuiltin-declaration-mismatch] 3089 | return strncmp (name, ".ctf", 4) == 0 && (name[4] == 0 || name[4] == '.'); | ^ <built-in>: note: built-in 'strncmp' declared here These warnings do not currently throw off the result of the configure check, but it's better to squash them anyway. libctf/ChangeLog 2021-02-03 Nick Alcock <nick.alcock@oracle.com> * configure.ac (ac_cv_libctf_bfd_elf): Include string.h. * configure: Regenerated.
2021-02-10libctf: require a Tcl capable of try/catch to run testsNick Alcock5-38/+138
The run_native_host_cmd implementation in testsuite/lib/ctf-lib.exp uses try/catch, which are new in Tcl 8.6. Require a Tcl that knows that try exists, as suggested by Jan Beulich. libctf/ChangeLog 2021-02-03 Nick Alcock <nick.alcock@oracle.com> * configure.ac (EXPECT): Check for, in order to define... (TCL_TRY): ... this, if Tcl supports try/catch. * Makefile.am (TCL_TRY): Run the testsuite only if set. * configure: Regenerated. * Makefile.in: Likewise.
2021-02-10bfd, opcodes, libctf: support --with-included-gettextNick Alcock5-19/+38
Right now, these libraries hardwire -L../intl -lintl on a few fixed platforms, which works fine on those platforms but on other platforms leads to shared libraries that lack libintl_* symbols when configured --with-included-gettext, and/or static libraries that contain libintl as *another* static library. If we instead use the LIBINTL variable defined in ../intl/config.intl, this gives us the right thing on all three classes of platform (gettext in libc, gettext in system libintl, gettext in ../intl/libintl.a).. This also means we can rip out some Darwin-specific machinery from configure.ac and also simplify the Cygwin side. This also means that the libctf testsuite (and other places that include libbfd, libopcodes or libctf) don't need to grow libintl dependencies just on account of those libraries (though they still need such dependencies if they themselves use gettext machinery). bfd/ChangeLog 2021-02-03 Nick Alcock <nick.alcock@oracle.com> * configure.ac (SHARED_LIBADD): Remove explicit -lintl population in favour of LIBINTL. * configure: Regenerated. libctf/ChangeLog 2021-02-02 Nick Alcock <nick.alcock@oracle.com> * configure.ac (CTF_LIBADD): Remove explicit -lintl population in favour of LIBINTL. * Makefile.am (libctf_nobfd_la_LIBADD): No longer explicitly include $(LIBINTL). (check-DEJAGNU): Pass down to tests as well. * configure: Regenerated. * Makefile.in: Likewise. opcodes/ChangeLog 2021-02-04 Nick Alcock <nick.alcock@oracle.com> * configure.ac (SHARED_LIBADD): Remove explicit -lintl population in favour of LIBINTL. * configure: Regenerated.
2021-02-04libctf: always name nameless types "", never NULLNick Alcock4-8/+26
The ctf_type_name_raw and ctf_type_aname_raw functions, which return the raw, unadorned name of CTF types, have one unfortunate wrinkle: they return NULL not only on error but when returning the name of types without a name in writable dicts. This was unintended: it not only makes it impossible to reliably tell if a given call to ctf_type_name_raw failed (due to a bad string offset say), but also complicates all its callers, who now have to check for both NULL and "". The written-out form of CTF has no concept of a NULL pointer instead of a string: all null strings are strtab offset 0, "". So the more we can do to remove this distinction from the writable form, the less complex the rest of our code needs to be. Armour against NULL in multiple places, arranging to return "" from ctf_type_name_raw if offset 0 is passed in, and removing a risky optimization from ctf_str_add* that avoided doing anything if a NULL was passed in: this added needless irregularity to the functions' API surface, since "" and NULL should be treated identically, and in the case of ctf_str_add_ref, we shouldn't skip adding the passed-in REF to the list of references to be updated no matter what the content of the string happens to be. This means we can simplify the deduplicator a tiny bit, also fixing a bug (latent when used by ld) where if the input dict was writable, we failed to realise when types were nameless and could end up creating deeply unhelpful synthetic forwards with no name, which we just banned a few commits ago, so the link failed. libctf/ChangeLog 2021-01-27 Nick Alcock <nick.alcock@oracle.com> * ctf-string.c (ctf_str_add): Treat adding a NULL as adding "". (ctf_str_add_ref): Likewise. (ctf_str_add_external): Likewise. * ctf-types.c (ctf_type_name_raw): Always return "" for offset 0. * ctf-dedup.c (ctf_dedup_multiple_input_dicts): Don't armour against NULL name. (ctf_dedup_maybe_synthesize_forward): Likewise.
2021-02-04libctf: fix uninitialized variable in symbol serialization error handlingNick Alcock2-1/+4
We declare a variable to hold errors at two scopes, and then initialize the inner one and jump to a scope where only the outer one is in scope. The consequences are minor: only the version of the error message printed in the debugging stream is impacted. libctf/ChangeLog 2021-01-27 Nick Alcock <nick.alcock@oracle.com> * ctf-create.c (ctf_serialize): Fix shadowing.
2021-02-04libctf: prohibit nameless ints, floats, typedefs and forwardsNick Alcock2-2/+16
Now that "anonymous typedef nodes" have been extirpated, we can mandate that things that have names in C must have names in CTF too. (Unlike the no-forwards embarrassment, the deduplicator does nothing special with names: types that have names in C will have the same name in CTF. So we can assume that the CTF rules and the C rules are the same.) include/ChangeLog 2021-01-27 Nick Alcock <nick.alcock@oracle.com> * ctf-api.h (ECTF_NONAME): New. (ECTF_NERR): Adjust. libctf/ChangeLog 2021-01-27 Nick Alcock <nick.alcock@oracle.com> * ctf-create.c (ctf_add_encoded): Add check for non-empty name. (ctf_add_forward): Likewise. (ctf_add_typedef): Likewise.
2021-02-04libctf: rip out dead code handling typedefs with no nameNick Alcock4-61/+14
There is special code in libctf to handle typedefs with no name, which the code calls "anonymous typedef nodes". These monsters are obviously not something C programs can include: the whole point of a ttypedef is to introduce a new name. Looking back at the history of DWARF in GCC, the only thing (outside C++ anonymous namespaces) which can generate a DW_TAG_typedef without a DW_AT_name is obsolete code to handle the long-removed -feliminate-dwarf2-dups option. Looking at OpenSolaris, typedef nodes with no name couldn't be generated by the DWARF->CTF converter at all (and its deduplicator barfed on them): the only reason for the existence of this code is a special case working around a peculiarity of stabs whereby types could sometimes be referenced before they were introduced. We don't need to carry code in libctf to handle special cases in an obsolete OpenSolaris converter (that yields a format that isn't readable by libctf anyway). So drop it. libctf/ChangeLog 2021-01-27 Nick Alcock <nick.alcock@oracle.com> * ctf-open.c (init_types): Rip out code to check anonymous typedef nodes. * ctf-create.c (ctf_add_reftype): Likewise. * ctf-lookup.c (refresh_pptrtab): Likewise.
2021-02-04libctf, ld: fix symtypetab and var section population under ld -rNick Alcock13-57/+592
The variable section in a CTF dict is meant to contain the types of variables that do not appear in the symbol table (mostly file-scope static declarations). We implement this by having the compiler emit all potential data symbols into both sections, then delete those symbols from the variable section that correspond to data symbols the linker has reported. Unfortunately, the check for this in ctf_serialize is wrong: rather than checking the set of linker-reported symbols, we check the set of names in the data object symtypetab section: if the linker has reported no symbols at all (usually if ld -r has been run, or if a non-linker program that does not use symbol tables is calling ctf_link) this will include every single symbol, emptying the variable section completely. Worse, when ld -r is in use, we want to force writeout of every symtypetab entry on the inputs, in an indexed section, whether or not the linker has reported them, since this isn't a final link yet and the symbol table is not finalized (and may grow more symbols than the linker has yet reported). But the check for this is flawed too: we were relying on ctf_link_shuffle_syms not having been called if no symbols exist, but that function is *always* called by ld even when ld -r is in use: ctf_link_add_linker_symbol is the one that's not called when there are no symbols. We clearly need to rethink this. Using the emptiness of the set of reported symbols as a test for ld -r is just ugly: the linker already knows if ld -r is underway and can just tell us. So add a new linker flag CTF_LINK_NO_FILTER_REPORTED_SYMS that is set to stop the linker filtering the symbols in the symtypetab sections using the set that the linker has reported: use the presence or absence of this flag to determine whether to emit unindexed symtabs: we only remove entries from the variable section when filtering symbols, and we only remove them if they are in the reported symbol set, fixing the case where no symbols are reported by the linker at all. (The negative sense of the new CTF_LINK flag is intentional: the common case, both for ld and for simple tools that want to do a ctf_link with no ELF symbol table in sight, is probably to filter out symbols that no linker has reported: i.e., for the simple tools, all of them.) There's another wrinkle, though. It is quite possible for a non-linker to add symbols to a dict via ctf_add_*_sym and then write it out via the ctf_write APIs: perhaps it's preparing a dict for a later linker invocation. Right now this would not lead to anything terribly meaningful happening: ctf_serialize just assumes it was called via ctf_link if symbols are present. So add an (internal-to-libctf) flag that indicates that a writeout is happening via ctf_link_write, and set it there (propagating it to child dicts as needed). ctf_serialize can then spot when it is not being called by a linker, and arrange to always write out an indexed, sorted symtypetab for fastest possible future symbol lookup by name in that case. (The writeouts done by ld -r are unsorted, because the only thing likely to use those symtabs is the linker, which doesn't benefit from symtypetab sorting.) Tests added for all three linking cases (ld -r, ld -shared, ld), with a bit of testsuite framework enhancement to stop it unconditionally linking the CTF to be checked by the lookup program with -shared, so tests can now examine CTF linked with -r or indeed with no flags at all, though the output filename is still foo.so even in this case. Another test added for the non-linker case that endeavours to determine whether the symtypetab is sorted by examining the order of entries returned from ctf_symbol_next: nobody outside libctf should rely on this ordering, but this test is not outside libctf :) include/ChangeLog 2021-01-26 Nick Alcock <nick.alcock@oracle.com> * ctf-api.h (CTF_LINK_NO_FILTER_REPORTED_SYMS): New. ld/ChangeLog 2021-01-26 Nick Alcock <nick.alcock@oracle.com> * ldlang.c (lang_merge_ctf): Set CTF_LINK_NO_FILTER_REPORTED_SYMS when appropriate. libctf/ChangeLog 2021-01-27 Nick Alcock <nick.alcock@oracle.com> * ctf-impl.c (_libctf_nonnull_): Add parameters. (LCTF_LINKING): New flag. (ctf_dict_t) <ctf_link_flags>: Mention it. * ctf-link.c (ctf_link): Keep LCTF_LINKING set across call. (ctf_write): Likewise, including in child dictionaries. (ctf_link_shuffle_syms): Make sure ctf_dynsyms is NULL if there are no reported symbols. * ctf-create.c (symtypetab_delete_nonstatic_vars): Make sure the variable has been reported as a symbol by the linker. (symtypetab_skippable): Mention relationship between SYMFP and the flags. (symtypetab_density): Adjust nonnullity. Exit early if no symbols were reported and force-indexing is off (i.e., we are doing a final link). (ctf_serialize): Handle the !LCTF_LINKING case by writing out an indexed, sorted symtypetab (and allow SYMFP to be NULL in this case). Turn sorting off if this is a non-final link. Only delete nonstatic vars if we are filtering symbols and the linker has reported some. * testsuite/libctf-regression/nonstatic-var-section-ld-r*: New test of variable and symtypetab section population when ld -r is used. * testsuite/libctf-regression/nonstatic-var-section-ld-executable.lk: Likewise, when ld of an executable is used. * testsuite/libctf-regression/nonstatic-var-section-ld.lk: Likewise, when ld -shared alone is used. * testsuite/libctf-regression/nonstatic-var-section-ld*.c: Lookup programs for the above. * testsuite/libctf-writable/symtypetab-nonlinker-writeout.*: New test, testing survival of symbols across ctf_write paths. * testsuite/lib/ctf-lib.exp (run_lookup_test): New option, nonshared, suppressing linking of the SOURCE with -shared.
2021-01-19libctf, create: fix ctf_type_add of structs with unnamed membersNick Alcock5-0/+106
Our recent commit to support unnamed structure members better ditched the old ctf_member_iter iterator body in favour of ctf_member_next. However, these functions treat unnamed structure members differently: ctf_member_iter just returned whatever the internal representation contained, while ctf_member_next took care to always return "" rather than sometimes returning "" and sometimes NULL depending on whether the dict was dynamic (a product of ctf_create) or not (a product of ctf_open). After this commit, ctf_member_iter did the same. It was always a bug for external callers not to treat a "" return from these functions as if it were NULL, so only buggy callers could be affected -- but one of those buggy callers was ctf_add_type, which assumed that it could just take whatever name was returned from ctf_member_iter and slam it directly into the internal representation of a dynamic dict -- which expects NULL for unnamed members, not "". The net effect of all of this is that taking a struct containing unnamed members and ctf_add_type'ing it into a dynamic dict produced a dict whose unnamed members were inaccessible to ctf_member_info (though if you wrote that dict out and then ctf_open'ed it, they would magically reappear again). Compensate for this by suitably transforming a "" name into NULL in the internal representation, as should have been done all along. libctf/ChangeLog 2021-01-19 Nick Alcock <nick.alcock@oracle.com> * ctf-create.c (membadd): Transform ""-named members into NULL-named ones. * testsuite/libctf-regression/type-add-unnamed-struct*: New test.
2021-01-19libctf: lookup_by_name: do not return success for nonexistent pointer typesNick Alcock5-10/+45
The recent work allowing lookups of pointers in child dicts when the pointed-to type is in the parent dict broke the case where a pointer type that does not exist at all is looked up: we mistakenly return the pointed-to type, which is likely not a pointer at all. This causes considerable confusion. Fixed, with a new testcase. libctf/ChangeLog 2021-01-19 Nick Alcock <nick.alcock@oracle.com> * ctf-lookup.c (ctf_lookup_by_name_internal): Do not return the base type if looking up a nonexistent pointer type. * testsuite/libctf-regression/pptrtab*: Test it.
2021-01-13Regen Makefile.in for jobserver.m4 aclocal.m4 dependencyAlan Modra2-0/+5
bfd/ * Makefile.in: Regenerate. * doc/Makefile.in: Regenerate. binutils/ * Makefile.in: Regenerate. * doc/Makefile.in: Regenerate. gas/ * Makefile.in: Regenerate. * Makefile.in: Regenerate. gprof/ * Makefile.in: Regenerate. ld/ * Makefile.in: Regenerate. libctf/ * Makefile.in: Regenerate. opcodes/ * Makefile.in: Regenerate.
2021-01-12Implement a workaround for GNU mak jobserverH.J. Lu4-0/+28
Compiling binutils using -flto=jobserver with GCC 11 leads to libtool: link: gcc -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -Wstack-usage=262144 -Wwrite-strings -I../../gas/../zlib -g -O2 -fprofile-generate -flto=jobserver -o as-new app.o as.o atof-generic.o compress-debug.o cond.o depend.o dwarf2dbg.o dw2gencfi.o ecoff.o ehopt.o expr.o flonum-copy.o flonum-konst.o flonum-mult.o frags.o hash.o input-file.o input-scrub.o listing.o literal.o macro.o messages.o output-file.o read.o remap.o sb.o stabs.o subsegs.o symbols.o write.o config/tc-i386.o config/obj-elf.o config/atof-ieee.o ../opcodes/.libs/libopcodes.a ../bfd/.libs/libbfd.a -L/tmp/binutils-gdb/objdir/zlib -lz ../libiberty/libiberty.a -ldl lto-wrapper: warning: jobserver is not available: '--jobserver-auth=' is not present in 'MAKEFLAGS' since the '+' is missing on the recipe line in Makefiles generated by automake. Add the '+' to the recipe line by hand. bfd/ PR binutils/26792 * configure.ac: Use GNU_MAKE_JOBSERVER. * aclocal.m4: Regenerated. * configure: Likewise. binutils/ PR binutils/26792 * configure.ac: Use GNU_MAKE_JOBSERVER. * aclocal.m4: Regenerated. * configure: Likewise. config/ PR binutils/26792 * jobserver.m4: New file. gas/ PR binutils/26792 * configure.ac: Use GNU_MAKE_JOBSERVER. * aclocal.m4: Regenerated. * configure: Likewise. gprof/ PR binutils/26792 * configure.ac: Use GNU_MAKE_JOBSERVER. * aclocal.m4: Regenerated. * configure: Likewise. ld/ PR binutils/26792 * configure.ac: Use GNU_MAKE_JOBSERVER. * aclocal.m4: Regenerated. * configure: Likewise. libctf/ PR binutils/26792 * configure.ac: Use GNU_MAKE_JOBSERVER. * aclocal.m4: Regenerated. * configure: Likewise. opcodes/ PR binutils/26792 * configure.ac: Use GNU_MAKE_JOBSERVER. * aclocal.m4: Regenerated. * configure: Likewise.
2021-01-11Binutils: Check if AR works with --plugin and rcH.J. Lu2-3/+16
Check if AR works with --plugin and rc before passing --plugin to AR and RANLIB. bfd/ PR ld/27173 binutils/ PR ld/27173 * configure: Regenerated. gas/ PR ld/27173 * configure: Regenerated. gprof/ PR ld/27173 * configure: Regenerated. ld/ PR ld/27173 * configure: Regenerated. libctf/ PR ld/27173 * configure: Regenerated. opcodes/ PR ld/27173 * configure: Regenerated.
2021-01-09Binutils: Pass --plugin to AR and RANLIBH.J. Lu2-2/+29
Detect GCC LTO plugin. Pass --plugin to AR and RANLIB to support LTO build. bfd/ * configure: Regenerated. binutils/ * configure: Regenerated. gas/ * configure: Regenerated. gprof/ * configure: Regenerated. ld/ * configure: Regenerated. libctf/ * configure: Regenerated. opcodes/ * configure: Regenerated.
2021-01-09Add Changelog entries and NEWS entries for 2.36 branchNick Clifton1-0/+4
2021-01-09configure regenAlan Modra2-2/+6
commit f478212851 did the regen by hand, missed a change in ld/configure and didn't update line numbers. Fix that, and an old regen of ld/Makefile.in with the wrong automake. bfd/ * configure: Regenerate. binutils/ * configure: Regenerate. gas/ * configure: Regenerate. gprof/ * configure: Regenerate. ld/ * Makefile.in: Regenerate. * configure: Regenerate. libctf/ * configure: Regenerate. opcodes/ * configure: Regenerate. zlib/ * configure: Regenerate.
2021-01-07libtool.m4: update GNU/Hurd test from upstream. In upstream libtool, ↵Samuel Thibault2-11/+5
47a889a4ca20 ("Improve GNU/Hurd support.") fixed detection of shlibpath_overrides_runpath, thus avoiding unnecessary relink. This backports it. . * libtool.m4: Match gnu* along other GNU systems. */ChangeLog: * configure: Re-generate.
2021-01-05libctf, testsuite: adjust for real return type of ctf_member_countNick Alcock2-3/+8
This returns an int, not a long int or an ssize_t (as one test was inconsistently assuming). libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * testsuite/libctf-lookup/struct-iteration.c (main): ctf_member_count returns an int.
2021-01-05libctf, testsuite: don't run without a suitable compilerNick Alcock6-3/+57
We never actually check to see if the compiler supports CTF, or even if a suitable compiler exists. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * Makefile.am (BASEDIR): New. (BFDDIR): Likewise. (check-DEJAGNU): Add development.exp to prerequisites. (development.exp): New. (CONFIG_STATUS_DEPENDENCIES): New. (EXTRA_DEJAGNU_SITE_CONFIG): Likewise. (DISTCLEANFILES): Likewise. * Makefile.in: Regenerated. * testsuite/lib/ctf-lib.exp (check_ctf_available): Return boolean. * testsuite/libctf-lookup/lookup.exp: Call check_ctf_available. * testsuite/libctf-regression/regression.exp: Likewise.
2021-01-05libctf, ld: fix formatting of forwards to unions and enumsNick Alcock2-1/+25
The type printer was unconditionally printing these as if they were forwards to structs, even if they were forwards to unions or enums. ld/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * testsuite/ld-ctf/enum-forward.c: New test. * testsuite/ld-ctf/enum-forward.c: New results. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * ctf-types.c (ctf_type_aname): Print forwards to unions and enums properly.
2021-01-05libctf: fix old ChangeLog typoNick Alcock1-1/+1
2021-01-05libctf: fix lookups of pointers by name in parent dictsNick Alcock13-33/+467
When you look up a type by name using ctf_lookup_by_name, in most cases libctf can just strip off any qualifiers and look for the name, but for pointer types this doesn't work, since the caller will want the pointer type itself. But pointer types are nameless, and while they cite the types they point to, looking up a type by name requires a link going the *other way*, from the type pointed to to the pointer type that points to it. libctf has always built this up at open time: ctf_ptrtab is an array of type indexes pointing from the index of every type to the index of the type that points to it. But because it is built up at open time (and because it uses type indexes and not type IDs) it is restricted to working within a single dict and ignoring parent/child relationships. This is normally invisible, unless you manage to get a dict with a type in the parent but the only pointer to it in a child. The ctf_ptrtab will not track this relationship, so lookups of this pointer type by name will fail. Since which type is in the parent and which in the child is largely opaque to the user (which goes where is up to the deduplicator, and it can and does reshuffle things to save space), this leads to a very bad user experience, with an obviously-visible pointer type which ctf_lookup_by_name claims doesn't exist. The fix is to have another array, ctf_pptrtab, which is populated in child dicts: like the parent's ctf_ptrtab, it has one element per type in the parent, but is all zeroes except for those types which are pointed to by types in the child: so it maps parent dict indices to child dict indices. The array is grown, and new child types scanned, whenever a lookup happens and new types have been added to the child since the last time a lookup happened that might need the pptrtab. (So for non-writable dicts, this only happens once, since new types cannot be added to non-writable dicts at all.) Since this introduces new complexity (involving updating only part of the ctf_pptrtab) which is only seen when a writable dict is in use, we introduce a new libctf-writable testsuite that contains lookup tests with no corresponding CTF-containing .c files (which can thus be run even on platforms with no .ctf-section support in the linker yet), and add a test to check that creation of pointers in children to types in parents and a following lookup by name works as expected. The non- writable case is tested in a new libctf-regression testsuite which is used to track now-fixed outright bugs in libctf. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * ctf-impl.h (ctf_dict_t) <ctf_pptrtab>: New. <ctf_pptrtab_len>: New. <ctf_pptrtab_typemax>: New. * ctf-create.c (ctf_serialize): Update accordingly. (ctf_add_reftype): Note that we don't need to update pptrtab here, despite updating ptrtab. * ctf-open.c (ctf_dict_close): Destroy the pptrtab. (ctf_import): Likewise. (ctf_import_unref): Likewise. * ctf-lookup.c (grow_pptrtab): New. (refresh_pptrtab): New, update a pptrtab. (ctf_lookup_by_name): Turn into a wrapper around (and rename to)... (ctf_lookup_by_name_internal): ... this: construct the pptrtab, and use it in addition to the parent's ptrtab when parent dicts are searched. * testsuite/libctf-regression/regression.exp: New testsuite for regression tests. * testsuite/libctf-regression/pptrtab*: New test. * testsuite/libctf-writable/writable.exp: New testsuite for tests of writable CTF dicts. * testsuite/libctf-writable/pptrtab*: New test.
2021-01-05libctf: remove outdated comment about parent dict importingNick Alcock2-3/+5
Parent dicts are nowadays imported automatically in most situations, so the comment in ctf_archive_iter warning people that they need to import parents by hand is wrong. Remove it. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * ctf-archive.c (ctf_archive_iter): Remove outdated comment.
2021-01-05libctf, include: support unnamed structure members betterNick Alcock11-101/+381
libctf has no intrinsic support for the GCC unnamed structure member extension. This principally means that you can't look up named members inside unnamed struct or union members via ctf_member_info: you have to tiresomely find out the type ID of the unnamed members via iteration, then look in each of these. This is ridiculous. Fix it by extending ctf_member_info so that it recurses into unnamed members for you: this is still unambiguous because GCC won't let you create ambiguously-named members even in the presence of this extension. For consistency, and because the release hasn't happened and we can still do this, break the ctf_member_next API and add flags: we specify one flag, CTF_MN_RECURSE, which if set causes ctf_member_next to automatically recurse into unnamed members for you, returning not only the members themselves but all their contained members, so that you can use ctf_member_next to identify every member that it would be valid to call ctf_member_info with. New lookup tests are added for all of this. include/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * ctf-api.h (CTF_MN_RECURSE): New. (ctf_member_next): Add flags argument. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * ctf-impl.h (struct ctf_next) <u.ctn_next>: Move to... <ctn_next>: ... here. * ctf-util.c (ctf_next_destroy): Unconditionally destroy it. * ctf-lookup.c (ctf_symbol_next): Adjust accordingly. * ctf-types.c (ctf_member_iter): Reimplement in terms of... (ctf_member_next): ... this. Support recursive unnamed member iteration (off by default). (ctf_member_info): Look up members in unnamed sub-structs. * ctf-dedup.c (ctf_dedup_rhash_type): Adjust ctf_member_next call. (ctf_dedup_emit_struct_members): Likewise. * testsuite/libctf-lookup/struct-iteration-ctf.c: Test empty unnamed members, and a normal member after the end. * testsuite/libctf-lookup/struct-iteration.c: Verify that ctf_member_count is consistent with the number of successful returns from a non-recursive ctf_member_next. * testsuite/libctf-lookup/struct-iteration-*: New, test iteration over struct members. * testsuite/libctf-lookup/struct-lookup.c: New test. * testsuite/libctf-lookup/struct-lookup.lk: New test.
2021-01-05libctf: warn about information loss because of unreleased format changesNick Alcock2-0/+35
In the last cycle there have been various changes that have replaced parts of the CTF format with other parts without format compatibility. This was not a compat break, because the old format was never accepted by any version of libctf (the not-in-official-release CTF compiler patch was emitting an invalid func info section), but nonetheless it can confuse users using that patch if they link together object files and find the func info sections in the inputs silently disappearing. Scan the linker inputs for this problem and emit a warning if any are found. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * ctf-link.c (ctf_link_warn_outdated_inputs): New. (ctf_link_write): Call it.
2021-01-05libctf: new test of enum lookups with the _next iteratorNick Alcock4-0/+166
I had reports that this doesn't work. This test shows it working (and also shows how annoying it is to do symbol lookup by name with the present API: we need a ctf_arc_lookup_symbol_name for users that don't already have a symtab handy). libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * testsuite/libctf-lookup/enum-symbol.lk: New symbol-lookup test. * testsuite/libctf-lookup/enum-symbol-ctf.c: New CTF input. * testsuite/libctf-lookup/enum-symbol.c: New lookup test.
2021-01-05libctf: new testsuiteNick Alcock13-24/+816
This introduces a new lookup testsuite under libctf, which operates by compiling (with libtool) a "lookup" .c file that uses libctf to analyze some other program, then compiling some number of test object files with CTF and optionally linking them together and running the lookup program on the test object files (or linked test binary), before diffing the result much as run_dump_test does. This lets us test the portions of libctf that are not previously testable, notably the portions that do lookup on linked output and that create dynamic dictionaries and then do lookup on them before writing them out, something that is not tested by the ld-ctf testsuite because the linker never does this. A couple of simple tests are added: one testing the functionality of enum lookups, and one testing that the recently-added commit adding extra paranoia to incomplete type handling doesn't break linking and that the result of the link is an (otherwise-impossible) array of forward type in the shared CTF dict. ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * Makefile.def (libctf): No longer no_check. Checking depends on all-ld. * Makefile.in: Regenerated. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * Makefile.am (EXPECT): New. (RUNTEST): Likewise. (RUNTESTFLAGS): Likewise. (CC_FOR_TARGET): Likewise. (check-DEJAGNU): Likewise. (AUTOMAKE_OPTIONS): Add dejagnu. * Makefile.in: Regenerated. * testsuite/config/default.exp: New. * testsuite/lib/ctf-lib.exp: Likewise. * testsuite/libctf-lookup/enum.lk: New test. * testsuite/libctf-lookup/enum-ctf.c: New CTF input. * testsuite/libctf-lookup/enum.c: New lookup test. * testsuite/libctf-lookup/ambiguous-struct*.c: New test. * testsuite/libctf-lookup/lookup.exp: New.
2021-01-05libctf: rip out BFD_DEPENDENCIES / BFD_LIBADDNick Alcock5-65/+36
This complex morass inherited from libopcodes, which endeavours to implement the effect of specifying ../bfd/libbfd.la in _LIBADD without actually doing so, appears to be working around a libtool bug which as far as I can see is no longer present (i.e., the install directory no longer appears in -L arguments in libtool link-mode invocations, so there is no danger of picking up old libbfds or other dependent libraries). Replaced with a simple reference to libbfd.la in the appropriate place. Also adjusted things a little more so that libctf.la and libctf-nobfd.la are self-contained, even when linking statically. This opens up the possibility of running libtool to link against libctf from inside the (upcoming) testsuite. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * configure.ac (BFD_LIBADD): Remove. (BFD_DEPENDENCIES): Likewise. Remove associated cases. (SHARED_LIBADD): Rename to... (CTF_LIBADD): ... this. Stick in a suitable libiberty even when linking statically. * Makefile.am (libctf_nobfd_la_LIBADD): Adjust accordingly. libctf uses libintl. (libctf_la_LIBADD): Reference libbfd.la directly, not via BFD_LIBADD. (libctf_la_DEPENDENCIES): Remove. * Makefile.in: Regenerate. * configure: Likewise.
2021-01-05libctf, ld: dump enums: generally improve dump formattingNick Alcock4-141/+199
This commit adds dumping of enumerands in this general form: 0x3: (kind 8) enum eleven_els (size 0x4) (aligned at 0x4) ELEVEN_ONE: 10 ELEVEN_TWO: 11 ELEVEN_THREE: -256 ELEVEN_FOUR: -255 ELEVEN_FIVE: -254 ... ELEVEN_SEVEN: -252 ELEVEN_EIGHT: -251 ELEVEN_NINE: -250 ELEVEN_TEN: -249 ELEVEN_ELEVEN: -248 The first and last enumerands in the enumerated type are printed so that you can tell if they've been cut off at one end or the other. (For now, there is no way to control how many enumerands are printed.) The dump output in general is improved, from this sort of thing a few days ago: 4c: char [0x0:0x8] (size 0x1) [0x0] (ID 0x4c) (kind 1) char:8 (aligned at 0x1, format 0x3, offset:bits 0x0:0x8) 4d: char * (size 0x8) -> 4c: char [0x0:0x8] (size 0x1) [0x0] (ID 0x4d) (kind 3) char * (aligned at 0x8) [...] 5a: struct _IO_FILE (size 0xd8) [0x0] (ID 0x5a) (kind 6) struct _IO_FILE (aligned at 0x4) [0x0] (ID 0x3) (kind 1) int _flags:32 (aligned at 0x4, format 0x1, offset:bits 0x0:0x20) [0x40] (ID 0x4d) (kind 3) char * _IO_read_ptr (aligned at 0x8) [0x80] (ID 0x4d) (kind 3) char * _IO_read_end (aligned at 0x8) [0xc0] (ID 0x4d) (kind 3) char * _IO_read_base (aligned at 0x8) 5b: __FILE (size 0xd8) -> 5a: struct _IO_FILE (size 0xd8) [0x0] (ID 0x5b) (kind 10) __FILE (aligned at 0x4) [0x0] (ID 0x3) (kind 1) int _flags:32 (aligned at 0x4, format 0x1, offset:bits 0x0:0x20) [0x40] (ID 0x4d) (kind 3) char * _IO_read_ptr (aligned at 0x8) [0x80] (ID 0x4d) (kind 3) char * _IO_read_end (aligned at 0x8) [0xc0] (ID 0x4d) (kind 3) char * _IO_read_base (aligned at 0x8) [...] 406: struct coff_link_hash_entry (size 0x60) [0x0] (ID 0x406) (kind 6) struct coff_link_hash_entry (aligned at 0x8) [0x0] (ID 0x2b3) (kind 6) struct bfd_link_hash_entry root (aligned at 0x8) [0x0] (ID 0x1d6) (kind 6) struct bfd_hash_entry root (aligned at 0x8) [0x0] (ID 0x1d7) (kind 3) struct bfd_hash_entry * next (aligned at 0x8) [0x40] (ID 0x61) (kind 3) const char * string (aligned at 0x8) [0x80] (ID 0x1) (kind 1) long unsigned int hash:64 (aligned at 0x8, format 0x0, offset:bits 0x0:0x40) [0xc0] (ID 0x397) (kind 8) enum bfd_link_hash_type type:8 (aligned at 0x1, format 0x0, offset:bits 0x0:0x8) [0xc8] (ID 0x1c7) (kind 1) unsigned int non_ir_ref_regular:1 (aligned at 0x1, format 0x0, offset:bits 0x8:0x1) [0xc9] (ID 0x1c8) (kind 1) unsigned int non_ir_ref_dynamic:1 (aligned at 0x1, format 0x0, offset:bits 0x9:0x1) [0xca] (ID 0x1c9) (kind 1) unsigned int linker_def:1 (aligned at 0x1, format 0x0, offset:bits 0xa:0x1) [0xcb] (ID 0x1ca) (kind 1) unsigned int ldscript_def:1 (aligned at 0x1, format 0x0, offset:bits 0xb:0x1) [0xcc] (ID 0x1cb) (kind 1) unsigned int rel_from_abs:1 (aligned at 0x1, format 0x0, offset:bits 0xc:0x1) ... to this: 0x4c: (kind 1) char (format 0x3) (size 0x1) (aligned at 0x1) 0x4d: (kind 3) char * (size 0x8) (aligned at 0x8) -> 0x4c: (kind 1) char (format 0x3) (size 0x1) (aligned at 0x1) 0x5a: (kind 6) struct _IO_FILE (size 0xd8) (aligned at 0x4) [0x0] _flags: ID 0x3: (kind 1) int (format 0x1) (size 0x4) (aligned at 0x4) [0x40] _IO_read_ptr: ID 0x4d: (kind 3) char * (size 0x8) (aligned at 0x8) [0x80] _IO_read_end: ID 0x4d: (kind 3) char * (size 0x8) (aligned at 0x8) [0xc0] _IO_read_base: ID 0x4d: (kind 3) char * (size 0x8) (aligned at 0x8) [0x100] _IO_write_base: ID 0x4d: (kind 3) char * (size 0x8) (aligned at 0x8) 0x5b: (kind 10) __FILE (size 0xd8) (aligned at 0x4) -> 0x5a: (kind 6) struct _IO_FILE (size 0xd8) (aligned at 0x4) [...] 0x406: (kind 6) struct coff_link_hash_entry (size 0x60) (aligned at 0x8) [0x0] root: ID 0x2b3: (kind 6) struct bfd_link_hash_entry (size 0x38) (aligned at 0x8) [0x0] root: ID 0x1d6: (kind 6) struct bfd_hash_entry (size 0x18) (aligned at 0x8) [0x0] next: ID 0x1d7: (kind 3) struct bfd_hash_entry * (size 0x8) (aligned at 0x8) [0x40] string: ID 0x61: (kind 3) const char * (size 0x8) (aligned at 0x8) [0x80] hash: ID 0x1: (kind 1) long unsigned int (format 0x0) (size 0x8) (aligned at 0x8) [0xc0] type: ID 0x397: (kind 8) enum bfd_link_hash_type (format 0x7f2e) (size 0x1) (aligned at 0x1) [0xc8] non_ir_ref_regular: ID 0x1c7: (kind 1) unsigned int:1 [slice 0x8:0x1] (format 0x0) (size 0x1) (aligned at 0x1) [0xc9] non_ir_ref_dynamic: ID 0x1c8: (kind 1) unsigned int:1 [slice 0x9:0x1] (format 0x0) (size 0x1) (aligned at 0x1) [0xca] linker_def: ID 0x1c9: (kind 1) unsigned int:1 [slice 0xa:0x1] (format 0x0) (size 0x1) (aligned at 0x1) [0xcb] ldscript_def: ID 0x1ca: (kind 1) unsigned int:1 [slice 0xb:0x1] (format 0x0) (size 0x1) (aligned at 0x1) [0xcc] rel_from_abs: ID 0x1cb: (kind 1) unsigned int:1 [slice 0xc:0x1] (format 0x0) (size 0x1) (aligned at 0x1) [...] In particular, indented subsections are only present for actual structs and unions, not forwards to them, and the structure itself doesn't add a spurious level of indentation; structure field names are easier to spot (at the cost of not making them look so much like C field declarations any more, but they weren't always shown in valid decl syntax even before this change) the size, type kind, and alignment are shown for all types for which they are meaningful; bitfield info is only shown for actual bitfields within structures and not ordinary integral fields; and type IDs are never omitted. Type printing is in general much more consistent and there is much less duplicated code in the type dumper. There is one user-visible effect outside the dumper: ctf_type_(a)name was erroneously emitting a trailing space on the name of slice types, even though a slice of an int and an int with the corresponding encoding represent the same type and should have the same print form. This trailing space is now gone. ld/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * testsuite/ld-ctf/array.d: Adjust for dumper changes. * testsuite/ld-ctf/conflicting-cycle-1.B-1.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-1.B-2.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-1.parent.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-2.A-1.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-2.A-2.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-2.parent.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-3.C-1.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-3.C-2.d: Likewise. * testsuite/ld-ctf/conflicting-cycle-3.parent.d: Likewise. * testsuite/ld-ctf/conflicting-enums.d: Likewise. * testsuite/ld-ctf/conflicting-typedefs.d: Likewise. * testsuite/ld-ctf/cross-tu-cyclic-conflicting.d: Likewise. * testsuite/ld-ctf/cross-tu-cyclic-nonconflicting.d: Likewise. * testsuite/ld-ctf/cross-tu-into-cycle.d: Likewise. * testsuite/ld-ctf/cross-tu-noncyclic.d: Likewise. * testsuite/ld-ctf/cycle-1.d: Likewise. * testsuite/ld-ctf/cycle-2.A.d: Likewise. * testsuite/ld-ctf/cycle-2.B.d: Likewise. * testsuite/ld-ctf/cycle-2.C.d: Likewise. * testsuite/ld-ctf/data-func-conflicted.d: Likewise. * testsuite/ld-ctf/diag-cttname-null.d: Likewise. * testsuite/ld-ctf/diag-cuname.d: Likewise. * testsuite/ld-ctf/diag-parlabel.d: Likewise. * testsuite/ld-ctf/diag-wrong-magic-number-mixed.d: Likewise. * testsuite/ld-ctf/forward.d: Likewise. * testsuite/ld-ctf/function.d: Likewise. * testsuite/ld-ctf/slice.d: Likewise. * testsuite/ld-ctf/super-sub-cycles.d: Likewise. * testsuite/ld-ctf/enums.c: New test. * testsuite/ld-ctf/enums.d: New test. libctf/ChangeLog 2021-01-05 Nick Alcock <nick.alcock@oracle.com> * ctf-decl.c (ctf_decl_push): Exclude slices from the decl stack. * ctf-types.c (ctf_type_aname): No longer deal with slices here. * ctf-dump.c (ctf_dump_membstate_t) <cdm_toplevel_indent>: Constify. (CTF_FT_REFS): New. (CTF_FT_BITFIELD): Likewise. (CTF_FT_ID): Likewise. (ctf_dump_member): Do not do indentation here. Migrate the type-printing parts of this into... (ctf_dump_format_type): ... here, to be shared by all type printers. Get the errno value for non-representable types right. Do not print bitfield info for non-bitfields. Improve the format and indentation of other type output. Shuffle spacing around to make all indentation either 'width of column' or 4 chars. (ctf_dump_label): Pass CTF_FT_REFS to ctf_dump_format_type. (ctf_dump_objts): Likewise. Spacing shuffle. (ctf_dump_var): Likewise. (type_hex_digits): Migrate down in the file, to above its new user. (ctf_dump_type): Indent here instead. Pass CTF_FT_REFS to ctf_dump_format_type. Don't trim off excess linefeeds now we no longer generate them. Dump enumerated types.