diff --git a/libkmod/libkmod-hash.c b/libkmod/libkmod-hash.c index f58e9db..8f647b4 100644 --- a/libkmod/libkmod-hash.c +++ b/libkmod/libkmod-hash.c @@ -83,6 +83,10 @@ void hash_free(struct hash *hash) free(hash); } +struct unaligned_short { + unsigned short v; +} __attribute__((packed)); + static inline unsigned int hash_superfast(const char *key, unsigned int len) { /* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html) @@ -90,14 +94,14 @@ static inline unsigned int hash_superfast(const char *key, unsigned int len) * EFL's eina and possible others. */ unsigned int tmp, hash = len, rem = len & 3; - const unsigned short *itr = (const unsigned short *)key; + const struct unaligned_short *itr = (const unsigned short *)key; len /= 4; /* Main loop */ for (; len > 0; len--) { - hash += itr[0]; - tmp = (itr[1] << 11) ^ hash; + hash += itr[0].v; + tmp = (itr[1].v << 11) ^ hash; hash = (hash << 16) ^ tmp; itr += 2; hash += hash >> 11; @@ -106,14 +110,14 @@ static inline unsigned int hash_superfast(const char *key, unsigned int len) /* Handle end cases */ switch (rem) { case 3: - hash += *itr; + hash += itr->v; hash ^= hash << 16; hash ^= key[2] << 18; hash += hash >> 11; break; case 2: - hash += *itr; + hash += itr->v; hash ^= hash << 11; hash += hash >> 17; break; @@ -243,6 +247,7 @@ void *hash_find(const struct hash *hash, const char *key) if (entry == NULL) return NULL; return (void *)entry->value; + } int hash_del(struct hash *hash, const char *key)