#include <stdlib.h> #include <errno.h> #include "elfutils.h" unsigned long elf_hash(const unsigned char *name) { unsigned long h = 0; unsigned long g; while (*name) { h = (h << 4) + *name++; if ((g = h & 0xF0000000)) h ^= g >> 24; h &= ~g; } return h; } unsigned long elf_gnu_hash(const unsigned char *name) { unsigned long h = 5381; unsigned char c; for (c = *name; c != '\0'; c = *++name) { h = h * 33 + c; } return h & 0xFFFFFFFF; } #ifndef HAVE_ELF_POSIX_MEMALIGN struct memalign_info { void *start_addr; char data[0]; }; int elf_malloc(void **memptr, size_t alignment, size_t size) { char *start_addr = NULL; struct memalign_info *info; if ((alignment & (alignment - 1)) != 0) return EINVAL; if (alignment % sizeof(void*) != 0) alignment = sizeof(void*); start_addr = malloc(size + (alignment > sizeof(struct memalign_info) ? alignment : sizeof(struct memalign_info))); if (start_addr == NULL) return ENOMEM; info = (struct memalign_info*)(start_addr - ((unsigned long)start_addr % alignment) + alignment - sizeof(struct memalign_info)); info->start_addr = start_addr; *memptr = info->data; return 0; } void elf_free(char *memptr) { struct memalign_info *info = (struct memalign_info*)(memptr - sizeof(struct memalign_info)); free(info->start_addr); } #else int elf_malloc(void **memptr, size_t alignment, size_t size) { if ((alignment & (alignment - 1)) != 0) return EINVAL; if (alignment % sizeof(void*) != 0) alignment = sizeof(void*); return posix_memalign(memptr, alignment, size); } void elf_free(void *memptr) { free(memptr); } #endif //HAVE_ELF_POSIX_MEMALIGN