From: Nick Alcock Date: Fri, 25 Apr 2025 16:54:48 +0000 (+0100) Subject: libctf: serialize: handle CTF-versus-BTF output format checks X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d5012389a44029018a92b113d2253afb79493e7e;p=thirdparty%2Fbinutils-gdb.git libctf: serialize: handle CTF-versus-BTF output format checks The internal function ctf_serialize_output_format centralizes all the checks for BTF-versus-CTF, checking to see if the type section, active suppressions, and BTF-emission mode permit BTF emission, setting ctf_serialize.cs_is_btf if we are actually BTF, and raising ECTF_NOTBTF if we are requiring BTF emission but the type section is such that we can't emit it. (There is a forcing parameter in place, as with most of these serialization functions, to allow for the caller to force CTF emission if it knows the output will be compressed or will be part of multi-member archives or something else external to the type section that BTF does not support.) --- diff --git a/libctf/ctf-serialize.c b/libctf/ctf-serialize.c index 2cbaafc4e17..ef4bcd4313d 100644 --- a/libctf/ctf-serialize.c +++ b/libctf/ctf-serialize.c @@ -1290,8 +1290,57 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr, /* Overall serialization. */ +/* Determine the output format. Returns 0 on successful determination or -1 and + an error if an attempt is being made to write out a CTF dict but the library + state prohibits it, or a per-dict prohibition is preventing the writeout of a + type kind that this dict contains. */ int +ctf_serialize_output_format (ctf_dict_t *fp, int force_ctf) +{ + int ctf_needed = 0; + + if (fp->ctf_flags & LCTF_NO_STR) + return (ctf_set_errno (fp, ECTF_NOPARENT)); + + /* Complain if we're asked to emit BTF only, but we have types that call for + CTFv4 extensions, or we are forced to emit CTF because the caller requested + compression. */ + + if (force_ctf) + ctf_needed = 1; + + if (ctf_needed && _libctf_btf_mode == LIBCTF_BTM_BTF) + goto err_not_btf; + + /* Relatively expensive, so done after cheap checks. */ + + if (!ctf_type_sect_is_btf (fp, force_ctf)) + ctf_needed = 1; + + if (ctf_needed && _libctf_btf_mode == LIBCTF_BTM_BTF) + goto err_not_btf; + + if (_libctf_btf_mode == LIBCTF_BTM_ALWAYS + || (_libctf_btf_mode == LIBCTF_BTM_POSSIBLE && ctf_needed)) + fp->ctf_serialize.cs_is_btf = 0; + else + fp->ctf_serialize.cs_is_btf = 1; + + fp->ctf_serialize.cs_initialized = 1; + + return 0; + + err_not_btf: + ctf_set_errno (fp, ECTF_NOTBTF); + /* TODO: a little more info? */ + if (force_ctf) + ctf_err_warn (fp, 0, 0, _("Cannot write out dict as BTF: compression requested")); + else + ctf_err_warn (fp, 0, 0, _("Cannot write out dict as BTF: would lose information")); + return -1; +} + /* Do all aspects of serialization up to strtab writeout, including final type ID assignment. The resulting dict will have the LCTF_PRESERIALIZED flag on and must not be modified in any way before serialization. (This is only