libctf: add mechanism to prohibit most operations without a strtab

We are about to add machinery that deduplicates a child dict's strtab
against its parent.  Obviously if you open such a dict but do not import its
parent, all strtab lookups must fail: so add an LCTF_NO_STR flag that is set
in that window and make most operations fail if it's not set.  (Two more
that will be set in future commits are serialization and string lookup
itself.)

Notably, not all symbol lookup is impossible in this window: you can still
look up by symbol index, as long as this dict is not using an indexed
strtypetab (which obviously requires string lookups to get the symbol name).

include/
	* ctf-api.h (_CTF_ERRORS) [ECTF_HASPARENT]: New.
        [ECTF_WRONGPARENT]: Likewise.
	(ECTF_NERR): Update.
        Update comments to note the new limitations on ctf_import et al.

libctf/
	* ctf-impl.h (LCTF_NO_STR): New.
	* ctf-create.c (ctf_rollback): Error out when LCTF_NO_STR.
	(ctf_add_generic): Likewise.
	(ctf_add_struct_sized): Likewise.
	(ctf_add_union_sized): Likewise.
	(ctf_add_enum): Likewise.
	(ctf_add_forward): Likewise.
	(ctf_add_unknown): Likewise.
	(ctf_add_enumerator): Likewise.
	(ctf_add_member_offset): Likewise.
	(ctf_add_variable): Likewise.
	(ctf_add_funcobjt_sym_forced): Likewise.
	(ctf_add_type): Likewise (on either dict).
	* ctf-dump.c (ctf_dump): Likewise.
	* ctf-lookup.c (ctf_lookup_by_name): Likewise.
	(ctf_lookup_variable): Likewise. Likewise.
	(ctf_lookup_enumerator): Likewise.
	(ctf_lookup_enumerator_next): Likewise.
	(ctf_symbol_next): Likewise.
	(ctf_lookup_by_sym_or_name): Likewise, if doing indexed lookups.
	* ctf-types.c (ctf_member_next): Likewise.
	(ctf_enum_next): Likewise.
	(ctf_type_aname): Likewise.
	(ctf_type_name_raw): Likewise.
	(ctf_type_compat): Likewise, for either dict.
	(ctf_member_info): Likewise.
	(ctf_enum_name): Likewise.
	(ctf_enum_value): Likewise.
	(ctf_type_rvisit): Likewise.
	(ctf_variable_next): Note that we don't need to test LCTF_NO_STR.
This commit is contained in:
Nick Alcock
2024-07-15 20:43:51 +01:00
parent 30cced0da6
commit 70d05ab0b2
6 changed files with 122 additions and 5 deletions

View File

@@ -105,6 +105,9 @@ ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
uint32_t max_vlen;
ctf_next_t *i = *it;
if (fp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (fp, ECTF_NOPARENT));
if (!i)
{
const ctf_type_t *tp;
@@ -274,6 +277,12 @@ ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
const char *name;
ctf_next_t *i = *it;
if (fp->ctf_flags & LCTF_NO_STR)
{
ctf_set_errno (fp, ECTF_NOPARENT);
return NULL;
}
if (!i)
{
const ctf_type_t *tp;
@@ -494,6 +503,9 @@ ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
ctf_next_t *i = *it;
ctf_id_t id;
/* (No need for a LCTF_NO_STR check: checking for a missing parent covers more
cases, and we need to do that anyway.) */
if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
return (ctf_set_typed_errno (fp, ECTF_NOPARENT));
@@ -649,6 +661,12 @@ ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
if (fp == NULL && type == CTF_ERR)
return NULL; /* Simplify caller code by permitting CTF_ERR. */
if (fp->ctf_flags & LCTF_NO_STR)
{
ctf_set_errno (fp, ECTF_NOPARENT);
return NULL;
}
ctf_decl_init (&cd);
ctf_decl_push (&cd, fp, type);
@@ -867,6 +885,12 @@ ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
{
const ctf_type_t *tp;
if (fp->ctf_flags & LCTF_NO_STR)
{
ctf_set_errno (fp, ECTF_NOPARENT);
return NULL;
}
if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
return NULL; /* errno is set for us. */
@@ -1268,6 +1292,12 @@ ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
uint32_t lkind, rkind;
int same_names = 0;
if (lfp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (lfp, ECTF_NOPARENT));
if (rfp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (rfp, ECTF_NOPARENT));
if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
return 1;
@@ -1368,6 +1398,9 @@ ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
ssize_t size, increment, vbytes;
uint32_t kind, n, i = 0;
if (fp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (fp, ECTF_NOPARENT));
if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
return -1; /* errno is set for us. */
@@ -1466,6 +1499,12 @@ ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
ssize_t increment;
uint32_t n;
if (fp->ctf_flags & LCTF_NO_STR)
{
ctf_set_errno (fp, ECTF_NOPARENT);
return NULL;
}
if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
return NULL; /* errno is set for us. */
@@ -1508,6 +1547,9 @@ ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int *valp)
ssize_t increment;
uint32_t n;
if (fp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (fp, ECTF_NOPARENT));
if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
return -1; /* errno is set for us. */
@@ -1634,6 +1676,9 @@ ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
int nonrepresentable = 0;
int rc;
if (fp->ctf_flags & LCTF_NO_STR)
return (ctf_set_errno (fp, ECTF_NOPARENT));
if ((type = ctf_type_resolve (fp, type)) == CTF_ERR) {
if (ctf_errno (fp) != ECTF_NONREPRESENTABLE)
return -1; /* errno is set for us. */