gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / libctf / ctf-hash.c
index adfe93e5c09a69c5d8cbf164f73e2d59598d1569..71c1f8e4e21e2229de4dcc163bd9d71c0ad25fea 100644 (file)
@@ -1,5 +1,5 @@
 /* Interface to hashtable implementations.
-   Copyright (C) 2006-2019 Free Software Foundation, Inc.
+   Copyright (C) 2006-2020 Free Software Foundation, Inc.
 
    This file is part of libctf.
 
@@ -82,6 +82,28 @@ ctf_hash_eq_string (const void *a, const void *b)
   return !strcmp((const char *) hep_a->key, (const char *) hep_b->key);
 }
 
+/* Hash a type_mapping_key.  */
+unsigned int
+ctf_hash_type_mapping_key (const void *ptr)
+{
+  ctf_helem_t *hep = (ctf_helem_t *) ptr;
+  ctf_link_type_mapping_key_t *k = (ctf_link_type_mapping_key_t *) hep->key;
+
+  return htab_hash_pointer (k->cltm_fp) + 59 * htab_hash_pointer ((void *) k->cltm_idx);
+}
+
+int
+ctf_hash_eq_type_mapping_key (const void *a, const void *b)
+{
+  ctf_helem_t *hep_a = (ctf_helem_t *) a;
+  ctf_helem_t *hep_b = (ctf_helem_t *) b;
+  ctf_link_type_mapping_key_t *key_a = (ctf_link_type_mapping_key_t *) hep_a->key;
+  ctf_link_type_mapping_key_t *key_b = (ctf_link_type_mapping_key_t *) hep_b->key;
+
+  return (key_a->cltm_fp == key_b->cltm_fp)
+    && (key_a->cltm_idx == key_b->cltm_idx);
+}
+
 /* The dynhash, used for hashes whose size is not known at creation time. */
 
 /* Free a single ctf_helem.  */
@@ -130,7 +152,9 @@ ctf_hashtab_lookup (struct htab *htab, const void *key, enum insert_option inser
 }
 
 static ctf_helem_t *
-ctf_hashtab_insert (struct htab *htab, void *key, void *value)
+ctf_hashtab_insert (struct htab *htab, void *key, void *value,
+                   ctf_hash_free_fun key_free,
+                   ctf_hash_free_fun value_free)
 {
   ctf_helem_t **slot;
 
@@ -147,8 +171,15 @@ ctf_hashtab_insert (struct htab *htab, void *key, void *value)
       *slot = malloc (sizeof (ctf_helem_t));
       if (!*slot)
        return NULL;
-      (*slot)->key = key;
     }
+  else
+    {
+      if (key_free)
+         key_free ((*slot)->key);
+      if (value_free)
+         value_free ((*slot)->value);
+    }
+  (*slot)->key = key;
   (*slot)->value = value;
   return *slot;
 }
@@ -158,13 +189,14 @@ ctf_dynhash_insert (ctf_dynhash_t *hp, void *key, void *value)
 {
   ctf_helem_t *slot;
 
-  slot = ctf_hashtab_insert (hp->htab, key, value);
+  slot = ctf_hashtab_insert (hp->htab, key, value,
+                            hp->key_free, hp->value_free);
 
   if (!slot)
     return errno;
 
   /* We need to keep the key_free and value_free around in each item because the
-     del function has no visiblity into the hash as a whole, only into the
+     del function has no visibility into the hash as a whole, only into the
      individual items.  */
 
   slot->key_free = hp->key_free;
@@ -176,7 +208,14 @@ ctf_dynhash_insert (ctf_dynhash_t *hp, void *key, void *value)
 void
 ctf_dynhash_remove (ctf_dynhash_t *hp, const void *key)
 {
-  htab_remove_elt (hp->htab, (void *) key);
+  ctf_helem_t hep = { (void *) key, NULL, NULL, NULL };
+  htab_remove_elt (hp->htab, &hep);
+}
+
+void
+ctf_dynhash_empty (ctf_dynhash_t *hp)
+{
+  htab_empty (hp->htab);
 }
 
 void *
@@ -192,6 +231,55 @@ ctf_dynhash_lookup (ctf_dynhash_t *hp, const void *key)
   return NULL;
 }
 
+typedef struct ctf_traverse_cb_arg
+{
+  ctf_hash_iter_f fun;
+  void *arg;
+} ctf_traverse_cb_arg_t;
+
+static int
+ctf_hashtab_traverse (void **slot, void *arg_)
+{
+  ctf_helem_t *helem = *((ctf_helem_t **) slot);
+  ctf_traverse_cb_arg_t *arg = (ctf_traverse_cb_arg_t *) arg_;
+
+  arg->fun (helem->key, helem->value, arg->arg);
+  return 1;
+}
+
+void
+ctf_dynhash_iter (ctf_dynhash_t *hp, ctf_hash_iter_f fun, void *arg_)
+{
+  ctf_traverse_cb_arg_t arg = { fun, arg_ };
+  htab_traverse (hp->htab, ctf_hashtab_traverse, &arg);
+}
+
+typedef struct ctf_traverse_remove_cb_arg
+{
+  struct htab *htab;
+  ctf_hash_iter_remove_f fun;
+  void *arg;
+} ctf_traverse_remove_cb_arg_t;
+
+static int
+ctf_hashtab_traverse_remove (void **slot, void *arg_)
+{
+  ctf_helem_t *helem = *((ctf_helem_t **) slot);
+  ctf_traverse_remove_cb_arg_t *arg = (ctf_traverse_remove_cb_arg_t *) arg_;
+
+  if (arg->fun (helem->key, helem->value, arg->arg))
+    htab_clear_slot (arg->htab, slot);
+  return 1;
+}
+
+void
+ctf_dynhash_iter_remove (ctf_dynhash_t *hp, ctf_hash_iter_remove_f fun,
+                         void *arg_)
+{
+  ctf_traverse_remove_cb_arg_t arg = { hp->htab, fun, arg_ };
+  htab_traverse (hp->htab, ctf_hashtab_traverse_remove, &arg);
+}
+
 void
 ctf_dynhash_destroy (ctf_dynhash_t *hp)
 {
@@ -221,23 +309,25 @@ int
 ctf_hash_insert_type (ctf_hash_t *hp, ctf_file_t *fp, uint32_t type,
                      uint32_t name)
 {
-  ctf_strs_t *ctsp = &fp->ctf_str[CTF_NAME_STID (name)];
-  const char *str = ctsp->cts_strs + CTF_NAME_OFFSET (name);
+  const char *str = ctf_strraw (fp, name);
 
   if (type == 0)
     return EINVAL;
 
-  if (ctsp->cts_strs == NULL)
+  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 (ctsp->cts_len <= CTF_NAME_OFFSET (name))
+  if (str == NULL)
     return ECTF_BADNAME;
 
   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)
+                         (void *) (ptrdiff_t) type, NULL, NULL) != NULL)
     return 0;
   return errno;
 }
This page took 0.029701 seconds and 4 git commands to generate.