/*
Patchdiff2
Portions (C) 2010 - 2011 Nicolas Pouvesle
Portions (C) 2007 - 2009 Tenable Network Security, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "precomp.hpp"
#include "hash.hpp"
#include "sig.hpp"
/*------------------------------------------------*/
/* function : hash_init */
/* description: Initializes hash table to NULL */
/*------------------------------------------------*/
hpsig_t * hash_init(size_t num)
{
unsigned int i;
hpsig_t * hsig;
static unsigned int primes[] = { 67, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 2097143 };
for (i=0; i < ((sizeof(primes) / sizeof(unsigned int)) - 1); i++)
if (primes[i] > (num/3)) break;
hsig = (hpsig_t *)qalloc(sizeof(*hsig));
if (!hsig) return NULL;
hsig->max_hash = primes[i];
hsig->table = (hsignature_t **) qalloc(hsig->max_hash * sizeof(*hsig->table));
if (!hsig->table)
{
qfree(hsig);
return NULL;
}
for (i = 0; i < hsig->max_hash; i++)
hsig->table[i] = NULL;
return hsig;
}
/*------------------------------------------------*/
/* function : hash_mk_ea */
/* description: Creates hash value */
/*------------------------------------------------*/
unsigned int hash_mk_ea(hpsig_t * htable, ea_t val)
{
char * ptr;
unsigned int h = 0;
int i;
ptr = (char *) &val;
for (i=0; i> 6 );
}
h += ( h << 3);
h ^= ( h >> 11 );
h += ( h >> 15 );
return h % htable->max_hash;
}
/*------------------------------------------------*/
/* function : hash_add_ea */
/* description: Adds element to the hash table */
/*------------------------------------------------*/
int hash_add_ea (hpsig_t * htable, psig_t * sig)
{
int id = hash_mk_ea(htable, sig->startEA);
hsignature_t * hsig = NULL;
hsig = (hsignature_t *)qalloc(sizeof(*hsig));
if (!hsig) return -1;
hsig->sig = sig;
hsig->next = htable->table[id];
htable->table[id] = hsig;
return 0;
}
/*------------------------------------------------*/
/* function : hash_find_ea */
/* description: Finds element in the hash table */
/*------------------------------------------------*/
psig_t * hash_find_ea (hpsig_t * htable, ea_t ea)
{
if (ea == BADADDR)
return NULL;
int id = hash_mk_ea(htable, ea);
hsignature_t * hsig;
hsig = htable->table[id];
while (hsig != NULL)
{
if (hsig->sig->startEA == ea)
return hsig->sig;
hsig = hsig->next;
}
return NULL;
}
/*------------------------------------------------*/
/* function : hash_free */
/* description: Frees hash table */
/*------------------------------------------------*/
void hash_free (hpsig_t * htable)
{
unsigned int i;
hsignature_t * hsig, * tmp;
for (i = 0; i < htable->max_hash; i++)
{
hsig = htable->table[i];
while (hsig != NULL)
{
tmp = hsig->next;
qfree (hsig);
hsig = tmp;
}
}
qfree(htable);
}