diff options
Diffstat (limited to 'libctf')
-rw-r--r-- | libctf/ctf-decl.c | 20 | ||||
-rw-r--r-- | libctf/ctf-dump.c | 7 | ||||
-rw-r--r-- | libctf/ctf-impl.h | 6 | ||||
-rw-r--r-- | libctf/ctf-lookup.c | 7 | ||||
-rw-r--r-- | libctf/ctf-open.c | 99 | ||||
-rw-r--r-- | libctf/ctf-serialize.c | 5 | ||||
-rw-r--r-- | libctf/ctf-types.c | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/array.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/const.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/datasec.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/decl-tag.lk | 8 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/forward.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/integer.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/pointer.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/restrict.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/struct.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/union.lk | 2 | ||||
-rw-r--r-- | libctf/testsuite/libctf-lookup/by-kind/volatile.lk | 2 |
18 files changed, 120 insertions, 54 deletions
diff --git a/libctf/ctf-decl.c b/libctf/ctf-decl.c index eec6196..4c1007f5 100644 --- a/libctf/ctf-decl.c +++ b/libctf/ctf-decl.c @@ -34,7 +34,7 @@ The functions in this file build a set of stacks from the type graph nodes corresponding to the C operator precedence levels in the appropriate order. - The code in ctf_type_name() can then iterate over the levels and nodes in + The code in ctf_type_aname() can then iterate over the levels and nodes in lexical precedence order and construct the final C declaration string. */ #include <ctf-impl.h> @@ -84,11 +84,17 @@ ctf_decl_push (ctf_decl_t *cd, ctf_dict_t *fp, ctf_id_t type) if ((tp = ctf_lookup_by_id (&fp, type, &suffix)) == NULL) { - cd->cd_err = fp->ctf_errno; - return; + if (ctf_errno (fp) != ECTF_NONREPRESENTABLE) + { + cd->cd_err = fp->ctf_errno; + return; + } + kind = CTF_K_UNKNOWN; } + else + kind = ctf_type_kind (fp, type); - switch (kind = ctf_type_kind (fp, type)) + switch (kind) { case CTF_K_ARRAY: (void) ctf_array_info (fp, type, &ar); @@ -121,6 +127,12 @@ ctf_decl_push (ctf_decl_t *cd, ctf_dict_t *fp, ctf_id_t type) prec = CTF_PREC_POINTER; break; + case CTF_K_DECL_TAG: + case CTF_K_VAR: + ctf_decl_push (cd, fp, suffix->ctt_type); + prec = CTF_PREC_BASE; /* UPTODO probably wrong */ + break; + case CTF_K_SLICE: /* Slices themselves have no print representation and should not appear in the decl stack. */ diff --git a/libctf/ctf-dump.c b/libctf/ctf-dump.c index ad43666..94eac10 100644 --- a/libctf/ctf-dump.c +++ b/libctf/ctf-dump.c @@ -614,6 +614,7 @@ ctf_dump_var (ctf_dict_t *fp, ctf_id_t type, { char *str; char *typestr; + int linkage; ctf_dump_state_t *state = arg; ctf_id_t otype = type; @@ -625,7 +626,11 @@ ctf_dump_var (ctf_dict_t *fp, ctf_id_t type, /* Specialized var dumper: only dump the linkage, not the type kind or anything related. */ - if ((typestr = ctf_type_aname (fp, type)) == NULL) + if ((linkage = ctf_type_linkage (fp, type)) < 0 + || asprintf (&typestr, "%s%s", linkage == 0 ? "static " + : (linkage == 2 ? "extern " : + (linkage == 1 ? "" : "(invalid linkage) ")), + ctf_type_name_raw (fp, type)) < 0) { ctf_err_warn (fp, 1, ctf_errno (fp), _("cannot format name dumping var 0x%lx"), type); diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index 214f265..8f8703c 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -432,12 +432,14 @@ struct ctf_dict uint32_t *ctf_sxlate; /* Translation table for unindexed symtypetab entries. */ unsigned long ctf_nsyms; /* Number of entries in symtab xlate table. */ - uint32_t *ctf_txlate; /* Translation table for type IDs. */ + ctf_type_t **ctf_txlate; /* Translation table for type IDs. */ uint32_t *ctf_ptrtab; /* Translation table for pointer-to lookups. */ size_t ctf_ptrtab_len; /* Num types storable in ptrtab currently. */ uint32_t *ctf_pptrtab; /* Parent types pointed to by child dicts. */ size_t ctf_pptrtab_len; /* Num types storable in pptrtab currently. */ uint32_t ctf_pptrtab_typemax; /* Max child type when pptrtab last updated. */ + ctf_type_t *ctf_void_type; /* void type, if dynamically constructed. (More + space allocated, due to vlen.) */ ctf_dynset_t *ctf_conflicting_enums; /* Tracks enum constants that conflict. */ uint32_t *ctf_funcidx_names; /* Name of each function symbol in symtypetab (if indexed). */ @@ -619,7 +621,7 @@ extern ctf_id_t ctf_index_to_type (const ctf_dict_t *, uint32_t); #define LCTF_INDEX_TO_TYPEPTR(fp, i) \ ((i > fp->ctf_stypes) ? \ ctf_dtd_lookup (fp, ctf_index_to_type (fp, i))->dtd_data : \ - (ctf_type_t *)((uintptr_t)(fp)->ctf_buf + (fp)->ctf_txlate[(i)])) + (fp)->ctf_txlate[(i)]) /* The non *INFO variants of these macros acquire the relevant info from the suffixed type, if the type is prefixed. (Internally to libctf, all types diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c index 815d1d8..532c5de 100644 --- a/libctf/ctf-lookup.c +++ b/libctf/ctf-lookup.c @@ -397,7 +397,7 @@ ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type, const ctf_type_t **suffix) ctf_set_errno (*fpp, ECTF_BADID); return NULL; } - + *fpp = fp; /* Possibly the parent CTF dict. */ if (idx > fp->ctf_stypes) { @@ -410,9 +410,8 @@ ctf_lookup_by_id (ctf_dict_t **fpp, ctf_id_t type, const ctf_type_t **suffix) } else { - ctf_type_t *tp; - - tp = (ctf_type_t *)((uintptr_t) fp->ctf_buf + fp->ctf_txlate[idx]); + ctf_type_t *tp = fp->ctf_txlate[idx]; + if (suffix) { ctf_type_t *suff; diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c index b978db3..a0f7238 100644 --- a/libctf/ctf-open.c +++ b/libctf/ctf-open.c @@ -756,7 +756,7 @@ init_static_types (ctf_dict_t *fp, ctf_header_t *cth, int is_btf) because later-added types will call grow_ptrtab() automatically, as needed. */ - fp->ctf_txlate = calloc (typemax + 1, sizeof (uint32_t)); + fp->ctf_txlate = calloc (typemax + 1, sizeof (ctf_type_t *)); fp->ctf_ptrtab = calloc (typemax + 1, sizeof (uint32_t)); fp->ctf_ptrtab_len = typemax + 1; fp->ctf_stypes = typemax; @@ -798,6 +798,9 @@ init_static_types_names (ctf_dict_t *fp, ctf_header_t *cth, int is_btf) return err; } +static int +init_void (ctf_dict_t *fp); + /* Initialize the parts of the CTF dict whose initialization depends on name or type lookup. This happens at open time except for child dicts, when (for CTFv4+ dicts) it happens at ctf_import time instead, because before then the @@ -810,16 +813,12 @@ static int init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth, int is_btf, ctf_dynset_t *all_enums) { - const ctf_type_t *tbuf; - const ctf_type_t *tend; + ctf_type_t *tbuf, *tend, *tp; + ctf_type_t **xp; - const ctf_type_t *tp; uint32_t id; - uint32_t *xp; ctf_id_t type; - unsigned long typemax = fp->ctf_typemax; - ctf_next_t *i = NULL; void *k; int err; @@ -831,22 +830,14 @@ init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth, int is_btf, assert (!(fp->ctf_flags & LCTF_NO_STR)); - xp = fp->ctf_txlate; - *xp++ = 0; /* Type id 0 is used as a sentinel value. */ + xp = &fp->ctf_txlate[1]; /* In this second pass through the types, we fill in each entry of the type and pointer tables and add names to the appropriate hashes. - (Not all names are added in this pass, only type names. See below.) + (Not all names are added in this pass, only type names. See below.) */ - Reset ctf_typemax and bump it as we go, but keep it one higher than normal, - so that the type being read in is considered a valid type and it is at - least barely possible to run simple lookups on it: but higher types are - not, since their names are not yet known. (It is kept at its standard - value before this function is called so that at least some type-related - operations work. */ - - for (id = 1, fp->ctf_typemax = 1, tp = tbuf; tp < tend; xp++, id++, fp->ctf_typemax++) + for (id = 1, tp = tbuf; tp < tend; xp++, id++) { unsigned short kind = LCTF_KIND (fp, tp); unsigned short isroot = LCTF_INFO_ISROOT (fp, tp->ctt_info); @@ -871,7 +862,7 @@ init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth, int is_btf, /* Cannot fail: shielded by call in init_static_types. */ vbytes = LCTF_VBYTES (fp, suffix, size); - *xp = (uint32_t) ((uintptr_t) tp - (uintptr_t) fp->ctf_buf); + *xp = tp; switch (kind) { @@ -1104,10 +1095,12 @@ init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth, int is_btf, } tp = (ctf_type_t *) ((uintptr_t) tp + increment + vbytes); } - fp->ctf_typemax--; - assert (fp->ctf_typemax == typemax); + assert (fp->ctf_typemax == id - 1); - ctf_dprintf ("%u total types processed\n", fp->ctf_typemax); + ctf_dprintf ("%u total types processed\n", id - 1); + + if ((err = init_void (fp) < 0)) + return err; /* In the third pass, we traverse the enums we spotted earlier and track all the enumeration constants to aid in future detection of duplicates. @@ -1185,6 +1178,52 @@ init_static_types_names_internal (ctf_dict_t *fp, ctf_header_t *cth, int is_btf, return 0; } +/* Prepare the void type. If present, index 0 is pointed at it: otherwise, we + make one in the ctf_void_type member and point index 0 at that. Because this + is index 0, it is not written out by serialization (which always starts at + index 1): because it is type 0, it is the type expected by BTF consumers: + because it is a real, queryable type, CTF consumers will get a proper type + back that they can query the properties of. + + As an initialization function, this returns a positive error code, or + zero. */ + +static int +init_void (ctf_dict_t *fp) +{ + ctf_id_t void_type; + ctf_type_t *void_tp; + + void_type = ctf_dynhash_lookup_type (ctf_name_table (fp, CTF_K_INTEGER), "void"); + + if (void_type == 0) + { + uint32_t *vlen; + + if ((void_tp = calloc (1, sizeof (ctf_type_t) + sizeof (uint32_t))) == NULL) + return ENOMEM; + vlen = (uint32_t *) (void_tp + 1); + + void_tp->ctt_name = ctf_str_add (fp, "void"); + void_tp->ctt_info = CTF_TYPE_INFO (CTF_K_INTEGER, 0, 0); + void_tp->ctt_size = 4; /* (bytes) */ + *vlen = CTF_INT_DATA (CTF_INT_SIGNED, 0, 0); + + fp->ctf_void_type = void_tp; + } + else + { + ctf_dict_t *tmp = fp; + + void_tp = (ctf_type_t *) ctf_lookup_by_id (&tmp, void_type, NULL); + assert (void_tp != NULL); + } + + fp->ctf_txlate[0] = void_tp; + + return 0; +} + /* Endianness-flipping routines. We flip everything, mindlessly, even 1-byte entities, so that future @@ -2392,6 +2431,7 @@ ctf_dict_close (ctf_dict_t *fp) free (err); } + free (fp->ctf_void_type); free (fp->ctf_sxlate); free (fp->ctf_txlate); free (fp->ctf_ptrtab); @@ -2530,6 +2570,7 @@ ctf_import_internal (ctf_dict_t *fp, ctf_dict_t *pfp, int unreffed) const char *old_parent_name = fp->ctf_parent_name; int old_unreffed = fp->ctf_parent_unreffed; int is_btf = 0; + size_t expected_prov_strings = 0; if (pfp == NULL || pfp == fp->ctf_parent) return 0; @@ -2586,16 +2627,22 @@ ctf_import_internal (ctf_dict_t *fp, ctf_dict_t *pfp, int unreffed) return (ctf_set_errno (fp, EINVAL)); } fp->ctf_header->cth_parent_ntypes = pfp->ctf_typemax; + + /* We expect one provisional string in this new dict, for the name of + the (non-reffed, non-written-out) void type. */ + expected_prov_strings++; } } - /* We might in time be able to lift this restriction, but it is unlikely to be - something anyone would want to do, so let's not bother for now. */ + /* No importing dicts with provisional strings in (except for the void one + added to all new dicts). We might in time be able to lift this + restriction, but it is unlikely to be something anyone would want to do, so + let's not bother for now. */ - if (ctf_dynhash_elements (fp->ctf_prov_strtab) != 0) + if (ctf_dynhash_elements (fp->ctf_prov_strtab) != expected_prov_strings) { ctf_err_warn (fp, 0, EINVAL, - _("ctf_import: child dict already has %zi bytes of strings, cannot import"), + _("ctf_import: child dict already has %zi strings, cannot import"), ctf_dynhash_elements (fp->ctf_prov_strtab)); return (ctf_set_errno (fp, EINVAL)); } diff --git a/libctf/ctf-serialize.c b/libctf/ctf-serialize.c index 60a6332..9825220 100644 --- a/libctf/ctf-serialize.c +++ b/libctf/ctf-serialize.c @@ -1248,8 +1248,9 @@ ctf_emit_type_sect (ctf_dict_t *fp, unsigned char **tptr) } #ifdef ENABLE_LIBCTF_HASH_DEBUGGING - ctf_dprintf ("%p: provisional ID assignment: %lx -> %lx\n", (void *) fp, - dtd->dtd_type, id); + if (dtd->dtd_type != id) + ctf_dprintf ("%p: provisional ID assignment: %lx -> %lx\n", (void *) fp, + dtd->dtd_type, id); #endif t += dtd->dtd_vlen_size; diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c index 3ef897f..b42d047 100644 --- a/libctf/ctf-types.c +++ b/libctf/ctf-types.c @@ -618,7 +618,7 @@ ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden) if (i->ctn_type > fp->ctf_stypes) tp = ctf_dtd_lookup (fp, ctf_index_to_type (fp, i->ctn_type))->dtd_data; else - tp = (ctf_type_t *)((uintptr_t) fp->ctf_buf + fp->ctf_txlate[i->ctn_type]); + tp = fp->ctf_txlate[i->ctn_type]; if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info))) { diff --git a/libctf/testsuite/libctf-lookup/by-kind/array.lk b/libctf/testsuite/libctf-lookup/by-kind/array.lk index 49e1280..7263af2 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/array.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/array.lk @@ -11,5 +11,5 @@ Types: 0x1: \(kind 1\) int .* 0x2: \(kind 1\) long unsigned int .* 0x3: \(kind 3\) int \[16\] .* -0x4: \(kind 14\) foo .* +0x4: \(kind 14\) int foo .* 0x5: \(kind 15\) DATASEC \(".bss"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/const.lk b/libctf/testsuite/libctf-lookup/by-kind/const.lk index ff0adfa..a7fe4fe 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/const.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/const.lk @@ -10,5 +10,5 @@ Types: 0x1: \(kind 1\) int .* 0x2: \(kind 10\) const int .* -0x3: \(kind 14\) foo .* +0x3: \(kind 14\) const int foo .* 0x4: \(kind 15\) DATASEC \(".rodata"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/datasec.lk b/libctf/testsuite/libctf-lookup/by-kind/datasec.lk index 86a6442..3014837 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/datasec.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/datasec.lk @@ -9,6 +9,6 @@ Section \.BAR: Types: 0x1: \(kind 1\) int .* -0x2: \(kind 14\) foo .* +0x2: \(kind 14\) int foo .* 0x3: \(kind 15\) DATASEC \(".BAR"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/decl-tag.lk b/libctf/testsuite/libctf-lookup/by-kind/decl-tag.lk index 3dbae5a..18c430a 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/decl-tag.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/decl-tag.lk @@ -15,9 +15,9 @@ Types: \[0x8\] b: ID 0x3: \(kind 1\) char .* 0x3: \(kind 1\) char .* #... -0x[45]: \(kind 14\) bar .* +0x[45]: \(kind 14\) struct bar .* #... -0x[56]: \(kind 14\) foo .* -0x[67]: \(kind 17\) btf_decl_tag \("dtag"\) .* -> 0x[56]: \(kind 14\) foo .* -0x[78]: \(kind 17\) btf_decl_tag \("dtag2"\) .* -> 0x2: \(kind 4\) struct .* +0x[56]: \(kind 14\) int foo .* +0x[67]: \(kind 17\) int foo btf_decl_tag \("dtag"\) .* -> 0x[56]: \(kind 14\) int foo .* +0x[78]: \(kind 17\) struct btf_decl_tag \("dtag2"\) .* -> 0x2: \(kind 4\) struct .* #... diff --git a/libctf/testsuite/libctf-lookup/by-kind/forward.lk b/libctf/testsuite/libctf-lookup/by-kind/forward.lk index e66396e..0cf3b03 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/forward.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/forward.lk @@ -10,5 +10,5 @@ Types: 0x1: \(kind 7\) struct foo 0x2: \(kind 2\) struct foo \* .* -> 0x1: \(kind 7\) struct foo -0x3: \(kind 14\) bar .* -> 0x2: \(kind 2\) struct foo \* .* -> 0x1: \(kind 7\) struct foo +0x3: \(kind 14\) struct foo bar .* -> 0x2: \(kind 2\) struct foo \* .* -> 0x1: \(kind 7\) struct foo 0x4: \(kind 15\) DATASEC \(".bss"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/integer.lk b/libctf/testsuite/libctf-lookup/by-kind/integer.lk index 09eb345..5fa7ce6 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/integer.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/integer.lk @@ -9,5 +9,5 @@ Section \.bss: Types: 0x1: \(kind 1\) int .* -0x2: \(kind 14\) foo .* +0x2: \(kind 14\) int foo .* 0x3: \(kind 15\) DATASEC \(".bss"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/pointer.lk b/libctf/testsuite/libctf-lookup/by-kind/pointer.lk index dba2e40..a60ba49 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/pointer.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/pointer.lk @@ -10,5 +10,5 @@ Types: 0x1: \(kind 1\) int .* 0x2: \(kind 2\) int \* .* -0x3: \(kind 14\) foo .* +0x3: \(kind 14\) int foo .* 0x4: \(kind 15\) DATASEC \(".bss"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/restrict.lk b/libctf/testsuite/libctf-lookup/by-kind/restrict.lk index 0783778..f6f27b0 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/restrict.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/restrict.lk @@ -11,5 +11,5 @@ Types: 0x1: \(kind 1\) int .* 0x2: \(kind 2\) int \* .* 0x3: \(kind 11\) int \*restrict .* -0x4: \(kind 14\) foo .* +0x4: \(kind 14\) int foo .* 0x5: \(kind 15\) DATASEC \(".bss"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/struct.lk b/libctf/testsuite/libctf-lookup/by-kind/struct.lk index 2fd0581..b5fc264 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/struct.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/struct.lk @@ -13,5 +13,5 @@ Types: \[0x4\] b:4: .* int .* \[0x[0-9a-f]*\] c: .* int .* 0x2: \(kind 1\) int .* -0x3: \(kind 14\) foo .* +0x3: \(kind 14\) struct foo .* 0x4: \(kind 15\) DATASEC \(".bss"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/union.lk b/libctf/testsuite/libctf-lookup/by-kind/union.lk index b37477c..b2d97f7 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/union.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/union.lk @@ -13,5 +13,5 @@ Types: \[0x0\] b:4: .* int .* \[0x0\] c: .* int .* 0x2: \(kind 1\) int .* -0x3: \(kind 14\) foo .* +0x3: \(kind 14\) union bar foo .* 0x4: \(kind 15\) DATASEC \(".bss"\) diff --git a/libctf/testsuite/libctf-lookup/by-kind/volatile.lk b/libctf/testsuite/libctf-lookup/by-kind/volatile.lk index c4af120..fbd5faa 100644 --- a/libctf/testsuite/libctf-lookup/by-kind/volatile.lk +++ b/libctf/testsuite/libctf-lookup/by-kind/volatile.lk @@ -10,5 +10,5 @@ Types: 0x1: \(kind 1\) int .* 0x2: \(kind 9\) volatile int .* -0x3: \(kind 14\) foo .* +0x3: \(kind 14\) volatile int foo .* 0x4: \(kind 15\) DATASEC \(".bss"\) |