In Vulkan loader GetProcAddr handlers, for functions that are
not specified in the Vulkan registry, the loader will try loading
the name from ICDs or layers, and store the function entry into
a hashtable. The hashtable uses |murmurhash()| function to hash
Vulkan function names.
murmurhash handles data as 4-byte chunks and read one chunk at a
time; and it simply converts uint8_t pointers to uint32_t pointers
while loading data. However, the address of function name might
not be 32-bit aligned and this will cause an undefined behavior in
C99 / C11.
This change fixes the murmurhash() behavior so that it handles
unaligned access correctly. For most common platforms that supports
unaligned memory access this could compile into a single mov/load
instruction even if compiling using -O0.
Change-Id: I16011720198a0ee96e556855858a9909f95ec376
#include "murmurhash.h"
+#include <memory.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
uint32_t h = 0;
uint32_t k = 0;
uint8_t *d = (uint8_t *)key; // 32 bit extract from `key'
- const uint32_t *chunks = NULL;
+ const uint8_t *chunks = NULL;
const uint8_t *tail = NULL; // tail - last 8 bytes
int i = 0;
int l = (int)len / 4; // chunk length
h = seed;
- chunks = (const uint32_t *)(d + l * 4); // body
+ chunks = (const uint8_t *)(d + l * 4); // body
tail = (const uint8_t *)(d + l * 4); // last 8 byte chunk of `key'
// for each 4 byte chunk of `key'
for (i = -l; i != 0; ++i) {
// next 4 byte chunk of `key'
- k = chunks[i];
+ memcpy(&k, chunks + i * 4, sizeof(k));
// encode next 4 byte chunk of `key'
k *= c1;