diff options
-rw-r--r-- | include/ChangeLog | 7 | ||||
-rw-r--r-- | include/ctf.h | 32 | ||||
-rw-r--r-- | libctf/ChangeLog | 11 | ||||
-rw-r--r-- | libctf/ctf-open.c | 31 |
4 files changed, 66 insertions, 15 deletions
diff --git a/include/ChangeLog b/include/ChangeLog index de93394..c2e8031 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 7e00005..f371cd7 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 7fa9fc0..64d644f 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 51f9edc..c96bad7 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); } @@ -1330,19 +1339,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)); |