Exemple #1
0
static inline
void compute_exported_hash(const struct elf_info *elf, enum ksymtab_type tp)
{

	struct kernel_symbol *sym;
	struct kernel_symbol *start = elf->ksym_tables[tp].start;
	struct kernel_symbol *stop = elf->ksym_tables[tp].stop;

	for (sym = start; sym < stop; sym++)
		sym->hash_value = gnu_hash(GET_KSTRING(sym, elf->kstr_offset));
}
static int fill_hashtable(struct elf_htable *htable,
			struct kernel_symbol *start,
			struct kernel_symbol *stop,
			long s_offset)
{
	struct kernel_symbol *ksym;
	uint32_t nb;
	unsigned long hvalue;
	int last_chain_slot;

	/* sanity check */
	if ((htable->elf_buckets == NULL) || (htable->chains == NULL))
		return -1;
	/* Initialize buckets and chains with -1 that means empty */
	memset(htable->elf_buckets, -1, htable->nbucket * sizeof(uint32_t));
	memset(htable->chains, -1, htable->nchain * sizeof(uint32_t));

	nb = htable->nbucket;
	for (ksym = start, hvalue = 0; ksym < stop; ksym++, hvalue++) {
		const unsigned char *name = GET_KSTRING(ksym, s_offset);
		unsigned long h = gnu_hash(name);
		unsigned long idx = h % nb;
		uint32_t *slot = &htable->elf_buckets[idx];

		/*
		 * Store the index of the export symbol ksym in its
		 * related __ksymtable in the hash table buckets for
		 * using during lookup.
		 * If the slot is alredy used ( != -1) then we have a collision
		 * it needs to create an entry in the chain
		 */
		 if (*slot == EMPTY_SLOT)
			*slot = hvalue;
		else {
			if (handle_collision(htable, *slot, hvalue) < 0)
			/* Something wrong happened */
				return -1;
		}
	}
	/*
	 * Update the chain lenght with the best value
	 * so that we will cut unused entries beyond this upper limit
	 * In the best case, when there are not collisions, htable->chains
	 * will be 0 size... good !
	 */
	/* Look for upper chains empty slot */
	for (last_chain_slot = htable->nchain; --last_chain_slot >= 0 &&
		htable->chains[last_chain_slot] == EMPTY_SLOT;);

	htable->nchain = last_chain_slot + 1;
	debugp("\t> Shortest chain lenght = %d\n", htable->nchain);
	return 0;
}