public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] libctf: remove static/dynamic name lookup distinction
@ 2024-04-19 15:51 Nick Alcock
  0 siblings, 0 replies; only message in thread
From: Nick Alcock @ 2024-04-19 15:51 UTC (permalink / raw)
  To: binutils-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=54a0219150d9dd2b0034e9682072900d4ec403b3

commit 54a0219150d9dd2b0034e9682072900d4ec403b3
Author: Nick Alcock <nick.alcock@oracle.com>
Date:   Mon Dec 18 17:47:48 2023 +0000

    libctf: remove static/dynamic name lookup distinction
    
    libctf internally maintains a set of hash tables for type name lookups,
    one for each valid C type namespace (struct, union, enum, and everything
    else).
    
    Or, rather, it maintains *two* sets of hash tables: one, a ctf_hash *,
    is meant for lookups in ctf_(buf)open()ed dicts with fixed content; the
    other, a ctf_dynhash *, is meant for lookups in ctf_create()d dicts.
    
    This distinction was somewhat valuable in the far pre-binutils past when
    two different hashtable implementations were used (one expanding, the
    other fixed-size), but those days are long gone: the hash table
    implementations are almost identical, both wrappers around the libiberty
    hashtab. The ctf_dynhash has many more capabilities than the ctf_hash
    (iteration, deletion, etc etc) and has no downsides other than starting
    at a fixed, arbitrary small size.
    
    That limitation is easy to lift (via a new ctf_dynhash_create_sized()),
    following which we can throw away nearly all the ctf_hash
    implementation, and all the code to choose between readable and writable
    hashtabs; the few convenience functions that are still useful (for
    insertion of name -> type mappings) can also be generalized a bit so
    that the extra string verification they do is potentially available to
    other string lookups as well.
    
    (libctf still has two hashtable implementations, ctf_dynhash, above,
    and ctf_dynset, which is a key-only hashtab that can avoid a great many
    malloc()s, used for high-volume applications in the deduplicator.)
    
    libctf/
    
            * ctf-create.c (ctf_create): Eliminate ctn_writable.
            (ctf_dtd_insert): Likewise.
            (ctf_dtd_delete): Likewise.
            (ctf_rollback): Likewise.
            (ctf_name_table): Eliminate ctf_names_t.
            * ctf-hash.c (ctf_dynhash_create): Comment update.
            Reimplement in terms of...
            (ctf_dynhash_create_sized): ... this new function.
            (ctf_hash_create): Remove.
            (ctf_hash_size): Remove.
            (ctf_hash_define_type): Remove.
            (ctf_hash_destroy): Remove.
            (ctf_hash_lookup_type): Rename to...
            (ctf_dynhash_lookup_type): ... this.
            (ctf_hash_insert_type): Rename to...
            (ctf_dynhash_insert_type): ... this, moving validation to...
            * ctf-string.c (ctf_strptr_validate): ... this new function.
            * ctf-impl.h (struct ctf_names): Extirpate.
            (struct ctf_lookup.ctl_hash): Now a ctf_dynhash_t.
            (struct ctf_dict): All ctf_names_t fields are now ctf_dynhash_t.
            (ctf_name_table): Now returns a ctf_dynhash_t.
            (ctf_lookup_by_rawhash): Remove.
            (ctf_hash_create): Likewise.
            (ctf_hash_insert_type): Likewise.
            (ctf_hash_define_type): Likewise.
            (ctf_hash_lookup_type): Likewise.
            (ctf_hash_size): Likewise.
            (ctf_hash_destroy): Likewise.
            (ctf_dynhash_create_sized): New.
            (ctf_dynhash_insert_type): New.
            (ctf_dynhash_lookup_type): New.
            (ctf_strptr_validate): New.
            * ctf-lookup.c (ctf_lookup_by_name_internal): Adapt.
            * ctf-open.c (init_types): Adapt.
            (ctf_set_ctl_hashes): Adapt.
            (ctf_dict_close): Adapt.
            * ctf-serialize.c (ctf_serialize): Adapt.
            * ctf-types.c (ctf_lookup_by_rawhash): Remove.

Diff:
---
 libctf/ctf-create.c    |  26 +++++-----
 libctf/ctf-hash.c      | 106 +++++++++++++-------------------------
 libctf/ctf-impl.h      |  34 +++++-------
 libctf/ctf-lookup.c    |   5 +-
 libctf/ctf-open.c      | 137 +++++++++++++++++++++++--------------------------
 libctf/ctf-serialize.c |   8 +--
 libctf/ctf-string.c    |  24 +++++++++
 libctf/ctf-types.c     |  18 +------
 8 files changed, 157 insertions(+), 201 deletions(-)

diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c
index 21fbad714a9..240f3dad9ff 100644
--- a/libctf/ctf-create.c
+++ b/libctf/ctf-create.c
@@ -154,10 +154,10 @@ ctf_create (int *errp)
   if ((fp = ctf_bufopen_internal (&cts, NULL, NULL, NULL, 1, errp)) == NULL)
     goto err_dv;
 
-  fp->ctf_structs.ctn_writable = structs;
-  fp->ctf_unions.ctn_writable = unions;
-  fp->ctf_enums.ctn_writable = enums;
-  fp->ctf_names.ctn_writable = names;
+  fp->ctf_structs = structs;
+  fp->ctf_unions = unions;
+  fp->ctf_enums = enums;
+  fp->ctf_names = names;
   fp->ctf_objthash = objthash;
   fp->ctf_funchash = funchash;
   fp->ctf_dthash = dthash;
@@ -203,19 +203,19 @@ ctf_update (ctf_dict_t *fp)
   return 0;
 }
 
-ctf_names_t *
+ctf_dynhash_t *
 ctf_name_table (ctf_dict_t *fp, int kind)
 {
   switch (kind)
     {
     case CTF_K_STRUCT:
-      return &fp->ctf_structs;
+      return fp->ctf_structs;
     case CTF_K_UNION:
-      return &fp->ctf_unions;
+      return fp->ctf_unions;
     case CTF_K_ENUM:
-      return &fp->ctf_enums;
+      return fp->ctf_enums;
     default:
-      return &fp->ctf_names;
+      return fp->ctf_names;
     }
 }
 
