[02/19] include: new header ctf-api.h

Message ID 20190430225706.159422-3-nick.alcock@oracle.com
State Superseded
Headers show
Series
  • libctf, and CTF support for objdump and readelf
Related show

Commit Message

Nick Alcock April 30, 2019, 10:56 p.m.
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.
---
 include/ctf-api.h | 130 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)
 create mode 100644 include/ctf-api.h

-- 
2.21.0.237.gd0cfaa883d

Comments

Nick Clifton May 2, 2019, 3:07 p.m. | #1
Hi Nick,

> This non-installed header is the means by which libctf consumers

> communicate with libctf.


By "non-installed" do you mean that it would not be placed into /usr/include ?
If so, then how do consumers know how to communicate with libctf, given that
they might be compiled without access to the ctf sources ?


> +/* Clients can open one or more CTF containers and obtain a pointer to an

> +   opaque ctf_file_t.  Types are identified by an opaque ctf_id_t token.

> +   They can also open or create read-only archives of CTF containers in a

> +   ctf_archive_t.


Are CTF archives just arbitrary collections of CTF containers or is there more
to them than that ?

Cheers
  Nick
Nick Alcock May 3, 2019, 11:23 a.m. | #2
On 2 May 2019, Nick Clifton verbalised:

> Hi Nick,

>

>> This non-installed header is the means by which libctf consumers

>> communicate with libctf.

>

> By "non-installed" do you mean that it would not be placed into /usr/include ?


Yes. Mostly because I assumed that the bar was higher for installed
headers than for non-installed ones, and there are no users of libctf
yet.

> If so, then how do consumers know how to communicate with libctf, given that

> they might be compiled without access to the ctf sources ?


At the moment, libctf is an automatically-synched copy of the upstream
libdtrace-ctf project. Our aim is to eventually make binutils the
upstream, whereupon we can drop libdtrace-ctf entirely, and turn this
into an installed header :)

(If we do make it an installed header, we want to set up things like
symbol versioning first. libdtrace-ctf already has all of that.)

>> +/* Clients can open one or more CTF containers and obtain a pointer to an

>> +   opaque ctf_file_t.  Types are identified by an opaque ctf_id_t token.

>> +   They can also open or create read-only archives of CTF containers in a

>> +   ctf_archive_t.

>

> Are CTF archives just arbitrary collections of CTF containers or is there more

> to them than that ?


They are usually arbitrary collections of *related* CTF containers (with
associated names): e.g. a parent container and a bunch of children that
reuse types from the parent.

The format is given in ctf-impl.h: it's just an mmappable archive which
isn't tar or cpio and so doesn't have to deal with the infinite horrors
of tar or cpio versioning. :) One feature it does have that tar and cpio
don't is that, like zip files, the compression happens at the level of
individual archive members, via the CTF_F_COMPRESS flag bit in the
header.

This means that you can elect to not compress CTF files that are already
"small enough" (say, smaller than a page), whereupon they can get read
via mmap() directly out of the CTF archive, with no copying or
decompression overhead. CTF files with parents are often very small:
looking at Linux kernel 5.0, of 2938 CTF files in the archive I
generated in my most recent test build, all but 188 are under 4096
bytes: but they all have as a parent the 1.2MiB shared CTF file that
contains types shared across kernel modules (in a non-kernel context,
the parent container will usually contain types shared across TUs).

(Nearly 2000 of them are under 512 bytes long. By this stage just the
gzip header is bloating the thing up substantially, and you gain nothing
from compression of things so small.)

Patch

diff --git a/include/ctf-api.h b/include/ctf-api.h
new file mode 100644
index 0000000000..e2f5dc7571
--- /dev/null
+++ b/include/ctf-api.h
@@ -0,0 +1,130 @@ 
+/* Public API to libctf.
+   Copyright (C) 2005-2019 Free Software Foundation, Inc.
+
+   This file is part of libctf.
+
+   libctf is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 2, or (at your option) any later
+   version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+   See the GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This header file defines the interfaces available from the CTF debugger
+   library, libctf.  This API can be used by a debugger to operate on data in
+   the Compact ANSI-C Type Format (CTF).  */
+
+#ifndef	_CTF_API_H
+#define	_CTF_API_H
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <ctf.h>
+
+#ifdef	__cplusplus
+extern "C"
+  {
+#endif
+
+/* Clients can open one or more CTF containers and obtain a pointer to an
+   opaque ctf_file_t.  Types are identified by an opaque ctf_id_t token.
+   They can also open or create read-only archives of CTF containers in a
+   ctf_archive_t.
+
+   These opaque definitions allow libctf to evolve without breaking clients.  */
+
+typedef struct ctf_file ctf_file_t;
+typedef struct ctf_archive ctf_archive_t;
+typedef long ctf_id_t;
+
+/* Functions that return integer status or a ctf_id_t use the following value
+   to indicate failure.  ctf_errno() can be used to obtain an error code.  */
+#define	CTF_ERR	(-1L)
+
+#define	ECTF_BASE	1000	/* Base value for libctf errnos.  */
+
+
+enum
+  {
+   ECTF_FMT = ECTF_BASE,	/* File is not in CTF or ELF format.  */
+   ECTF_ELFVERS,		/* ELF version is more recent than libctf.  */
+   ECTF_CTFVERS,		/* CTF version is more recent than libctf.  */
+   ECTF_ENDIAN,			/* Data is different endian-ness than lib.  */
+   ECTF_SYMTAB,			/* Symbol table uses invalid entry size.  */
+   ECTF_SYMBAD,			/* Symbol table data buffer invalid.  */
+   ECTF_STRBAD,			/* String table data buffer invalid.  */
+   ECTF_CORRUPT,		/* File data corruption detected.  */
+   ECTF_NOCTFDATA,		/* ELF file does not contain CTF data.  */
+   ECTF_NOCTFBUF,		/* Buffer does not contain CTF data.  */
+   ECTF_NOSYMTAB,		/* Symbol table data is not available.  */
+   ECTF_NOPARENT,		/* Parent CTF container is not available.  */
+   ECTF_DMODEL,			/* Data model mismatch.  */
+   ECTF_MMAP,			/* Failed to mmap a data section.  */
+   ECTF_ZALLOC,			/* Failed to allocate (de)compression buffer.  */
+   ECTF_DECOMPRESS,		/* Failed to decompress CTF data.  */
+   ECTF_STRTAB,			/* String table for this string is missing.  */
+   ECTF_BADNAME,		/* String offset is corrupt w.r.t. strtab.  */
+   ECTF_BADID,			/* Invalid type ID number.  */
+   ECTF_NOTSOU,			/* Type is not a struct or union.  */
+   ECTF_NOTENUM,		/* Type is not an enum.  */
+   ECTF_NOTSUE,			/* Type is not a struct, union, or enum.  */
+   ECTF_NOTINTFP,		/* Type is not an integer, float, or enum.  */
+   ECTF_NOTARRAY,		/* Type is not an array.  */
+   ECTF_NOTREF,			/* Type does not reference another type.  */
+   ECTF_NAMELEN,		/* Buffer is too small to hold type name.  */
+   ECTF_NOTYPE,			/* No type found corresponding to name.  */
+   ECTF_SYNTAX,			/* Syntax error in type name.  */
+   ECTF_NOTFUNC,		/* Symtab entry does not refer to a function.  */
+   ECTF_NOFUNCDAT,		/* No func info available for function.  */
+   ECTF_NOTDATA,		/* Symtab entry does not refer to a data obj.  */
+   ECTF_NOTYPEDAT,		/* No type info available for object.  */
+   ECTF_NOLABEL,		/* No label found corresponding to name.  */
+   ECTF_NOLABELDATA,		/* File does not contain any labels.  */
+   ECTF_NOTSUP,			/* Feature not supported.  */
+   ECTF_NOENUMNAM,		/* Enum element name not found.  */
+   ECTF_NOMEMBNAM,		/* Member name not found.  */
+   ECTF_RDONLY,			/* CTF container is read-only.  */
+   ECTF_DTFULL,			/* CTF type is full (no more members allowed).  */
+   ECTF_FULL,			/* CTF container is full.  */
+   ECTF_DUPLICATE,		/* Duplicate member or variable name.  */
+   ECTF_CONFLICT,		/* Conflicting type definition present.  */
+   ECTF_OVERROLLBACK,		/* Attempt to roll back past a ctf_update.  */
+   ECTF_COMPRESS,		/* Failed to compress CTF data.  */
+   ECTF_ARCREATE,		/* Error creating CTF archive.  */
+   ECTF_ARNNAME,		/* Name not found in CTF archive.  */
+   ECTF_SLICEOVERFLOW,		/* Overflow of type bitness or offset in slice.  */
+   ECTF_DUMPSECTUNKNOWN,	/* Unknown section number in dump.  */
+   ECTF_DUMPSECTCHANGED		/* Section changed in middle of dump.  */
+  };
+
+/* The CTF data model is inferred to be the caller's data model or the data
+   model of the given object, unless ctf_setmodel() is explicitly called.  */
+#define	CTF_MODEL_ILP32 1	/* Object data model is ILP32.  */
+#define	CTF_MODEL_LP64  2	/* Object data model is LP64.  */
+#ifdef _LP64
+# define CTF_MODEL_NATIVE CTF_MODEL_LP64
+#else
+# define CTF_MODEL_NATIVE CTF_MODEL_ILP32
+#endif
+
+/* Dynamic CTF containers can be created using ctf_create().  The ctf_add_*
+   routines can be used to add new definitions to the dynamic container.
+   New types are labeled as root or non-root to determine whether they are
+   visible at the top-level program scope when subsequently doing a lookup.  */
+
+#define	CTF_ADD_NONROOT	0	/* Type only visible in nested scope.  */
+#define	CTF_ADD_ROOT	1	/* Type visible at top-level scope.  */
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif				/* _CTF_API_H */