summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ChangeLog7
-rw-r--r--include/ctf.h32
-rw-r--r--libctf/ChangeLog11
-rw-r--r--libctf/ctf-open.c31
4 files changed, 66 insertions, 15 deletions
diff --git a/include/ChangeLog b/include/ChangeLog
index de933943ce5..c2e80315aa1 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,10 @@
+2019-07-11 Nick Alcock <nick.alcock@oracle.com>
+
+ * ctf.h: Add object index and function index sections. Describe
+ them. Improve the description of the variable section and clarify
+ the constraints on backward-pointing type nodes.
+ (ctf_header): Add cth_objtidxoff, cth_funcidxoff.
+
2019-07-06 Nick Alcock <nick.alcock@oracle.com>
* ctf-api.h (ctf_cuname): New function.
diff --git a/include/ctf.h b/include/ctf.h
index 7e00005d27e..f371cd73c94 100644
--- a/include/ctf.h
+++ b/include/ctf.h
@@ -52,10 +52,15 @@ extern "C"
The CTF file or section itself has the following structure:
- +--------+--------+---------+----------+----------+-------+--------+
- | file | type | data | function | variable | data | string |
- | header | labels | objects | info | info | types | table |
- +--------+--------+---------+----------+----------+-------+--------+
+ +--------+--------+---------+----------+--------+----------+...
+ | file | type | data | function | object | function |...
+ | header | labels | objects | info | index | index |...
+ +--------+--------+---------+----------+--------+----------+...
+
+ ...+----------+-------+--------+
+ ...| variable | data | string |
+ ...| info | types | table |
+ +----------+-------+--------+
The file header stores a magic number and version information, encoding
flags, and the byte offset of each of the sections relative to the end of the
@@ -74,14 +79,27 @@ extern "C"
For each data object, the type ID (a small integer) is recorded. For each
function, the type ID of the return type and argument types is recorded.
+ For situations in which the order of the symbols in the symtab is not known,
+ a pair of optional indexes follow the data object and function info sections:
+ each of these is an array of strtab indexes, mapped 1:1 to the corresponding
+ data object / function info section, giving each entry in those sections a
+ name so that the linker can correlate them with final symtab entries and
+ reorder them accordingly (dropping the indexes in the process).
+
Variable records (as distinct from data objects) provide a modicum of support
for non-ELF systems, mapping a variable name to a CTF type ID. The variable
- names are sorted into ASCIIbetical order, permitting binary searching.
+ names are sorted into ASCIIbetical order, permitting binary searching. We do
+ not define how the consumer maps these variable names to addresses or
+ anything else, or indeed what these names represent: they might be names
+ looked up at runtime via dlsym() or names extracted at runtime by a debugger
+ or anything else the consumer likes.
The data types section is a list of variable size records that represent each
type, in order by their ID. The types themselves form a directed graph,
where each node may contain one or more outgoing edges to other type nodes,
- denoted by their ID.
+ denoted by their ID. Most type nodes are standalone or point backwards to
+ earlier nodes, but this is not required: nodes can point to later nodes,
+ particularly structure and union members.
Strings are recorded as a string table ID (0 or 1) and a byte offset into the
string table. String table 0 is the internal CTF string table. String table
@@ -149,6 +167,8 @@ typedef struct ctf_header
uint32_t cth_lbloff; /* Offset of label section. */
uint32_t cth_objtoff; /* Offset of object section. */
uint32_t cth_funcoff; /* Offset of function section. */
+ uint32_t cth_objtidxoff; /* Offset of object index section. */
+ uint32_t cth_funcidxoff; /* Offset of function index section. */
uint32_t cth_varoff; /* Offset of variable section. */
uint32_t cth_typeoff; /* Offset of type section. */
uint32_t cth_stroff; /* Offset of string section. */
diff --git a/libctf/ChangeLog b/libctf/ChangeLog
index e2c1cbe6b17..775778f17f2 100644
--- a/libctf/ChangeLog
+++ b/libctf/ChangeLog
@@ -1,5 +1,16 @@
2019-07-13 Nick Alcock <nick.alcock@oracle.com>
+ * ctf-open.c (init_symtab): Check for overflow against the right
+ section.
+ (upgrade_header): Set cth_objtidxoff, cth_funcidxoff to zero-length.
+ (upgrade_types_v1): Note that these sections are not checked.
+ (flip_header): Endian-swap the header fields.
+ (flip_ctf): Endian-swap the sections.
+ (flip_objts): Update comment.
+ (ctf_bufopen): Check header offsets and alignment for validity.
+
+2019-07-13 Nick Alcock <nick.alcock@oracle.com>
+
* ctf-open-bfd.c: Add <assert.h>.
(ctf_bfdopen_ctfsect): Open string and symbol tables using
techniques borrowed from bfd_elf_sym_name.
diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c
index 61c5c880629..ee09ca123b5 100644
--- a/libctf/ctf-open.c
+++ b/libctf/ctf-open.c
@@ -278,7 +278,7 @@ init_symtab (ctf_file_t *fp, const ctf_header_t *hp,
break;
case STT_FUNC:
- if (funcoff >= hp->cth_typeoff)
+ if (funcoff >= hp->cth_objtidxoff)
{
*xp = -1u;
break;
@@ -376,6 +376,8 @@ upgrade_header (ctf_header_t *hp)
hp->cth_stroff = oldhp->cth_stroff;
hp->cth_typeoff = oldhp->cth_typeoff;
hp->cth_varoff = oldhp->cth_varoff;
+ hp->cth_funcidxoff = hp->cth_varoff; /* No index sections. */
+ hp->cth_objtidxoff = hp->cth_funcidxoff;
hp->cth_funcoff = oldhp->cth_funcoff;
hp->cth_objtoff = oldhp->cth_objtoff;
hp->cth_lbloff = oldhp->cth_lbloff;
@@ -388,6 +390,9 @@ upgrade_header (ctf_header_t *hp)
The upgrade is not done in-place: the ctf_base is moved. ctf_strptr() must
not be called before reallocation is complete.
+ Sections not checked here due to nonexistence or nonpopulated state in older
+ formats: objtidx, funcidx.
+
Type kinds not checked here due to nonexistence in older formats:
CTF_K_SLICE. */
static int
@@ -967,6 +972,8 @@ flip_header (ctf_header_t *cth)
swap_thing (cth->cth_cuname);
swap_thing (cth->cth_objtoff);
swap_thing (cth->cth_funcoff);
+ swap_thing (cth->cth_objtidxoff);
+ swap_thing (cth->cth_funcidxoff);
swap_thing (cth->cth_varoff);
swap_thing (cth->cth_typeoff);
swap_thing (cth->cth_stroff);
@@ -987,10 +994,10 @@ flip_lbls (void *start, size_t len)
}
}
-/* Flip the endianness of the data-object or function sections, an array of
- uint32_t. (The function section has more internal structure, but that
- structure is an array of uint32_t, so can be treated as one big array for
- byte-swapping.) */
+/* Flip the endianness of the data-object or function sections or their indexes,
+ all arrays of uint32_t. (The function section has more internal structure,
+ but that structure is an array of uint32_t, so can be treated as one big
+ array for byte-swapping.) */
static void
flip_objts (void *start, size_t len)
@@ -1176,7 +1183,9 @@ flip_ctf (ctf_header_t *cth, unsigned char *buf)
{
flip_lbls (buf + cth->cth_lbloff, cth->cth_objtoff - cth->cth_lbloff);
flip_objts (buf + cth->cth_objtoff, cth->cth_funcoff - cth->cth_objtoff);
- flip_objts (buf + cth->cth_funcoff, cth->cth_varoff - cth->cth_funcoff);
+ flip_objts (buf + cth->cth_funcoff, cth->cth_objtidxoff - cth->cth_funcoff);
+ flip_objts (buf + cth->cth_objtidxoff, cth->cth_funcidxoff - cth->cth_objtidxoff);
+ flip_objts (buf + cth->cth_funcidxoff, cth->cth_varoff - cth->cth_funcidxoff);
flip_vars (buf + cth->cth_varoff, cth->cth_typeoff - cth->cth_varoff);
return flip_types (buf + cth->cth_typeoff, cth->cth_stroff - cth->cth_typeoff);
}
@@ -1331,19 +1340,23 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
(unsigned long) fp->ctf_size);
if (hp->cth_lbloff > fp->ctf_size || hp->cth_objtoff > fp->ctf_size
- || hp->cth_funcoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
+ || hp->cth_funcoff > fp->ctf_size || hp->cth_objtidxoff > fp->ctf_size
+ || hp->cth_funcidxoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
|| hp->cth_stroff > fp->ctf_size)
return (ctf_set_open_errno (errp, ECTF_CORRUPT));
if (hp->cth_lbloff > hp->cth_objtoff
|| hp->cth_objtoff > hp->cth_funcoff
|| hp->cth_funcoff > hp->cth_typeoff
- || hp->cth_funcoff > hp->cth_varoff
+ || hp->cth_funcoff > hp->cth_objtidxoff
+ || hp->cth_objtidxoff > hp->cth_funcidxoff
+ || hp->cth_funcidxoff > hp->cth_varoff
|| hp->cth_varoff > hp->cth_typeoff || hp->cth_typeoff > hp->cth_stroff)
return (ctf_set_open_errno (errp, ECTF_CORRUPT));
if ((hp->cth_lbloff & 3) || (hp->cth_objtoff & 2)
- || (hp->cth_funcoff & 2) || (hp->cth_varoff & 3)
+ || (hp->cth_funcoff & 2) || (hp->cth_objtidxoff & 2)
+ || (hp->cth_funcidxoff & 2) || (hp->cth_varoff & 3)
|| (hp->cth_typeoff & 3))
return (ctf_set_open_errno (errp, ECTF_CORRUPT));