diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2025-03-20 16:40:06 +0000 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2025-03-20 16:40:06 +0000 |
commit | c4bc0f74f9b623df0d62742af106d24f3c1af1fe (patch) | |
tree | 851e45a826a75b453f142a9906dc48b9144c38ec | |
parent | aba7ef898745fd09d03ad4ebedcd11f68abc5160 (diff) | |
download | binutils-c4bc0f74f9b623df0d62742af106d24f3c1af1fe.zip binutils-c4bc0f74f9b623df0d62742af106d24f3c1af1fe.tar.gz binutils-c4bc0f74f9b623df0d62742af106d24f3c1af1fe.tar.bz2 |
libctf: more compilation error fixes
Compiles now. Still doesn't work yet...
-rw-r--r-- | include/ctf.h | 24 | ||||
-rw-r--r-- | libctf/ctf-create.c | 4 | ||||
-rw-r--r-- | libctf/ctf-hash.c | 10 | ||||
-rw-r--r-- | libctf/ctf-impl.h | 20 | ||||
-rw-r--r-- | libctf/ctf-inlines.h | 6 | ||||
-rw-r--r-- | libctf/ctf-lookup.c | 4 | ||||
-rw-r--r-- | libctf/ctf-open-bfd.c | 28 | ||||
-rw-r--r-- | libctf/ctf-open-compat.c | 14 | ||||
-rw-r--r-- | libctf/ctf-open.c | 176 | ||||
-rw-r--r-- | libctf/ctf-serialize.c | 134 | ||||
-rw-r--r-- | libctf/ctf-types.c | 377 |
11 files changed, 420 insertions, 377 deletions
diff --git a/include/ctf.h b/include/ctf.h index 749e266..cc0fe76 100644 --- a/include/ctf.h +++ b/include/ctf.h @@ -285,7 +285,7 @@ typedef struct ctf_header #define CTF_F_MAX_3 (CTF_F_COMPRESS | CTF_F_NEWFUNCINFO | CTF_F_IDXSORTED \ | CTF_F_DYNSTR) -#define CTF_MAX (CTF_F_COMPRESS | CTF_F_IDXSORTED); +#define CTF_F_MAX (CTF_F_COMPRESS | CTF_F_IDXSORTED) /* CTFv3 and below: variable entries. */ typedef struct ctf_varent_v3 @@ -621,11 +621,11 @@ union the following macros. (However, you can also encode the offset and bitness in a slice.) */ -#define CTF_V3_FP_ENCODING(data) (((data) & 0xff000000) >> 24) -#define CTF_V3_FP_OFFSET(data) (((data) & 0x00ff0000) >> 16) -#define CTF_V3_FP_BITS(data) (((data) & 0x0000ffff)) +#define CTF_FP_ENCODING(data) (((data) & 0xff000000) >> 24) +#define CTF_FP_OFFSET(data) (((data) & 0x00ff0000) >> 16) +#define CTF_FP_BITS(data) (((data) & 0x0000ffff)) -#define CTF_V3_FP_DATA(encoding, offset, bits) \ +#define CTF_FP_DATA(encoding, offset, bits) \ (((encoding) << 24) | ((offset) << 16) | (bits)) /* Variant data when kind is CTF_K_FLOAT is an encoding in the top eight bits. @@ -753,7 +753,7 @@ typedef struct ctf_member #define CTF_MAX_BIT_OFFSET 0xffffff #define CTF_MEMBER_BIT_SIZE(val) ((val) >> 24) -#define CTF_MEMBER_BIT_OFFSET(val) ((val) & CTF_MAX_BIT_OFFSET); +#define CTF_MEMBER_BIT_OFFSET(val) ((val) & CTF_MAX_BIT_OFFSET) #define CTF_MEMBER_MAKE_BIT_OFFSET(size, offset) ((size) << 24 | offset) /* Data sections, aligned with btf_var_secinfo. @@ -829,8 +829,10 @@ typedef struct ctf_enum64 This is *not* the same as the data structure returned by the ctf_arc_*() functions: this is the low-level on-disk representation. */ +/* UPTODO: new native-endianness archive format */ +#if 0 #define CTFA_MAGIC 0x8b47f2a4d7623eec /* Incremented. */ -struct ctf_archive +typedef struct ctf_archive { /* Magic number. (In loaded files, overwritten with the file size so ctf_arc_close() knows how much to munmap()). */ @@ -854,11 +856,11 @@ struct ctf_archive /* Offset of the CTF table. Each element starts with a size (a little- endian uint64_t) then a ctf_dict_t of that size. */ uint64_t ctfa_ctfs; -}; - -#define CTFA_MAGIC_V1 0x8b47f2a4d7623eeb /* Random. */ +} ctf_archive_t; +#endif +#define CTFA_MAGIC 0x8b47f2a4d7623eeb /* Random. */ -struct ctf_archive_v1 +typedef struct ctf_archive { /* Magic number. (In loaded files, overwritten with the file size so ctf_arc_close() knows how much to munmap()). */ diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index 6eb7192..19156ee 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -1596,7 +1596,7 @@ ctf_add_member_bitfield (ctf_dict_t *fp, ctf_id_t souid, const char *name, if (name != NULL && name[0] == '\0') name = NULL; - if ((prefix = ctf_find_prefix (fp, dtd->dtd_buf, CTF_K_BIG)) == NULL) + if ((prefix = (ctf_type_t *) ctf_find_prefix (fp, dtd->dtd_buf, CTF_K_BIG)) == NULL) return (ctf_set_errno (ofp, ECTF_CORRUPT)); kind = LCTF_KIND (fp, prefix); @@ -1734,7 +1734,7 @@ ctf_add_member_bitfield (ctf_dict_t *fp, ctf_id_t souid, const char *name, /* Hunt down the prefix and member list again: they may have been moved by the realloc()s involved in field additions. */ - if ((prefix = ctf_find_prefix (fp, dtd->dtd_buf, CTF_K_BIG)) == NULL) + if ((prefix = (ctf_type_t *) ctf_find_prefix (fp, dtd->dtd_buf, CTF_K_BIG)) == NULL) return (ctf_set_errno (ofp, ECTF_CORRUPT)); vlen = LCTF_VLEN (fp, prefix); diff --git a/libctf/ctf-hash.c b/libctf/ctf-hash.c index 64657bd..7cde73f 100644 --- a/libctf/ctf-hash.c +++ b/libctf/ctf-hash.c @@ -396,7 +396,7 @@ ctf_dynhash_empty (ctf_dynhash_t *hp) } size_t -ctf_dynhash_elements (ctf_dynhash_t *hp) +ctf_dynhash_elements (const ctf_dynhash_t *hp) { return htab_elements (hp->htab); } @@ -523,7 +523,7 @@ ctf_dynhash_iter_remove (ctf_dynhash_t *hp, ctf_hash_iter_remove_f fun, of this into some sort of errno or ctf_errno, which is invariably positive. So doing this simplifies essentially all callers. */ int -ctf_dynhash_next (ctf_dynhash_t *h, ctf_next_t **it, void **key, void **value) +ctf_dynhash_next (const ctf_dynhash_t *h, ctf_next_t **it, void **key, void **value) { ctf_next_t *i = *it; ctf_helem_t *slot; @@ -602,7 +602,7 @@ ctf_dynhash_sort_by_name (const ctf_next_hkv_t *one, const ctf_next_hkv_t *two, If SORT_FUN is null, thunks to ctf_dynhash_next. */ int -ctf_dynhash_next_sorted (ctf_dynhash_t *h, ctf_next_t **it, void **key, +ctf_dynhash_next_sorted (const ctf_dynhash_t *h, ctf_next_t **it, void **key, void **value, ctf_hash_sort_f sort_fun, void *sort_arg) { ctf_next_t *i = *it; @@ -767,7 +767,7 @@ ctf_dynset_remove (ctf_dynset_t *hp, const void *key) } size_t -ctf_dynset_elements (ctf_dynset_t *hp) +ctf_dynset_elements (const ctf_dynset_t *hp) { return htab_elements ((struct htab *) hp); } @@ -830,7 +830,7 @@ ctf_dynset_lookup_any (ctf_dynset_t *hp) Otherwise, just like ctf_dynhash_next. */ int -ctf_dynset_next (ctf_dynset_t *hp, ctf_next_t **it, void **key) +ctf_dynset_next (const ctf_dynset_t *hp, ctf_next_t **it, void **key) { struct htab *htab = (struct htab *) hp; ctf_next_t *i = *it; diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 642ff6e..921820e 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -560,7 +560,7 @@ struct ctf_next size_t ctn_size; ssize_t ctn_increment; const ctf_type_t *ctn_tp; - uint32_t ctn_n; + size_t ctn_n; /* Some iterators contain other iterators, in addition to their other state. We allow for inner and outer iterators, for two-layer nested loops @@ -637,7 +637,8 @@ extern ctf_id_t ctf_index_to_type (const ctf_dict_t *, uint32_t); extern ctf_dynhash_t *ctf_name_table (ctf_dict_t *, int); extern const ctf_type_t *ctf_lookup_by_id (ctf_dict_t **, ctf_id_t, const ctf_type_t **suffix); -extern ctf_type_t *ctf_find_prefix (ctf_dict_t *, ctf_type_t *, int kind); +extern const ctf_type_t *ctf_find_prefix (ctf_dict_t *, const ctf_type_t *, + int kind); extern ctf_id_t ctf_lookup_by_sym_or_name (ctf_dict_t *, unsigned long symidx, const char *symname, int try_parent, int is_function); @@ -690,7 +691,7 @@ extern ctf_dynhash_t *ctf_dynhash_create_sized (unsigned long, ctf_hash_fun, extern int ctf_dynhash_insert (ctf_dynhash_t *, void *, void *); extern void ctf_dynhash_remove (ctf_dynhash_t *, const void *); -extern size_t ctf_dynhash_elements (ctf_dynhash_t *); +extern size_t ctf_dynhash_elements (const ctf_dynhash_t *); extern void ctf_dynhash_empty (ctf_dynhash_t *); extern int ctf_dynhash_insert_type (ctf_dict_t *, ctf_dynhash_t *, uint32_t, uint32_t); extern ctf_id_t ctf_dynhash_lookup_type (ctf_dynhash_t *, const char *); @@ -706,22 +707,22 @@ extern void *ctf_dynhash_iter_find (ctf_dynhash_t *, ctf_hash_iter_find_f, extern int ctf_dynhash_sort_by_name (const ctf_next_hkv_t *, const ctf_next_hkv_t *, void * _libctf_unused_); -extern int ctf_dynhash_next (ctf_dynhash_t *, ctf_next_t **, +extern int ctf_dynhash_next (const ctf_dynhash_t *, ctf_next_t **, void **key, void **value); -extern int ctf_dynhash_next_sorted (ctf_dynhash_t *, ctf_next_t **, +extern int ctf_dynhash_next_sorted (const ctf_dynhash_t *, ctf_next_t **, void **key, void **value, ctf_hash_sort_f, void *); extern ctf_dynset_t *ctf_dynset_create (htab_hash, htab_eq, ctf_hash_free_fun); extern int ctf_dynset_insert (ctf_dynset_t *, void *); extern void ctf_dynset_remove (ctf_dynset_t *, const void *); -extern size_t ctf_dynset_elements (ctf_dynset_t *); +extern size_t ctf_dynset_elements (const ctf_dynset_t *); extern void ctf_dynset_destroy (ctf_dynset_t *); extern void ctf_dynset_destroy_arg (ctf_dynset_t *, void *unused); extern void *ctf_dynset_lookup (ctf_dynset_t *, const void *); extern int ctf_dynset_exists (ctf_dynset_t *, const void *key, const void **orig_key); -extern int ctf_dynset_next (ctf_dynset_t *, ctf_next_t **, void **key); +extern int ctf_dynset_next (const ctf_dynset_t *, ctf_next_t **, void **key); extern void *ctf_dynset_lookup_any (ctf_dynset_t *); extern void ctf_sha1_init (ctf_sha1_t *); @@ -798,7 +799,7 @@ extern struct ctf_archive *ctf_arc_open_internal (const char *, int *); extern void ctf_arc_close_internal (struct ctf_archive *); extern const ctf_preamble_t *ctf_arc_bufpreamble (const ctf_sect_t *); extern void *ctf_set_open_errno (int *, int); -extern void ctf_flip_header (void *, int, int); +extern int ctf_flip_header (void *, int, int); extern int ctf_flip (ctf_dict_t *, ctf_header_t *, unsigned char *, int is_btf, int to_foreign); @@ -843,6 +844,9 @@ extern ctf_link_sym_t *ctf_elf32_to_link_sym (ctf_dict_t *fp, ctf_link_sym_t *ds extern ctf_link_sym_t *ctf_elf64_to_link_sym (ctf_dict_t *fp, ctf_link_sym_t *dst, const Elf64_Sym *src, uint32_t symidx); +ssize_t get_ctt_size_v2_unconverted (const ctf_dict_t *, const ctf_type_t *, + ssize_t *sizep, ssize_t *incrementp); + /* Variables, all underscore-prepended. */ extern const char _CTF_SECTION[]; /* name of CTF ELF section */ diff --git a/libctf/ctf-inlines.h b/libctf/ctf-inlines.h index d1f0691..bf4b61e 100644 --- a/libctf/ctf-inlines.h +++ b/libctf/ctf-inlines.h @@ -47,7 +47,7 @@ ctf_forwardable_kind (int kind) } static inline int -ctf_dynhash_cnext_sorted (ctf_dynhash_t *h, ctf_next_t **i, const void **key, +ctf_dynhash_cnext_sorted (const ctf_dynhash_t *h, ctf_next_t **i, const void **key, const void **value, ctf_hash_sort_f sort_fun, void *sort_arg) { @@ -56,7 +56,7 @@ ctf_dynhash_cnext_sorted (ctf_dynhash_t *h, ctf_next_t **i, const void **key, } static inline int -ctf_dynhash_cnext (ctf_dynhash_t *h, ctf_next_t **it, +ctf_dynhash_cnext (const ctf_dynhash_t *h, ctf_next_t **it, const void **key, const void **value) { return ctf_dynhash_next (h, it, (void **) key, (void **) value); @@ -69,7 +69,7 @@ ctf_dynhash_cinsert (ctf_dynhash_t *h, const void *k, const void *v) } static inline int -ctf_dynset_cnext (ctf_dynset_t *h, ctf_next_t **it, const void **key) +ctf_dynset_cnext (const ctf_dynset_t *h, ctf_next_t **it, const void **key) { return ctf_dynset_next (h, it, (void **) key); } diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c index 6ebcc18..c8ed72d 100644 --- a/libctf/ctf-lookup.c +++ b/libctf/ctf-lookup.c @@ -428,8 +428,8 @@ ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type, const ctf_type_t **suffix) } /* Find a given prefix in some type, if any. */ -ctf_type_t * -ctf_find_prefix (ctf_dict_t *fp, ctf_type_t *tp, int kind) +const ctf_type_t * +ctf_find_prefix (ctf_dict_t *fp, const ctf_type_t *tp, int kind) { uint32_t kind_ = kind; diff --git a/libctf/ctf-open-bfd.c b/libctf/ctf-open-bfd.c index 354efac..731303c 100644 --- a/libctf/ctf-open-bfd.c +++ b/libctf/ctf-open-bfd.c @@ -258,26 +258,32 @@ ctf_fdopen (int fd, const char *filename, const char *target, int *errp) struct stat st; ssize_t nbytes; - ctf_preamble_t ctfhdr; + ctf_preamble_v3_t *ctfhdr; + ctf_btf_preamble_t btfhdr; uint64_t arc_magic; - memset (&ctfhdr, 0, sizeof (ctfhdr)); + memset (&btfhdr, 0, sizeof (btfhdr)); libctf_init_debug(); if (fstat (fd, &st) == -1) return (ctf_set_open_errno (errp, errno)); - if ((nbytes = ctf_pread (fd, &ctfhdr, sizeof (ctfhdr), 0)) <= 0) + if ((nbytes = ctf_pread (fd, &btfhdr, sizeof (btfhdr) > sizeof (ctfhdr) + ? sizeof (btfhdr) : sizeof (ctfhdr), 0)) <= 0) return (ctf_set_open_errno (errp, nbytes < 0 ? errno : ECTF_FMT)); - - /* If we have read enough bytes to form a CTF header and the magic string - matches, in either endianness, attempt to interpret the file as raw - CTF. */ - - if ((size_t) nbytes >= sizeof (ctf_preamble_t) - && (ctfhdr.ctp_magic == CTF_MAGIC - || ctfhdr.ctp_magic == bswap_16 (CTF_MAGIC))) + ctfhdr = (ctf_preamble_v3_t *) &btfhdr; + + /* If we have read enough bytes to form a CTF or BTF header and the magic + string matches, in either endianness, attempt to interpret the file as raw + CTF/BTF. */ + + if (((size_t) nbytes >= sizeof (ctf_preamble_v3_t) + && (ctfhdr->ctp_magic == CTF_MAGIC + || ctfhdr->ctp_magic == bswap_16 (CTF_MAGIC))) + || ((size_t) nbytes >= sizeof (ctf_btf_preamble_t) + && (btfhdr.btf_magic == CTF_BTF_MAGIC + || btfhdr.btf_magic == bswap_16 (CTF_BTF_MAGIC)))) { ctf_dict_t *fp = NULL; void *data; diff --git a/libctf/ctf-open-compat.c b/libctf/ctf-open-compat.c index be9c7be..4e5b994 100644 --- a/libctf/ctf-open-compat.c +++ b/libctf/ctf-open-compat.c @@ -67,6 +67,20 @@ upgrade_header_v3 (ctf_header_t *hp) hp->cth_parent_ntypes = 0; } +/* Set the version of the CTF file. */ + +/* When this is reset, LCTF_* changes behaviour, but there is no guarantee that + the variable data list associated with each type has been upgraded: the + caller must ensure this has been done in advance. */ + +static void +ctf_set_version (ctf_dict_t *fp, ctf_header_t *cth, int ctf_version) +{ + fp->ctf_version = ctf_version; + cth->cth_version = ctf_version; + fp->ctf_dictops = &ctf_dictops[ctf_version]; +} + /* Upgrade the type table to CTF_VERSION_3 (really CTF_VERSION_1_UPGRADED_3) from CTF_VERSION_1. diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index 18aa416..91083f3 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -188,7 +188,7 @@ get_ctt_size_v1 (const ctf_dict_t *fp, const ctf_type_t *tp, /* Return the size that a v1 will be once it is converted to v2. */ -static ssize_t +ssize_t get_ctt_size_v2_unconverted (const ctf_dict_t *fp, const ctf_type_t *tp, ssize_t *sizep, ssize_t *incrementp) { @@ -385,7 +385,7 @@ static const ctf_dictops_t ctf_dictops[] = { get_prefixed_vlen_v2, get_ctt_size_v2, get_vbytes_v2}, /* CTF_VERSION_4, always BTF-compatible. */ {get_kind_v4, get_prefixed_kind_v4, get_root_v4, get_vlen_v4, - get_prefixed_vlen_v1, get_ctt_size_v4, get_vbytes_v4}, + get_prefixed_vlen_v4, get_ctt_size_v4, get_vbytes_v4}, }; /* Initialize the symtab translation table as appropriate for its indexing @@ -797,6 +797,7 @@ init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth, int is_btf, const ctf_type_t *tp; uint32_t id; uint32_t *xp; + ctf_id_t type; ssize_t biggest_datasec = -1; unsigned long typemax = fp->ctf_typemax; @@ -1132,20 +1133,20 @@ init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth, int is_btf, open time: if another datasec grows to be larger due to dynamic additions, its membership is still recorded. */ - while ((id = ctf_type_kind_next (fp, &i, CTF_K_DATASEC)) != CTF_ERR) + while ((type = ctf_type_kind_next (fp, &i, CTF_K_DATASEC)) != CTF_ERR) { ctf_next_t *i_sec = NULL; - ctf_id_t var_id; + ctf_id_t var_type; - if (id == fp->ctf_default_var_datasec) + if (type == fp->ctf_default_var_datasec) continue; - while ((var_id = ctf_datasec_var_next (fp, id, &i_sec, NULL, NULL)) + while ((var_type = ctf_datasec_var_next (fp, type, &i_sec, NULL, NULL)) != CTF_ERR) { err = ctf_dynhash_insert (fp->ctf_var_datasecs, - (void *) (ptrdiff_t) var_id, - (void *) (ptrdiff_t) id); + (void *) (ptrdiff_t) var_type, + (void *) (ptrdiff_t) type); if (err != 0) return err * -1; } @@ -1203,8 +1204,10 @@ ctf_flip_header (void *cthp, int is_btf, int ctf_version) } else { +#if 0 ctf_header_v2_t *h2p = (ctf_header_v2_t *) cthp; ctf_header_v3_t *h3p = (ctf_header_v3_t *) cthp; +#endif /* Non-BTF-compatible: old CTF release. */ switch (ctf_version) { @@ -1212,14 +1215,14 @@ ctf_flip_header (void *cthp, int is_btf, int ctf_version) case CTF_VERSION_1_UPGRADED_3: case CTF_VERSION_2: ctf_err_warn (NULL, 0, ECTF_INTERNAL, "Implementation of backward-compatible CTF reading still underway\n"); - return (ctf_set_open_errno (errp, ECTF_INTERNAL)); -/* ctf_flip_header_v2 (cth); */ + return -ECTF_INTERNAL; +/* ctf_flip_header_v2 (h2p); */ break; case CTF_VERSION_3: ctf_err_warn (NULL, 0, ECTF_INTERNAL, "Implementation of backward-compatible CTF reading still underway\n"); - return (ctf_set_open_errno (errp, ECTF_INTERNAL)); + return -ECTF_INTERNAL; -/* ctf_flip_header_v3 (cth); */ +/* ctf_flip_header_v3 (h3p); */ } return 0; } @@ -1269,17 +1272,15 @@ flip_types (ctf_dict_t *fp, void *start, size_t len, int to_foreign) { uint32_t kind; uint32_t raw_kind; - size_t size; uint32_t vlen; size_t vbytes; - const ctf_type_t *tprefixed; + ctf_type_t *tprefixed; if (to_foreign) { kind = LCTF_KIND (fp, t); - raw_kind = CTF_INFO_UNPREFIXED_KIND (t->ctt_info); - size = t->ctt_size; - vlen = CTF_VLEN (fp, t); + raw_kind = LCTF_INFO_UNPREFIXED_KIND (fp, t->ctt_info); + vlen = LCTF_VLEN (fp, t); vbytes = get_vbytes_v4 (fp, t, 0); } @@ -1294,30 +1295,29 @@ flip_types (ctf_dict_t *fp, void *start, size_t len, int to_foreign) { tprefixed++; - if (tprefixed > ((uintptr_t) start) + len) + if ((uintptr_t) tprefixed > ((uintptr_t) start) + len) goto overflow; swap_thing (tprefixed->ctt_name); swap_thing (tprefixed->ctt_info); swap_thing (tprefixed->ctt_size); - raw_kind = CTF_INFO_UNPREFIXED_KIND (tprefixed->ctt_info); + raw_kind = LCTF_INFO_UNPREFIXED_KIND (fp, tprefixed->ctt_info); } if (!to_foreign) { kind = LCTF_KIND (fp, t); - raw_kind = LCTF_INFO_UNPREFIXED_KIND (t->ctt_info); - size = t->ctt_size; - vlen = CTF_VLEN (fp, t); + raw_kind = LCTF_INFO_UNPREFIXED_KIND (fp, t->ctt_info); + vlen = LCTF_VLEN (fp, t); vbytes = get_vbytes_v4 (fp, t, 0); } /* Move on to the vlen region. */ - raw_kind = CTF_INFO_UNPREFIXED_KIND (t->ctt_info); + raw_kind = LCTF_INFO_UNPREFIXED_KIND (fp, t->ctt_info); while (LCTF_IS_PREFIXED_KIND (raw_kind)) { t++; - raw_kind = CTF_INFO_UNPREFIXED_KIND (t->ctt_info); + raw_kind = LCTF_INFO_UNPREFIXED_KIND (fp, t->ctt_info); } if (((uintptr_t) t) + sizeof (ctf_type_t) + vbytes @@ -1604,7 +1604,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_header_v3_t *header_v3 = NULL; ctf_dict_t *fp; void *fliphp; - const size_t ctf_adjustment = 0; + size_t ctf_adjustment = 0; /* These match the CTF_VERSION definitions up to IS_BTF. */ enum @@ -1627,7 +1627,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, ctf_dprintf ("ctf_bufopen %zi+%zi+%zi bytes: validating\n", ctfsect ? ctfsect->cts_size : 0, - symsect ? symsect->cts_size : 0 + symsect ? symsect->cts_size : 0, strsect ? strsect->cts_size : 0); if ((ctfsect == NULL) || ((symsect != NULL) && (strsect == NULL))) @@ -1661,8 +1661,8 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, /* First, deal with the unprefixed cases: BTF, and CTFv1--v3: swap them into native endianness if need be. Verify the prefixed endiannesses first. */ - bp = (const ctf_preamble_t *) ctfsect->cts_data; - pp = (const ctf_preamble_t *) ctfsect->cts_data; /* CTFv3 or below. */ + bp = (const ctf_btf_preamble_t *) ctfsect->cts_data; + pp = (const ctf_preamble_v3_t *) ctfsect->cts_data; /* CTFv3 or below. */ if (_libctf_unlikely_ (bp->btf_magic != CTF_BTF_MAGIC)) { @@ -1681,9 +1681,9 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, version = bp->btf_version; } - if (format == IS_UNKNOWN && pp->ctf_magic == CTF_MAGIC) + if (format == IS_UNKNOWN && pp->ctp_magic == CTF_MAGIC) format = pp->ctp_version; - else if (format == IS_UNKNOWN && pp->ctf_magic == bswap_16 (CTF_MAGIC)) + else if (format == IS_UNKNOWN && pp->ctp_magic == bswap_16 (CTF_MAGIC)) { format = pp->ctp_version; foreign_endian = 1; @@ -1695,14 +1695,17 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, { switch (format) { - case CTF_VERSION_1: - case CTF_VERSION_2: + case IS_CTFv1: + case IS_CTFv2: hdrsz = sizeof (ctf_header_v2_t); break; - case CTF_VERSION_1_UPGRADED_3: - case CTF_VERSION_3: + case IS_CTFv1_UPGRADED_3: + case IS_CTFv3: hdrsz = sizeof (ctf_header_v3_t); break; + default: + /* Cannot happen: placate the compiler. */ + hdrsz = sizeof (ctf_header_t); } version = pp->ctp_version; } @@ -1711,7 +1714,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, compensate for BTF offsets being relative to the end of the BTF header, while everything else is relative to the end of the CTF header. */ - if (format == IS_BTF && ctfsect->cts_size >= sizeof (ctf_header)) + if (format == IS_BTF && ctfsect->cts_size >= sizeof (ctf_header_t)) { hp = (ctf_header_t *) ctfsect->cts_data; @@ -1735,7 +1738,8 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (ctfsect->cts_size < hdrsz) { - ctf_err_warn (NULL, 0, ECTF_NOTC, _("ctf_bufopen: size %zi too small for expected header size %zi"), + ctf_err_warn (NULL, 0, ECTF_NOCTFBUF, + _("ctf_bufopen: size %zi too small for expected header size %zi"), ctfsect->cts_size, hdrsz); return (ctf_set_open_errno (errp, ECTF_NOCTFBUF)); } @@ -1747,7 +1751,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, case IS_CTFv2: desc = "CTFv2"; break; case IS_CTFv3: desc = "CTFv3"; break; case IS_BTF: desc = "BTF"; break; - case IS_CTFv4: desc = "CTFv4"; break; + case IS_CTF: desc = "CTFv4"; break; default: desc = "unknown"; } @@ -1766,41 +1770,47 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (ctf_flip_header (fliphp, format >= IS_BTF, version) < 0) { free (fliphp); - return NULL; /* errno is set for us. */ + return (ctf_set_open_errno (errp, ECTF_INTERNAL)); } } - if ((hp = malloc (sizeof (struct ctf_header_t))) == NULL) + if ((hp = malloc (sizeof (ctf_header_t))) == NULL) { free (fliphp); return (ctf_set_open_errno (errp, ENOMEM)); } - memset (hp, 0, sizeof (struct ctf_header_t)); + memset (hp, 0, sizeof (ctf_header_t)); memcpy (hp, fliphp, hdrsz); free (fliphp); if (format < CTF_VERSION_3) { - ctf_err_warn (ECTF_INTERNAL, "Implementation of backward-compatible CTF reading still underway\n"); + ctf_err_warn (NULL, 0, ECTF_INTERNAL, + "Implementation of backward-compatible CTF reading still underway\n"); return (ctf_set_open_errno (errp, ECTF_INTERNAL)); -/* upgrade_header_v2 (hp); /* Upgrades to v3 */ +#if 0 + upgrade_header_v2 (hp); /* Upgrades to v3 */ +#endif } if (format < CTF_VERSION_4) { - header_v3 = hp; + header_v3 = (ctf_header_v3_t *) hp; - if ((hp = malloc (sizeof (struct ctf_header_t))) == NULL) + if ((hp = malloc (sizeof (ctf_header_t))) == NULL) { free (header_v3); return (ctf_set_open_errno (errp, ENOMEM)); } - memcpy (hp, header_v3, sizeof (struct ctf_header_t)); + memcpy (hp, header_v3, sizeof (ctf_header_t)); - ctf_err_warn (ECTF_INTERNAL, "Implementation of backward-compatible CTF reading still underway\n"); + ctf_err_warn (NULL, 0, ECTF_INTERNAL, + "Implementation of backward-compatible CTF reading still underway\n"); return (ctf_set_open_errno (errp, ECTF_INTERNAL)); -/* upgrade_header_v3 (hp); */ +#if 0 + upgrade_header_v3 (hp); +#endif } /* Validation. */ @@ -1819,18 +1829,20 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, goto validation_fail; } - if (_libctf_unlikely (format == IS_BTF && version != 1 - || hp->btf.bth_hdr_len != sizeof (struct ctf_btf_header))) + if (_libctf_unlikely_ (format == IS_BTF + && (version != 1 || hp->btf.bth_hdr_len + != sizeof (struct ctf_btf_header)))) { ctf_err_warn (NULL, 0, ECTF_CTFVERS, - _("BTF version %zi or header length %zi unknown: expecting 1, %zi\n"), + _("BTF version %i or header length %i unknown: expecting 1, %zi\n"), version, hp->btf.bth_hdr_len, sizeof (struct ctf_btf_header)); ctf_set_open_errno (errp, ECTF_CTFVERS); goto validation_fail; } - if (format != IS_BTF && (symsect != NULL) && (version < CTF_VERSION_2)) + if (_libctf_unlikely_ (format != IS_BTF && (symsect != NULL) + && (version < CTF_VERSION_2))) { /* The symtab can contain function entries which contain embedded CTF info. We do not support dynamically upgrading such entries (none @@ -1843,7 +1855,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, goto validation_fail; } - if (format < IS_BTF && _libctf_unlikely_ (pp->ctp_flags > CTF_F_MAX_3)) + if (_libctf_unlikely_ (format < IS_BTF && pp->ctp_flags > CTF_F_MAX_3)) { ctf_err_warn (NULL, 0, ECTF_FLAGS, _("ctf_bufopen: invalid header " "flags: %x"), @@ -1852,7 +1864,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, goto validation_fail; } - if (format >= IS_BTF && _libctf_unlikely_ (bp->btf_flags) != 0) + if (_libctf_unlikely_ (format >= IS_BTF && bp->btf_flags != 0)) { ctf_err_warn (NULL, 0, ECTF_FLAGS, _("ctf_bufopen: nonzero BTF header " "flags: %x"), @@ -1861,7 +1873,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, goto validation_fail; } - if (format == IS_CTF && _libctf_unlikely_ (hp->cth_flags & ~(CTF_F_MAX)) != 0) + if (_libctf_unlikely_ (format == IS_CTF && (hp->cth_flags & ~(CTF_F_MAX)) != 0)) { ctf_err_warn (NULL, 0, ECTF_FLAGS, _("ctf_bufopen: invalid header " "flags: %llx"), @@ -1880,7 +1892,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, || hp->cth_func_off + hp->cth_func_len > hp->cth_objtidx_off || hp->cth_objtidx_off + hp->cth_objtidx_len > hp->cth_funcidx_off || hp->cth_funcidx_off + hp->cth_funcidx_len > hp->btf.bth_type_off - || hp->btf.bth_type_off + hp->btf.bth_type_len > hp->btf.cth_str_off + || hp->btf.bth_type_off + hp->btf.bth_type_len > hp->btf.bth_str_off || hp->cth_objt_off < ctf_adjustment || hp->cth_func_off < ctf_adjustment || hp->cth_objtidx_off < ctf_adjustment @@ -1896,7 +1908,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (_libctf_unlikely_ ((hp->cth_objt_off & 2) || (hp->cth_func_off & 2) || (hp->cth_objtidx_off & 2) - || (hp->cth_funcidx_off & 2) || (hp->btf.cth_type_off & 3))) + || (hp->cth_funcidx_off & 2) || (hp->btf.bth_type_off & 3))) { ctf_err_warn (NULL, 0, ECTF_CORRUPT, _("CTF sections not properly aligned")); @@ -1918,11 +1930,11 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, } /* v3 only needs this invariant if CTF_F_NEWFUNCINFO is set: if it's not, the - section is ignored anyway. */ - if (_libctf_unlikely_ ((hp->cth_functidx_len != 0) && + section is ignored anyway. Always true for v4. */ + if (_libctf_unlikely_ ((hp->cth_funcidx_len != 0) && (hp->cth_funcidx_len != hp->cth_func_len) && - ((header_v3 && hp->cth_flags & CTF_F_NEWFUNCINFO)) - || !header_v3)) + ((header_v3 && hp->cth_flags & CTF_F_NEWFUNCINFO) + || !header_v3))) { ctf_err_warn (NULL, 0, ECTF_CORRUPT, _("Function index section is neither empty nor the " @@ -1934,7 +1946,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, if (_libctf_unlikely_ (hp->cth_parent_strlen != 0 && - ((hp->cth_parent_name != 0 && && hp->cth_parent_name < hp->cth_parent_strlen) + ((hp->cth_parent_name != 0 && hp->cth_parent_name < hp->cth_parent_strlen) || (hp->cth_cu_name != 0 && hp->cth_cu_name < hp->cth_parent_strlen)))) { ctf_err_warn (NULL, 0, ECTF_CORRUPT, @@ -1962,13 +1974,13 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, /* The ctf_size includes the entire CTFv4 header excepting only the portion shared with BTF (see ctf_adjustment). */ - fp->ctf_size = hp->btf.cth_str_off + hp->btf.cth_str_len; + fp->ctf_size = hp->btf.bth_str_off + hp->btf.bth_str_len; - if (_libctf_unlikely (hp->cth_objt_off > fp->ctf_size - || hp->cth_func_off > fp->ctf_size - || hp->cth_objtidx_off > fp->ctf_size - || hp->cth_funcidx_off > fp->ctf_size - || hp->btf.cth_type_off > fp->ctf_size)) + if (_libctf_unlikely_ (hp->cth_objt_off > fp->ctf_size + || hp->cth_func_off > fp->ctf_size + || hp->cth_objtidx_off > fp->ctf_size + || hp->cth_funcidx_off > fp->ctf_size + || hp->btf.bth_type_off > fp->ctf_size)) { ctf_err_warn (NULL, 0, ECTF_CORRUPT, _("header offset or length exceeds CTF size")); err = ECTF_CORRUPT; @@ -2003,7 +2015,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, src = (unsigned char *) ctfsect->cts_data + hdrsz; srclen = ctfsect->cts_size - hdrsz; - dstlen = fp->ctf_size - fp->ctf_adjustment; + dstlen = fp->ctf_size - ctf_adjustment; fp->ctf_buf = fp->ctf_base; /* Stick the CTF-only header portion into the buffer. Not much use, but @@ -2051,7 +2063,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, } fp->ctf_dynbase = fp->ctf_base; memcpy (fp->ctf_base, ((unsigned char *) ctfsect->cts_data) - + sizeof (ctf_btf_header), fp->ctf_size); + + sizeof (ctf_btf_header_t), fp->ctf_size); } else { @@ -2079,11 +2091,14 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, know so far, this CTF dict can be written as BTF without losing information. */ - if (version == IS_BTF) - hp->cth_preamble.ctp_magic_version = (CTFv4_MAGIC << 16) | CTF_VERSION; + if (format == IS_BTF) + { + hp->cth_preamble.ctp_magic_version = (CTFv4_MAGIC << 16) | CTF_VERSION; + version = CTF_VERSION; + } - fp->ctf_version = hp->cth_version; - fp->ctf_dictops = &ctf_dictops[ctf_version]; + fp->ctf_version = version; + fp->ctf_dictops = &ctf_dictops[fp->ctf_version]; /* Temporary assignment, just enough to be able to initialize the atoms table. This does not guarantee that we can look up strings: in v4, child dicts @@ -2157,7 +2172,7 @@ ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect, } if (foreign_endian && - (err = ctf_flip (fp, hp, 0, fp->ctf_buf, 0)) != 0) + (err = ctf_flip (fp, hp, fp->ctf_buf, format == IS_BTF, 0)) != 0) { /* We can be certain that ctf_flip() will have endian-flipped everything other than the types table when we return. In particular the header @@ -2464,7 +2479,7 @@ ctf_parent_name_set (ctf_dict_t *fp, const char *name) const char * ctf_cuname (ctf_dict_t *fp) { - return fp->ctf_cuname; + return fp->ctf_cu_name; } /* Set the compilation unit name. */ @@ -2476,7 +2491,7 @@ ctf_cuname_set (ctf_dict_t *fp, const char *name) if ((fp->ctf_dyn_cu_name = strdup (name)) == NULL) return (ctf_set_errno (fp, ENOMEM)); - fp->ctf_cuname = fp->ctf_dyn_cu_name; + fp->ctf_cu_name = fp->ctf_dyn_cu_name; return 0; } @@ -2489,6 +2504,7 @@ ctf_import_internal (ctf_dict_t *fp, ctf_dict_t *pfp, int unreffed) ctf_dict_t *old_parent = fp->ctf_parent; const char *old_parent_name = fp->ctf_parent_name; int old_unreffed = fp->ctf_parent_unreffed; + int is_btf = 0; if (pfp == NULL || pfp == fp->ctf_parent) return 0; @@ -2576,12 +2592,16 @@ ctf_import_internal (ctf_dict_t *fp, ctf_dict_t *pfp, int unreffed) fp->ctf_parent = pfp; /* If this is a dict that hasn't previously allowed string lookups, - we can allow them now, and finish initialization. */ + we can allow them now, and finish initialization. (This requires us to + figure out whether the buffer contains pure BTF or not: we can do that by + checking the CTF-specific magic number in the header we read in.) */ fp->ctf_flags |= LCTF_CHILD; fp->ctf_flags &= ~LCTF_NO_STR; - if (no_strings && (err = init_static_types_names (fp, fp->ctf_header)) < 0) + is_btf = CTH_MAGIC (fp->ctf_header) != CTFv4_MAGIC; + if (no_strings && (err = init_static_types_names (fp, fp->ctf_header, + is_btf) < 0)) { /* Undo everything other than cache flushing. */ diff --git a/libctf/ctf-serialize.c b/libctf/ctf-serialize.c index 75cac32..a638c40 100644 --- a/libctf/ctf-serialize.c +++ b/libctf/ctf-serialize.c @@ -773,7 +773,7 @@ ctf_write_suppress_kind (ctf_dict_t *fp, int kind, int prohibited) if (!set) { - set = ctf_dynset_create (fp, ctf_hash_integer, ctf_hash_eq_integer, NULL); + set = ctf_dynset_create (ctf_hash_integer, ctf_hash_eq_integer, NULL); if (!set) return (ctf_set_errno (fp, errno)); @@ -783,7 +783,7 @@ ctf_write_suppress_kind (ctf_dict_t *fp, int kind, int prohibited) fp->ctf_write_suppressions = set; } - if ((ctf_dynset_cinsert (fp, (const void *) kind)) < 0) + if ((ctf_dynset_cinsert (set, (const void *) (uintptr_t) kind)) < 0) return (ctf_set_errno (fp, errno)); return 0; @@ -808,8 +808,8 @@ ctf_type_sect_is_btf (ctf_dict_t *fp, int force_ctf) if (fp->ctf_write_prohibitions) { - while (err = ctf_dynset_next (fp->ctf_write_prohibitions, - &prohibit_i, &pkind) == 0) + while ((err = ctf_dynset_next (fp->ctf_write_prohibitions, + &prohibit_i, &pkind)) == 0) { int kind = (uintptr_t) pkind; @@ -818,13 +818,14 @@ ctf_type_sect_is_btf (ctf_dict_t *fp, int force_ctf) ctf_next_destroy (i); ctf_next_destroy (prohibit_i); ctf_err_warn (fp, 0, ECTF_KIND_PROHIBITED, - _("Attempt to write out kind %i, which is prohibited by ctf_write_suppress_kind"), i); + _("Attempt to write out kind %i, which is prohibited by ctf_write_suppress_kind"), + kind); return (ctf_set_errno (fp, ECTF_KIND_PROHIBITED)); } } - if ((err != ECTF_NEXT_END) ((err != 0))) + if (err != ECTF_NEXT_END) { - ctf_next_destroy (fp, prohibit_i); + ctf_next_destroy (prohibit_i); ctf_err_warn (fp, 0, err, _("ctf_write: iteration error checking prohibited kinds")); return (ctf_set_errno (fp, err)); } @@ -847,13 +848,14 @@ ctf_type_sect_is_btf (ctf_dict_t *fp, int force_ctf) /* Any un-suppressed prefixes other than an empty/redundant CTF_K_BIG must be CTF. (Redundant CTF_K_BIGs will be elided instead.) */ - while (LCTF_IS_PREFIXED_KIND (kind = LCTF_INFO_UNPREFIXED_KIND (tp->ctt_info))) + while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info), + LCTF_IS_PREFIXED_KIND (kind)) { if ((kind != CTF_K_BIG) || tp->ctt_size != 0 - || LCTF_INFO_UNPREFIXED_VLEN (tp->ctt_info) != 0) + || LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) != 0) if (!fp->ctf_write_suppressions || ctf_dynset_lookup (fp->ctf_write_suppressions, - (const void *) kind) == NULL) + (const void *) (uintptr_t) kind) == NULL) return 0; tp++; @@ -862,11 +864,11 @@ ctf_type_sect_is_btf (ctf_dict_t *fp, int force_ctf) /* Prefixes checked. If this kind is suppressed, it won't influence the result. */ - kind = LCTF_INFO_UNPREFIXED_KIND (tp->ctt_info); + kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info); if (fp->ctf_write_suppressions && ctf_dynset_lookup (fp->ctf_write_suppressions, - (const void *) kind)) + (const void *) (uintptr_t) kind)) continue; if (kind == CTF_K_FLOAT || kind == CTF_K_SLICE) @@ -876,8 +878,9 @@ ctf_type_sect_is_btf (ctf_dict_t *fp, int force_ctf) { ctf_member_t *memb = (ctf_member_t *) dtd->dtd_vlen; size_t off = 0; + size_t j; - for (i = 0; i < LCTF_VLEN (fp, dtd->dtd_buf); i++) + for (j = 0; j < LCTF_VLEN (fp, dtd->dtd_buf); j++) { /* For bitfields, we must check if the individual members will still fit into a BTF type if they are encoded as offsets rather @@ -885,15 +888,15 @@ ctf_type_sect_is_btf (ctf_dict_t *fp, int force_ctf) by a check of the ctt_size, which is equivalent to checking that the CTF_K_BIG's ctt_size is zero, done above.) */ - if (LCTF_INFO_KFLAG (tp->ctt_info)) + if (CTF_INFO_KFLAG (tp->ctt_info)) { - off += CTF_MEMBER_BIT_OFFSET (memb[i].ctm_offset); + off += CTF_MEMBER_BIT_OFFSET (memb[j].ctm_offset); if (off > CTF_MAX_BIT_OFFSET) return 0; } /* Check for nameless padding members. */ - if (memb[i].ctt_name == 0 && memb[i].ctt_type == CTF_K_UNKNOWN) + if (memb[j].ctm_name == 0 && memb[j].ctm_type == CTF_K_UNKNOWN) return 0; } } @@ -926,12 +929,13 @@ ctf_type_sect_size (ctf_dict_t *fp) { int suppress = 0; - while (LCTF_IS_PREFIXED_KIND (kind = LCTF_INFO_UNPREFIXED_KIND (tp->ctt_info))) + while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info), + LCTF_IS_PREFIXED_KIND (kind)) { if ((kind != CTF_K_BIG) || tp->ctt_size != 0 - || LCTF_INFO_UNPREFIXED_VLEN (tp->ctt_info) != 0) + || LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) != 0) if (ctf_dynset_lookup (fp->ctf_write_suppressions, - (const void *) kind) == NULL) + (const void *) (uintptr_t) kind) == NULL) { type_size += sizeof (ctf_type_t); suppress = 1; @@ -947,10 +951,11 @@ ctf_type_sect_size (ctf_dict_t *fp) /* Type headers: elide CTF_K_BIG from types if possible. */ tp = dtd->dtd_buf; - while (LCTF_IS_PREFIXED_KIND (kind = LCTF_INFO_UNPREFIXED_KIND (tp->ctt_info))) + while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info), + LCTF_IS_PREFIXED_KIND (kind)) { if ((kind != CTF_K_BIG) || tp->ctt_size != 0 - || LCTF_INFO_UNPREFIXED_VLEN (tp->ctt_info) != 0) + || LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) != 0) type_size += sizeof (ctf_type_t); tp++; } @@ -958,7 +963,7 @@ ctf_type_sect_size (ctf_dict_t *fp) type_size += dtd->dtd_vlen_size; } - return type_size + fp->ctf_header->btf.btf_type_len; + return type_size + fp->ctf_header->btf.bth_type_len; } /* Take a final lap through the dynamic type definition list and copy the @@ -983,10 +988,10 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) for (dtd = ctf_list_next (&fp->ctf_dtdefs); dtd != NULL; dtd = ctf_list_next (dtd), id++) { - uint32_t kind = LCTF_KIND (fp, dtd->dtd_buf); + uint32_t kind; size_t vlen = LCTF_VLEN (fp, dtd->dtd_buf); ctf_type_t *tp = dtd->dtd_buf; - ctf_stype_t *copied; + ctf_type_t *copied; const char *name; int suppress = 0; int big = 0; @@ -1001,27 +1006,30 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) /* Suppress everything if this kind is suppressed. */ - while (LCTF_IS_PREFIXED_KIND (kind = LCTF_INFO_UNPREFIXED_KIND (tp->ctt_info))) + while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info), + LCTF_IS_PREFIXED_KIND (kind)) { if (ctf_dynset_lookup (fp->ctf_write_suppressions, - (const void *) kind) == NULL) - if (_libctf_btf_mode == CTF_BTM_BTF) - { - ctf_err_warn (fp, 0, ECTF_NOTBTF, _("type %lx: Attempt to write out CTF-specific kind %i, as BTF"), - id, kind); - return (ctf_set_errno (fp, ECTF_NOTBTF)); - } - else - { - suppress = 1; - break; - } + (const void *) (uintptr_t) kind) == NULL) + { + if (_libctf_btf_mode == LIBCTF_BTM_BTF) + { + ctf_err_warn (fp, 0, ECTF_NOTBTF, _("type %lx: Attempt to write out CTF-specific kind %i, as BTF"), + id, kind); + return (ctf_set_errno (fp, ECTF_NOTBTF)); + } + else + { + suppress = 1; + break; + } + } tp++; } - kind = CTF_INFO_UNPREFIXED_KIND (tp->ctt_info); + kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info); if (ctf_dynset_lookup (fp->ctf_write_suppressions, - (const void *) kind) != NULL) + (const void *) (uintptr_t) kind) != NULL) suppress = 1; if (suppress) @@ -1038,13 +1046,14 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) this type is BIG. */ tp = dtd->dtd_buf; - while (LCTF_IS_PREFIXED_KIND (kind = LCTF_INFO_UNPREFIXED_KIND (tp->ctt_info))) + while (kind = LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info), + LCTF_IS_PREFIXED_KIND (kind)) { if (kind == CTF_K_BIG) { big = 1; if (tp->ctt_size == 0 - && LCTF_INFO_UNPREFIXED_VLEN (tp->ctt_info) == 0) + && LCTF_INFO_UNPREFIXED_VLEN (fp, tp->ctt_info) == 0) continue; } @@ -1136,7 +1145,7 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) case CTF_K_UNION: { size_t offset = 0; - int bitwise = LCTF_INFO_KFLAG (tp->ctt_info); + int bitwise = CTF_INFO_KFLAG (tp->ctt_info); ctf_member_t *memb = (ctf_member_t *) t; ctf_member_t *dtd_memb = (ctf_member_t *) dtd->dtd_vlen; @@ -1155,7 +1164,7 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) if (bitwise) { this_offset = CTF_MEMBER_BIT_OFFSET (memb[i].ctm_offset); - this_size = CTF_MEMBER_BIT_SIZE (memb[i].ctm_size); + this_size = CTF_MEMBER_BIT_SIZE (memb[i].ctm_offset); offset += this_offset; memb[i].ctm_offset = CTF_MEMBER_MAKE_BIT_OFFSET (this_size, offset); @@ -1206,14 +1215,14 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) } case CTF_K_DATASEC: { - ctf_datasec_t *vlen = (ctf_secinfo_t *) t; + ctf_var_secinfo_t *sec = (ctf_var_secinfo_t *) t; if (dtd->dtd_flags & DTD_F_UNSORTED) ctf_datasec_sort (fp, dtd); for (i = 0; i < vlen; i++) { - if (ctf_type_add_ref (fp, vlen[i].cvs_type) < 0) + if (ctf_type_add_ref (fp, &sec[i].cvs_type) < 0) return -1; /* errno is set for us. */ } break; @@ -1252,7 +1261,6 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) int ctf_adjustment; unsigned char *t; - unsigned long i; size_t buf_size, type_size, objt_size, func_size; size_t funcidx_size, objtidx_size; unsigned char *buf = NULL; @@ -1292,7 +1300,7 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) read-in buffer. You can emit such dicts using ctf_link, which can change type IDs arbitrarily, resolving all overlaps. */ - if (fp->ctf_header->cth_stroff - fp->ctf_header->cth_typeoff > 0 && + if (fp->ctf_header->btf.bth_str_len > 0 && fp->ctf_header->cth_parent_ntypes < fp->ctf_parent->ctf_typemax) { ctf_set_errno (fp, ECTF_NOTSERIALIZED); @@ -1329,10 +1337,10 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) ctf_btf_header_t portion of this structure. */ memset (&hdr, 0, sizeof (hdr)); - hdr.btf.bth_preamble.btf_magic = BTF_MAGIC; + hdr.btf.bth_preamble.btf_magic = CTF_BTF_MAGIC; hdr.btf.bth_preamble.btf_version = CTF_BTF_VERSION; hdr.btf.bth_preamble.btf_flags = 0; - hdr.btf.bth_hdr_len = sizeof (struct ctf_btf_header_t); + hdr.btf.bth_hdr_len = sizeof (ctf_btf_header_t); hdr.cth_preamble.ctp_magic_version = (CTFv4_MAGIC << 16) | CTF_VERSION; /* Propagate all symbols in the symtypetabs into the dynamic state, so that @@ -1378,7 +1386,7 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) /* Relatively expensive, so done after cheap checks. */ - type_sect_is_btf = ctf_type_sect_is_btf (fp); + type_sect_is_btf = ctf_type_sect_is_btf (fp, force_ctf); if (!type_sect_is_btf) ctf_needed = 1; @@ -1398,14 +1406,14 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) ctf_adjustment = sizeof (ctf_header_t) - sizeof (ctf_btf_header_t); hdr.cth_objt_off = 0; - hdr.cth.objt_len = objt_size; + hdr.cth_objt_len = objt_size; hdr.cth_func_off = hdr.cth_objt_off + objt_size; hdr.cth_func_len = func_size; hdr.cth_objtidx_off = hdr.cth_func_off + func_size; hdr.cth_objtidx_len = objtidx_size; hdr.cth_funcidx_off = hdr.cth_objtidx_off + objtidx_size; hdr.cth_funcidx_len = funcidx_size; - hdr.btf.bth_type_off = hdr.funcidx_off + hdx.funcidx_size + ctf_adjustment; + hdr.btf.bth_type_off = hdr.cth_funcidx_off + funcidx_size + ctf_adjustment; hdr.btf.bth_type_len = type_size; hdr.btf.bth_str_off = hdr.btf.bth_type_off + type_size; hdr.btf.bth_str_len = 0; @@ -1413,7 +1421,7 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) if (fp->ctf_parent) hdr.cth_parent_ntypes = fp->ctf_parent->ctf_typemax; - if (_libctf_btf_mode = LIBCTF_BTM_ALWAYS + if (_libctf_btf_mode == LIBCTF_BTM_ALWAYS || (_libctf_btf_mode == LIBCTF_BTM_POSSIBLE && ctf_needed)) hdr_len = sizeof (ctf_header_t); else @@ -1430,7 +1438,7 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) fp->ctf_serializing_is_btf = (hdr_len == sizeof (ctf_btf_header_t)); memcpy (buf, &hdr, hdr_len); - t = (unsigned char *) buf + hdr_len + objt_off; + t = (unsigned char *) buf + hdr_len + hdr.cth_objt_off; hdrp = (ctf_header_t *) buf; @@ -1439,8 +1447,8 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent_name != NULL)) ctf_str_add_no_dedup_ref (fp, fp->ctf_parent_name, &hdrp->cth_parent_name); - if (fp->ctf_cuname != NULL) - ctf_str_add_no_dedup_ref (fp, fp->ctf_cuname, &hdrp->cth_cu_name); + if (fp->ctf_cu_name != NULL) + ctf_str_add_no_dedup_ref (fp, fp->ctf_cu_name, &hdrp->cth_cu_name); if (ctf_emit_symtypetab_sects (fp, &symstate, &t, objt_size, func_size, objtidx_size, funcidx_size) < 0) @@ -1459,7 +1467,7 @@ ctf_preserialize (ctf_dict_t *fp, int force_ctf) goto err; assert (t == (unsigned char *) buf + sizeof (ctf_btf_header_t) - + hdr.bth_str_off); + + hdr.btf.bth_str_off); /* All types laid out: update all refs to types to cite the final IDs. */ @@ -1604,7 +1612,7 @@ err: the header uncompressed, and the CTF opening functions work on them without manual decompression.) - No support for (testing-only) endian-flipping. */ + No support for (testing-only) endian-flipping or pure BTF writing. */ int ctf_gzwrite (ctf_dict_t *fp, gzFile fd) { @@ -1613,7 +1621,7 @@ ctf_gzwrite (ctf_dict_t *fp, gzFile fd) size_t bufsiz; size_t len, written = 0; - if ((buf = ctf_serialize (fp, &bufsiz)) == NULL) + if ((buf = ctf_serialize (fp, &bufsiz, 1)) == NULL) return -1; /* errno is set for us. */ p = buf; @@ -1701,7 +1709,7 @@ ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold) if (!uncompressed && !fp->ctf_serializing_is_btf) hp->cth_flags |= CTF_F_COMPRESS; - src = rawbuf + hdrsz; + src = rawbuf + hdrlen; if (flip_endian) { @@ -1717,7 +1725,7 @@ ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold) size_t compress_len = alloc_len - sizeof (ctf_header_t); if ((rc = compress (bp, (uLongf *) &compress_len, - src, rawbufsiz - hdrsz)) != Z_OK) + src, rawbufsiz - hdrlen)) != Z_OK) { ctf_set_errno (fp, ECTF_COMPRESS); ctf_err_warn (fp, 0, 0, _("zlib deflate err: %s"), zError (rc)); @@ -1727,8 +1735,8 @@ ctf_write_mem (ctf_dict_t *fp, size_t *size, size_t threshold) } else { - memcpy (bp, src, rawbufsiz - hdrsz); - *size += rawbufsiz - hdrsz; + memcpy (bp, src, rawbufsiz - hdrlen); + *size += rawbufsiz - hdrlen; } free (rawbuf); diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index 2d12644..737468f 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -141,7 +141,7 @@ ctf_index_to_type (const ctf_dict_t *fp, uint32_t idx) /* Figure out the vlen and optionally vlen length for some type. */ static unsigned char * -ctf_vlen (ctf_dict_t *fp, ctf_id_t type, ctf_type_t *tp, size_t *vlen_len) +ctf_vlen (ctf_dict_t *fp, ctf_id_t type, const ctf_type_t *tp, size_t *vlen_len) { ctf_dtdef_t *dtd; @@ -170,13 +170,15 @@ ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg) { ctf_next_t *i = NULL; ssize_t offset; + int bit_width; const char *name; ctf_id_t membtype; - while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0) + while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, + &bit_width, 0)) >= 0) { int rc; - if ((rc = func (fp, name, membtype, offset, arg)) != 0) + if ((rc = func (fp, name, membtype, offset, bit_width, arg)) != 0) { ctf_next_destroy (i); return rc; @@ -203,14 +205,15 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, size_t nmemb; unsigned char *vlen; ctf_next_t *i = *it; - ctf_type_t *prefix; + const ctf_type_t *prefix; if (fp->ctf_flags & LCTF_NO_STR) return (ctf_set_errno (fp, ECTF_NOPARENT)); if (!i) { - ctf_type_t *tp; + const ctf_type_t *tp; + if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return -1; /* errno is set for us. */ @@ -250,10 +253,10 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, can move it, and hunt down any CTF_K_BIG prefix. */ if (i->u.ctn_dtd) - i->u.ctn_tp = dtd->dtd_buf; + i->ctn_tp = i->u.ctn_dtd->dtd_buf; - if ((prefix = ctf_find_prefix (fp, i->u.ctn_tp, CTF_K_BIG)) == NULL) - prefix = i->u.ctn_tp; + if ((prefix = ctf_find_prefix (fp, i->ctn_tp, CTF_K_BIG)) == NULL) + prefix = i->ctn_tp; /* When we hit an unnamed struct/union member, we set ctn_type to indicate that we are inside one, then return the unnamed member: on the next call, @@ -265,7 +268,6 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, { ctf_member_t *memb = (ctf_member_t *) vlen; const char *membname; - size_t offset; if (i->ctn_n >= nmemb) goto end_iter; @@ -299,12 +301,10 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, /* CTF_K_BIG offsets are gap sizes: convert to offset-from-start. Keep track of the offset-so-far in ctn_size. */ - if (prefix != i->u.ctn_tp) + if (prefix != i->ctn_tp) { - if (width) - *width = offset + i->ctn_size; i->ctn_size += offset; - offset += i->ctn_size; + offset = i->ctn_size; } if (membname[0] == 0 @@ -326,7 +326,7 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, else { ssize_t ret = ctf_member_next (fp, i->ctn_type, &i->ctn_next, name, - membtype, flags, width); + membtype, bit_width, flags); if (ret >= 0) return ret + i->ctn_increment; @@ -359,12 +359,12 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, /* Iterate over the members of an ENUM. We pass the string name and associated integer value of each enum element to the specified callback function. */ -int +int64_t ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg) { ctf_next_t *i = NULL; const char *name; - int val; + int64_t val; while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL) { @@ -403,7 +403,6 @@ ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it, if (!i) { const ctf_type_t *tp; - ctf_dtdef_t *dtd; unsigned char *en; if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR) @@ -563,10 +562,10 @@ ctf_type_kind_iter (ctf_dict_t *fp, int kind, ctf_type_kind_f *func, void *arg) ctf_next_t *i = NULL; ctf_id_t type; - while ((type = ctf_type_kind_next (fp, &i, kind, arg)) != CTF_ERR) + while ((type = ctf_type_kind_next (fp, &i, kind)) != CTF_ERR) { int rc; - if ((rc = func (dict, type, kind, arg)) != 0) + if ((rc = func (fp, type, kind, arg)) != 0) { ctf_next_destroy (i); return rc; @@ -696,7 +695,7 @@ ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg) while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR) { int rc; - if ((rc = func (name, type, arg)) != 0) + if ((rc = func (fp, name, type, arg)) != 0) { ctf_next_destroy (i); return rc; @@ -731,7 +730,7 @@ ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name) i->cu.ctn_fp = fp; i->ctn_iter_fun = (void (*) (void)) ctf_variable_next; - i->u.ctn_next = NULL; + i->ctn_next = NULL; *it = i; } @@ -743,9 +742,13 @@ ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name) if ((id = ctf_type_kind_next (fp, &i->ctn_next, CTF_K_VAR)) == CTF_ERR) { - if (ctf_errno (fp, id) == CTF_NEXT_END) + if (ctf_errno (fp) == ECTF_NEXT_END) ctf_next_destroy (i); } + + if (name) + *name = ctf_type_name_raw (fp, id); + return id; } @@ -760,9 +763,8 @@ ctf_datasec_var_iter (ctf_dict_t *fp, ctf_id_t datasec, ctf_next_t *i = NULL; ctf_id_t type; size_t size, offset; - const char *name; - while ((type = ctf_datasec_next (fp, datasec, &i, &size, &offset)) != CTF_ERR) + while ((type = ctf_datasec_var_next (fp, datasec, &i, &size, &offset)) != CTF_ERR) { int rc; if ((rc = func (fp, type, offset, size, arg)) != 0) @@ -789,44 +791,35 @@ ctf_datasec_var_next (ctf_dict_t *fp, ctf_id_t datasec, ctf_next_t **it, size_t *size, size_t *offset) { ctf_next_t *i = *it; - ctf_id_t type; - ctf_dtdef_t *dtd; if (!i) { const ctf_type_t *tp; - ctf_dtdef_t *dtd; unsigned char *vlen; + ctf_dict_t *ofp = fp; - if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR) - return NULL; /* errno is set for us. */ + if ((datasec = ctf_type_resolve_unsliced (fp, datasec)) == CTF_ERR) + return CTF_ERR; /* errno is set for us. */ - if (ctf_type_kind (fp, type) != CTF_K_DATASEC) - { - ctf_next_destroy (i); - ctf_set_errno (ofp, ECTF_NOTDATASEC); - return NULL; - } + if (ctf_type_kind (fp, datasec) != CTF_K_DATASEC) + return (ctf_set_typed_errno (ofp, ECTF_NOTDATASEC)); - if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL) - return NULL; /* errno is set for us. */ + if ((tp = ctf_lookup_by_id (&fp, datasec, NULL)) == NULL) + return CTF_ERR; /* errno is set for us. */ if ((i = ctf_next_create ()) == NULL) - { - ctf_set_errno (ofp, ENOMEM); - return NULL; - } - i->cu.ctn_fp = ofp; + return (ctf_set_typed_errno (ofp, ENOMEM)); + i->cu.ctn_fp = ofp; i->ctn_iter_fun = (void (*) (void)) ctf_datasec_var_next; - vlen = ctf_vlen (fp, type, tp, &i->ctn_n); + vlen = ctf_vlen (fp, datasec, tp, &i->ctn_n); - i->u.ctn_datasec = (const ctf_enum_t *) en; + i->u.ctn_datasec = (const ctf_var_secinfo_t *) vlen; *it = i; } - if ((void (*) (void)) ctf_datasec_next != i->ctn_iter_fun) + if ((void (*) (void)) ctf_datasec_var_next != i->ctn_iter_fun) return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFUN)); if (fp != i->cu.ctn_fp) @@ -835,21 +828,20 @@ ctf_datasec_var_next (ctf_dict_t *fp, ctf_id_t datasec, ctf_next_t **it, if (i->ctn_n == 0) goto end_iter; - type = i->u.ctn_datasec->cvs_type; if (size) *size = i->u.ctn_datasec->cvs_size; if (offset) *offset = i->u.ctn_datasec->cvs_offset; - i->ctn_datasec++; + i->u.ctn_datasec++; i->ctn_n--; - return type; + return i->u.ctn_datasec->cvs_type; end_iter: ctf_next_destroy (i); *it = NULL; - return ctf_set_typed_errno (fp, ECTF_NEXT_END); + return (ctf_set_typed_errno (fp, ECTF_NEXT_END)); } /* Iterate over all tags with the given TAG, returning the ID of each tag. */ @@ -858,22 +850,17 @@ ctf_id_t ctf_tag_next (ctf_dict_t *fp, const char *tag, ctf_next_t **it) { ctf_next_t *i = *it; - ctf_id_t type; - ctf_dtdef_t *dtd; int err; - const void *type; + void *type; if (!i) { if ((i = ctf_next_create ()) == NULL) - { - ctf_set_errno (ofp, ENOMEM); - return NULL; - } - i->cu.ctn_fp = ofp; + return (ctf_set_typed_errno (fp, ENOMEM)); + i->cu.ctn_fp = fp; i->ctn_iter_fun = (void (*) (void)) ctf_tag_next; - i->cu.ctn_s = ctf_dynhash_lookup (ctf->ctf_tags, tag); + i->cu.ctn_s = ctf_dynhash_lookup (fp->ctf_tags, tag); *it = i; } @@ -884,8 +871,8 @@ ctf_tag_next (ctf_dict_t *fp, const char *tag, ctf_next_t **it) if (fp != i->cu.ctn_fp) return (ctf_set_typed_errno (fp, ECTF_NEXT_WRONGFP)); - err = ctf_dynset_next (i->cu.ctn_s, &i->u.ctn_next, &type); - if (err != 0 && err != CTF_NEXT_END) + err = ctf_dynset_next (i->cu.ctn_s, &i->ctn_next, &type); + if (err != 0 && err != ECTF_NEXT_END) return ctf_set_typed_errno (fp, err); if (err == 0) @@ -919,8 +906,6 @@ ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type) while ((tp = ctf_lookup_by_id (&fp, type, NULL)) != NULL) { - ctf_dtdef_t *dtd; - switch (LCTF_KIND (fp, tp)) { case CTF_K_TYPEDEF: @@ -958,13 +943,12 @@ ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type) { ctf_dict_t *ofp = fp; const ctf_type_t *tp; - ctf_dtdef_t *dtd; ctf_id_t resolved_type; if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return CTF_ERR; - if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) + if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL) return CTF_ERR; /* errno is set for us. */ resolved_type = type; @@ -979,7 +963,7 @@ ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type) if ((resolved_type = ctf_type_resolve (fp, type)) == CTF_ERR) return CTF_ERR; - if ((tp = ctf_lookup_by_id (&fp, resolved_type)) == NULL) + if ((tp = ctf_lookup_by_id (&fp, resolved_type, NULL)) == NULL) return CTF_ERR; /* errno is set for us. */ } while (LCTF_KIND (fp, tp) == CTF_K_SLICE); @@ -1061,7 +1045,6 @@ ctf_type_aname (ctf_dict_t *fp, ctf_id_t type) { ctf_dict_t *rfp = fp; const ctf_type_t *tp = NULL; - ctf_dtdef_t *dtd; const char *name; ctf_lookup_by_id (&rfp, cdp->cd_type, &tp); @@ -1094,7 +1077,10 @@ ctf_type_aname (ctf_dict_t *fp, ctf_id_t type) return NULL; } - ctf_decl_sprintf (&cd, "%s", name); + if (cdp->cd_kind != CTF_K_DATASEC) + ctf_decl_sprintf (&cd, "%s", name); + else + ctf_decl_sprintf (&cd, "DATASEC (\"%s\")", name); break; case CTF_K_POINTER: ctf_decl_sprintf (&cd, "*"); @@ -1178,20 +1164,23 @@ ctf_type_aname (ctf_dict_t *fp, ctf_id_t type) ctf_decl_sprintf (&cd, "%s", name); break; /* UPTODO: decl tags... I guess we print them when we print the - associated variable, somehow? */ + associated variable, somehow? For now, just this... */ + case CTF_K_DECL_TAG: + ctf_decl_sprintf (&cd, "btf_decl_tag (\"%s\")", name); + break; case CTF_K_FUNC_LINKAGE: case CTF_K_VAR: { - ctf_linkage_t l; - if (ctf_type_linkage (fp, cdp->cd_type, &l) < 0) + int linkage; + if ((linkage = ctf_type_linkage (fp, cdp->cd_type)) < 0) { ctf_set_errno (fp, ECTF_CORRUPT); ctf_decl_fini (&cd); return NULL; } - + ctf_decl_sprintf (&cd, "%s%s", linkage == 0 ? "static " : - (linkage == 2 ? "extern " : "") name); + (linkage == 2 ? "extern " : ""), name); break; } case CTF_K_FORWARD: @@ -1224,15 +1213,6 @@ ctf_type_aname (ctf_dict_t *fp, ctf_id_t type) case CTF_K_RESTRICT: ctf_decl_sprintf (&cd, "restrict"); break; - case CTF_K_TYPE_TAG: - ctf_decl_sprintf (&cd, "btf_type_tag (\"%s\")", name); - break; - case CTF_K_DECL_TAG: - ctf_decl_sprintf (&cd, "btf_decl_tag (\"%s\")", name); - break; - case CTF_K_DATASEC: - ctf_decl_sprintf (&cd, "DATASEC (\"%s\")", name); - break; case CTF_K_UNKNOWN: if (name[0] == '\0') @@ -1339,7 +1319,6 @@ ctf_type_size (ctf_dict_t *fp, ctf_id_t type) { ctf_dict_t *ofp = fp; const ctf_type_t *tp; - ctf_dtdef_t *dtd; ssize_t size; ctf_arinfo_t ar; @@ -1409,8 +1388,8 @@ ctf_type_align_natural (ctf_dict_t *fp, ctf_id_t prev_type, /* Ignore incompleteness and nonrepresentability of the type we're inserting: just assume such a type has no alignment constraints of its own. */ - if (ctf_errno (fp, type) == ECTF_NONREPRESENTABLE - || ctf_errno (fp, type) == ECTF_INCOMPLETE) + if (ctf_errno (fp) == ECTF_NONREPRESENTABLE + || ctf_errno (fp) == ECTF_INCOMPLETE) align = 0; else return -1; /* errno is set for us. */ @@ -1447,7 +1426,6 @@ ctf_type_align (ctf_dict_t *fp, ctf_id_t type) { const ctf_type_t *tp; ctf_dict_t *ofp = fp; - ctf_dtdef_t *dtd; int kind; if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) @@ -1477,7 +1455,8 @@ ctf_type_align (ctf_dict_t *fp, ctf_id_t type) { size_t align = 0; unsigned char *vlen; - uint32_t i = 0, n; + uint32_t i = 0; + size_t n; vlen = ctf_vlen (fp, type, tp, &n); @@ -1488,7 +1467,7 @@ ctf_type_align (ctf_dict_t *fp, ctf_id_t type) { ctf_member_t *memb = (ctf_member_t *) vlen; - ssize_t am = ctf_type_align (ofp, memb[i->ctn_n].ctm_type); + ssize_t am = ctf_type_align (ofp, memb[i].ctm_type); align = MAX (align, (size_t) am); } return align; @@ -1512,8 +1491,6 @@ ctf_type_align (ctf_dict_t *fp, ctf_id_t type) int ctf_type_kind_unsliced_tp (ctf_dict_t *fp, const ctf_type_t *tp) { - const ctf_type_t *suffix = NULL; - if (LCTF_KIND (fp, tp) == CTF_K_ENUM && LCTF_VLEN (fp, tp) == 0) return CTF_K_FORWARD; @@ -1534,11 +1511,11 @@ ctf_type_kind_tp (ctf_dict_t *fp, const ctf_type_t *tp) if (kind == CTF_K_SLICE) { - unsigned char *vlen; const ctf_slice_t *sp; + ssize_t increment; - vlen = ctf_vlen (fp, type, tp, NULL); - sp = (const ctf_slice_t *) vlen; + ctf_get_ctt_size (fp, tp, NULL, &increment); + sp = (const ctf_slice_t *) tp + increment; kind = ctf_type_kind_unsliced (fp, sp->cts_type); } @@ -1552,21 +1529,18 @@ int ctf_type_kind_forwarded_tp (ctf_dict_t *fp, const ctf_type_t *tp) { int kind; - const ctf_type_t *tp; /* The suffixed kind, if prefixed */ - if ((kind = ctf_type_kind (fp, type)) < 0) + if ((kind = ctf_type_kind_tp (fp, tp)) < 0) return -1; /* errno is set for us. */ + /* Covers forwards to enums, too. */ if (kind != CTF_K_FORWARD) return kind; - if (LCTF_KIND (fp, tp) == CTF_K_ENUM) - return CTF_K_ENUM; - while (LCTF_IS_PREFIXED_KIND (LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info))) tp++; - if (LCTF_INFO_KFLAG (tp->ctt_info)) + if (CTF_INFO_KFLAG (tp->ctt_info)) return CTF_K_UNION; else return CTF_K_STRUCT; @@ -1586,11 +1560,7 @@ ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type) if ((tp = ctf_lookup_by_id (&fp, type, &suffix)) == NULL) return -1; /* errno is set for us. */ - if (LCTF_KIND (fp, tp) == CTF_K_ENUM - && LCTF_VLEN (fp, tp) == 0) - return CTF_K_FORWARD; - - return (LCTF_KIND (fp, tp)); + return (ctf_type_kind_unsliced_tp (fp, tp)); } /* Return the kind (CTF_K_* constant) for the specified type ID. @@ -1619,26 +1589,17 @@ ctf_type_kind (ctf_dict_t *fp, ctf_id_t type) int ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type) { - int kind; + int ret; ctf_dict_t *ofp = fp; - const ctf_type_t *tp; /* The suffixed kind, if prefixed */ + const ctf_type_t *tp, *suffix; - if (ctf_lookup_by_id (&fp, type, &tp) == NULL) + if ((tp = ctf_lookup_by_id (&fp, type, &suffix)) == NULL) return -1; /* errno is set for us. */ - if ((kind = ctf_type_kind_tp (fp, tp)) < 0) + if ((ret = ctf_type_kind_forwarded_tp (fp, tp)) < 0) return (ctf_set_errno (ofp, ctf_errno (fp))); - if (kind != CTF_K_FORWARD) - return kind; - - if (LCTF_KIND (fp, tp) == CTF_K_ENUM) - return CTF_K_ENUM; - - if (LCTF_INFO_KFLAG (tp->ctt_info)) - return CTF_K_UNION; - else - return CTF_K_STRUCT; + return ret; } /* Return nonzero if this type is conflicting, nonzero if it's not, < 0 on @@ -1647,11 +1608,10 @@ ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type) known). */ int -ctf_type_conflicting (ctf_dict_t *, ctf_id_t, const char **cuname) +ctf_type_conflicting (ctf_dict_t *fp, ctf_id_t type, const char **cuname) { ctf_dict_t *ofp = fp; const ctf_type_t *tp; - uint32_t kind; if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return -1; /* errno is set for us. */ @@ -1665,8 +1625,14 @@ ctf_type_conflicting (ctf_dict_t *, ctf_id_t, const char **cuname) if (!cuname) return 1; - while (CTF_INFO_KIND (tp->ctt_info) != CTF_K_CONFLICTING) - prefix++; + while (LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info) != CTF_K_CONFLICTING + && LCTF_IS_PREFIXED_KIND (LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info))) + tp++; + + /* We already checked that this is a non-root-visible type, so this must be + CTF_K_CONFLICTING. */ + if (!ctf_assert (ofp, LCTF_IS_PREFIXED_KIND (LCTF_INFO_UNPREFIXED_KIND (fp, tp->ctt_info)))) + return -1; /* errno is set for us. */ *cuname = ctf_strptr (fp, tp->ctt_name); return 1; @@ -1691,9 +1657,9 @@ ctf_type_reference (ctf_dict_t *fp, ctf_id_t type) case CTF_K_VOLATILE: case CTF_K_CONST: case CTF_K_RESTRICT: - case CTF_K_FUNC: case CTF_K_TYPE_TAG: case CTF_K_DECL_TAG: + case CTF_K_FUNCTION: case CTF_K_FUNC_LINKAGE: case CTF_K_VAR: return suffix->ctt_type; @@ -1725,7 +1691,7 @@ ctf_decl_tag (ctf_dict_t *fp, ctf_id_t decl_tag, int64_t *component_idx) if ((tp = ctf_lookup_by_id (&fp, decl_tag, &suffix)) == NULL) return CTF_ERR; /* errno is set for us. */ - if (LCTF_KIND (fp, tp) != CTF_DECL_TAG) + if (LCTF_KIND (fp, tp) != CTF_K_DECL_TAG) return (ctf_set_typed_errno (ofp, ECTF_NOTDECLTAG)); vlen = ctf_vlen (fp, decl_tag, tp, NULL); @@ -1745,19 +1711,19 @@ ctf_tag (ctf_dict_t *fp, ctf_id_t tag) { int kind = ctf_type_kind (fp, tag); int64_t component_idx; - int ref; + ctf_id_t ref; - if (kind != CTF_TYPE_TAG && kind != CTF_DECL_TAG) + if (kind != CTF_K_TYPE_TAG && kind != CTF_K_DECL_TAG) return (ctf_set_typed_errno (fp, ECTF_NOTTAG)); - if (ref = ctf_type_reference (fp, tag) < 0) - return -1; /* errno is set for us. */ + if ((ref = ctf_type_reference (fp, tag)) == CTF_ERR) + return CTF_ERR; /* errno is set for us. */ - if (kind == CTF_TYPE_TAG) + if (kind == CTF_K_TYPE_TAG) return ref; - if (ctf_decl_tag (fp, decl_tag, &component_idx) == CTF_ERR) - return -1; /* errno is set for us. */ + if (ctf_decl_tag (fp, tag, &component_idx) == CTF_ERR) + return CTF_ERR; /* errno is set for us. */ if (component_idx == -1) return ref; @@ -1766,24 +1732,26 @@ ctf_tag (ctf_dict_t *fp, ctf_id_t tag) switch (ctf_type_kind (fp, ref)) { - ctf_id_t type; - ctf_funcinfo_t fi; - case CTF_K_STRUCT: case CTF_K_UNION: { ctf_next_t *i = NULL; + int64_t j = 0; + ctf_id_t type; - while (ctf_member_next (fp, ref, &i, NULL, &type, NULL, 0) != CTF_ERR) + while (ctf_member_next (fp, ref, &i, NULL, &type, NULL, 0) >= 0) { - if (i++ == component_idx) + if (j++ == component_idx) { ctf_next_destroy (i); return type; } } if (ctf_errno (fp) != ECTF_NEXT_END) - return -1; /* errno is set for us. */ + { + ctf_next_destroy (i); + return CTF_ERR; /* errno is set for us. */ + } } break; case CTF_K_FUNC_LINKAGE: @@ -1794,9 +1762,9 @@ ctf_tag (ctf_dict_t *fp, ctf_id_t tag) ctf_id_t argtype; if (ctf_func_type_info (fp, ref, &fi) < 0) - return -1; /* errno is set for us. */ + return CTF_ERR; /* errno is set for us. */ - if (component_idx + 1 > fi.ctc_argc) + if (component_idx + 1 > (ssize_t) fi.ctc_argc) break; if ((args = malloc ((component_idx + 1) * sizeof (ctf_id_t))) == NULL) @@ -1805,7 +1773,7 @@ ctf_tag (ctf_dict_t *fp, ctf_id_t tag) if (ctf_func_type_args (fp, ref, component_idx + 1, args)) { free (args); - return -1; /* errno is set for us. */ + return CTF_ERR; /* errno is set for us. */ } argtype = args[component_idx]; free (args); @@ -1813,14 +1781,14 @@ ctf_tag (ctf_dict_t *fp, ctf_id_t tag) } default: - return -1; /* errno is set for us. */ + return CTF_ERR; /* errno is set for us. */ } - ctf_err_warn (ofp, 0, ECTF_NOTREF, _("decl tag %lx refers to type %x, " - "component %i, which does not exist"), - tag, ref, component_idx); + ctf_err_warn (fp, 0, ECTF_NOTREF, _("decl tag %lx refers to type %lx, " + "component %" PRIi64 ", which does not exist"), + tag, (long) ref, component_idx); - return ECTF_NOTREF; + return (ctf_set_typed_errno (fp, ECTF_NOTREF)); } /* Find a pointer to type by looking in fp->ctf_ptrtab and fp->ctf_pptrtab. If @@ -1851,7 +1819,7 @@ ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type) if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return (ctf_set_typed_errno (ofp, ECTF_NOTYPE)); - if (ctf_lookup_by_id (&fp, type) == NULL) + if (ctf_lookup_by_id (&fp, type, NULL) == NULL) return (ctf_set_typed_errno (ofp, ECTF_NOTYPE)); idx = ctf_type_to_index (fp, type); @@ -2096,7 +2064,9 @@ ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name, ctf_membinfo_t *mip) { ctf_dict_t *ofp = fp; - const ctf_type_t *tp; + const ctf_type_t *tp, *suffix; + int big = 0; + size_t total_offset = 0; unsigned char *vlen; uint32_t kind, i = 0; size_t n; @@ -2107,7 +2077,7 @@ ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name, if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return -1; /* errno is set for us. */ - if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL) + if ((tp = ctf_lookup_by_id (&fp, type, &suffix)) == NULL) return -1; /* errno is set for us. */ kind = LCTF_KIND (fp, tp); @@ -2117,26 +2087,51 @@ ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name, vlen = ctf_vlen (fp, type, tp, &n); + big = (ctf_find_prefix (fp, tp, CTF_K_BIG) != NULL); + for (; n != 0; n--, i++) { ctf_member_t *memb = (ctf_member_t *) vlen; const char *membname; + size_t offset; + int bit_width = 0; + + membname = ctf_strptr (fp, memb->ctm_name); + + if (CTF_INFO_KFLAG (suffix->ctt_info)) + { + offset = CTF_MEMBER_BIT_OFFSET (memb->ctm_offset); + bit_width = CTF_MEMBER_BIT_SIZE (memb->ctm_offset); + } + else + offset = memb->ctm_offset; - membname = ctf_strptr (fp, memb.ctlm_name); + total_offset += offset; + /* Unnamed struct/union member. */ if (membname[0] == 0 - && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT - || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION) - && (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0)) + && (ctf_type_kind (fp, memb->ctm_type) == CTF_K_STRUCT + || ctf_type_kind (fp, memb->ctm_type) == CTF_K_UNION) + && (ctf_member_info (fp, memb->ctm_type, name, mip) == 0)) { - mip->ctm_offset += (unsigned long) CTF_LMEM_OFFSET (&memb); + if (!big) + mip->ctm_offset += total_offset; + else + mip->ctm_offset += offset; + return 0; } + /* Ordinary member. */ if (strcmp (membname, name) == 0) { - mip->ctm_type = memb.ctlm_type; - mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (&memb); + mip->ctm_type = memb->ctm_type; + if (big) + mip->ctm_offset = total_offset + memb->ctm_offset; + else + mip->ctm_offset = memb->ctm_offset; + mip->ctm_bit_width = bit_width; + return 0; } } @@ -2237,7 +2232,6 @@ ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int64_t *valp) ctf_dict_t *ofp = fp; const ctf_type_t *tp; unsigned char *vlen; - const ctf_enum_t *ep; int kind; size_t n; @@ -2290,10 +2284,10 @@ ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int64_t *valp) /* Like ctf_enum_value, but returns an unsigned int64_t instead. */ int -ctf_enum_unsigned_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int64_t *valp) +ctf_enum_unsigned_value (ctf_dict_t *fp, ctf_id_t type, const char *name, uint64_t *valp) { int ret; - uint64_t retval; + int64_t retval; ret = ctf_enum_value (fp, type, name, &retval); *valp = (uint64_t) retval; @@ -2311,12 +2305,12 @@ ctf_enum_unsigned (ctf_dict_t *fp, ctf_id_t type) return -1; /* errno is set for us. */ if (kind != CTF_K_ENUM && kind != CTF_K_ENUM64) - retrn (ctf_set_errno (fp, ECTF_NOTENUM)) + return (ctf_set_errno (fp, ECTF_NOTENUM)); if (ctf_lookup_by_id (&fp, type, &tp) == NULL) return -1; /* errno is set for us. */ - return !LCTF_INFO_KFLAG (tp->ctt_info); + return !CTF_INFO_KFLAG (tp->ctt_info); } /* Return nonzero if this struct or union uses bitfield encoding. */ @@ -2330,12 +2324,12 @@ ctf_struct_bitfield (ctf_dict_t * fp, ctf_id_t type) return -1; /* errno is set for us. */ if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) - retrn (ctf_set_errno (fp, ECTF_NOTSOU)) + return (ctf_set_errno (fp, ECTF_NOTSOU)); if (ctf_lookup_by_id (&fp, type, &tp) == NULL) return -1; /* errno is set for us. */ - return LCTF_INFO_KFLAG (tp->ctt_info); + return CTF_INFO_KFLAG (tp->ctt_info); } /* Given a type ID relating to a function type, return info on return types and @@ -2389,7 +2383,7 @@ ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv unsigned char *vlen; ctf_funcinfo_t f; - if ((type = ctf_type_resolve (fp, type, NULL)) == CTF_ERR) + if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return -1; /* errno is set for us. */ if (ctf_type_kind (fp, type) == CTF_K_FUNC_LINKAGE) @@ -2405,7 +2399,7 @@ ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv args = (const ctf_param_t *) vlen; for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--) - *argv++ = *(args++).cfp_type; + *argv++ = (args++)->cfp_type; return 0; } @@ -2422,7 +2416,7 @@ ctf_func_type_arg_names (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, unsigned char *vlen; ctf_funcinfo_t f; - if ((type = ctf_type_resolve (fp, type, NULL)) == CTF_ERR) + if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) return -1; /* errno is set for us. */ if (ctf_type_kind (fp, type) == CTF_K_FUNC_LINKAGE) @@ -2435,10 +2429,10 @@ ctf_func_type_arg_names (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, return -1; /* errno is set for us. */ vlen = ctf_vlen (fp, type, tp, NULL); - args = (const ctf_param_t * *) vlen; + args = (const ctf_param_t *) vlen; for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--) - *arg_names++ = ctf_strptr (fp, *(args++).cfp_name); + *arg_names++ = ctf_strptr (fp, (args++)->cfp_name); return 0; } @@ -2464,19 +2458,19 @@ ctf_type_linkage (ctf_dict_t *fp, ctf_id_t type) vlen = ctf_vlen (fp, type, tp, NULL); l = (ctf_linkage_t *) vlen; - return linkage.ctl_linkage; + return l->ctl_linkage; } /* bsearch_r comparison function for datasec searches. */ static int search_datasec_by_offset (const void *key_, const void *arr_) { - ctf_datasec_t *key = (ctf_datasec_t *) key_; - ctf_datasec_t *arr = (ctf_datasec_t *) arr_; + uint32_t *key = (uint32_t *) key_; + ctf_var_secinfo_t *arr = (ctf_var_secinfo_t *) arr_; - if (key->cvs_offset < arr->cvs_offset) + if (*key < arr->cvs_offset) return -1; - else if (key->cvs_offset > arr->cvs_offset) + else if (*key > arr->cvs_offset) return 1; return 0; @@ -2487,9 +2481,8 @@ search_datasec_by_offset (const void *key_, const void *arr_) Errors with ECTF_NOTYPEDAT if not found. */ ctf_id_t -ctf_datasec_variable_offset (ctf_dict_t *fp, ctf_id_t datasec, uint32_t offset) +ctf_datasec_var_offset (ctf_dict_t *fp, ctf_id_t datasec, uint32_t offset) { - ctf_id_t type; ctf_dtdef_t *dtd; const ctf_type_t *tp; unsigned char *vlen; @@ -2498,7 +2491,7 @@ ctf_datasec_variable_offset (ctf_dict_t *fp, ctf_id_t datasec, uint32_t offset) ctf_var_secinfo_t *el; ssize_t size; - if ((tp = ctf_lookup_by_id (&fp, type, NULL)) == NULL) + if ((tp = ctf_lookup_by_id (&fp, datasec, NULL)) == NULL) return -1; /* errno is set for us. */ if (ctf_type_kind (fp, datasec) != CTF_K_DATASEC) @@ -2510,7 +2503,7 @@ ctf_datasec_variable_offset (ctf_dict_t *fp, ctf_id_t datasec, uint32_t offset) ctf_datasec_sort (fp, dtd); } - vlen = ctf_vlen (fp, type, tp, &vlen_len); + vlen = ctf_vlen (fp, datasec, tp, &vlen_len); sec = (ctf_var_secinfo_t *) vlen; if ((el = bsearch (&offset, sec, vlen_len, sizeof (ctf_var_secinfo_t), @@ -2534,21 +2527,19 @@ ctf_datasec_variable_offset (ctf_dict_t *fp, ctf_id_t datasec, uint32_t offset) ctf_var_secinfo_t * ctf_datasec_entry (ctf_dict_t *fp, ctf_id_t datasec, int component_idx) { - ctf_type_t *tp; + const ctf_type_t *tp; unsigned char *vlen; size_t vlen_len; ctf_var_secinfo_t *sec; - ctf_var_secinfo_t *el; - ssize_t size; - if ((tp = ctf_lookup_by_id (&fp, type)) == NULL) + if ((tp = ctf_lookup_by_id (&fp, datasec, NULL)) == NULL) return NULL; /* errno is set for us. */ /* No type kind check: internal function. */ - vlen = ctf_vlen (fp, type, tp, &vlen_len); + vlen = ctf_vlen (fp, datasec, tp, &vlen_len); sec = (ctf_var_secinfo_t *) vlen; - if (component_idx > vlen_len) + if (component_idx < 0 || (size_t) component_idx > vlen_len) { ctf_set_errno (fp, EOVERFLOW); return NULL; @@ -2561,15 +2552,14 @@ ctf_datasec_entry (ctf_dict_t *fp, ctf_id_t datasec, int component_idx) ctf_id_t ctf_variable_datasec (ctf_dict_t *fp, ctf_id_t var) { - ctf_id_t sec; - void *sec_v; + void *sec; if (ctf_type_kind (fp, var) != CTF_K_VAR) return (ctf_set_typed_errno (fp, ECTF_NOTVAR)); if (ctf_dynhash_lookup_kv (fp->ctf_var_datasecs, (void *) (ptrdiff_t) var, - NULL, &sec_v)) - return (ctf_id_t) sec_v; + NULL, &sec)) + return (ctf_id_t) sec; return fp->ctf_default_var_datasec; } @@ -2583,16 +2573,15 @@ ctf_id_t ctf_variable_datasec (ctf_dict_t *fp, ctf_id_t var) static int ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg, const char *name, unsigned long offset, - int bit_offset, int depth) + int bit_width, int depth) { - ctf_dict_t *ofp = fp; ctf_id_t otype = type; int nonrepresentable = 0; uint32_t kind; ctf_next_t *it = NULL; ctf_id_t membtype; - size_t this_offset, bit_offset; - int bit_width; + ssize_t this_offset; + int this_bit_width; int rc; if (fp->ctf_flags & LCTF_NO_STR) @@ -2605,7 +2594,7 @@ ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, nonrepresentable = 1; } - if ((rc = func (fp, name, otype, offset, bit_offset, depth, arg)) != 0) + if ((rc = func (fp, name, otype, offset, bit_width, depth, arg)) != 0) return rc; if (!nonrepresentable) @@ -2614,11 +2603,11 @@ ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, if (nonrepresentable || (kind != CTF_K_STRUCT && kind != CTF_K_UNION)) return 0; - while ((offset = ctf_member_next (fp, type, &it, &name, &membtype, - &bit_width, 0)) >= 0) + while ((this_offset = ctf_member_next (fp, type, &it, &name, &membtype, + &this_bit_width, 0)) >= 0) { - if ((rc = ctf_type_rvisit (fp, membtype, func, arg, name, offset, - offset + this_offset, bit_offset, + if ((rc = ctf_type_rvisit (fp, membtype, func, arg, name, + offset + this_offset, this_bit_width, depth + 1)) != 0) return rc; } |