891813beaa
25 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
Alan Modra
|
b3adc24a07 | Update year range in copyright notice of binutils files | ||
Nick Alcock
|
de07e349be |
libctf: remove ctf_malloc, ctf_free and ctf_strdup
These just get in the way of auditing for erroneous usage of strdup and add a huge irregular surface of "ctf_malloc or malloc? ctf_free or free? ctf_strdup or strdup?" ctf_malloc and ctf_free usage has not reliably matched up for many years, if ever, making the whole game pointless. Go back to malloc, free, and strdup like everyone else: while we're at it, fix a bunch of places where we weren't properly checking for OOM. This changes the interface of ctf_cuname_set and ctf_parent_name_set, which could strdup but could not return errors (like ENOMEM). New in v4. include/ * ctf-api.h (ctf_cuname_set): Can now fail, returning int. (ctf_parent_name_set): Likewise. libctf/ * ctf-impl.h (ctf_alloc): Remove. (ctf_free): Likewise. (ctf_strdup): Likewise. * ctf-subr.c (ctf_alloc): Remove. (ctf_free): Likewise. * ctf-util.c (ctf_strdup): Remove. * ctf-create.c (ctf_serialize): Use malloc, not ctf_alloc; free, not ctf_free; strdup, not ctf_strdup. (ctf_dtd_delete): Likewise. (ctf_dvd_delete): Likewise. (ctf_add_generic): Likewise. (ctf_add_function): Likewise. (ctf_add_enumerator): Likewise. (ctf_add_member_offset): Likewise. (ctf_add_variable): Likewise. (membadd): Likewise. (ctf_compress_write): Likewise. (ctf_write_mem): Likewise. * ctf-decl.c (ctf_decl_push): Likewise. (ctf_decl_fini): Likewise. (ctf_decl_sprintf): Likewise. Check for OOM. * ctf-dump.c (ctf_dump_append): Use malloc, not ctf_alloc; free, not ctf_free; strdup, not ctf_strdup. (ctf_dump_free): Likewise. (ctf_dump): Likewise. * ctf-open.c (upgrade_types_v1): Likewise. (init_types): Likewise. (ctf_file_close): Likewise. (ctf_bufopen_internal): Likewise. Check for OOM. (ctf_parent_name_set): Likewise: report the OOM to the caller. (ctf_cuname_set): Likewise. (ctf_import): Likewise. * ctf-string.c (ctf_str_purge_atom_refs): Use malloc, not ctf_alloc; free, not ctf_free; strdup, not ctf_strdup. (ctf_str_free_atom): Likewise. (ctf_str_create_atoms): Likewise. (ctf_str_add_ref_internal): Likewise. (ctf_str_remove_ref): Likewise. (ctf_str_write_strtab): Likewise. |
||
Nick Alcock
|
791915db42 |
libctf: handle nonrepresentable types at link time
GCC can emit references to type 0 to indicate that this type is one that is not representable in the version of CTF it emits (for instance, version 3 cannot encode vector types). Type 0 is already used in the function section to indicate padding inserted to skip functions we do not want to encode the type of, so using zero in this way is a good extension of the format: but libctf reports such types as ECTF_BADID, which is indistinguishable from file corruption via links to truly nonexistent types with IDs like 0xDEADBEEF etc, which we really do want to stop for. In particular, this stops all traversals of types dead at this point, preventing us from even dumping CTF files containing unrepresentable types to see what's going on! So add a new error, ECTF_NONREPRESENTABLE, which is returned by recursive type resolution when a reference to a zero type is found. (No zero type is ever emitted into the CTF file by GCC, only references to one). We can't do much with types that are ultimately nonrepresentable, but we can do enough to keep functioning. Adjust ctf_add_type to ensure that top-level types of type zero and structure and union members of ultimate type zero are simply skipped without reporting an error, so we can copy structures and unions that contain nonrepresentable members (skipping them and leaving a hole where they would be, so no consumers downstream of the linker need to worry about this): adjust the dumper so that we dump members of nonrepresentable types in a simple form that indicates nonrepresentability rather than terminating the dump, and do not falsely assume all errors to be -ENOMEM: adjust the linker so that types that fail to get added are simply skipped, so that both nonrepresentable types and outright errors do not terminate the type addition, which could skip many valid types and cause further errors when variables of those types are added. In future, when we gain the ability to call back to the linker to report link-time type resolution errors, we should report failures to add all but nonrepresentable types. But we can't do that yet. v5: Fix tabdamage. include/ * ctf-api.h (ECTF_NONREPRESENTABLE): New. libctf/ * ctf-types.c (ctf_type_resolve): Return ECTF_NONREPRESENTABLE on type zero. * ctf-create.c (ctf_add_type): Detect and skip nonrepresentable members and types. (ctf_add_variable): Likewise for variables pointing to them. * ctf-link.c (ctf_link_one_type): Do not warn for nonrepresentable type link failure, but do warn for others. * ctf-dump.c (ctf_dump_format_type): Likewise. Do not assume all errors to be ENOMEM. (ctf_dump_member): Likewise. (ctf_dump_type): Likewise. (ctf_dump_header_strfield): Do not assume all errors to be ENOMEM. (ctf_dump_header_sectfield): Do not assume all errors to be ENOMEM. (ctf_dump_header): Likewise. (ctf_dump_label): likewise. (ctf_dump_objts): likewise. (ctf_dump_funcs): likewise. (ctf_dump_var): likewise. (ctf_dump_str): Likewise. |
||
Nick Alcock
|
87279e3cef |
libctf: installable libctf as a shared library
This lets other programs read and write CTF-format data. Two versioned shared libraries are created: libctf.so and libctf-nobfd.so. They contain identical content except that libctf-nobfd.so contains no references to libbfd and does not implement ctf_open, ctf_fdopen, ctf_bfdopen or ctf_bfdopen_ctfsect, so it can be used by programs that cannot use BFD, like readelf. The soname major version is presently .0 until the linker API stabilizes, when it will flip to .1 and hopefully never change again. New in v3. v4: libtoolize and turn into a pair of shared libraries. Drop --enable-install-ctf: now controlled by --enable-shared and --enable-install-libbfd, like everything else. v5: Add ../bfd to ACLOCAL_AMFLAGS and AC_CONFIG_MACRO_DIR. Fix tabdamage. * Makefile.def (host_modules): libctf is no longer no_install. * Makefile.in: Regenerated. libctf/ * configure.ac (AC_DISABLE_SHARED): New, like opcodes/. (LT_INIT): Likewise. (AM_INSTALL_LIBBFD): Likewise. (dlopen): Note why this is necessary in a comment. (SHARED_LIBADD): Initialize for possibly-PIC libiberty: derived from opcodes/. (SHARED_LDFLAGS): Likewise. (BFD_LIBADD): Likewise, for libbfd. (BFD_DEPENDENCIES): Likewise. (VERSION_FLAGS): Initialize, using a version script if ld supports one, or libtool -export-symbols-regex otherwise. (AC_CONFIG_MACRO_DIR): Add ../BFD. * Makefile.am (ACLOCAL_AMFLAGS): Likewise. (INCDIR): New. (AM_CPPFLAGS): Use $(srcdir), not $(top_srcdir). (noinst_LIBRARIES): Replace with... [INSTALL_LIBBFD] (lib_LTLIBRARIES): This, or... [!INSTALL_LIBBFD] (noinst_LTLIBRARIES): ... this, mentioning new libctf-nobfd.la as well. [INSTALL_LIBCTF] (include_HEADERS): Add the CTF headers. [!INSTALL_LIBCTF] (include_HEADERS): New, empty. (libctf_a_SOURCES): Rename to... (libctf_nobfd_la_SOURCES): ... this, all of libctf other than ctf-open-bfd.c. (libctf_la_SOURCES): Now derived from libctf_nobfd_la_SOURCES, with ctf-open-bfd.c added. (libctf_nobfd_la_LIBADD): New, using @SHARED_LIBADD@. (libctf_la_LIBADD): New, using @BFD_LIBADD@ as well. (libctf_la_DEPENDENCIES): New, using @BFD_DEPENDENCIES@. * Makefile.am [INSTALL_LIBCTF]: Use it. * aclocal.m4: Add ../bfd/acinclude.m4, ../config/acx.m4, and the libtool macros. * libctf.ver: New, everything is version LIBCTF_1.0 currently (even the unstable components). * Makefile.in: Regenerated. * config.h.in: Likewise. * configure: Likewise. binutils/ * Makefile.am (LIBCTF): Mention the .la file. (LIBCTF_NOBFD): New. (readelf_DEPENDENCIES): Use it. (readelf_LDADD): Likewise. * Makefile.in: Regenerated. ld/ * configure.ac (TESTCTFLIB): Set to the .so or .a, like TESTBFDLIB. * Makefile.am (TESTCTFLIB): Use it. (LIBCTF): Use the .la file. (check-DEJAGNU): Use it. * Makefile.in: Regenerated. * configure: Likewise. include/ * ctf-api.h: Note the instability of the ctf_link interfaces. |
||
Nick Alcock
|
7e97445a5a |
libctf: get rid of a disruptive public include of <sys/param.h>
This hoary old header defines things like MAX that users of libctf might perfectly reasonably define themselves. The CTF headers do not need it: move it into libctf/ctf-impl.h instead. include/ * ctf-api.h (includes): No longer include <sys/param.h>. libctf/ * ctf-impl.h (includes): Include <sys/param.h> here. |
||
Nick Alcock
|
49ea9b450b |
libctf: add CU-mapping machinery
Once the deduplicator is capable of actually detecting conflicting types with the same name (i.e., not yet) we will place such conflicting types, and types that depend on them, into CTF dictionaries that are the child of the main dictionary we usually emit: currently, this will lead to the .ctf section becoming a CTF archive rather than a single dictionary, with the default-named archive member (_CTF_SECTION, or NULL) being the main shared dictionary with most of the types in it. By default, the sections are named after the compilation unit they come from (complete path and all), with the cuname field in the CTF header providing further evidence of the name without requiring the caller to engage in tiresome parsing. But some callers may not wish the mapping from input CU to output sub-dictionary to be purely CU-based. The machinery here allows this to be freely changed, in two ways: - callers can call ctf_link_add_cu_mapping to specify that a single input compilation unit should have its types placed in some other CU if they conflict: the CU will always be created, even if empty, so the consuming program can depend on its existence. You can map multiple input CUs to one output CU to force all their types to be merged together: if some of *those* types conflict, the behaviour is currently unspecified (the new deduplicator will specify it). - callers can call ctf_link_set_memb_name_changer to provide a function which is passed every CTF sub-dictionary name in turn (including _CTF_SECTION) and can return a new name, or NULL if no change is desired. The mapping from input to output names should not map two input names to the same output name: if this happens, the two are not merged but will result in an archive with two members with the same name (technically valid, but it's hard to access the second same-named member: you have to do an iteration over archive members). This is used by the kernel's ctfarchive machinery (not yet upstream) to encode CTF under member names like {module name}.ctf rather than .ctf.CU, but it is anticipated that other large projects may wish to have their own storage for CTF outside of .ctf sections and may wish to have new naming schemes that suit their special-purpose consumers. New in v3. v4: check for strdup failure. v5: fix tabdamage. include/ * ctf-api.h (ctf_link_add_cu_mapping): New. (ctf_link_memb_name_changer_f): New. (ctf_link_set_memb_name_changer): New. libctf/ * ctf-impl.h (ctf_file_t) <ctf_link_cu_mappping>: New. <ctf_link_memb_name_changer>: Likewise. <ctf_link_memb_name_changer_arg>: Likewise. * ctf-create.c (ctf_update): Update accordingly. * ctf-open.c (ctf_file_close): Likewise. * ctf-link.c (ctf_create_per_cu): Apply the cu mapping. (ctf_link_add_cu_mapping): New. (ctf_link_set_memb_name_changer): Likewise. (ctf_change_parent_name): New. (ctf_name_list_accum_cb_arg_t) <dynames>: New, storage for names allocated by the caller's ctf_link_memb_name_changer. <ndynames>: Likewise. (ctf_accumulate_archive_names): Call the ctf_link_memb_name_changer. (ctf_link_write): Likewise (for _CTF_SECTION only): also call ctf_change_parent_name. Free any resulting names. |
||
Nick Alcock
|
eabb7154df |
libctf: add linking of the variable section
The compiler describes the name and type of all file-scope variables in this section. Merging it at link time requires using the type mapping added in the previous commit to determine the appropriate type for the variable in the output, given its type in the input: we check the shared container first, and if the type doesn't exist there, it must be a conflicted type in the per-CU child, and the variable should go there too. We also put the variable in the per-CU child if a variable with the same name but a different type already exists in the parent: we ignore any such conflict in the child because CTF cannot represent such things, nor can they happen unless a third-party linking program has overridden the mapping of CU to CTF archive member name (using machinery added in a later commit). v3: rewritten using an algorithm that actually works in the case of conflicting names. Some code motion from the next commit. Set the per-CU parent name. v4: check for strdup failure. v5: fix tabdamage. include/ * ctf-api.h (ECTF_INTERNAL): New. libctf/ * ctf-link.c (ctf_create_per_cu): New, refactored out of... (ctf_link_one_type): ... here, with parent-name setting added. (check_variable): New. (ctf_link_one_variable): Likewise. (ctf_link_one_input_archive_member): Call it. * ctf-error.c (_ctf_errlist): Updated with new errors. |
||
Nick Alcock
|
72c83edd92 |
libctf: add the ctf_link machinery
This is the start of work on the core of the linking mechanism for CTF sections. This commit handles the type and string sections. The linker calls these functions in sequence: ctf_link_add_ctf: to add each CTF section in the input in turn to a newly-created ctf_file_t (which will appear in the output, and which itself will become the shared parent that contains types that all TUs have in common (in all link modes) and all types that do not have conflicting definitions between types (by default). Input files that are themselves products of ld -r are supported, though this is not heavily tested yet. ctf_link: called once all input files are added to merge the types in all the input containers into the output container, eliminating duplicates. ctf_link_add_strtab: called once the ELF string table is finalized and all its offsets are known, this calls a callback provided by the linker which returns the string content and offset of every string in the ELF strtab in turn: all these strings which appear in the input CTF strtab are eliminated from it in favour of the ELF strtab: equally, any strings that only appear in the input strtab will reappear in the internal CTF strtab of the output. ctf_link_shuffle_syms (not yet implemented): called once the ELF symtab is finalized, this calls a callback provided by the linker which returns information on every symbol in turn as a ctf_link_sym_t. This is then used to shuffle the function info and data object sections in the CTF section into symbol table order, eliminating the index sections which map those sections to symbol names before that point. Currently just returns ECTF_NOTYET. ctf_link_write: Returns a buffer containing either a serialized ctf_file_t (if there are no types with conflicting definitions in the object files in the link) or a ctf_archive_t containing a large ctf_file_t (the common types) and a bunch of small ones named after individual CUs in which conflicting types are found (containing the conflicting types, and all types that reference them). A threshold size above which compression takes place is passed as one parameter. (Currently, only gzip compression is supported, but I hope to add lzma as well.) Lifetime rules for this are simple: don't close the input CTF files until you've called ctf_link for the last time. We do not assume that symbols or strings passed in by the callback outlast the call to ctf_link_add_strtab or ctf_link_shuffle_syms. Right now, the duplicate elimination mechanism is the one already present as part of the ctf_add_type function, and is not particularly good: it misses numerous actual duplicates, and the conflicting-types detection hardly ever reports that types conflict, even when they do (one of them just tends to get silently dropped): it is also very slow. This will all be fixed in the next few weeks, but the fix hardly touches any of this code, and the linker does work without it, just not as well as it otherwise might. (And when no CTF section is present, there is no effect on performance, of course. So only people using a trunk GCC with not-yet-committed patches will even notice. By the time it gets upstream, things should be better.) v3: Fix error handling. v4: check for strdup failure. v5: fix tabdamage. include/ * ctf-api.h (struct ctf_link_sym): New, a symbol in flight to the libctf linking machinery. (CTF_LINK_SHARE_UNCONFLICTED): New. (CTF_LINK_SHARE_DUPLICATED): New. (ECTF_LINKADDEDLATE): New, replacing ECTF_UNUSED. (ECTF_NOTYET): New, a 'not yet implemented' message. (ctf_link_add_ctf): New, add an input file's CTF to the link. (ctf_link): New, merge the type and string sections. (ctf_link_strtab_string_f): New, callback for feeding strtab info. (ctf_link_iter_symbol_f): New, callback for feeding symtab info. (ctf_link_add_strtab): New, tell the CTF linker about the ELF strtab's strings. (ctf_link_shuffle_syms): New, ask the CTF linker to shuffle its symbols into symtab order. (ctf_link_write): New, ask the CTF linker to write the CTF out. libctf/ * ctf-link.c: New file, linking of the string and type sections. * Makefile.am (libctf_a_SOURCES): Add it. * Makefile.in: Regenerate. * ctf-impl.h (ctf_file_t): New fields ctf_link_inputs, ctf_link_outputs. * ctf-create.c (ctf_update): Update accordingly. * ctf-open.c (ctf_file_close): Likewise. * ctf-error.c (_ctf_errlist): Updated with new errors. |
||
Nick Alcock
|
5537f9b9a3 |
libctf: write CTF files to memory, and CTF archives to fds
Before now, we've been able to write CTF files to gzFile descriptors or fds, and CTF archives to named files only. Make this a bit less irregular by allowing CTF archives to be written to fds with the new function ctf_arc_write_fd: also allow CTF files to be written to a new memory buffer via ctf_write_mem. (It would be nice to complete things by adding a new function to write CTF archives to memory, but this is too difficult to do given the short time the linker is expected to be writing them out: we will transition to a better format in format v4, though we will always support reading CTF archives that are stored in .ctf sections.) include/ * ctf-api.h (ctf_arc_write_fd): New. (ctf_write_mem): Likewise. (ctf_gzwrite): Spacing fix. libctf/ * ctf-archive.c (ctf_arc_write): Split off, and reimplement in terms of... (ctf_arc_write_fd): ... this new function. * ctf-create.c (ctf_write_mem): New. |
||
Nick Alcock
|
0ac6231298 |
libctf: Add iteration over non-root types
The existing function ctf_type_iter lets you iterate over root-visible types (types you can look up by name). There is no way to iterate over non-root-visible types, which is troublesome because both the linker and dumper want to do that. So add a new function that can do it: the callback it takes accepts an extra parameter which indicates whether the type is root-visible or not. include/ * ctf-api.h (ctf_type_all_f): New. (ctf_type_iter_all): New. libctf/ * ctf_types.c (ctf_type_iter_all): New. |
||
Nick Alcock
|
fd55eae84d |
libctf: allow the header to change between versions
libctf supports dynamic upgrading of the type table as file format versions change, but before now has not supported changes to the CTF header. Doing this is complicated by the baroque storage method used: the CTF header is kept prepended to the rest of the CTF data, just as when read from the file, and written out from there, and is endian-flipped in place. This makes accessing it needlessly hard and makes it almost impossible to make the header larger if we add fields. The general storage machinery around the malloced ctf pointer (the 'ctf_base') is also overcomplicated: the pointer is sometimes malloced locally and sometimes assigned from a parameter, so freeing it requires checking to see if that parameter was used, needlessly coupling ctf_bufopen and ctf_file_close together. So split the header out into a new ctf_file_t.ctf_header, which is written out explicitly: squeeze it out of the CTF buffer whenever we reallocate it, and use ctf_file_t.ctf_buf to skip past the header when we do not need to reallocate (when no upgrading or endian-flipping is required). We now track whether the CTF base can be freed explicitly via a new ctf_dynbase pointer which is non-NULL only when freeing is possible. With all this done, we can upgrade the header on the fly and add new fields as desired, via a new upgrade_header function in ctf-open. As with other forms of upgrading, libctf upgrades older headers automatically to the latest supported version at open time. For a first use of this field, we add a new string field cth_cuname, and a corresponding setter/getter pair ctf_cuname_set and ctf_cuname: this is used by debuggers to determine whether a CTF section's types relate to a single compilation unit, or to all compilation units in the program. (Types with ambiguous definitions in different CUs have only one of these types placed in the top-level shared .ctf container: the rest are placed in much smaller per-CU containers, which have the shared container as their parent. Since CTF must be useful in the absence of DWARF, we store the names of the relevant CUs ourselves, so the debugger can look them up.) v5: fix tabdamage. include/ * ctf-api.h (ctf_cuname): New function. (ctf_cuname_set): Likewise. * ctf.h: Improve comment around upgrading, no longer implying that v2 is the target of upgrades (it is v3 now). (ctf_header_v2_t): New, old-format header for backward compatibility. (ctf_header_t): Add cth_cuname: this is the first of several header changes in format v3. libctf/ * ctf-impl.h (ctf_file_t): New fields ctf_header, ctf_dynbase, ctf_cuname, ctf_dyncuname: ctf_base and ctf_buf are no longer const. * ctf-open.c (ctf_set_base): Preserve the gap between ctf_buf and ctf_base: do not assume that it is always sizeof (ctf_header_t). Print out ctf_cuname: only print out ctf_parname if set. (ctf_free_base): Removed, ctf_base is no longer freed: free ctf_dynbase instead. (ctf_set_version): Fix spacing. (upgrade_header): New, in-place header upgrading. (upgrade_types): Rename to... (upgrade_types_v1): ... this. Free ctf_dynbase, not ctf_base. No longer track old and new headers separately. No longer allow for header sizes explicitly: squeeze the headers out on upgrade (they are preserved in fp->ctf_header). Set ctf_dynbase, ctf_base and ctf_buf explicitly. Use ctf_free, not ctf_free_base. (upgrade_types): New, also handle ctf_parmax updating. (flip_header): Flip ctf_cuname. (flip_types): Flip BUF explicitly rather than deriving BUF from BASE. (ctf_bufopen): Store the header in fp->ctf_header. Correct minimum required alignment of objtoff and funcoff. No longer store it in the ctf_buf unless that buf is derived unmodified from the input. Set ctf_dynbase where ctf_base is dynamically allocated. Drop locals that duplicate fields in ctf_file: move allocation of ctf_file further up instead. Call upgrade_header as needed. Move version-specific ctf_parmax initialization into upgrade_types. More concise error handling. (ctf_file_close): No longer test for null pointers before freeing. Free ctf_dyncuname, ctf_dynbase, and ctf_header. Do not call ctf_free_base. (ctf_cuname): New. (ctf_cuname_set): New. * ctf-create.c (ctf_update): Populate ctf_cuname. (ctf_gzwrite): Write out the header explicitly. Remove obsolescent comment. (ctf_write): Likewise. (ctf_compress_write): Get the header from ctf_header, not ctf_base. Fix the compression length: fp->ctf_size never counted the CTF header. Simplify the compress call accordingly. |
||
Nick Alcock
|
12a0b67d28 |
libctf: introduce ctf_func_type_{info,args}, ctf_type_aname_raw
The first two of these allow you to get function type info and args out of the types section give a type ID: astonishingly, this was missing from libctf before now: so even though types of kind CTF_K_FUNCTION were supported, you couldn't find out anything about them. (The existing ctf_func_info and ctf_func_args only allow you to get info about functions in the function section, i.e. given symbol table indexes, not type IDs.) The second of these allows you to get the raw undecorated name out of the CTF section (strdupped for safety) without traversing subtypes to build a full C identifier out of it. It's useful for things that are already tracking the type kind etc and just need an unadorned name. include/ * ctf-api.h (ECTF_NOTFUNC): Fix description. (ctf_func_type_info): New. (ctf_func_type_args): Likewise. libctf/ * ctf-types.c (ctf_type_aname_raw): New. (ctf_func_type_info): Likewise. (ctf_func_type_args): Likewise. * ctf-error.c (_ctf_errlist): Fix description. |
||
Jose E. Marchesi
|
a0486bac41 |
libctf: fix a number of build problems found on Solaris and NetBSD
- Use of nonportable <endian.h> - Use of qsort_r - Use of zlib without appropriate magic to pull in the binutils zlib - Use of off64_t without checking (fixed by dropping the unused fields that need off64_t entirely) - signedness problems due to long being too short a type on 32-bit platforms: ctf_id_t is now 'unsigned long', and CTF_ERR must be used only for functions that return ctf_id_t - One lingering use of bzero() and of <sys/errno.h> All fixed, using code from gnulib where possible. Relatedly, set cts_size in a couple of places it was missed (string table and symbol table loading upon ctf_bfdopen()). binutils/ * objdump.c (make_ctfsect): Drop cts_type, cts_flags, and cts_offset. * readelf.c (shdr_to_ctf_sect): Likewise. include/ * ctf-api.h (ctf_sect_t): Drop cts_type, cts_flags, and cts_offset. (ctf_id_t): This is now an unsigned type. (CTF_ERR): Cast it to ctf_id_t. Note that it should only be used for ctf_id_t-returning functions. libctf/ * Makefile.am (ZLIB): New. (ZLIBINC): Likewise. (AM_CFLAGS): Use them. (libctf_a_LIBADD): New, for LIBOBJS. * configure.ac: Check for zlib, endian.h, and qsort_r. * ctf-endian.h: New, providing htole64 and le64toh. * swap.h: Code style fixes. (bswap_identity_64): New. * qsort_r.c: New, from gnulib (with one added #include). * ctf-decls.h: New, providing a conditional qsort_r declaration, and unconditional definitions of MIN and MAX. * ctf-impl.h: Use it. Do not use <sys/errno.h>. (ctf_set_errno): Now returns unsigned long. * ctf-util.c (ctf_set_errno): Adjust here too. * ctf-archive.c: Use ctf-endian.h. (ctf_arc_open_by_offset): Use memset, not bzero. Drop cts_type, cts_flags and cts_offset. (ctf_arc_write): Drop debugging dependent on the size of off_t. * ctf-create.c: Provide a definition of roundup if not defined. (ctf_create): Drop cts_type, cts_flags and cts_offset. (ctf_add_reftype): Do not check if type IDs are below zero. (ctf_add_slice): Likewise. (ctf_add_typedef): Likewise. (ctf_add_member_offset): Cast error-returning ssize_t's to size_t when known error-free. Drop CTF_ERR usage for functions returning int. (ctf_add_member_encoded): Drop CTF_ERR usage for functions returning int. (ctf_add_variable): Likewise. (enumcmp): Likewise. (enumadd): Likewise. (membcmp): Likewise. (ctf_add_type): Likewise. Cast error-returning ssize_t's to size_t when known error-free. * ctf-dump.c (ctf_is_slice): Drop CTF_ERR usage for functions returning int: use CTF_ERR for functions returning ctf_type_id. (ctf_dump_label): Likewise. (ctf_dump_objts): Likewise. * ctf-labels.c (ctf_label_topmost): Likewise. (ctf_label_iter): Likewise. (ctf_label_info): Likewise. * ctf-lookup.c (ctf_func_args): Likewise. * ctf-open.c (upgrade_types): Cast to size_t where appropriate. (ctf_bufopen): Likewise. Use zlib types as needed. * ctf-types.c (ctf_member_iter): Drop CTF_ERR usage for functions returning int. (ctf_enum_iter): Likewise. (ctf_type_size): Likewise. (ctf_type_align): Likewise. Cast to size_t where appropriate. (ctf_type_kind_unsliced): Likewise. (ctf_type_kind): Likewise. (ctf_type_encoding): Likewise. (ctf_member_info): Likewise. (ctf_array_info): Likewise. (ctf_enum_value): Likewise. (ctf_type_rvisit): Likewise. * ctf-open-bfd.c (ctf_bfdopen): Drop cts_type, cts_flags and cts_offset. (ctf_simple_open): Likewise. (ctf_bfdopen_ctfsect): Likewise. Set cts_size properly. * Makefile.in: Regenerate. * aclocal.m4: Likewise. * config.h: Likewise. * configure: Likewise. |
||
Nick Alcock
|
a30b3e182a |
libctf: debug dumping
This introduces ctf_dump(), an iterator which returns a series of strings, each representing a debugging dump of one item from a given section in the CTF file. The items may be multiline: a callback is provided to allow the caller to decorate each line as they desire before the line is returned. libctf/ * ctf-dump.c: New. include/ * ctf-api.h (ctf_dump_decorate_f): New. (ctf_dump_state_t): new. (ctf_dump): New. |
||
Nick Alcock
|
6dbf2b7340 |
libctf: labels
This facility allows you to associate regions of type IDs with *labels*, a labelled tiling of the type ID space. You can use these to define CTF containers with distinct parents for distinct ranges of the ID space, or to assist with parallelization of CTF processing, or for any other purpose you can think of. Notably absent from here (though declared in the API header) is any way to define new labels: this will probably be introduced soon, as part of the linker deduplication work. (One existed in the past, but was deeply tied to the Solaris CTF file generator and had to be torn out.) libctf/ * ctf-labels.c: New. include/ * ctf-api.h (ctf_label_f): New. (ctf_label_set): New. (ctf_label_get): New. (ctf_label_topmost): New. (ctf_label_info): New. (ctf_label_iter): New. |
||
Nick Alcock
|
6c33b742ce |
libctf: library version enforcement
This old Solaris standard allows callers to specify that they are expecting one particular API and/or CTF file format from the library. libctf/ * ctf-impl.h (_libctf_version): New declaration. * ctf-subr.c (_libctf_version): Define it. (ctf_version): New. include/ * ctf-api.h (ctf_version): New. |
||
Nick Alcock
|
b437bfe0f4 |
libctf: lookups by name and symbol
These functions allow you to look up types given a name in a simple subset of C declarator syntax (no function pointers), to look up the types of variables given a name, and to look up the types of data objects and the type signatures of functions given symbol table offsets. (Despite its name, one function in this commit, ctf_lookup_symbol_name(), is for the internal use of libctf only, and does not appear in any public header files.) libctf/ * ctf-lookup.c (isqualifier): New. (ctf_lookup_by_name): Likewise. (struct ctf_lookup_var_key): Likewise. (ctf_lookup_var): Likewise. (ctf_lookup_variable): Likewise. (ctf_lookup_symbol_name): Likewise. (ctf_lookup_by_symbol): Likewise. (ctf_func_info): Likewise. (ctf_func_args): Likewise. include/ * ctf-api.h (ctf_func_info): New. (ctf_func_args): Likewise. (ctf_lookup_by_symbol): Likewise. (ctf_lookup_by_symbol): Likewise. (ctf_lookup_variable): Likewise. |
||
Nick Alcock
|
316afdb130 |
libctf: core type lookup
Finally we get to the functions used to actually look up and enumerate properties of types in a container (names, sizes, members, what type a pointer or cv-qual references, determination of whether two types are assignment-compatible, etc). With a very few exceptions these do not work for types newly added via ctf_add_*(): they only work on types in read-only containers, or types added before the most recent call to ctf_update(). This also adds support for lookup of "variables" (string -> type ID mappings) and for generation of C type names corresponding to a type ID. libctf/ * ctf-decl.c: New file. * ctf-types.c: Likewise. * ctf-impl.h: New declarations. include/ * ctf-api.h (ctf_visit_f): New definition. (ctf_member_f): Likewise. (ctf_enum_f): Likewise. (ctf_variable_f): Likewise. (ctf_type_f): Likewise. (ctf_type_isparent): Likewise. (ctf_type_ischild): Likewise. (ctf_type_resolve): Likewise. (ctf_type_aname): Likewise. (ctf_type_lname): Likewise. (ctf_type_name): Likewise. (ctf_type_sizee): Likewise. (ctf_type_align): Likewise. (ctf_type_kind): Likewise. (ctf_type_reference): Likewise. (ctf_type_pointer): Likewise. (ctf_type_encoding): Likewise. (ctf_type_visit): Likewise. (ctf_type_cmp): Likewise. (ctf_type_compat): Likewise. (ctf_member_info): Likewise. (ctf_array_info): Likewise. (ctf_enum_name): Likewise. (ctf_enum_value): Likewise. (ctf_member_iter): Likewise. (ctf_enum_iter): Likewise. (ctf_type_iter): Likewise. (ctf_variable_iter): Likewise. |
||
Nick Alcock
|
143dce8481 |
libctf: ELF file opening via BFD
These functions let you open an ELF file with a customarily-named CTF section in it, automatically opening the CTF file or archive and associating the symbol and string tables in the ELF file with the CTF container, so that you can look up the types of symbols in the ELF file via ctf_lookup_by_symbol(), and so that strings can be shared between the ELF file and CTF container, to save space. It uses BFD machinery to do so. This has now been lightly tested and seems to work. In particular, if you already have a bfd you can pass it in to ctf_bfdopen(), and if you want a bfd made for you you can call ctf_open() or ctf_fdopen(), optionally specifying a target (or try once without a target and then again with one if you get ECTF_BFD_AMBIGUOUS back). We use a forward declaration for the struct bfd in ctf-api.h, so that ctf-api.h users are not required to pull in <bfd.h>. (This is mostly for the sake of readelf.) libctf/ * ctf-open-bfd.c: New file. * ctf-open.c (ctf_close): New. * ctf-impl.h: Include bfd.h. (ctf_file): New members ctf_data_mmapped, ctf_data_mmapped_len. (ctf_archive_internal): New members ctfi_abfd, ctfi_data, ctfi_bfd_close. (ctf_bfdopen_ctfsect): New declaration. (_CTF_SECTION): likewise. include/ * ctf-api.h (struct bfd): New forward. (ctf_fdopen): New. (ctf_bfdopen): Likewise. (ctf_open): Likewise. (ctf_arc_open): Likewise. |
||
Nick Alcock
|
9402cc593f |
libctf: mmappable archives
If you need to store a large number of CTF containers somewhere, this provides a dedicated facility for doing so: an mmappable archive format like a very simple tar or ar without all the system-dependent format horrors or need for heavy file copying, with built-in compression of files above a particular size threshold. libctf automatically mmap()s uncompressed elements of these archives, or uncompresses them, as needed. (If the platform does not support mmap(), copying into dynamically-allocated buffers is used.) Archive iteration operations are partitioned into raw and non-raw forms. Raw operations pass thhe raw archive contents to the callback: non-raw forms open each member with ctf_bufopen() and pass the resulting ctf_file_t to the iterator instead. This lets you manipulate the raw data in the archive, or the contents interpreted as a CTF file, as needed. It is not yet known whether we will store CTF archives in a linked ELF object in one of these (akin to debugdata) or whether they'll get one section per TU plus one parent container for types shared between them. (In the case of ELF objects with very large numbers of TUs, an archive of all of them would seem preferable, so we might just use an archive, and add lzma support so you can assume that .gnu_debugdata and .ctf are compressed using the same algorithm if both are present.) To make usage easier, the ctf_archive_t is not the on-disk representation but an abstraction over both ctf_file_t's and archives of many ctf_file_t's: users see both CTF archives and raw CTF files as ctf_archive_t's upon opening, the only difference being that a raw CTF file has only a single "archive member", named ".ctf" (the default if a null pointer is passed in as the name). The next commit will make use of this facility, in addition to providing the public interface to actually open archives. (In the future, it should be possible to have all CTF sections in an ELF file appear as an "archive" in the same fashion.) This machinery is also used to allow library-internal creators of ctf_archive_t's (such as the next commit) to stash away an ELF string and symbol table, so that all opens of members in a given archive will use them. This lets CTF archives exploit the ELF string and symbol table just like raw CTF files can. (All this leads to somewhat confusing type naming. The ctf_archive_t is a typedef for the opaque internal type, struct ctf_archive_internal: the non-internal "struct ctf_archive" is the on-disk structure meant for other libraries manipulating CTF files. It is probably clearest to use the struct name for struct ctf_archive_internal inside the program, and the typedef names outside.) libctf/ * ctf-archive.c: New. * ctf-impl.h (ctf_archive_internal): New type. (ctf_arc_open_internal): New declaration. (ctf_arc_bufopen): Likewise. (ctf_arc_close_internal): Likewise. include/ * ctf.h (CTFA_MAGIC): New. (struct ctf_archive): New. (struct ctf_archive_modent): Likewise. * ctf-api.h (ctf_archive_member_f): New. (ctf_archive_raw_member_f): Likewise. (ctf_arc_write): Likewise. (ctf_arc_close): Likewise. (ctf_arc_open_by_name): Likewise. (ctf_archive_iter): Likewise. (ctf_archive_raw_iter): Likewise. (ctf_get_arc): Likewise. |
||
Nick Alcock
|
72f3392127 |
libctf: opening
This fills in the other half of the opening/creation puzzle: opening of already-existing CTF files. Such files are always read-only: if you want to add to a CTF file opened with one of the opening functions in this file, use ctf_add_type(), in a later commit, to copy appropriate types into a newly ctf_create()d, writable container. The lowest-level opening functions are in here: ctf_bufopen(), which takes ctf_sect_t structures akin to ELF section headers, and ctf_simple_open(), which can be used if you don't have an entire ELF section header to work from. Both will malloc() new space for the buffers only if necessary, will mmap() directly from the file if requested, and will mprotect() it afterwards to prevent accidental corruption of the types. These functions are also used by ctf_update() when converting types in a writable container into read-only types that can be looked up using the lookup functions (in later commits). The files are always of the native endianness of the system that created them: at read time, the endianness of the header magic number is used to determine whether or not the file needs byte-swapping, and the entire thing is aggressively byte-swapped. The agggressive nature of this swapping avoids complicating the rest of the code with endianness conversions, while the native endianness introduces no byte-swapping overhead in the common case. (The endianness-independence code is also much newer than everything else in this file, and deserves closer scrutiny.) The accessors at the top of the file are there to transparently support older versions of the CTF file format, allowing translation from older formats that have different sizes for the structures in ctf.h: currently, these older formats are intermingled with the newer ones in ctf.h: they will probably migrate to a compatibility header in time, to ease readability. The ctf_set_base() function is split out for the same reason: when conversion code to a newer format is written, it would need to malloc() new storage for the entire ctf_file_t if a file format change causes it to grow, and for that we need ctf_set_base() to be a separate function. One pair of linked data structures supported by this file has no creation code in libctf yet: the data and function object sections read by init_symtab(). These will probably arrive soon, when the linker comes to need them. (init_symtab() has hardly been changed since 2009, but if any code in libctf has rotted over time, this will.) A few simple accessors are also present that can even be called on read-only containers because they don't actually modify them, since the relevant things are not stored in the container but merely change its operation: ctf_setmodel(), which lets you specify whether a container is LP64 or not (used to statically determine the sizes of a few types), ctf_import(), which is the only way to associate a parent container with a child container, and ctf_setspecific(), which lets the caller associate an arbitrary pointer with the CTF container for any use. If the user doesn't call these functions correctly, libctf will misbehave: this is particularly important for ctf_import(), since a container built against a given parent container will not be able to resolve types that depend on types in the parent unless it is ctf_import()ed with a parent container with the same set of types at the same IDs, or a superset. Possible future extensions (also noted in the ctf-hash.c file) include storing a count of things so that we don't need to do one pass over the CTF file counting everything, and computing a perfect hash at CTF creation time in some compact form, storing it in the CTF file, and using it to hash things so we don't need to do a second pass over the entire CTF file to set up the hashes used to go from names to type IDs. (There are multiple such hashes, one for each C type namespace: types, enums, structs, and unions.) libctf/ * ctf-open.c: New file. * swap.h: Likewise. include/ * ctf-api.h (ctf_file_close): New declaration. (ctf_getdatasect): Likewise. (ctf_parent_file): Likewise. (ctf_parent_name): Likewise. (ctf_parent_name_set): Likewise. (ctf_import): Likewise. (ctf_setmodel): Likewise. (ctf_getmodel): Likewise. (ctf_setspecific): Likewise. (ctf_getspecific): Likewise. |
||
Nick Alcock
|
47d546f427 |
libctf: creation functions
The CTF creation process looks roughly like (error handling elided): int err; ctf_file_t *foo = ctf_create (&err); ctf_id_t type = ctf_add_THING (foo, ...); ctf_update (foo); ctf_*write (...); Some ctf_add_THING functions accept other type IDs as arguments, depending on the type: cv-quals, pointers, and structure and union members all take other types as arguments. So do 'slices', which let you take an existing integral type and recast it as a type with a different bitness or offset within a byte, for bitfields. One class of THING is not a type: "variables", which are mappings of names (in the internal string table) to types. These are mostly useful when encoding variables that do not appear in a symbol table but which some external user has some other way to figure out the address of at runtime (dynamic symbol lookup or querying a VM interpreter or something). You can snapshot the creation process at any point: rolling back to a snapshot deletes all types and variables added since that point. You can make arbitrary type queries on the CTF container during the creation process, but you must call ctf_update() first, which translates the growing dynamic container into a static one (this uses the CTF opening machinery, added in a later commit), which is quite expensive. This function must also be called after adding types and before writing the container out. Because addition of types involves looking up existing types, we add a little of the type lookup machinery here, as well: only enough to look up types in dynamic containers under construction. libctf/ * ctf-create.c: New file. * ctf-lookup.c: New file. include/ * ctf-api.h (zlib.h): New include. (ctf_sect_t): New. (ctf_sect_names_t): Likewise. (ctf_encoding_t): Likewise. (ctf_membinfo_t): Likewise. (ctf_arinfo_t): Likewise. (ctf_funcinfo_t): Likewise. (ctf_lblinfo_t): Likewise. (ctf_snapshot_id_t): Likewise. (CTF_FUNC_VARARG): Likewise. (ctf_simple_open): Likewise. (ctf_bufopen): Likewise. (ctf_create): Likewise. (ctf_add_array): Likewise. (ctf_add_const): Likewise. (ctf_add_enum_encoded): Likewise. (ctf_add_enum): Likewise. (ctf_add_float): Likewise. (ctf_add_forward): Likewise. (ctf_add_function): Likewise. (ctf_add_integer): Likewise. (ctf_add_slice): Likewise. (ctf_add_pointer): Likewise. (ctf_add_type): Likewise. (ctf_add_typedef): Likewise. (ctf_add_restrict): Likewise. (ctf_add_struct): Likewise. (ctf_add_union): Likewise. (ctf_add_struct_sized): Likewise. (ctf_add_union_sized): Likewise. (ctf_add_volatile): Likewise. (ctf_add_enumerator): Likewise. (ctf_add_member): Likewise. (ctf_add_member_offset): Likewise. (ctf_add_member_encoded): Likewise. (ctf_add_variable): Likewise. (ctf_set_array): Likewise. (ctf_update): Likewise. (ctf_snapshot): Likewise. (ctf_rollback): Likewise. (ctf_discard): Likewise. (ctf_write): Likewise. (ctf_gzwrite): Likewise. (ctf_compress_write): Likewise. |
||
Nick Alcock
|
479604f44f |
libctf: error handling
CTF functions return zero on success or an extended errno value which can be translated into a string via the functions in this commit. The errno numbers start at -CTF_BASE. libctf/ * ctf-error.c: New file. include/ * ctf-api.h (ctf_errno): New declaration. (ctf_errmsg): Likewise. |
||
Nick Alcock
|
60da9d9559 |
libctf: lowest-level memory allocation and debug-dumping wrappers
The memory-allocation wrappers are simple things to allow malloc interposition: they are only used inconsistently at present, usually where malloc debugging was required in the past. These provide a default implementation that is environment-variable triggered (initialized on the first call to the libctf creation and file-opening functions, the first functions people will use), and a ctf_setdebug()/ctf_getdebug() pair that allows the caller to explicitly turn debugging off and on. If ctf_setdebug() is called, the automatic setting from an environment variable is skipped. libctf/ * ctf-impl.h: New file. * ctf-subr.c: New file. include/ * ctf-api.h (ctf_setdebug): New. (ctf_getdebug): Likewise. |
||
Nick Alcock
|
2e94b05630 |
include: new header ctf-api.h
This non-installed header is the means by which libctf consumers communicate with libctf. This header will be extended in subsequent commits. include/ * ctf-api.h: New file. |