forked from Imagelibrary/binutils-gdb
libctf: serialize: user control over BTF-versus-CTF writeout
We need some way for users to declare that they want BTF or CTF in
particular to be written out when they ask for it, or that they don't mind
which. Adding this to all the ctf_write functions (like the compression
threshold already is) would be a bit of a nightmare: there are a great many
of them and this doesn't seem like something people would want to change
on a per-dict basis (even if we did, we'd need to think about archives and
linking, which work on a higher level than single dicts).
So we repurpose an unused, vestigial existing function, ctf_version(), which
was originally intended to do some sort of rather unclear API switching at
runtime, to allow switching between different CTF file format versions (not
yet supported, you have to pass CTF_VERSION) and BTF writeout modes:
/* BTF/CTF writeout version info.
ctf_btf_mode has three levels:
- LIBCTF_BTM_ALWAYS writes out full-blown CTFv4 at all times
- LIBCTF_BTM_POSSIBLE writes out CTFv4 if needed to avoid information loss,
BTF otherwise. If compressing, the same as LIBCTF_BTM_ALWAYS.
- LIBCTF_BTM_BTF writes out BTF always, and errors otherwise.
Note that no attempt is made to downgrade existing CTF dicts to BTF: if you
read in a CTF dict and turn on LIBCTF_BTM_POSSIBLE, you'll get a CTF dict; if
you turn on LIBCTF_BTM_BTF, you'll get an unconditional error. Thus, this is
really useful only when reading in BTF dicts or when creating new dicts. */
typedef enum ctf_btf_mode
{
LIBCTF_BTM_BTF = 0,
LIBCTF_BTM_POSSIBLE = 1,
LIBCTF_BTM_ALWAYS = 2
} ctf_btf_mode_t;
/* Set the CTF library client version to the specified version: this is the
version of dicts written out by the ctf_write* functions. If version is
zero, we just return the default library version number. The BTF version
(for CTFv4 and above) is indicated via btf_hdr_len, also zero for "no
change".
You can influence what type kinds are written out to a CTFv4 dict via the
ctf_write_suppress_kind() function. */
extern int ctf_version (int ctf_version_, size_t btf_hdr_len,
ctf_btf_mode_t btf_mode);
(We retain the ctf_version_ stuff to leave space in the API to let the
library possibly do file format downgrades in future, since we've already
had requests for such things from users.)
This commit is contained in:
@@ -533,13 +533,38 @@ extern void *ctf_getspecific (ctf_dict_t *);
|
|||||||
extern int ctf_errno (ctf_dict_t *);
|
extern int ctf_errno (ctf_dict_t *);
|
||||||
extern const char *ctf_errmsg (int);
|
extern const char *ctf_errmsg (int);
|
||||||
|
|
||||||
/* Return the version of CTF dicts written by writeout functions. The
|
/* BTF/CTF writeout version info.
|
||||||
argument must currently be zero. All dicts with versions below the value
|
|
||||||
returned by this function can be read by the library. CTF dicts written
|
|
||||||
by other non-GNU CTF libraries (e.g. that in FreeBSD) are not compatible
|
|
||||||
and cannot be read by this library. */
|
|
||||||
|
|
||||||
extern int ctf_version (int);
|
ctf_btf_mode has three levels:
|
||||||
|
|
||||||
|
- LIBCTF_BTM_ALWAYS writes out full-blown CTFv4 at all times
|
||||||
|
- LIBCTF_BTM_POSSIBLE writes out CTFv4 if needed to avoid information loss,
|
||||||
|
BTF otherwise. If compressing, the same as LIBCTF_BTM_ALWAYS.
|
||||||
|
- LIBCTF_BTM_BTF writes out BTF always, and errors otherwise.
|
||||||
|
|
||||||
|
Note that no attempt is made to downgrade existing CTF dicts to BTF: if you
|
||||||
|
read in a CTF dict and turn on LIBCTF_BTM_POSSIBLE, you'll get a CTF dict; if
|
||||||
|
you turn on LIBCTF_BTM_BTF, you'll get an unconditional error. Thus, this is
|
||||||
|
really useful only when reading in BTF dicts or when creating new dicts. */
|
||||||
|
|
||||||
|
typedef enum ctf_btf_mode
|
||||||
|
{
|
||||||
|
LIBCTF_BTM_BTF = 0,
|
||||||
|
LIBCTF_BTM_POSSIBLE = 1,
|
||||||
|
LIBCTF_BTM_ALWAYS = 2
|
||||||
|
} ctf_btf_mode_t;
|
||||||
|
|
||||||
|
/* Set the CTF library client version to the specified version: this is the
|
||||||
|
version of dicts written out by the ctf_write* functions. If version is
|
||||||
|
zero, we just return the default library version number. The BTF version
|
||||||
|
(for CTFv4 and above) is indicated via btf_hdr_len, also zero for "no
|
||||||
|
change".
|
||||||
|
|
||||||
|
You can influence what type kinds are written out to a CTFv4 dict via the
|
||||||
|
ctf_write_suppress_kind() function. */
|
||||||
|
|
||||||
|
extern int ctf_version (int ctf_version_, size_t btf_hdr_len,
|
||||||
|
ctf_btf_mode_t btf_mode);
|
||||||
|
|
||||||
/* Given a symbol table index corresponding to a function symbol, return info on
|
/* Given a symbol table index corresponding to a function symbol, return info on
|
||||||
the type of a given function's arguments or return value, or its parameter
|
the type of a given function's arguments or return value, or its parameter
|
||||||
@@ -1057,13 +1082,17 @@ extern ctf_snapshot_id_t ctf_snapshot (ctf_dict_t *);
|
|||||||
extern int ctf_rollback (ctf_dict_t *, ctf_snapshot_id_t);
|
extern int ctf_rollback (ctf_dict_t *, ctf_snapshot_id_t);
|
||||||
extern int ctf_discard (ctf_dict_t *);
|
extern int ctf_discard (ctf_dict_t *);
|
||||||
|
|
||||||
/* Dict writeout.
|
/* Dict writeout. See ctf_version().
|
||||||
|
|
||||||
ctf_write: write out an uncompressed dict to an fd.
|
ctf_write: write out an uncompressed dict to an fd.
|
||||||
ctf_compress_write: write out a compressed dict to an fd (currently always
|
ctf_compress_write: write out a compressed dict to an fd (currently always
|
||||||
gzip, but this may change in future).
|
gzip, but this may change in future).
|
||||||
ctf_write_mem: write out a dict to a buffer and return it and its size,
|
ctf_write_mem: write out a dict to a buffer and return it and its size,
|
||||||
compressing it if its uncompressed size is over THRESHOLD. */
|
compressing it if its uncompressed size is over THRESHOLD.
|
||||||
|
|
||||||
|
If the ctf_btf_mode is not LIBCTF_BTM_ALWAYS and the threshold is -1,
|
||||||
|
the resulting dict may be pure BTF.
|
||||||
|
*/
|
||||||
|
|
||||||
extern int ctf_write (ctf_dict_t *, int);
|
extern int ctf_write (ctf_dict_t *, int);
|
||||||
extern int ctf_compress_write (ctf_dict_t * fp, int fd);
|
extern int ctf_compress_write (ctf_dict_t * fp, int fd);
|
||||||
|
|||||||
@@ -27,33 +27,63 @@
|
|||||||
#define ENOTSUP ENOSYS
|
#define ENOTSUP ENOSYS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int _libctf_version = CTF_VERSION; /* Library client version. */
|
static int _libctf_version = CTF_VERSION; /* Library client version. */
|
||||||
int _libctf_debug = 0; /* Debugging messages enabled. */
|
static size_t _btf_hdr_len = sizeof (ctf_btf_header_t);
|
||||||
|
static int _libctf_debug = 0; /* Debugging messages enabled. */
|
||||||
|
|
||||||
/* Set the CTF library client version to the specified version. If version is
|
ctf_btf_mode_t _libctf_btf_mode = LIBCTF_BTM_POSSIBLE; /* BTF writeout mode. */
|
||||||
zero, we just return the default library version number. */
|
|
||||||
|
/* Set the CTF library client version to the specified version: this is the
|
||||||
|
version of dicts written out by the ctf_write* functions. If version is
|
||||||
|
zero, we just return the default library version number. The BTF version
|
||||||
|
(for CTFv4 and above) is indicated via btf_hdr_len, also zero for "no
|
||||||
|
change".
|
||||||
|
|
||||||
|
btf_mode has three levels:
|
||||||
|
|
||||||
|
- LIBCTF_BTM_ALWAYS writes out full-blown CTFv4 at all times
|
||||||
|
- LIBCTF_BTM_POSSIBLE writes out CTFv4 if needed to avoid
|
||||||
|
information loss, BTF otherwise (and always writes out CTFv4
|
||||||
|
if compressing)
|
||||||
|
- LIBCTF_BTM_BTF writes out BTF always, and errors otherwise (e.g.
|
||||||
|
if compressing)
|
||||||
|
|
||||||
|
You can influence what type kinds are written out to a CTFv4 dict via the
|
||||||
|
ctf_write_suppress_kind() function. */
|
||||||
int
|
int
|
||||||
ctf_version (int version)
|
ctf_version (int ctf_version_, size_t btf_hdr_len, ctf_btf_mode_t btf_mode)
|
||||||
{
|
{
|
||||||
if (version < 0)
|
if (ctf_version_ < 0 || btf_mode < 0 || btf_mode > 2)
|
||||||
{
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version > 0)
|
if (ctf_version_ > 0)
|
||||||
{
|
{
|
||||||
/* Dynamic version switching is not presently supported. */
|
/* Dynamic version switching is not presently supported. */
|
||||||
if (version != CTF_VERSION)
|
if (ctf_version_ != _libctf_version)
|
||||||
{
|
goto err;
|
||||||
errno = ENOTSUP;
|
|
||||||
return -1;
|
ctf_dprintf ("ctf_version: client using version %i\n", ctf_version_);
|
||||||
}
|
|
||||||
ctf_dprintf ("ctf_version: client using version %d\n", version);
|
|
||||||
_libctf_version = version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _libctf_version;
|
if (btf_hdr_len > 0)
|
||||||
|
{
|
||||||
|
/* Dynamic version switching is not presently supported. */
|
||||||
|
if (btf_hdr_len != _btf_hdr_len)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
ctf_dprintf ("ctf_version: client using BTF header length %zi\n", btf_hdr_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
_libctf_btf_mode = btf_mode;
|
||||||
|
|
||||||
|
return ctf_version_;
|
||||||
|
|
||||||
|
err:
|
||||||
|
errno = ENOTSUP;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the specified error code into errp if it is non-NULL, and then
|
/* Store the specified error code into errp if it is non-NULL, and then
|
||||||
|
|||||||
@@ -858,9 +858,7 @@ ssize_t get_ctt_size_v2_unconverted (const ctf_dict_t *, const ctf_type_t *,
|
|||||||
|
|
||||||
extern const char _CTF_SECTION[]; /* name of CTF ELF section */
|
extern const char _CTF_SECTION[]; /* name of CTF ELF section */
|
||||||
extern const char _CTF_NULLSTR[]; /* empty string */
|
extern const char _CTF_NULLSTR[]; /* empty string */
|
||||||
|
extern ctf_btf_mode_t _libctf_btf_mode; /* BTF writeout mode. */
|
||||||
extern int _libctf_version; /* library client version */
|
|
||||||
extern int _libctf_debug; /* debugging messages enabled */
|
|
||||||
|
|
||||||
#include "ctf-inlines.h"
|
#include "ctf-inlines.h"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user