@@ -230,7 +230,7 @@ ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
   if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
       && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
     {
-      if (ctf_dynhash_insert (ctf_name_table (fp, kind)->ctn_writable,
+      if (ctf_dynhash_insert (ctf_name_table (fp, kind),
 			      (char *) name, (void *) (uintptr_t)
 			      dtd->dtd_type) < 0)
 	{
@@ -287,8 +287,7 @@ ctf_dtd_delete (ctf_dict_t *fp, ctf_dtdef_t *dtd)
       && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
       && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
     {
-      ctf_dynhash_remove (ctf_name_table (fp, name_kind)->ctn_writable,
-			  name);
+      ctf_dynhash_remove (ctf_name_table (fp, name_kind), name);
       ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
     }
 
@@ -410,8 +409,7 @@ ctf_rollback (ctf_dict_t *fp, ctf_snapshot_id_t id)
 	  && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL
 	  && LCTF_INFO_ISROOT (fp, dtd->dtd_data.ctt_info))
 	{
-	  ctf_dynhash_remove (ctf_name_table (fp, kind)->ctn_writable,
-			      name);
+	  ctf_dynhash_remove (ctf_name_table (fp, kind), name);
 	  ctf_str_remove_ref (fp, name, &dtd->dtd_data.ctt_name);
 	}
 
diff --git a/libctf/ctf-hash.c b/libctf/ctf-hash.c
index 1bc539e3617..f8032ae4d86 100644
--- a/libctf/ctf-hash.c
+++ b/libctf/ctf-hash.c
@@ -22,25 +22,22 @@
 #include "libiberty.h"
 #include "hashtab.h"
 
-/* We have three hashtable implementations:
-
-   - ctf_hash_* is an interface to a fixed-size hash from const char * ->
-     ctf_id_t with number of elements specified at creation time, that should
-     support addition of items but need not support removal.
+/* We have two hashtable implementations:
 
    - ctf_dynhash_* is an interface to a dynamically-expanding hash with
-     unknown size that should support addition of large numbers of items, and
-     removal as well, and is used only at type-insertion time and during
-     linking.
+     unknown size that should support addition of large numbers of items,
+     and removal as well, and is used only at type-insertion time and during
+     linking.  It can be constructed with an expected initial number of
+     elements, but need not be.
 
    - ctf_dynset_* is an interface to a dynamically-expanding hash that contains
      only keys: no values.
 
    These can be implemented by the same underlying hashmap if you wish.  */
 
-/* The helem is used for general key/value mappings in both the ctf_hash and
-   ctf_dynhash: the owner may not have space allocated for it, and will be
-   garbage (not NULL!) in that case.  */
+/* The helem is used for general key/value mappings in the ctf_dynhash: the
+   owner may not have space allocated for it, and will be garbage (not
+   NULL!) in that case.  */
 
 typedef struct ctf_helem
 {
@@ -157,8 +154,9 @@ ctf_dynhash_item_free (void *item)
 }
 
 ctf_dynhash_t *
-ctf_dynhash_create (ctf_hash_fun hash_fun, ctf_hash_eq_fun eq_fun,
-                    ctf_hash_free_fun key_free, ctf_hash_free_fun value_free)
+ctf_dynhash_create_sized (unsigned long nelems, ctf_hash_fun hash_fun,
+			  ctf_hash_eq_fun eq_fun, ctf_hash_free_fun key_free,
+			  ctf_hash_free_fun value_free)
 {
   ctf_dynhash_t *dynhash;
   htab_del del = ctf_dynhash_item_free;
@@ -173,8 +171,7 @@ ctf_dynhash_create (ctf_hash_fun hash_fun, ctf_hash_eq_fun eq_fun,
   if (key_free == NULL && value_free == NULL)
     del = free;
 
-  /* 7 is arbitrary and untested for now.  */
-  if ((dynhash->htab = htab_create_alloc (7, (htab_hash) hash_fun, eq_fun,
+  if ((dynhash->htab = htab_create_alloc (nelems, (htab_hash) hash_fun, eq_fun,
 					  del, xcalloc, free)) == NULL)
     {
       free (dynhash);
@@ -190,6 +187,15 @@ ctf_dynhash_create (ctf_hash_fun hash_fun, ctf_hash_eq_fun eq_fun,
   return dynhash;
 }
 
+ctf_dynhash_t *
+ctf_dynhash_create (ctf_hash_fun hash_fun, ctf_hash_eq_fun eq_fun,
+		    ctf_hash_free_fun key_free, ctf_hash_free_fun value_free)
+{
+  /* 7 is arbitrary and not benchmarked yet.  */
+
+  return ctf_dynhash_create_sized (7, hash_fun, eq_fun, key_free, value_free);
+}
+
 static ctf_helem_t **
 ctf_hashtab_lookup (struct htab *htab, const void *key, enum insert_option insert)
 {
@@ -767,80 +773,38 @@ ctf_dynset_next (ctf_dynset_t *hp, ctf_next_t **it, void **key)
   return ECTF_NEXT_END;
 }
 
-/* ctf_hash, used for fixed-size maps from const char * -> ctf_id_t without
-   removal.  This is a straight cast of a hashtab.  */
-
-ctf_hash_t *
-ctf_hash_create (unsigned long nelems, ctf_hash_fun hash_fun,
-		 ctf_hash_eq_fun eq_fun)
-{
-  return (ctf_hash_t *) htab_create_alloc (nelems, (htab_hash) hash_fun,
-					   eq_fun, free, xcalloc, free);
-}
-
-uint32_t
-ctf_hash_size (const ctf_hash_t *hp)
-{
-  return htab_elements ((struct htab *) hp);
-}
+/* Helper functions for insertion/removal of types.  */
 
 int
-ctf_hash_insert_type (ctf_hash_t *hp, ctf_dict_t *fp, uint32_t type,
-		      uint32_t name)
+ctf_dynhash_insert_type (ctf_dict_t *fp, ctf_dynhash_t *hp, uint32_t type,
+			 uint32_t name)
 {
-  const char *str = ctf_strraw (fp, name);
+  const char *str;
+  int err;
 
   if (type == 0)
     return EINVAL;
 
-  if (str == NULL
-      && CTF_NAME_STID (name) == CTF_STRTAB_1
-      && fp->ctf_syn_ext_strtab == NULL
-      && fp->ctf_str[CTF_NAME_STID (name)].cts_strs == NULL)
-    return ECTF_STRTAB;
-
-  if (str == NULL)
-    return ECTF_BADNAME;
+  if ((str = ctf_strptr_validate (fp, name)) == NULL)
+    return ctf_errno (fp);
 
   if (str[0] == '\0')
     return 0;		   /* Just ignore empty strings on behalf of caller.  */
 
-  if (ctf_hashtab_insert ((struct htab *) hp, (char *) str,
-			  (void *) (ptrdiff_t) type, NULL, NULL) != NULL)
+  if ((err = ctf_dynhash_insert (hp, (char *) str,
+				 (void *) (ptrdiff_t) type)) == 0)
     return 0;
-  return errno;
-}
-
-/* if the key is already in the hash, override the previous definition with
-   this new official definition. If the key is not present, then call
-   ctf_hash_insert_type and hash it in.  */
-int
-ctf_hash_define_type (ctf_hash_t *hp, ctf_dict_t *fp, uint32_t type,
-                      uint32_t name)
-{
-  /* This matches the semantics of ctf_hash_insert_type in this
-     implementation anyway.  */
 
-  return ctf_hash_insert_type (hp, fp, type, name);
+  return err;
 }
 
 ctf_id_t
-ctf_hash_lookup_type (ctf_hash_t *hp, ctf_dict_t *fp __attribute__ ((__unused__)),
-		      const char *key)
+ctf_dynhash_lookup_type (ctf_dynhash_t *hp, const char *key)
 {
-  ctf_helem_t **slot;
+  void *value;
 
-  slot = ctf_hashtab_lookup ((struct htab *) hp, key, NO_INSERT);
-
-  if (slot)
-    return (ctf_id_t) (uintptr_t) ((*slot)->value);
+  if (ctf_dynhash_lookup_kv (hp, key, NULL, &value))
+    return (ctf_id_t) (uintptr_t) value;
 
   return 0;
 }
-
-void
-ctf_hash_destroy (ctf_hash_t *hp)
-{
-  if (hp != NULL)
-    htab_delete ((struct htab *) hp);
-}
diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h
index 0fe9c20127a..8cbb2ae8242 100644
--- a/libctf/ctf-impl.h
+++ b/libctf/ctf-impl.h
@@ -123,17 +123,11 @@ typedef struct ctf_dmodel
   size_t ctd_long;		/* Size of long in bytes.  */
 } ctf_dmodel_t;
 
-typedef struct ctf_names
-{
-  ctf_hash_t *ctn_readonly;	/* Hash table when readonly.  */
-  ctf_dynhash_t *ctn_writable;	/* Hash table when writable.  */
-} ctf_names_t;
-
 typedef struct ctf_lookup
 {
   const char *ctl_prefix;	/* String prefix for this lookup.  */
   size_t ctl_len;		/* Length of prefix string in bytes.  */
-  ctf_names_t *ctl_hash;	/* Pointer to hash table for lookup.  */
+  ctf_dynhash_t *ctl_hash;	/* Pointer to hash table for lookup.  */
 } ctf_lookup_t;
 
 typedef struct ctf_dictops
@@ -382,10 +376,10 @@ struct ctf_dict
   ctf_dynhash_t *ctf_syn_ext_strtab; /* Maps ext-strtab offsets to names.  */
   void *ctf_data_mmapped;	    /* CTF data we mmapped, to free later.  */
   size_t ctf_data_mmapped_len;	    /* Length of CTF data we mmapped.  */
-  ctf_names_t ctf_structs;	    /* Hash table of struct types.  */
-  ctf_names_t ctf_unions;	    /* Hash table of union types.  */
-  ctf_names_t ctf_enums;	    /* Hash table of enum types.  */
-  ctf_names_t ctf_names;	    /* Hash table of remaining type names.  */
+  ctf_dynhash_t *ctf_structs;	    /* Hash table of struct types.  */
+  ctf_dynhash_t *ctf_unions;	    /* Hash table of union types.  */
+  ctf_dynhash_t *ctf_enums;	    /* Hash table of enum types.  */
+  ctf_dynhash_t *ctf_names;	    /* Hash table of remaining type names.  */
   ctf_lookup_t ctf_lookups[5];	    /* Pointers to nametabs for name lookup.  */
   ctf_strs_t ctf_str[2];	    /* Array of string table base and bounds.  */
   ctf_dynhash_t *ctf_str_atoms;	    /* Hash table of ctf_str_atoms_t.  */
@@ -597,10 +591,9 @@ struct ctf_next
 #define LCTF_DIRTY	0x0004	/* CTF dict has been modified.  */
 #define LCTF_LINKING	0x0008  /* CTF link is underway: respect ctf_link_flags.  */
 
-extern ctf_names_t *ctf_name_table (ctf_dict_t *, int);
+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);
 extern ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *, int, const char *);
-extern ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *, ctf_names_t *, const char *);
 extern void ctf_set_ctl_hashes (ctf_dict_t *);
 
 extern int ctf_symtab_skippable (ctf_link_sym_t *sym);
@@ -629,19 +622,19 @@ typedef int (*ctf_hash_iter_find_f) (void *key, void *value, void *arg);
 typedef int (*ctf_hash_sort_f) (const ctf_next_hkv_t *, const ctf_next_hkv_t *,
 				void *arg);
 
-extern ctf_hash_t *ctf_hash_create (unsigned long, ctf_hash_fun, ctf_hash_eq_fun);
-extern int ctf_hash_insert_type (ctf_hash_t *, ctf_dict_t *, uint32_t, uint32_t);
-extern int ctf_hash_define_type (ctf_hash_t *, ctf_dict_t *, uint32_t, uint32_t);
-extern ctf_id_t ctf_hash_lookup_type (ctf_hash_t *, ctf_dict_t *, const char *);
-extern uint32_t ctf_hash_size (const ctf_hash_t *);
-extern void ctf_hash_destroy (ctf_hash_t *);
-
 extern ctf_dynhash_t *ctf_dynhash_create (ctf_hash_fun, ctf_hash_eq_fun,
 					  ctf_hash_free_fun, ctf_hash_free_fun);
+extern ctf_dynhash_t *ctf_dynhash_create_sized (unsigned long, ctf_hash_fun,
+						ctf_hash_eq_fun,
+						ctf_hash_free_fun,
+						ctf_hash_free_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 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 *);
 extern void *ctf_dynhash_lookup (ctf_dynhash_t *, const void *);
 extern int ctf_dynhash_lookup_kv (ctf_dynhash_t *, const void *key,
 				  const void **orig_key, void **value);
@@ -720,6 +713,7 @@ extern const char *ctf_strptr (ctf_dict_t *, uint32_t);
 extern const char *ctf_strraw (ctf_dict_t *, uint32_t);
 extern const char *ctf_strraw_explicit (ctf_dict_t *, uint32_t,
 					ctf_strs_t *);
+extern const char *ctf_strptr_validate (ctf_dict_t *, uint32_t);
 extern int ctf_str_create_atoms (ctf_dict_t *);
 extern void ctf_str_free_atoms (ctf_dict_t *);
 extern uint32_t ctf_str_add (ctf_dict_t *, const char *);
diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c
index 9e736a8659c..b5d2637fe01 100644
--- a/libctf/ctf-lookup.c
+++ b/libctf/ctf-lookup.c
@@ -276,8 +276,9 @@ ctf_lookup_by_name_internal (ctf_dict_t *fp, ctf_dict_t *child,
 		    return ctf_set_typed_errno (fp, ENOMEM);
 		}
 
-	      if ((type = ctf_lookup_by_rawhash (fp, lp->ctl_hash,
-						 fp->ctf_tmp_typeslice)) == 0)
+	      if ((type = (ctf_id_t) (uintptr_t)
+		   ctf_dynhash_lookup (lp->ctl_hash,
+				       fp->ctf_tmp_typeslice)) == 0)
 		goto notype;
 
 	      break;
diff --git a/libctf/ctf-open.c b/libctf/ctf-open.c
index cf0cb54720d..2945228ff2a 100644
--- a/libctf/ctf-open.c
+++ b/libctf/ctf-open.c
@@ -740,33 +740,33 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
   /* Now that we've counted up the number of each type, we can allocate
      the hash tables, type translation table, and pointer table.  */
 
-  if ((fp->ctf_structs.ctn_readonly
-       = ctf_hash_create (pop[CTF_K_STRUCT], ctf_hash_string,
-			  ctf_hash_eq_string)) == NULL)
+  if ((fp->ctf_structs
+       = ctf_dynhash_create_sized (pop[CTF_K_STRUCT], ctf_hash_string,
+				   ctf_hash_eq_string, NULL, NULL)) == NULL)
     return ENOMEM;
 
-  if ((fp->ctf_unions.ctn_readonly
-       = ctf_hash_create (pop[CTF_K_UNION], ctf_hash_string,
-			  ctf_hash_eq_string)) == NULL)
+  if ((fp->ctf_unions
+       = ctf_dynhash_create_sized (pop[CTF_K_UNION], ctf_hash_string,
+				   ctf_hash_eq_string, NULL, NULL)) == NULL)
     return ENOMEM;
 
-  if ((fp->ctf_enums.ctn_readonly
-       = ctf_hash_create (pop[CTF_K_ENUM], ctf_hash_string,
-			  ctf_hash_eq_string)) == NULL)
+  if ((fp->ctf_enums
+       = ctf_dynhash_create_sized (pop[CTF_K_ENUM], ctf_hash_string,
+				   ctf_hash_eq_string, NULL, NULL)) == NULL)
     return ENOMEM;
 
-  if ((fp->ctf_names.ctn_readonly
-       = ctf_hash_create (pop[CTF_K_UNKNOWN] +
-			  pop[CTF_K_INTEGER] +
-			  pop[CTF_K_FLOAT] +
-			  pop[CTF_K_FUNCTION] +
-			  pop[CTF_K_TYPEDEF] +
-			  pop[CTF_K_POINTER] +
-			  pop[CTF_K_VOLATILE] +
-			  pop[CTF_K_CONST] +
-			  pop[CTF_K_RESTRICT],
-			  ctf_hash_string,
-			  ctf_hash_eq_string)) == NULL)
+  if ((fp->ctf_names
+       = ctf_dynhash_create_sized (pop[CTF_K_UNKNOWN] +
+				   pop[CTF_K_INTEGER] +
+				   pop[CTF_K_FLOAT] +
+				   pop[CTF_K_FUNCTION] +
+				   pop[CTF_K_TYPEDEF] +
+				   pop[CTF_K_POINTER] +
+				   pop[CTF_K_VOLATILE] +
+				   pop[CTF_K_CONST] +
+				   pop[CTF_K_RESTRICT],
+				   ctf_hash_string,
+				   ctf_hash_eq_string, NULL, NULL)) == NULL)
     return ENOMEM;
 
   fp->ctf_txlate = malloc (sizeof (uint32_t) * (fp->ctf_typemax + 1));
@@ -810,11 +810,10 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
 	     root-visible version so that we can be sure to find it when
 	     checking for conflicting definitions in ctf_add_type().  */
 
-	  if (((ctf_hash_lookup_type (fp->ctf_names.ctn_readonly,
-				      fp, name)) == 0)
+	  if (((ctf_dynhash_lookup_type (fp->ctf_names, name)) == 0)
 	      || isroot)
 	    {
-	      err = ctf_hash_define_type (fp->ctf_names.ctn_readonly, fp,
+	      err = ctf_dynhash_insert_type (fp, fp->ctf_names,
 					  LCTF_INDEX_TO_TYPE (fp, id, child),
 					  tp->ctt_name);
 	      if (err != 0)
@@ -832,9 +831,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
 	  if (!isroot)
 	    break;
 
-	  err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
-				      LCTF_INDEX_TO_TYPE (fp, id, child),
-				      tp->ctt_name);
+	  err = ctf_dynhash_insert_type (fp, fp->ctf_names,
+					 LCTF_INDEX_TO_TYPE (fp, id, child),
+					 tp->ctt_name);
 	  if (err != 0)
 	    return err;
 	  break;
@@ -846,9 +845,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
 	  if (!isroot)
 	    break;
 
-	  err = ctf_hash_define_type (fp->ctf_structs.ctn_readonly, fp,
-				      LCTF_INDEX_TO_TYPE (fp, id, child),
-				      tp->ctt_name);
+	  err = ctf_dynhash_insert_type (fp, fp->ctf_structs,
+					 LCTF_INDEX_TO_TYPE (fp, id, child),
+					 tp->ctt_name);
 
 	  if (err != 0)
 	    return err;
@@ -862,9 +861,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
 	  if (!isroot)
 	    break;
 
-	  err = ctf_hash_define_type (fp->ctf_unions.ctn_readonly, fp,
-				      LCTF_INDEX_TO_TYPE (fp, id, child),
-				      tp->ctt_name);
+	  err = ctf_dynhash_insert_type (fp, fp->ctf_unions,
+					 LCTF_INDEX_TO_TYPE (fp, id, child),
+					 tp->ctt_name);
 
 	  if (err != 0)
 	    return err;
@@ -874,9 +873,9 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
 	  if (!isroot)
 	    break;
 
-	  err = ctf_hash_define_type (fp->ctf_enums.ctn_readonly, fp,
-				      LCTF_INDEX_TO_TYPE (fp, id, child),
-				      tp->ctt_name);
+	  err = ctf_dynhash_insert_type (fp, fp->ctf_enums,
+					 LCTF_INDEX_TO_TYPE (fp, id, child),
+					 tp->ctt_name);
 
 	  if (err != 0)
 	    return err;
@@ -886,27 +885,26 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
 	  if (!isroot)
 	    break;
 
-	  err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
-				      LCTF_INDEX_TO_TYPE (fp, id, child),
-				      tp->ctt_name);
+	  err = ctf_dynhash_insert_type (fp, fp->ctf_names,
+					 LCTF_INDEX_TO_TYPE (fp, id, child),
+					 tp->ctt_name);
 	  if (err != 0)
 	    return err;
 	  break;
 
 	case CTF_K_FORWARD:
 	  {
-	    ctf_names_t *np = ctf_name_table (fp, tp->ctt_type);
+	    ctf_dynhash_t *h = ctf_name_table (fp, tp->ctt_type);
 
 	    if (!isroot)
 	      break;
 
 	    /* Only insert forward tags into the given hash if the type or tag
 	       name is not already present.  */
-	    if (ctf_hash_lookup_type (np->ctn_readonly, fp, name) == 0)
+	    if (ctf_dynhash_lookup_type (h, name) == 0)
 	      {
-		err = ctf_hash_insert_type (np->ctn_readonly, fp,
-					    LCTF_INDEX_TO_TYPE (fp, id, child),
-					    tp->ctt_name);
+		err = ctf_dynhash_insert_type (fp, h, LCTF_INDEX_TO_TYPE (fp, id, child),
+					       tp->ctt_name);
 		if (err != 0)
 		  return err;
 	      }
@@ -929,15 +927,15 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
 	  if (!isroot)
 	    break;
 
-	  err = ctf_hash_insert_type (fp->ctf_names.ctn_readonly, fp,
-				      LCTF_INDEX_TO_TYPE (fp, id, child),
-				      tp->ctt_name);
+	  err = ctf_dynhash_insert_type (fp, fp->ctf_names,
+					 LCTF_INDEX_TO_TYPE (fp, id, child),
+					 tp->ctt_name);
 	  if (err != 0)
 	    return err;
 	  break;
 	default:
 	  ctf_err_warn (fp, 0, ECTF_CORRUPT,
-			_("init_types(): unhandled CTF kind: %x"), kind);
+			_("init_static_types(): unhandled CTF kind: %x"), kind);
 	  return ECTF_CORRUPT;
 	}
 
@@ -946,14 +944,14 @@ init_types (ctf_dict_t *fp, ctf_header_t *cth)
     }
 
   ctf_dprintf ("%lu total types processed\n", fp->ctf_typemax);
-  ctf_dprintf ("%u enum names hashed\n",
-	       ctf_hash_size (fp->ctf_enums.ctn_readonly));
-  ctf_dprintf ("%u struct names hashed (%d long)\n",
-	       ctf_hash_size (fp->ctf_structs.ctn_readonly), nlstructs);
-  ctf_dprintf ("%u union names hashed (%d long)\n",
-	       ctf_hash_size (fp->ctf_unions.ctn_readonly), nlunions);
-  ctf_dprintf ("%u base type names hashed\n",
-	       ctf_hash_size (fp->ctf_names.ctn_readonly));
+  ctf_dprintf ("%zu enum names hashed\n",
+	       ctf_dynhash_elements (fp->ctf_enums));
+  ctf_dprintf ("%zu struct names hashed (%d long)\n",
+	       ctf_dynhash_elements (fp->ctf_structs), nlstructs);
+  ctf_dprintf ("%zu union names hashed (%d long)\n",
+	       ctf_dynhash_elements (fp->ctf_unions), nlunions);
+  ctf_dprintf ("%zu base type names hashed\n",
+	       ctf_dynhash_elements (fp->ctf_names));
 
   return 0;
 }
@@ -1235,16 +1233,16 @@ void ctf_set_ctl_hashes (ctf_dict_t *fp)
      array of type name prefixes and the corresponding ctf_hash to use.  */
   fp->ctf_lookups[0].ctl_prefix = "struct";
   fp->ctf_lookups[0].ctl_len = strlen (fp->ctf_lookups[0].ctl_prefix);
-  fp->ctf_lookups[0].ctl_hash = &fp->ctf_structs;
+  fp->ctf_lookups[0].ctl_hash = fp->ctf_structs;
   fp->ctf_lookups[1].ctl_prefix = "union";
   fp->ctf_lookups[1].ctl_len = strlen (fp->ctf_lookups[1].ctl_prefix);
-  fp->ctf_lookups[1].ctl_hash = &fp->ctf_unions;
+  fp->ctf_lookups[1].ctl_hash = fp->ctf_unions;
   fp->ctf_lookups[2].ctl_prefix = "enum";
   fp->ctf_lookups[2].ctl_len = strlen (fp->ctf_lookups[2].ctl_prefix);
-  fp->ctf_lookups[2].ctl_hash = &fp->ctf_enums;
+  fp->ctf_lookups[2].ctl_hash = fp->ctf_enums;
   fp->ctf_lookups[3].ctl_prefix = _CTF_NULLSTR;
   fp->ctf_lookups[3].ctl_len = strlen (fp->ctf_lookups[3].ctl_prefix);
-  fp->ctf_lookups[3].ctl_hash = &fp->ctf_names;
+  fp->ctf_lookups[3].ctl_hash = fp->ctf_names;
   fp->ctf_lookups[4].ctl_prefix = NULL;
   fp->ctf_lookups[4].ctl_len = 0;
   fp->ctf_lookups[4].ctl_hash = NULL;
@@ -1764,20 +1762,11 @@ ctf_dict_close (ctf_dict_t *fp)
       ctf_dtd_delete (fp, dtd);
     }
   ctf_dynhash_destroy (fp->ctf_dthash);
-  if (fp->ctf_flags & LCTF_RDWR)
-    {
-      ctf_dynhash_destroy (fp->ctf_structs.ctn_writable);
-      ctf_dynhash_destroy (fp->ctf_unions.ctn_writable);
-      ctf_dynhash_destroy (fp->ctf_enums.ctn_writable);
-      ctf_dynhash_destroy (fp->ctf_names.ctn_writable);
-    }
-  else
-    {
-      ctf_hash_destroy (fp->ctf_structs.ctn_readonly);
-      ctf_hash_destroy (fp->ctf_unions.ctn_readonly);
-      ctf_hash_destroy (fp->ctf_enums.ctn_readonly);
-      ctf_hash_destroy (fp->ctf_names.ctn_readonly);
-    }
+
+  ctf_dynhash_destroy (fp->ctf_structs);
+  ctf_dynhash_destroy (fp->ctf_unions);
+  ctf_dynhash_destroy (fp->ctf_enums);
+  ctf_dynhash_destroy (fp->ctf_names);
 
   for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL; dvd = nvd)
     {
diff --git a/libctf/ctf-serialize.c b/libctf/ctf-serialize.c
index 11cbe75601e..511c5116140 100644
--- a/libctf/ctf-serialize.c
+++ b/libctf/ctf-serialize.c
@@ -1203,10 +1203,10 @@ ctf_serialize (ctf_dict_t *fp)
   memset (fp->ctf_lookups, 0, sizeof (fp->ctf_lookups));
   memset (&fp->ctf_in_flight_dynsyms, 0, sizeof (fp->ctf_in_flight_dynsyms));
   memset (&fp->ctf_dedup, 0, sizeof (fp->ctf_dedup));
-  fp->ctf_structs.ctn_writable = NULL;
-  fp->ctf_unions.ctn_writable = NULL;
-  fp->ctf_enums.ctn_writable = NULL;
-  fp->ctf_names.ctn_writable = NULL;
+  fp->ctf_structs = NULL;
+  fp->ctf_unions = NULL;
+  fp->ctf_enums = NULL;
+  fp->ctf_names = NULL;
 
   memcpy (&ofp, fp, sizeof (ctf_dict_t));
   memcpy (fp, nfp, sizeof (ctf_dict_t));
diff --git a/libctf/ctf-string.c b/libctf/ctf-string.c
index 58ebcd9d785..a16cd3398b7 100644
--- a/libctf/ctf-string.c
+++ b/libctf/ctf-string.c
@@ -73,6 +73,30 @@ ctf_strptr (ctf_dict_t *fp, uint32_t name)
   return (s != NULL ? s : "(?)");
 }
 
+/* As above, but return info on what is wrong in more detail.
+   (Used for type lookups.) */
+
+const char *
+ctf_strptr_validate (ctf_dict_t *fp, uint32_t name)
+{
+  const char *str = ctf_strraw (fp, name);
+
+  if (str == NULL)
+    {
+      if (CTF_NAME_STID (name) == CTF_STRTAB_1
+	  && fp->ctf_syn_ext_strtab == NULL
+	  && fp->ctf_str[CTF_NAME_STID (name)].cts_strs == NULL)
+	{
+	  ctf_set_errno (fp, ECTF_STRTAB);
+	  return NULL;
+	}
+
+      ctf_set_errno (fp, ECTF_BADNAME);
+      return NULL;
+    }
+  return str;
+}
+
 /* Remove all refs to a given atom.  */
 static void
 ctf_str_purge_atom_refs (ctf_str_atom_t *atom)
diff --git a/libctf/ctf-types.c b/libctf/ctf-types.c
index 0eaafa13619..10bb6d1596a 100644
--- a/libctf/ctf-types.c
+++ b/libctf/ctf-types.c
@@ -635,22 +635,8 @@ ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
 
 ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
 {
-  return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
-}
-
-/* Look up a name in the given name table, in the appropriate hash given the
-   readability state of the dictionary.  The name is a raw, undecorated
-   identifier.  */
-
-ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
-{
-  ctf_id_t id;
-
-  if (fp->ctf_flags & LCTF_RDWR)
-    id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
-  else
-    id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
-  return id;
+  return (ctf_id_t) (uintptr_t)
+    ctf_dynhash_lookup (ctf_name_table (fp, kind), name);
 }
 
 /* Lookup the given type ID and return its name as a new dynamically-allocated

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-19 15:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-19 15:51 [binutils-gdb] libctf: remove static/dynamic name lookup distinction Nick Alcock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).