The hashcode handling code never accesses the underlying structure
'struct funcdesc_value', but only operates on pointer to pointers,
so we can use void** instead.

Also, pass in the functions to generate and compare a hash entry.
This is a minor functional change to inject function pointers
instead of using it inline functions.

This change is in preparation to support tls descriptors, which
require a different hash and compare function.

Signed-off-by: Chris Zankel <[email protected]>
Signed-off-by: Baruch Siach <[email protected]>
---
 ldso/include/inline-hashtab.h | 41 ++++++++++++++++++-----------------------
 ldso/ldso/fdpic/dl-inlines.h  | 19 +++++++++++++++++--
 2 files changed, 35 insertions(+), 25 deletions(-)

diff --git a/ldso/include/inline-hashtab.h b/ldso/include/inline-hashtab.h
index 5e82cc9..4a48120 100644
--- a/ldso/include/inline-hashtab.h
+++ b/ldso/include/inline-hashtab.h
@@ -71,7 +71,7 @@ higher_prime_number(unsigned long n)
 struct funcdesc_ht
 {
        /* Table itself */
-       struct funcdesc_value **entries;
+       void **entries;
 
        /* Current size (in entries) of the hash table */
        size_t size;
@@ -80,12 +80,6 @@ struct funcdesc_ht
        size_t n_elements;
 };
 
-static __always_inline int
-hash_pointer(const void *p)
-{
-       return (int) ((long)p >> 3);
-}
-
 static __always_inline struct funcdesc_ht *
 htab_create(void)
 {
@@ -95,7 +89,7 @@ htab_create(void)
        if (!ht)
                return NULL;
        ht->size = 3;
-       ent_size = sizeof(struct funcdesc_ht_value *) * ht->size;
+       ent_size = sizeof(void *) * ht->size;
        ht->entries = _dl_malloc(ent_size);
        if (!ht->entries)
                return NULL;
@@ -131,12 +125,12 @@ htab_delete(struct funcdesc_ht *htab)
  * This function also assumes there are no deleted entries in the table.
  * HASH is the hash value for the element to be inserted.
  */
-static __always_inline struct funcdesc_value **
+static __always_inline void **
 find_empty_slot_for_expand(struct funcdesc_ht *htab, int hash)
 {
        size_t size = htab->size;
        unsigned int index = hash % size;
-       struct funcdesc_value **slot = htab->entries + index;
+       void **slot = htab->entries + index;
        int hash2;
 
        if (!*slot)
@@ -164,12 +158,12 @@ find_empty_slot_for_expand(struct funcdesc_ht *htab, int 
hash)
  * expanded.  If all goes well, it will return a non-zero value.
  */
 static __always_inline int
-htab_expand(struct funcdesc_ht *htab)
+htab_expand(struct funcdesc_ht *htab, int (*hash_fn) (void *))
 {
-       struct funcdesc_value **oentries;
-       struct funcdesc_value **olimit;
-       struct funcdesc_value **p;
-       struct funcdesc_value **nentries;
+       void **oentries;
+       void **olimit;
+       void **p;
+       void **nentries;
        size_t nsize;
 
        oentries = htab->entries;
@@ -194,7 +188,7 @@ htab_expand(struct funcdesc_ht *htab)
        p = oentries;
        do {
                if (*p)
-                       *find_empty_slot_for_expand(htab, 
hash_pointer((*p)->entry_point)) = *p;
+                       *find_empty_slot_for_expand(htab, hash_fn(*p)) = *p;
                p++;
        } while (p < olimit);
 
@@ -223,19 +217,20 @@ htab_expand(struct funcdesc_ht *htab)
  * When inserting an entry, NULL may be returned if memory allocation
  * fails.
  */
-static __always_inline struct funcdesc_value **
-htab_find_slot(struct funcdesc_ht *htab, void *ptr, int insert)
+static __always_inline void **
+htab_find_slot(struct funcdesc_ht *htab, void *ptr, int insert,
+              int (*hash_fn)(void *), int (*eq_fn)(void *, void *))
 {
        unsigned int index;
        int hash, hash2;
        size_t size;
-       struct funcdesc_value **entry;
+       void **entry;
 
        if (htab->size * 3 <= htab->n_elements * 4 &&
-           htab_expand(htab) == 0)
+           htab_expand(htab, hash_fn) == 0)
                return NULL;
 
-       hash = hash_pointer(ptr);
+       hash = hash_fn(ptr);
 
        size = htab->size;
        index = hash % size;
@@ -243,7 +238,7 @@ htab_find_slot(struct funcdesc_ht *htab, void *ptr, int 
insert)
        entry = &htab->entries[index];
        if (!*entry)
                goto empty_entry;
-       else if ((*entry)->entry_point == ptr)
+       else if (eq_fn(*entry, ptr))
                return entry;
 
        hash2 = 1 + hash % (size - 2);
@@ -255,7 +250,7 @@ htab_find_slot(struct funcdesc_ht *htab, void *ptr, int 
insert)
                entry = &htab->entries[index];
                if (!*entry)
                        goto empty_entry;
-               else if ((*entry)->entry_point == ptr)
+               else if (eq_fn(*entry, ptr))
                        return entry;
        }
 
diff --git a/ldso/ldso/fdpic/dl-inlines.h b/ldso/ldso/fdpic/dl-inlines.h
index 46e4ba3..ebbd033 100644
--- a/ldso/ldso/fdpic/dl-inlines.h
+++ b/ldso/ldso/fdpic/dl-inlines.h
@@ -145,6 +145,20 @@ __dl_addr_in_loadaddr(void *p, struct elf32_fdpic_loadaddr 
loadaddr)
        return 0;
 }
 
+static int
+hash_pointer(void *p)
+{
+       return (int) ((long)p >> 3);
+}
+
+static int
+eq_pointer(void *p, void *q)
+{
+       struct funcdesc_value *entry = p;
+
+       return entry->entry_point == q;
+}
+
 void *
 _dl_funcdesc_for (void *entry_point, void *got_value)
 {
@@ -161,7 +175,7 @@ _dl_funcdesc_for (void *entry_point, void *got_value)
                tpnt->funcdesc_ht = ht;
        }
 
-       entry = htab_find_slot(ht, entry_point, 1);
+       entry = htab_find_slot(ht, entry_point, 1, hash_pointer, eq_pointer);
        if (*entry) {
                _dl_assert((*entry)->entry_point == entry_point);
                return _dl_stabilize_funcdesc(*entry);
@@ -196,7 +210,8 @@ _dl_lookup_address(void const *address)
                if (fd->got_value != rpnt->loadaddr.got_value)
                        continue;
 
-               address = htab_find_slot(rpnt->funcdesc_ht, (void 
*)fd->entry_point, 0);
+               address = htab_find_slot(rpnt->funcdesc_ht, (void 
*)fd->entry_point, 0,
+                               hash_pointer, eq_pointer);
 
                if (address && *(struct funcdesc_value *const*)address == fd) {
                        address = (*(struct funcdesc_value 
*const*)address)->entry_point;
-- 
1.8.4.rc3

_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to