90 lines
1.6 KiB
C
90 lines
1.6 KiB
C
#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
|