From patchwork Wed Nov 6 09:23:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 288805 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from hemlock.osuosl.org (hemlock.osuosl.org [140.211.166.133]) by ozlabs.org (Postfix) with ESMTP id E8CE62C00C4 for ; Wed, 6 Nov 2013 20:27:13 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 9BFCC93117; Wed, 6 Nov 2013 09:27:12 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6aFM22jSdS97; Wed, 6 Nov 2013 09:27:11 +0000 (UTC) Received: from ash.osuosl.org (ash.osuosl.org [140.211.166.34]) by hemlock.osuosl.org (Postfix) with ESMTP id 5EDA5930F0; Wed, 6 Nov 2013 09:27:11 +0000 (UTC) X-Original-To: uclibc@lists.busybox.net Delivered-To: uclibc@osuosl.org Received: from hemlock.osuosl.org (hemlock.osuosl.org [140.211.166.133]) by ash.osuosl.org (Postfix) with ESMTP id 6E09F1BFA6A for ; Wed, 6 Nov 2013 09:27:09 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by hemlock.osuosl.org (Postfix) with ESMTP id 69314930F0 for ; Wed, 6 Nov 2013 09:27:09 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from hemlock.osuosl.org ([127.0.0.1]) by localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1-1eVIMBgq1Y for ; Wed, 6 Nov 2013 09:27:06 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from tango.tkos.co.il (tango.tkos.co.il [62.219.50.35]) by hemlock.osuosl.org (Postfix) with ESMTPS id 7385F930DD for ; Wed, 6 Nov 2013 09:27:06 +0000 (UTC) Received: from tarshish.tkos.co.il (80.179.12.157.static.012.net.il [80.179.12.157]) (authenticated bits=0) by tango.tkos.co.il (8.14.4/8.12.11) with ESMTP id rA69NPqg017685; Wed, 6 Nov 2013 11:23:31 +0200 From: Baruch Siach To: uclibc@uclibc.org Subject: [PATCH 2/2] ldso: make hashcode handling more generic Date: Wed, 6 Nov 2013 11:23:06 +0200 Message-Id: <1f3a9aacda749bd59246003a9d9590a9889f9dbe.1383729687.git.baruch@tkos.co.il> X-Mailer: git-send-email 1.8.4.rc3 In-Reply-To: References: X-Scanned-By: MIMEDefang 2.62 on 62.219.50.35 X-BeenThere: uclibc@uclibc.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Discussion and development of uClibc \(the embedded C library\)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: uclibc-bounces@uclibc.org Sender: uclibc-bounces@uclibc.org 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 Signed-off-by: Baruch Siach --- 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;